diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json new file mode 100644 index 000000000000..cadf2fb312eb --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet1": { + "default_brkout_mode": "1x200G" + }, + "Ethernet5": { + "default_brkout_mode": "1x200G" + }, + "Ethernet9": { + "default_brkout_mode": "1x200G" + }, + "Ethernet13": { + "default_brkout_mode": "1x200G" + }, + "Ethernet17": { + "default_brkout_mode": "1x200G" + }, + "Ethernet21": { + "default_brkout_mode": "1x200G" + }, + "Ethernet25": { + "default_brkout_mode": "1x200G" + }, + "Ethernet29": { + "default_brkout_mode": "1x200G" + }, + "Ethernet33": { + "default_brkout_mode": "1x200G" + }, + "Ethernet37": { + "default_brkout_mode": "1x200G" + }, + "Ethernet41": { + "default_brkout_mode": "1x200G" + }, + "Ethernet45": { + "default_brkout_mode": "1x200G" + }, + "Ethernet49": { + "default_brkout_mode": "1x200G" + }, + "Ethernet53": { + "default_brkout_mode": "1x200G" + }, + "Ethernet57": { + "default_brkout_mode": "1x200G" + }, + "Ethernet61": { + "default_brkout_mode": "1x200G" + }, + "Ethernet65": { + "default_brkout_mode": "1x200G" + }, + "Ethernet69": { + "default_brkout_mode": "1x200G" + }, + "Ethernet73": { + "default_brkout_mode": "1x200G" + }, + "Ethernet77": { + "default_brkout_mode": "1x200G" + }, + "Ethernet81": { + "default_brkout_mode": "1x200G" + }, + "Ethernet85": { + "default_brkout_mode": "1x200G" + }, + "Ethernet89": { + "default_brkout_mode": "1x200G" + }, + "Ethernet93": { + "default_brkout_mode": "1x200G" + }, + "Ethernet97": { + "default_brkout_mode": "1x400G" + }, + "Ethernet105": { + "default_brkout_mode": "1x400G" + }, + "Ethernet113": { + "default_brkout_mode": "1x400G" + }, + "Ethernet121": { + "default_brkout_mode": "1x400G" + }, + "Ethernet129": { + "default_brkout_mode": "1x400G" + }, + "Ethernet137": { + "default_brkout_mode": "1x400G" + }, + "Ethernet145": { + "default_brkout_mode": "1x400G" + }, + "Ethernet153": { + "default_brkout_mode": "1x400G" + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini new file mode 100644 index 000000000000..1a166a9a8367 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet1 25,26,27,28 twoHundredGigE0/1 0 200000 +Ethernet5 29,30,31,32 twoHundredGigE0/2 1 200000 +Ethernet9 41,42,43,44 twoHundredGigE0/3 2 200000 +Ethernet13 45,46,47,48 twoHundredGigE0/4 3 200000 +Ethernet17 49,50,51,52 twoHundredGigE0/5 4 200000 +Ethernet21 53,54,55,56 twoHundredGigE0/6 5 200000 +Ethernet25 57,58,59,60 twoHundredGigE0/7 6 200000 +Ethernet29 61,62,63,64 twoHundredGigE0/8 7 200000 +Ethernet33 9,10,11,12 twoHundredGigE0/9 8 200000 +Ethernet37 13,14,15,16 twoHundredGigE0/10 9 200000 +Ethernet41 17,18,19,20 twoHundredGigE0/11 10 200000 +Ethernet45 21,22,23,24 twoHundredGigE0/12 11 200000 +Ethernet49 81,82,83,84 twoHundredGigE0/13 12 200000 +Ethernet53 85,86,87,88 twoHundredGigE0/14 13 200000 +Ethernet57 89,90,91,92 twoHundredGigE0/15 14 200000 +Ethernet61 93,94,95,96 twoHundredGigE0/16 15 200000 +Ethernet65 97,98,99,100 twoHundredGigE0/17 16 200000 +Ethernet69 101,102,103,104 twoHundredGigE0/18 17 200000 +Ethernet73 137,138,139,140 twoHundredGigE0/19 18 200000 +Ethernet77 141,142,143,144 twoHundredGigE0/20 19 200000 +Ethernet81 145,146,147,148 twoHundredGigE0/21 20 200000 +Ethernet85 149,150,151,152 twoHundredGigE0/22 21 200000 +Ethernet89 153,154,155,156 twoHundredGigE0/23 22 200000 +Ethernet93 157,158,159,160 twoHundredGigE0/24 23 200000 +Ethernet97 1,2,3,4,5,6,7,8 fourHundredGigE0/1 24 400000 +Ethernet105 33,34,35,36,37,38,39,40 fourHundredGigE0/2 25 400000 +Ethernet113 65,66,67,68,69,70,71,72 fourHundredGigE0/3 26 400000 +Ethernet121 73,74,75,76,77,78,79,80 fourHundredGigE0/4 27 400000 +Ethernet129 105,106,107,108,109,110,111,112 fourHundredGigE0/5 28 400000 +Ethernet137 113,114,115,116,117,118,119,120 fourHundredGigE0/6 29 400000 +Ethernet145 121,122,123,124,125,126,127,128 fourHundredGigE0/7 30 400000 +Ethernet153 129,130,131,132,133,134,135,136 fourHundredGigE0/8 31 400000 diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile new file mode 100644 index 000000000000..4b3cbf7154af --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml new file mode 100644 index 000000000000..8a7c7a7e9fbc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml @@ -0,0 +1,4114 @@ +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + pktio_mode: 1 + warmboot_knet_shutdown_mode: 1 + sai_optimized_mmu: 1 + sai_pfc_defaults_disable: 1 + sai_postinit_cmd_file: /usr/share/sonic/platform/postinit_cmd_file.soc +... + +--- +bcm_device: + 0: + port: + 11: + dport_map_port: 1 + 12: + dport_map_port: 2 + 13: + dport_map_port: 3 + 14: + dport_map_port: 4 + 20: + dport_map_port: 5 + 21: + dport_map_port: 6 + 22: + dport_map_port: 7 + 23: + dport_map_port: 8 + 24: + dport_map_port: 9 + 25: + dport_map_port: 10 + 26: + dport_map_port: 11 + 27: + dport_map_port: 12 + 28: + dport_map_port: 13 + 29: + dport_map_port: 14 + 30: + dport_map_port: 15 + 31: + dport_map_port: 16 + 3: + dport_map_port: 17 + 4: + dport_map_port: 18 + 5: + dport_map_port: 19 + 6: + dport_map_port: 20 + 7: + dport_map_port: 21 + 8: + dport_map_port: 22 + 9: + dport_map_port: 23 + 10: + dport_map_port: 24 + 40: + dport_map_port: 25 + 41: + dport_map_port: 26 + 42: + dport_map_port: 27 + 43: + dport_map_port: 28 + 44: + dport_map_port: 29 + 45: + dport_map_port: 30 + 46: + dport_map_port: 31 + 47: + dport_map_port: 32 + 48: + dport_map_port: 33 + 49: + dport_map_port: 34 + 50: + dport_map_port: 35 + 51: + dport_map_port: 36 + 64: + dport_map_port: 37 + 65: + dport_map_port: 38 + 66: + dport_map_port: 39 + 67: + dport_map_port: 40 + 68: + dport_map_port: 41 + 69: + dport_map_port: 42 + 70: + dport_map_port: 43 + 71: + dport_map_port: 44 + 72: + dport_map_port: 45 + 73: + dport_map_port: 46 + 74: + dport_map_port: 47 + 75: + dport_map_port: 48 + 1: + dport_map_port: 49 + 2: + dport_map_port: 50 + 15: + dport_map_port: 51 + 16: + dport_map_port: 52 + 32: + dport_map_port: 53 + 33: + dport_map_port: 54 + 34: + dport_map_port: 55 + 35: + dport_map_port: 56 + 52: + dport_map_port: 57 + 53: + dport_map_port: 58 + 54: + dport_map_port: 59 + 55: + dport_map_port: 60 + 60: + dport_map_port: 61 + 61: + dport_map_port: 62 + 62: + dport_map_port: 63 + 63: + dport_map_port: 64 +... + +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73510624 + RX_LANE_MAP: 0x46270513 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52317046 + RX_LANE_MAP: 0x31247056 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x47 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25047361 + RX_LANE_MAP: 0x10452736 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45673210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0x4a + RX_POLARITY_FLIP: 0xf3 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02476531 + RX_LANE_MAP: 0x05261734 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37065241 + RX_LANE_MAP: 0x04175263 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54762301 + RX_LANE_MAP: 0x13025467 + TX_POLARITY_FLIP: 0x70 + RX_POLARITY_FLIP: 0x6f + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73125046 + RX_LANE_MAP: 0x21437056 + TX_POLARITY_FLIP: 0x78 + RX_POLARITY_FLIP: 0x5c + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32104567 + RX_LANE_MAP: 0x64572310 + TX_POLARITY_FLIP: 0xd6 + RX_POLARITY_FLIP: 0xad + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03172465 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36175042 + RX_LANE_MAP: 0x04176253 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74615203 + RX_LANE_MAP: 0x51704236 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x56 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26374051 + RX_LANE_MAP: 0x37046251 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45672310 + RX_LANE_MAP: 0x32105476 + TX_POLARITY_FLIP: 0x15 + RX_POLARITY_FLIP: 0x92 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70465321 + RX_LANE_MAP: 0x63107542 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015476 + RX_LANE_MAP: 0x64752301 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x6c +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 5 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 7 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 9 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 11 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 24 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 26 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 28 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 85 + ? + PORT_ID: 44 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 46 + : + PC_PHYS_PORT_ID: 93 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 101 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 64 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 141 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 70 + : + PC_PHYS_PORT_ID: 149 + ? + PORT_ID: 72 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 74 + : + PC_PHYS_PORT_ID: 157 + +... + +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [3, 5, 7, 9, 11, 13, + 20, 22, 24, 26, 28, 30, + 40, 42, 44, 46, 48, 50, + 64, 66, 68, 70, 72, 74] + : + ENABLE: 0 + SPEED: 200000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 4 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [1, 15, 32, 34, 52, 54, 60, 62] + : + ENABLE: 0 + SPEED: 400000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 8 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +device: + 0: + PC_TX_TAPS: + ? + PORT_ID: 11 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 26 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 28 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 30 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 30 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 30 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 30 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 3 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 7 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 9 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 40 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 40 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 40 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 40 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 42 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 42 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 42 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 42 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 44 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 46 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 48 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 50 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 50 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 50 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 50 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 +... diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml new file mode 100644 index 000000000000..779f4b79d1b9 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml @@ -0,0 +1,4125 @@ +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 0 + shared_block_mask_section: uc_bc + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + svi_my_station_optimization: 1 + sai_nbr_bcast_ifp_optimized: 2 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + pktio_mode: 1 + sai_optimized_mmu: 1 + sai_pfc_defaults_disable: 1 + warmboot_knet_shutdown_mode: 1 + sai_postinit_cmd_file: /usr/share/sonic/platform/postinit_cmd_file.soc +... + +--- +device: + 0: + FP_CONFIG: + #FP_ING_OPERMODE: PIPE_UNIQUE + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + 11: + dport_map_port: 1 + 12: + dport_map_port: 2 + 13: + dport_map_port: 3 + 14: + dport_map_port: 4 + 20: + dport_map_port: 5 + 21: + dport_map_port: 6 + 22: + dport_map_port: 7 + 23: + dport_map_port: 8 + 24: + dport_map_port: 9 + 25: + dport_map_port: 10 + 26: + dport_map_port: 11 + 27: + dport_map_port: 12 + 28: + dport_map_port: 13 + 29: + dport_map_port: 14 + 30: + dport_map_port: 15 + 31: + dport_map_port: 16 + 3: + dport_map_port: 17 + 4: + dport_map_port: 18 + 5: + dport_map_port: 19 + 6: + dport_map_port: 20 + 7: + dport_map_port: 21 + 8: + dport_map_port: 22 + 9: + dport_map_port: 23 + 10: + dport_map_port: 24 + 40: + dport_map_port: 25 + 41: + dport_map_port: 26 + 42: + dport_map_port: 27 + 43: + dport_map_port: 28 + 44: + dport_map_port: 29 + 45: + dport_map_port: 30 + 46: + dport_map_port: 31 + 47: + dport_map_port: 32 + 48: + dport_map_port: 33 + 49: + dport_map_port: 34 + 50: + dport_map_port: 35 + 51: + dport_map_port: 36 + 64: + dport_map_port: 37 + 65: + dport_map_port: 38 + 66: + dport_map_port: 39 + 67: + dport_map_port: 40 + 68: + dport_map_port: 41 + 69: + dport_map_port: 42 + 70: + dport_map_port: 43 + 71: + dport_map_port: 44 + 72: + dport_map_port: 45 + 73: + dport_map_port: 46 + 74: + dport_map_port: 47 + 75: + dport_map_port: 48 + 1: + dport_map_port: 49 + 2: + dport_map_port: 50 + 15: + dport_map_port: 51 + 16: + dport_map_port: 52 + 32: + dport_map_port: 53 + 33: + dport_map_port: 54 + 34: + dport_map_port: 55 + 35: + dport_map_port: 56 + 52: + dport_map_port: 57 + 53: + dport_map_port: 58 + 54: + dport_map_port: 59 + 55: + dport_map_port: 60 + 60: + dport_map_port: 61 + 61: + dport_map_port: 62 + 62: + dport_map_port: 63 + 63: + dport_map_port: 64 +... + +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73510624 + RX_LANE_MAP: 0x46270513 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52317046 + RX_LANE_MAP: 0x31247056 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x47 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25047361 + RX_LANE_MAP: 0x10452736 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45673210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0x4a + RX_POLARITY_FLIP: 0xf3 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02476531 + RX_LANE_MAP: 0x05261734 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37065241 + RX_LANE_MAP: 0x04175263 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54762301 + RX_LANE_MAP: 0x13025467 + TX_POLARITY_FLIP: 0x70 + RX_POLARITY_FLIP: 0x6f + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73125046 + RX_LANE_MAP: 0x21437056 + TX_POLARITY_FLIP: 0x78 + RX_POLARITY_FLIP: 0x5c + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32104567 + RX_LANE_MAP: 0x64572310 + TX_POLARITY_FLIP: 0xd6 + RX_POLARITY_FLIP: 0xad + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03172465 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36175042 + RX_LANE_MAP: 0x04176253 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74615203 + RX_LANE_MAP: 0x51704236 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x56 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26374051 + RX_LANE_MAP: 0x37046251 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45672310 + RX_LANE_MAP: 0x32105476 + TX_POLARITY_FLIP: 0x15 + RX_POLARITY_FLIP: 0x92 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70465321 + RX_LANE_MAP: 0x63107542 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015476 + RX_LANE_MAP: 0x64752301 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x6c +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 5 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 7 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 9 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 11 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 24 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 26 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 28 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 85 + ? + PORT_ID: 44 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 46 + : + PC_PHYS_PORT_ID: 93 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 101 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 64 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 141 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 70 + : + PC_PHYS_PORT_ID: 149 + ? + PORT_ID: 72 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 74 + : + PC_PHYS_PORT_ID: 157 + +... + +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [3, 5, 7, 9, 11, 13, + 20, 22, 24, 26, 28, 30, + 40, 42, 44, 46, 48, 50, + 64, 66, 68, 70, 72, 74] + : + ENABLE: 0 + SPEED: 200000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 4 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [1, 15, 32, 34, 52, 54, 60, 62] + : + ENABLE: 0 + SPEED: 400000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 8 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +device: + 0: + PC_TX_TAPS: + ? + PORT_ID: 11 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 14 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 16 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 16 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 148 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 124 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 124 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 +... diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint new file mode 100644 index 000000000000..e286d3cf42a6 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint @@ -0,0 +1,85 @@ +cint_reset(); + +int cint_field_group_create(int unit, bcm_field_group_t grp) +{ + int rv; + + bcm_field_qset_t qset; + bcm_field_aset_t aset; + + BCM_FIELD_QSET_INIT(qset); + BCM_FIELD_QSET_ADD(qset,bcmFieldQualifyDstMac); + BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageIngress); + + BCM_FIELD_ASET_INIT(aset); + BCM_FIELD_ASET_ADD(aset, bcmFieldActionCopyToCpu); + + rv = bcm_field_group_create_mode_id(unit, qset, 103, bcmFieldGroupModeAuto, grp); + if (rv != BCM_E_NONE) { + printf("bcm_field_group_create_mode_id failed, rv = %d\r\n", rv); + return -1; + } + printf("cint_field_group_create success!!!, rv = %d\r\n", rv); + + bcm_field_group_dump(unit,grp); + return 0; +} + +int cint_field_entry_create1(int unit, bcm_field_group_t grp,bcm_field_entry_t entry) +{ + int rv; + bcm_mac_t dst_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + bcm_mac_t mac_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + rv = bcm_field_entry_create_id(unit, grp, entry); + if (rv != BCM_E_NONE) { + printf("bcm_field_entry_create_id failed, rv = %d\r\n", rv); + return -1; + } + + + rv =bcm_field_qualify_DstMac(unit, entry, dst_mac, mac_mask); + if (rv != BCM_E_NONE) { + printf("bcm_field_qualify_DstMac failed,ret = %d\r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 1, 0); + if (rv != BCM_E_NONE) { + printf("bcm_field_action_add failed, rv = %d \r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_action_add(unit, entry, bcmFieldActionDrop, 1, 0); + if (rv != BCM_E_NONE) { + printf("bcm_field_action_add failed, rv = %d \r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_entry_install(unit, entry); + if (rv != BCM_E_NONE) { + printf("bcm_field_entry_install failed,ret = %d\r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + printf("********************* BEGIN ****************************\r\n"); + bcm_field_entry_dump(unit, entry); + printf("*********************** END ****************************\r\n"); + + return 0; +} + +cint_field_group_create(0,5); +cint_field_entry_create1(0,5,2048); + +//bcm_field_entry_destroy(0, 2048); +//bcm_field_group_destroy(0, 5); + + + + + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin new file mode 100644 index 000000000000..b3185be90620 Binary files /dev/null and b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin differ diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/default_sku b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/default_sku new file mode 100644 index 000000000000..afadd24f36c5 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/default_sku @@ -0,0 +1 @@ +M2-W6520-24DC8QC l2 diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/dev.xml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/dev.xml new file mode 100644 index 000000000000..e71ddf3237b3 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/dev.xml @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py new file mode 100644 index 000000000000..f95164e03601 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json new file mode 100644 index 000000000000..cadf2fb312eb --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet1": { + "default_brkout_mode": "1x200G" + }, + "Ethernet5": { + "default_brkout_mode": "1x200G" + }, + "Ethernet9": { + "default_brkout_mode": "1x200G" + }, + "Ethernet13": { + "default_brkout_mode": "1x200G" + }, + "Ethernet17": { + "default_brkout_mode": "1x200G" + }, + "Ethernet21": { + "default_brkout_mode": "1x200G" + }, + "Ethernet25": { + "default_brkout_mode": "1x200G" + }, + "Ethernet29": { + "default_brkout_mode": "1x200G" + }, + "Ethernet33": { + "default_brkout_mode": "1x200G" + }, + "Ethernet37": { + "default_brkout_mode": "1x200G" + }, + "Ethernet41": { + "default_brkout_mode": "1x200G" + }, + "Ethernet45": { + "default_brkout_mode": "1x200G" + }, + "Ethernet49": { + "default_brkout_mode": "1x200G" + }, + "Ethernet53": { + "default_brkout_mode": "1x200G" + }, + "Ethernet57": { + "default_brkout_mode": "1x200G" + }, + "Ethernet61": { + "default_brkout_mode": "1x200G" + }, + "Ethernet65": { + "default_brkout_mode": "1x200G" + }, + "Ethernet69": { + "default_brkout_mode": "1x200G" + }, + "Ethernet73": { + "default_brkout_mode": "1x200G" + }, + "Ethernet77": { + "default_brkout_mode": "1x200G" + }, + "Ethernet81": { + "default_brkout_mode": "1x200G" + }, + "Ethernet85": { + "default_brkout_mode": "1x200G" + }, + "Ethernet89": { + "default_brkout_mode": "1x200G" + }, + "Ethernet93": { + "default_brkout_mode": "1x200G" + }, + "Ethernet97": { + "default_brkout_mode": "1x400G" + }, + "Ethernet105": { + "default_brkout_mode": "1x400G" + }, + "Ethernet113": { + "default_brkout_mode": "1x400G" + }, + "Ethernet121": { + "default_brkout_mode": "1x400G" + }, + "Ethernet129": { + "default_brkout_mode": "1x400G" + }, + "Ethernet137": { + "default_brkout_mode": "1x400G" + }, + "Ethernet145": { + "default_brkout_mode": "1x400G" + }, + "Ethernet153": { + "default_brkout_mode": "1x400G" + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf new file mode 100644 index 000000000000..7a9fec8cc99c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_idle.max_cstate=0 idle=poll" \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json new file mode 100644 index 000000000000..1d7f598d2fe8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json @@ -0,0 +1,1476 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff2", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "1": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "2": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "3": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "4": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "5": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "6": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "7": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "8": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "9": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "10": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "11": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "12": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "13": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "14": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "15": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "16": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "17": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "18": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "19": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "20": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff0", + "lane2": "0xfffffff8", + "lane3": "0xfffffff0" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "21": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "22": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "23": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "24": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000094", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000088", + "lane5": "0x00000090", + "lane6": "0x0000007C", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0x00000000", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "25": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "26": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000088", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "27": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "28": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "29": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "30": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000084", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "31": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000088", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x0000007C", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py new file mode 100644 index 000000000000..5fc287892e50 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py @@ -0,0 +1,402 @@ +#!/usr/bin/python3 +# * onboard temperature sensors +# * FAN trays +# * PSU +# +import os +from lxml import etree as ET +import glob +import json +from decimal import Decimal +from fru import ipmifru + + +MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + +CONFIG_NAME = "dev.xml" + + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) + try: + with open(location, 'r') as fd: + retval = fd.read() + except Exception as error: + return "ERR %s" % str(error) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +# Get a mailbox register +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'rb') as fd: + retval = fd.read() + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +class checktype(): + def __init__(self, test1): + self.test1 = test1 + + @staticmethod + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU + @staticmethod + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru + + @staticmethod + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name.strip() == psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) + + +class status(): + def __init__(self, productname): + self.productname = productname + + @staticmethod + def getETroot(filename): + tree = ET.parse(filename) + root = tree.getroot() + return root + + @staticmethod + def getDecodValue(collection, decode): + decodes = collection.find('decode') + testdecode = decodes.find(decode) + test = {} + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): + test[neighbor.attrib["key"]] = neighbor.attrib["value"] + return test + + @staticmethod + def getfileValue(location): + return checktype.getValue(location, " ", " ") + + @staticmethod + def getETValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + prob_t = {} + prob_t.update(neighbor.attrib) + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' + for pros in neighbor.iter("property"): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" + else: + val = ret["type"] + if 'bit' not in ret.keys(): + bit = "0" + else: + bit = ret["bit"] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] + if str(s) != ret["default"]: + prob_t['errcode'] = -1 + break + else: + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) + else: + s = rt[str(s).replace("\x00", "").rstrip()] + name = ret["name"] + prob_t[name] = str(s) + a.append(prob_t) + + @staticmethod + def getCPUValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + location = neighbor.attrib["location"] + L = [] + for dirpath, dirnames, filenames in os.walk(location): + for file in filenames: + if file.endswith("input"): + L.append(os.path.join(dirpath, file)) + L = sorted(L, reverse=False) + for i in range(len(L)): + prob_t = {} + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 + a.append(prob_t) + + @staticmethod + def getFileName(): + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + + @staticmethod + def checkFan(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "fan" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getTemp(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "temp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getPsu(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "psu" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getcputemp(ret): + _filename = status.getFileName() + _tagname = "cpus" + status.getCPUValue(ret, _filename, _tagname) + + @staticmethod + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml new file mode 100644 index 000000000000..ee025879f7f8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml @@ -0,0 +1,581 @@ +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- bus: '00' + dev: '02' + fn: '3' + id: 6f07 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 05)' +- 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 05)' +- bus: '00' + dev: '03' + fn: '1' + id: 6f09 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- 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 05)' +- bus: '00' + dev: '03' + fn: '3' + id: 6f0b + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- bus: '00' + dev: '04' + fn: '0' + id: 6f20 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 0 (rev 05)' +- bus: '00' + dev: '04' + fn: '1' + id: 6f21 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 1 (rev 05)' +- bus: '00' + dev: '04' + fn: '2' + id: 6f22 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 2 (rev 05)' +- bus: '00' + dev: '04' + fn: '3' + id: 6f23 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 3 (rev 05)' +- bus: '00' + dev: '04' + fn: '4' + id: 6f24 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 4 (rev 05)' +- bus: '00' + dev: '04' + fn: '5' + id: 6f25 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 5 (rev 05)' +- bus: '00' + dev: '04' + fn: '6' + id: 6f26 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 6 (rev 05)' +- bus: '00' + dev: '04' + fn: '7' + id: 6f27 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 7 (rev 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 + 05)' +- bus: '00' + dev: '05' + fn: '6' + id: 6f39 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IO Performance Monitoring (rev 05)' +- bus: '00' + dev: '06' + fn: '0' + id: 6f10 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '1' + id: 6f11 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '2' + id: 6f12 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '3' + id: 6f13 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '4' + id: 6f14 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '5' + id: 6f15 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '6' + id: 6f16 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '7' + id: 6f17 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '0' + id: 6f18 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '1' + id: 6f19 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '2' + id: 6f1a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '3' + id: 6f1b + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '4' + id: 6f1c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- 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: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- 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: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '06' + dev: '00' + fn: '0' + id: b780 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b780 (rev 01)' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7011' + name: 'Memory controller: Xilinx Corporation Device 7011' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- bus: ff + dev: '12' + fn: '2' + id: 6f70 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 Debug (rev 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- 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 05)' +- bus: ff + dev: 1e + fn: '7' + id: 6f9f + name: 'System peripheral: Intel Corporation Device 6f9f (rev 05)' +- 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 05)' +- 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 05)' diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json new file mode 100644 index 000000000000..d22eee94c31b --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json @@ -0,0 +1,1010 @@ +{ + "chassis": { + "name": "M2-W6520-24DC8QC", + "thermal_manager": false, + "status_led": { + "controllable": false, + "colors": [ + "green", + "blinking_green", + "amber", + "blinking_amber" + ] + }, + "components": [ + { + "name": "CPU_CPLD" + }, + { + "name": "CONNECT_CPLD" + }, + { + "name": "MAC_CPLDA" + }, + { + "name": "MAC_CPLDB" + }, + { + "name": "FAN_CPLD" + }, + { + "name": "FPGA" + }, + { + "name": "BIOS" + } + ], + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray5_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray5_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray6_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray6_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + } + ], + "fan_drawers": [ + { + "name": "Fantray1", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray2", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray3", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray4", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray5", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray5_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray5_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray6", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray6_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray6_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "psus": [ + { + "name": "Psu1", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU1_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Psu2", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU2_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "thermals": [ + { + "name": "BOARD_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "CPU_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "INLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "OUTLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "ASIC_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU1_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU2_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + } + ], + "modules": [], + "sfps": [] + }, + "interfaces": { + "Ethernet1": { + "index": "0,0,0,0", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x200G": [ + "Eth1" + ], + "2x100G": [ + "Eth1/1", + "Eth1/2" + ] + } + }, + "Ethernet5": { + "index": "1,1,1,1", + "lanes": "29,30,31,32", + "breakout_modes": { + "1x200G": [ + "Eth2" + ], + "2x100G": [ + "Eth2/1", + "Eth2/2" + ] + } + }, + "Ethernet9": { + "index": "2,2,2,2", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x200G": [ + "Eth3" + ], + "2x100G": [ + "Eth3/1", + "Eth3/2" + ] + } + }, + "Ethernet13": { + "index": "3,3,3,3", + "lanes": "45,46,47,48", + "breakout_modes": { + "1x200G": [ + "Eth4" + ], + "2x100G": [ + "Eth4/1", + "Eth4/2" + ] + } + }, + "Ethernet17": { + "index": "4,4,4,4", + "lanes": "49,50,51,52", + "breakout_modes": { + "1x200G": [ + "Eth5" + ], + "2x100G": [ + "Eth5/1", + "Eth5/2" + ] + } + }, + "Ethernet21": { + "index": "5,5,5,5", + "lanes": "53,54,55,56", + "breakout_modes": { + "1x200G": [ + "Eth6" + ], + "2x100G": [ + "Eth6/1", + "Eth6/2" + ] + } + }, + "Ethernet25": { + "index": "6,6,6,6", + "lanes": "57,58,59,60", + "breakout_modes": { + "1x200G": [ + "Eth7" + ], + "2x100G": [ + "Eth7/1", + "Eth7/2" + ] + } + }, + "Ethernet29": { + "index": "7,7,7,7", + "lanes": "61,62,63,64", + "breakout_modes": { + "1x200G": [ + "Eth8" + ], + "2x100G": [ + "Eth8/1", + "Eth8/2" + ] + } + }, + "Ethernet33": { + "index": "8,8,8,8", + "lanes": "9,10,11,12", + "breakout_modes": { + "1x200G": [ + "Eth9" + ], + "2x100G": [ + "Eth9/1", + "Eth9/2" + ] + } + }, + "Ethernet37": { + "index": "9,9,9,9", + "lanes": "13,14,15,16", + "breakout_modes": { + "1x200G": [ + "Eth10" + ], + "2x100G": [ + "Eth10/1", + "Eth10/2" + ] + } + }, + "Ethernet41": { + "index": "10,10,10,10", + "lanes": "17,18,19,20", + "breakout_modes": { + "1x200G": [ + "Eth11" + ], + "2x100G": [ + "Eth11/1", + "Eth11/2" + ] + } + }, + "Ethernet45": { + "index": "11,11,11,11", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x200G": [ + "Eth12" + ], + "2x100G": [ + "Eth12/1", + "Eth12/2" + ] + } + }, + "Ethernet49": { + "index": "12,12,12,12", + "lanes": "81,82,83,84", + "breakout_modes": { + "1x200G": [ + "Eth13" + ], + "2x100G": [ + "Eth13/1", + "Eth13/2" + ] + } + }, + "Ethernet53": { + "index": "13,13,13,13", + "lanes": "85,86,87,88", + "breakout_modes": { + "1x200G": [ + "Eth14" + ], + "2x100G": [ + "Eth14/1", + "Eth14/2" + ] + } + }, + "Ethernet57": { + "index": "14,14,14,14", + "lanes": "89,90,91,92", + "breakout_modes": { + "1x200G": [ + "Eth15" + ], + "2x100G": [ + "Eth15/1", + "Eth15/2" + ] + } + }, + "Ethernet61": { + "index": "15,15,15,15", + "lanes": "93,94,95,96", + "breakout_modes": { + "1x200G": [ + "Eth16" + ], + "2x100G": [ + "Eth16/1", + "Eth16/2" + ] + } + }, + "Ethernet65": { + "index": "16,16,16,16", + "lanes": "97,98,99,100", + "breakout_modes": { + "1x200G": [ + "Eth17" + ], + "2x100G": [ + "Eth17/1", + "Eth17/2" + ] + } + }, + "Ethernet69": { + "index": "17,17,17,17", + "lanes": "101,102,103,104", + "breakout_modes": { + "1x200G": [ + "Eth18" + ], + "2x100G": [ + "Eth18/1", + "Eth18/2" + ] + } + }, + "Ethernet73": { + "index": "18,18,18,18", + "lanes": "137,138,139,140", + "breakout_modes": { + "1x200G": [ + "Eth19" + ], + "2x100G": [ + "Eth19/1", + "Eth19/2" + ] + } + }, + "Ethernet77": { + "index": "19,19,19,19", + "lanes": "141,142,143,144", + "breakout_modes": { + "1x200G": [ + "Eth20" + ], + "2x100G": [ + "Eth20/1", + "Eth20/2" + ] + } + }, + "Ethernet81": { + "index": "20,20,20,20", + "lanes": "145,146,147,148", + "breakout_modes": { + "1x200G": [ + "Eth21" + ], + "2x100G": [ + "Eth21/1", + "Eth21/2" + ] + } + }, + "Ethernet85": { + "index": "21,21,21,21", + "lanes": "149,150,151,152", + "breakout_modes": { + "1x200G": [ + "Eth22" + ], + "2x100G": [ + "Eth22/1", + "Eth22/2" + ] + } + }, + "Ethernet89": { + "index": "22,22,22,22", + "lanes": "153,154,155,156", + "breakout_modes": { + "1x200G": [ + "Eth23" + ], + "2x100G": [ + "Eth23/1", + "Eth23/2" + ] + } + }, + "Ethernet93": { + "index": "23,23,23,23", + "lanes": "157,158,159,160", + "breakout_modes": { + "1x200G": [ + "Eth24" + ], + "2x100G": [ + "Eth24/1", + "Eth24/2" + ] + } + }, + "Ethernet97": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x400G": [ + "Eth25" + ], + "2x200G[100G]": [ + "Eth25/1", + "Eth25/2" + ] + } + }, + "Ethernet105": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x400G": [ + "Eth26" + ], + "2x200G[100G]": [ + "Eth26/1", + "Eth26/2" + ] + } + }, + "Ethernet113": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x400G": [ + "Eth27" + ], + "2x200G[100G]": [ + "Eth27/1", + "Eth27/2" + ] + } + }, + "Ethernet121": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x400G": [ + "Eth28" + ], + "2x200G[100G]": [ + "Eth28/1", + "Eth28/2" + ] + } + }, + "Ethernet129": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x400G": [ + "Eth29" + ], + "2x200G[100G]": [ + "Eth29/1", + "Eth29/2" + ] + } + }, + "Ethernet137": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x400G": [ + "Eth30" + ], + "2x200G[100G]": [ + "Eth30/1", + "Eth30/2" + ] + } + }, + "Ethernet145": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x400G": [ + "Eth31" + ], + "2x200G[100G]": [ + "Eth31/1", + "Eth31/2" + ] + } + }, + "Ethernet153": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x400G": [ + "Eth32" + ], + "2x200G[100G]": [ + "Eth32/1", + "Eth32/2" + ] + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic new file mode 100644 index 000000000000..960467652765 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json new file mode 100644 index 000000000000..8fc136f7b9b1 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json @@ -0,0 +1,16 @@ +{ + "chassis": { + "M2-W6520-24DC8QC": { + "component": { + "CPU_CPLD": { }, + "CONNECT_CPLD": { }, + "FAN_CPLD": { }, + "MAC_CPLDA": { }, + "MAC_CPLDB": { }, + "FPGA": { }, + "BIOS": { } + } + } + } +} + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf new file mode 100644 index 000000000000..fc119184d5c1 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf @@ -0,0 +1,2 @@ +is_ltsw_chip=1 +SYNCD_SHM_SIZE=1g diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py new file mode 100644 index 000000000000..f6c4e0477c57 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py @@ -0,0 +1,365 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import re + import os + import threading + import traceback + import subprocess + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.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 = 31 + PORTS_IN_BLOCK = 32 + + EEPROM_OFFSET = 46 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + QSFP_DD_DEVICE_TYPE = "optoe3" + I2C_MAX_ATTEMPT = 3 + + OPTOE_TYPE1 = 1 + OPTOE_TYPE2 = 2 + OPTOE_TYPE3 = 3 + + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping ={} + port_dict = {} + + qsfp_ports_list = [] + qsfp_dd_ports_list = [] + + @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_list + + @property + def qsfp_dd_ports(self): + return self.qsfp_dd_ports_list + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + self.qsfp_ports_list = [] + self.qsfp_dd_ports_list = [] + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + + if self.get_presence(x): + self.port_dict[x] = self.SFP_STATUS_INSERTED + else: + self.port_dict[x] = self.SFP_STATUS_REMOVED + + if (self.check_is_qsfpdd(x)): + self.qsfp_dd_ports_list.append(x) + self.check_optoe_type(x, self.OPTOE_TYPE3) + else: + self.qsfp_ports_list.append(x) + self.check_optoe_type(x, self.OPTOE_TYPE1) + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + else: + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + else: + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_file = open(sysfs_nd_path, "w") + nd_str = "%s %s" % (devtype, hex(devaddr)) + nd_file.write(nd_str) + nd_file.close() + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + if port_num in self.port_to_eeprom_mapping.keys(): + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + else: + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + 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): + if port_num in self.qsfp_dd_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DD_DEVICE_TYPE) + elif port_num in self.qsfp_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + else: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + 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 _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv == False: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + 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.IDENTITY_EEPROM_ADDR, 256) + + 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 + + cmd = "cat /sys/wb_plat/sff/sff{}/present".format(str(port_num+1)) + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + return False + if output == "1": + return True + return False + + def check_is_qsfpdd(self, port_num): + try: + if self.get_presence(port_num) == False: + return False + + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, 0, 1) + # according to sff-8024 A0h Byte 0 is '1e' or '18' means the transceiver is qsfpdd + if (eeprom_raw[0] == '1e' or eeprom_raw[0] == '18'): + return True + except Exception as e: + print(traceback.format_exc()) + + return False + + def check_optoe_type(self, port_num, optoe_type): + if self.get_presence(port_num) == False: + return True + try: + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + dev_class_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/dev_class' + i2c_path = dev_class_path.format(str(self.port_to_i2cbus_mapping[port_num])) + cmd = "cat " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + if int(output) != optoe_type: + cmd = "echo " + str(optoe_type) + " > " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + return True + + except Exception as e: + print(traceback.format_exc()) + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + 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 + + return True + + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + current_port_dict = {} + 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, {} + + 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 + + while timeout >= 0: + # Check for OIR events and return updated port_dict + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(x): + current_port_dict[x] = self.SFP_STATUS_INSERTED + else: + current_port_dict[x] = self.SFP_STATUS_REMOVED + if (current_port_dict == self.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, {} + else: + # Update reg value + self.port_dict = current_port_dict + return True, self.port_dict + print ("get_transceiver_change_event: Should not reach here.") + return False, {} + + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False + + for port in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(port) == False: + continue + + presence_flag = True + + if port in self.qsfp_dd_ports: + offset = 14 + elif port in self.qsfp_ports: + offset = 22 + else: + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + if len(eeprom_raw) != 0: + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + if hightest_temperature < result: + hightest_temperature = result + except Exception as e: + pass + + # all port not presence + if presence_flag == False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag == False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag == True and temperature_valid_flag == False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py new file mode 100644 index 000000000000..e8cf2e1a7cbc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py @@ -0,0 +1,318 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_storage.storage_base import StorageBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(StorageBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" }, + "MTFDDAV240TCB-1AR1ZABAA" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + if self.health == 'N/A': + return "NA" + else: + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + if self.temperature == 'N/A': + return 'NA' + else: + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc new file mode 100644 index 000000000000..6167c3d68f33 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc @@ -0,0 +1,7 @@ +led load /usr/share/sonic/platform/custom_led.bin + +led auto on + +led start + +linkscan SwPortBitMap=xe,ce,cd diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/system_health_monitoring_config.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 38c1a9521388..caac3b74f1b0 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -98,7 +98,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(UFISPACE_S9301_32D_PLATFORM_MODULE) \ $(UFISPACE_S9301_32DB_PLATFORM_MODULE) \ $(MICAS_M2_W6510_48V8C_PLATFORM_MODULE) \ - $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE) + $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE) \ + $(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_BUILD_INSTALLS = $(BRCM_OPENNSL_KERNEL) $(BRCM_DNX_OPENNSL_KERNEL) ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/broadcom/platform-modules-micas.mk b/platform/broadcom/platform-modules-micas.mk index 5b7fd2cdcb07..fb2277921950 100644 --- a/platform/broadcom/platform-modules-micas.mk +++ b/platform/broadcom/platform-modules-micas.mk @@ -16,3 +16,11 @@ export MICAS_M2_W6510_48GT4V_PLATFORM_MODULE_VERSION MICAS_M2_W6510_48GT4V_PLATFORM_MODULE = platform-modules-micas-m2-w6510-48gt4v_$(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE_VERSION)_amd64.deb $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6510-48gt4v-r0 $(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE))) + +## M2-W6520-24DC8QC +MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION = 1.0 +export MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION + +MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE = platform-modules-micas-m2-w6520-24dc8qc_$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION)_amd64.deb +$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6520-24dc8qc-r0 +$(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c index 93ed6066efed..71d6cd510a88 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c @@ -1,3 +1,23 @@ +/* + * An dfd_debug driver for dfd debug function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c index c82b0baad4c3..dbf5f8462eb6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c @@ -1,3 +1,22 @@ +/* + * An dfd_utest driver for dfd utest function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -1865,10 +1884,6 @@ static int mdiodev_arg_parse(int argc, char* argv[], int *mdio_index, int *phyad } regaddr = strtoul(argv[4], &end, 0); - if (*end || regaddr > 0xffff) { - fprintf(stderr, "Error: regaddr invalid!\n"); - return -EINVAL; - } if (argc > 5) { value = strtoul(argv[5], &end, 0); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h index 1ae65148ea9c..71445a449abd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h @@ -1,4 +1,23 @@ -/* monitor_utest.h */ +/* + * A header definition for dfd_utest driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_UTEST_H__ #define __DFD_UTEST_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c index 2045608d5c3b..7141ef08be56 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c @@ -1,3 +1,23 @@ +/* + * An fw_upgrade driver for firmware upgrade function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c index a7a78d011011..0ee3a6f52ef0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c @@ -1,3 +1,23 @@ +/* + * An fw_upgrade_debug driver for firmware upgrade debug function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h index bd806a94b154..aa012b8ab6d7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h @@ -1,3 +1,23 @@ +/* + * A header definition for fw_upgrade driver + * + * Copyright (C) 2024 Micas 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 + * 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 _FW_UPGRADE_H_ #define _FW_UPGRADE_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h index 05911da62a7e..bc6a6ff33404 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h @@ -1,3 +1,23 @@ +/* + * A header definition for fw_upgrade_debug driver + * + * Copyright (C) 2024 Micas 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 + * 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 __FW_UPGRADE_DEBUG_H__ #define __FW_UPGRADE_DEBUG_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py index 81fd596e7fee..34aa0f8866ac 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import copy diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py index 3bb46b286998..3a284230271c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py index 25c2069fea66..93a4ec545627 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import copy diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py index 940c722ce467..ea401f78fd00 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py @@ -1,5 +1,20 @@ #!/usr/bin/python -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py index 4be78e7fdc03..f7f2d7731ed7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 . class FantlvException(Exception): def __init__(self, message='fantlverror', code=-100): @@ -32,18 +46,34 @@ def dstatus(self): def typename(self): return self._typename + @typename.setter + def typename(self, value): + self._typename = value + @property def typesn(self): return self._typesn + @typesn.setter + def typesn(self, value): + self._typesn = value + @property def typehwinfo(self): return self._typehwinfo + @typehwinfo.setter + def typehwinfo(self, value): + self._typehwinfo = value + @property def typedevtype(self): return self._typedevtype + @typedevtype.setter + def typedevtype(self, value): + self._typedevtype = value + def __init__(self): self._typename = "" self._typesn = "" @@ -61,15 +91,15 @@ def strtoarr(self, val): def hex_to_str(self, s): len_t = len(s) - if len_t % 2 != 0: + if int(len_t % 2) != 0: return 0 ret = "" - for t in range(0, len_t / 2): + for t in range(0, int(len_t / 2)): ret += chr(int(s[2 * t:2 * t + 2], 16)) return ret - def generate_fan_value(self): - bin_buffer = [chr(0xff)] * 256 + def generate_fan_value(self, size=256): + bin_buffer = [chr(0x00)] * size bin_buffer[0] = chr(self.VERSION) bin_buffer[1] = chr(self.FLAG) bin_buffer[2] = chr(self.HW_VER) @@ -80,6 +110,10 @@ def generate_fan_value(self): total_len = len(self.typename) + len(self.typesn) + \ len(self.typehwinfo) + len(typedevtype_t) + 8 + rawdata_len = self._FAN_TLV_HDR_LEN + total_len + 2 + if rawdata_len > size: + raise FantlvException("Generate rg tlv value failed, totallen: %d more than e2_size: %d" % (rawdata_len, size), -10) + bin_buffer[4] = chr(total_len >> 8) bin_buffer[5] = chr(total_len & 0x00FF) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py index f95164e03601..c409a4e11202 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py @@ -1,7 +1,22 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 collections from datetime import datetime, timedelta -from bitarray import bitarray __DEBUG__ = "N" @@ -27,17 +42,19 @@ def d_print(debug_info): class FruUtil(): @staticmethod def decodeLength(value): - a = bitarray(8) - a.setall(True) - a[0:1] = 0 - a[1:2] = 0 - x = ord(a.tobytes()) - return x & ord(value) + return 0x3f & ord(value) @staticmethod - def minToData(): + def minToData(endtime = None): starttime = datetime(1996, 1, 1, 0, 0, 0) - endtime = datetime.now() + if isinstance(endtime, str): + try: + endtime = datetime.strptime(endtime, "%Y-%m-%d %H:%M:%S") + except Exception as e: + d_print("Invalid endtime format, endtime: %s, errmsg: %s, used datetime.now" % (endtime, str(e))) + endtime = datetime.now() + else: + endtime = datetime.now() seconds = (endtime - starttime).total_seconds() mins = seconds // 60 m = int(round(mins)) @@ -51,12 +68,7 @@ def getTimeFormat(): def getTypeLength(value): if value is None or len(value) == 0: return 0 - a = bitarray(8) - a.setall(False) - a[0:1] = 1 - a[1:2] = 1 - x = ord(a.tobytes()) - return x | len(value) + return 0xc0 | len(value) @staticmethod def checksum(b): @@ -146,7 +158,7 @@ class BoardInfoArea(BaseArea): def __str__(self): formatstr = "version : %x\n" \ "length : %d \n" \ - "language : %x \n" \ + "language : %d \n" \ "mfg_date : %s \n" \ "boardManufacturer : %s \n" \ "boardProductName : %s \n" \ @@ -247,8 +259,9 @@ def fruSetValue(self, field, value): def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) - d_print("boardInfoArea language:%x" % self.language) - self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea language:%d" % self.language) + + self.mfg_date = FruUtil.minToData(self.mfg_date) d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ @@ -396,7 +409,7 @@ class ProductInfoArea(BaseArea): def __str__(self): formatstr = "version : %x\n" \ "length : %d \n" \ - "language : %x \n" \ + "language : %d \n" \ "productManufacturer : %s \n" \ "productName : %s \n" \ "productPartModelName: %s \n" \ @@ -576,7 +589,7 @@ def fruSetValue(self, field, value): def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) - d_print("product language:%x" % self.language) + d_print("product language:%d" % self.language) self.data = chr(ord(self.areaversion)) + \ chr(self.size // 8) + chr(self.language) @@ -928,7 +941,7 @@ def recalcuteCommonHead(self): if totallen < self._frusize: self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than %d' % self._frusize, -2) + raise FruException("Generate fru value failed, totallen: %d more than e2_size: %d" % (totallen, self._frusize), -2) def recalcutebin(self): self.bodybin = "" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py index a90f8f8453c8..e61b982ea122 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py @@ -1,4 +1,20 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 binascii @@ -12,7 +28,7 @@ def __init__(self, message='onietlverror', code=-100): class onie_tlv(object): TLV_INFO_ID_STRING = "TlvInfo\x00" - TLV_INFO_INIA_ID = "\x00\x00\x13\x11" + TLV_INFO_IANA_HEADER = "\x00" TLV_INFO_VERSION = 0x01 TLV_INFO_LENGTH = 0x00 TLV_INFO_LENGTH_VALUE = 0xba @@ -186,7 +202,7 @@ def generate_ext(self, cardid): ret = chr(0x01) + chr(len(ret)) + ret return ret - def generate_value(self, _t): + def generate_value(self, _t, size=256): ret = [] for i in self.TLV_INFO_ID_STRING: ret.append(i) @@ -195,7 +211,8 @@ def generate_value(self, _t): ret.append(chr(self.TLV_INFO_LENGTH_VALUE)) total_len = 0 - for key in _t: + key_list = sorted(_t.keys()) + for key in key_list: x = self.getTLV_BODY(key, _t[key]) ret += x total_len += len(x) @@ -207,8 +224,11 @@ def generate_value(self, _t): for t in range(0, 4): ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16))) totallen = len(ret) - if totallen < 256: - for left_t in range(0, 256 - totallen): + if totallen > size: + raise OnietlvException("Generate ONIE tlv value failed, totallen: %d more than e2_size: %d" % (totallen, size), -1) + + if totallen < size: + for left_t in range(0, size - totallen): ret.append(chr(0x00)) return (ret, True) @@ -236,7 +256,7 @@ def decode(self, e): ret = self.decode_tlv(e[tlv_index:tlv_end]) for item in ret: if item['code'] == self.TLV_CODE_VENDOR_EXT: - if item["value"][0:4] == self.TLV_INFO_INIA_ID: + if item["value"][0] == self.TLV_INFO_IANA_HEADER: rt = self.decode_tlv(item["value"][4:]) else: rt = self.decode_tlv(item["value"][0:]) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py new file mode 100755 index 000000000000..139977eccc7b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py @@ -0,0 +1,418 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 re + +class WedgeException(Exception): + def __init__(self, message='wedgeerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + +class Wedge(): + MAGIC_HEAD_INFO = 0xfbfb + VERSION = 0x03 + WEDGE_SIZE = 196 + + _FBW_EEPROM_F_MAGIC = 2 + _FBW_EEPROM_F_VERSION = 1 + _FBW_EEPROM_F_PRODUCT_NAME = 20 + _FBW_EEPROM_F_PRODUCT_NUMBER = 8 + _FBW_EEPROM_F_ASSEMBLY_NUMBER = 12 + _FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER = 12 + _FBW_EEPROM_F_FACEBOOK_PCB_NUMBER = 12 + _FBW_EEPROM_F_ODM_PCBA_NUMBER = 13 + _FBW_EEPROM_F_ODM_PCBA_SERIAL = 13 + _FBW_EEPROM_F_PRODUCT_STATE = 1 + _FBW_EEPROM_F_PRODUCT_VERSION = 1 + _FBW_EEPROM_F_PRODUCT_SUBVERSION = 1 + _FBW_EEPROM_F_PRODUCT_SERIAL = 13 + _FBW_EEPROM_F_PRODUCT_ASSET = 12 + _FBW_EEPROM_F_SYSTEM_MANUFACTURER = 8 + _FBW_EEPROM_F_SYSTEM_MANU_DATE = 4 + _FBW_EEPROM_F_PCB_MANUFACTURER = 8 + _FBW_EEPROM_F_ASSEMBLED = 8 + _FBW_EEPROM_F_LOCAL_MAC = 12 + _FBW_EEPROM_F_EXT_MAC_BASE = 12 + _FBW_EEPROM_F_EXT_MAC_SIZE = 2 + _FBW_EEPROM_F_LOCATION = 20 + _FBW_EEPROM_F_CRC8 = 1 + + def __init__(self): + self.magic = "" + self.fbw_version = "" + self.fbw_product_name = "" + self.fbw_product_number = "" + self.fbw_assembly_number = "" + self.fbw_facebook_pcba_number = "" + self.fbw_facebook_pcb_number = "" + self.fbw_odm_pcba_number = "" + self.fbw_odm_pcba_serial = "" + self.fbw_production_state = "" + self.fbw_product_version = "" + self.fbw_product_subversion = "" + self.fbw_product_serial = "" + self.fbw_product_asset = "" + self.fbw_system_manufacturer = "" + self.fbw_system_manufacturing_date = "" + self.fbw_system_manufacturing_date_show = "" + self.fbw_pcb_manufacturer = "" + self.fbw_assembled = "" + self.fbw_local_mac = "" + self.fbw_local_mac_show = "" + self.fbw_mac_base = "" + self.fbw_mac_base_show = "" + self.fbw_mac_size = "" + self.fbw_location = "" + self.fbw_crc8 = "" + + def isValidMac(self, mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + def mac_addr_decode(self, origin_mac): + mac = origin_mac.replace("0x", "") + if len(mac) != 12: + msg = "Invalid MAC address: %s" % origin_mac + return False, msg + release_mac = "" + for i in range(len(mac) // 2): + if i == 0: + release_mac += mac[i * 2:i * 2 + 2] + else: + release_mac += ":" + mac[i * 2:i * 2 + 2] + return True, release_mac + + def wedge_crc8(self, v): + # TBD + return '0x00' + + def strtoarr(self, str_tmp, size): + if len(str_tmp) > size: + raise WedgeException("Wedge eeprom str:%s exceed max len: %d" % (str_tmp, size), -10) + + s = [] + for index in str_tmp: + s.append(index) + + append_len = size - len(str_tmp) + if append_len > 0: + append_list = [chr(0x00)] * append_len + s.extend(append_list) + return s + + def generate_value(self, size=256): + bin_buffer = [chr(0x00)] * size + bin_buffer[0] = chr(0xfb) + bin_buffer[1] = chr(0xfb) + bin_buffer[2] = chr(0x03) + + index_start = 3 + # Product Name + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_NAME] = self.strtoarr(self.fbw_product_name, + self._FBW_EEPROM_F_PRODUCT_NAME) + index_start += self._FBW_EEPROM_F_PRODUCT_NAME + # Product Part Numbe + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_NUMBER] = self.strtoarr(self.fbw_product_number, + self._FBW_EEPROM_F_PRODUCT_NUMBER) + index_start += self._FBW_EEPROM_F_PRODUCT_NUMBER + + # System Assembly Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ASSEMBLY_NUMBER] = self.strtoarr(self.fbw_assembly_number, + self._FBW_EEPROM_F_ASSEMBLY_NUMBER) + index_start += self._FBW_EEPROM_F_ASSEMBLY_NUMBER + + # Facebook PCBA Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER] = self.strtoarr(self.fbw_facebook_pcba_number, + self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER) + index_start += self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER + + # Facebook PCB Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER] = self.strtoarr(self.fbw_facebook_pcb_number, + self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER) + index_start += self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER + + # ODM PCBA Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ODM_PCBA_NUMBER] = self.strtoarr(self.fbw_odm_pcba_number, + self._FBW_EEPROM_F_ODM_PCBA_NUMBER) + index_start += self._FBW_EEPROM_F_ODM_PCBA_NUMBER + + # ODM PCBA Serial Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ODM_PCBA_SERIAL] = self.strtoarr(self.fbw_odm_pcba_serial, + self._FBW_EEPROM_F_ODM_PCBA_SERIAL) + index_start += self._FBW_EEPROM_F_ODM_PCBA_SERIAL + + # Product Production State + if self.fbw_production_state > 0xff: + raise WedgeException("Product Production State: %d config error, exceed 255" + % self.fbw_production_state, -10) + bin_buffer[index_start] = chr(self.fbw_production_state) + index_start += self._FBW_EEPROM_F_PRODUCT_STATE + + # Product Version + if self.fbw_product_version > 0xff: + raise WedgeException("Product Version: %d config error, exceed 255" + % self.fbw_product_version, -10) + bin_buffer[index_start] = chr(self.fbw_product_version) + index_start += self._FBW_EEPROM_F_PRODUCT_VERSION + + # Product Sub Version + if self.fbw_product_subversion > 0xff: + raise WedgeException("Product Sub Version: %d config error, exceed 255" + % self.fbw_product_subversion, -10) + bin_buffer[index_start] = chr(self.fbw_product_subversion) + index_start += self._FBW_EEPROM_F_PRODUCT_SUBVERSION + + # Product Serial Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_SERIAL] = self.strtoarr(self.fbw_product_serial, self._FBW_EEPROM_F_PRODUCT_SERIAL) + index_start += self._FBW_EEPROM_F_PRODUCT_SERIAL + + # Product Asset Tag + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_ASSET] = self.strtoarr(self.fbw_product_asset, self._FBW_EEPROM_F_PRODUCT_ASSET) + index_start += self._FBW_EEPROM_F_PRODUCT_ASSET + + # System Manufacturer + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_SYSTEM_MANUFACTURER] = self.strtoarr(self.fbw_system_manufacturer, self._FBW_EEPROM_F_SYSTEM_MANUFACTURER) + index_start += self._FBW_EEPROM_F_SYSTEM_MANUFACTURER + + # System Manufacturing Date + if (len(self.fbw_system_manufacturing_date) != 8): + raise WedgeException("System Manufacturing Date config error, value: %s" + % self.fbw_system_manufacturing_date, -10) + + year = int(self.fbw_system_manufacturing_date[0:4]) + month = int(self.fbw_system_manufacturing_date[4:6]) + day = int(self.fbw_system_manufacturing_date[6:8]) + if month < 1 or month > 12 or day < 1 or day > 31: + raise WedgeException("System Manufacturing Date config error, value: %s" + % self.fbw_system_manufacturing_date, -10) + bin_buffer[index_start] = chr(year & 0xff) + bin_buffer[index_start + 1] = chr((year & 0xff00) >> 8) + bin_buffer[index_start + 2] = chr(month) + bin_buffer[index_start + 3] = chr(day) + index_start += self._FBW_EEPROM_F_SYSTEM_MANU_DATE + + # PCB Manufacturer + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PCB_MANUFACTURER] = self.strtoarr(self.fbw_pcb_manufacturer, + self._FBW_EEPROM_F_PCB_MANUFACTURER) + index_start += self._FBW_EEPROM_F_PCB_MANUFACTURER + + # Assembled At + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ASSEMBLED] = self.strtoarr(self.fbw_assembled, + self._FBW_EEPROM_F_ASSEMBLED) + index_start += self._FBW_EEPROM_F_ASSEMBLED + + # Local MAC Address + status, mac = self.mac_addr_decode(self.fbw_local_mac) + if self.isValidMac(mac) is False: + msg = "Invalid Local MAC Address: %s" % self.fbw_local_mac + raise WedgeException(msg , -10) + + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_LOCAL_MAC] = self.strtoarr(self.fbw_local_mac, self._FBW_EEPROM_F_LOCAL_MAC) + index_start += self._FBW_EEPROM_F_LOCAL_MAC + # Extended MAC Address + status, mac = self.mac_addr_decode(self.fbw_mac_base) + if self.isValidMac(mac) is False: + msg = "Invalid Extended MAC Address: %s" % self.fbw_mac_base + raise WedgeException(msg , -10) + + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_EXT_MAC_BASE] = self.strtoarr(self.fbw_mac_base, self._FBW_EEPROM_F_EXT_MAC_BASE) + index_start += self._FBW_EEPROM_F_EXT_MAC_BASE + + # Extended MAC Address Size + if self.fbw_mac_size > 0xffff: + raise WedgeException("Extended MAC Address Size: %d config error, exceed 65535" + % self.fbw_mac_size, -10) + bin_buffer[index_start] = chr(self.fbw_mac_size & 0xff) + bin_buffer[index_start + 1] = chr((self.fbw_mac_size & 0xff00) >> 8) + index_start += self._FBW_EEPROM_F_EXT_MAC_SIZE + + # Location on Fabric + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_LOCATION] = self.strtoarr(self.fbw_location, + self._FBW_EEPROM_F_LOCATION) + index_start += self._FBW_EEPROM_F_LOCATION + + # CRC8 + bin_buffer[index_start] = chr(0x00) + index_start += self._FBW_EEPROM_F_CRC8 + return bin_buffer + + def decode(self, e2): + # header check + e2_index = 0 + head = ord(e2[0]) | (ord(e2[1]) << 8) + if head != self.MAGIC_HEAD_INFO: + raise WedgeException("Wedge eeprom head info error, not Wedge eeprom type, head:0x%04x" % head, -10) + self.magic = "0x%04x" % self.MAGIC_HEAD_INFO + e2_index += self._FBW_EEPROM_F_MAGIC + + # E2 format version check + if ord(e2[e2_index]) != self.VERSION: + raise WedgeException("Wedge eeprom version: 0x%02x, not V3 format" % ord(e2[e2_index]), -10) + self.fbw_version = self.VERSION + e2_index += self._FBW_EEPROM_F_VERSION + + # crc + self.fbw_crc8 = ord(e2[self.WEDGE_SIZE-1]) + + # Product Name + self.fbw_product_name = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_NAME]) + e2_index += self._FBW_EEPROM_F_PRODUCT_NAME + + # Product Part Numbe + self.fbw_product_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_PRODUCT_NUMBER] + #self.fbw_product_number = "%s-%s" % (e2[e2_index:e2_index+2], e2[e2_index + 2: e2_index + 8]) + e2_index += self._FBW_EEPROM_F_PRODUCT_NUMBER + + # System Assembly Part Number + self.fbw_assembly_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_ASSEMBLY_NUMBER] + #self.fbw_assembly_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_ASSEMBLY_NUMBER + + # Facebook PCBA Part Number + self.fbw_facebook_pcba_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER] + #self.fbw_facebook_pcba_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER + + # Facebook PCB Part Number + self.fbw_facebook_pcb_number ="%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER] + #self.fbw_facebook_pcb_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER + + # ODM PCBA Part Number + self.fbw_odm_pcba_number = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ODM_PCBA_NUMBER]) + e2_index += self._FBW_EEPROM_F_ODM_PCBA_NUMBER + + # ODM PCBA Serial Number + self.fbw_odm_pcba_serial = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ODM_PCBA_SERIAL]) + e2_index += self._FBW_EEPROM_F_ODM_PCBA_SERIAL + + # Product Production State + self.fbw_production_state = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_STATE + + # Product Version + self.fbw_product_version = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_VERSION + + # Product Version + self.fbw_product_subversion = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_SUBVERSION + + # Product Serial Number + self.fbw_product_serial = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_SERIAL]) + e2_index += self._FBW_EEPROM_F_PRODUCT_SERIAL + + # Product Asset Tag + self.fbw_product_asset = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_ASSET]) + e2_index += self._FBW_EEPROM_F_PRODUCT_ASSET + + # System Manufacturer + self.fbw_system_manufacturer = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_SYSTEM_MANUFACTURER]) + e2_index += self._FBW_EEPROM_F_SYSTEM_MANUFACTURER + + # System Manufacturing Date + year = ord(e2[e2_index]) | (ord(e2[e2_index + 1]) << 8) + month = ord(e2[e2_index + 2]) + day = ord(e2[e2_index + 3]) + self.fbw_system_manufacturing_date = "%04d%02d%02d" % (year, month, day) + self.fbw_system_manufacturing_date_show = "%02d-%02d-%04d" % (month, day, year) + e2_index += self._FBW_EEPROM_F_SYSTEM_MANU_DATE + + # PCB Manufacturer + self.fbw_pcb_manufacturer = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PCB_MANUFACTURER]) + e2_index += self._FBW_EEPROM_F_PCB_MANUFACTURER + + # Assembled At + self.fbw_assembled = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ASSEMBLED]) + e2_index += self._FBW_EEPROM_F_ASSEMBLED + + # Local MAC Address + self.fbw_local_mac = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_LOCAL_MAC]) + status, mac = self.mac_addr_decode(self.fbw_local_mac) + if status is False: + raise WedgeException("Wedge eeprom decode local MAC error, msg: %s" % mac, -10) + self.fbw_local_mac_show = mac.upper() + e2_index += self._FBW_EEPROM_F_LOCAL_MAC + + # Extended MAC Address + self.fbw_mac_base = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_EXT_MAC_BASE]) + status, mac = self.mac_addr_decode(self.fbw_mac_base) + if status is False: + raise WedgeException("Wedge eeprom decode local MAC error, msg: %s" % mac, -10) + self.fbw_mac_base_show = mac.upper() + e2_index += self._FBW_EEPROM_F_EXT_MAC_BASE + + # Extended MAC Address Size + mac_size = ord(e2[e2_index]) | (ord(e2[e2_index + 1]) << 8) + self.fbw_mac_size = mac_size + e2_index += self._FBW_EEPROM_F_EXT_MAC_SIZE + + # Location on Fabric + self.fbw_location = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_LOCATION]) + e2_index += self._FBW_EEPROM_F_LOCATION + return + + + def __str__(self): + formatstr = "Version : %d \n" \ + "Product Name : %s \n" \ + "Product Part Number : %s \n" \ + "System Assembly Part Number : %s \n" \ + "Facebook PCBA Part Number : %s \n" \ + "Facebook PCB Part Number : %s \n" \ + "ODM PCBA Part Number : %s \n" \ + "ODM PCBA Serial Number : %s \n" \ + "Product Production State : %d \n" \ + "Product Version : %d \n" \ + "Product Sub-Version : %d \n" \ + "Product Serial Number : %s \n" \ + "Product Asset Tag : %s \n" \ + "System Manufacturer : %s \n" \ + "System Manufacturing Date : %s \n" \ + "PCB Manufacturer : %s \n" \ + "Assembled At : %s \n" \ + "Local MAC : %s \n" \ + "Extended MAC Base : %s \n" \ + "Extended MAC Address Size : %d \n" \ + "Location on Fabric : %s \n" \ + "CRC8 : 0x%02x \n" + str_tmp = formatstr % (self.fbw_version, + self.fbw_product_name, + self.fbw_product_number, + self.fbw_assembly_number, + self.fbw_facebook_pcba_number, + self.fbw_facebook_pcb_number, + self.fbw_odm_pcba_number, + self.fbw_odm_pcba_serial, + self.fbw_production_state, + self.fbw_product_version, + self.fbw_product_subversion, + self.fbw_product_serial, + self.fbw_product_asset, + self.fbw_system_manufacturer, + self.fbw_system_manufacturing_date_show, + self.fbw_pcb_manufacturer, + self.fbw_assembled, + self.fbw_local_mac_show, + self.fbw_mac_base_show, + self.fbw_mac_size, + self.fbw_location, + self.fbw_crc8) + return str_tmp.replace("\x00","") \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py new file mode 100755 index 000000000000..4d42865f619b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py @@ -0,0 +1,591 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 re + +class WedgeException(Exception): + def __init__(self, message='wedgeerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + +class WedgeV5(): + MAGIC_HEAD_INFO = 0xfbfb + VERSION = 0x05 + + FBWV5_PRODUCT_NAME = 0x01 + FBWV5_PRODUCT_PART_NUMBER = 0x02 + FBWV5_ASSEMBLY_PART_NUMBER = 0x03 + FBWV5_ASSEMBLY_PART_NUMBER_LEN = 8 + FBWV5_META_PCBA_PART_NUMBER = 0x04 + FBWV5_META_PCBA_PART_NUMBER_LEN = 12 + FBWV5_META_PCB_PART_NUMBER = 0x05 + FBWV5_META_PCB_PART_NUMBER_LEN = 12 + FBWV5_ODM_PCBA_PART_NUMBER = 0x06 + FBWV5_ODM_PCBA_SERIAL_NUMBER = 0x07 + FBWV5_PRODUCT_PRODUCTION_STATE = 0x08 + FBWV5_PRODUCT_PRODUCTION_STATE_LEN = 1 + FBWV5_PRODUCT_VERSION = 0x09 + FBWV5_PRODUCT_VERSION_LEN = 1 + FBWV5_PRODUCT_SUB_VERSION = 0x0A + FBWV5_PRODUCT_SUB_VERSION_LEN = 1 + FBWV5_PRODUCT_SERIAL_NUMBER = 0x0B + FBWV5_SYSTEM_MANUFACTURER = 0x0C + FBWV5_SYSTEM_MANUFACTURING_DATE = 0x0D + FBWV5_SYSTEM_MANUFACTURING_DATE_LEN = 8 + FBWV5_PCB_MANUFACTURER = 0x0E + FBWV5_ASSEMBLED_AT = 0x0F + FBWV5_E2_LOCATION_ON_FABRIC = 0x10 + FBWV5_X86_CPU_MAC = 0x11 + FBWV5_X86_CPU_MAC_LEN = 8 + FBWV5_BMC_MAC = 0x12 + FBWV5_BMC_MAC_LEN = 8 + FBWV5_SWITCH_ASIC_MAC = 0x13 + FBWV5_SWITCH_ASIC_MAC_LEN = 8 + FBWV5_META_RESERVED_MAC = 0x14 + FBWV5_META_RESERVED_MAC_LEN = 8 + FBWV5_CRC16 = 0xFA + + + @property + def product_name(self): + return self._ProductName + + @property + def product_part_number(self): + return self._ProductPartNumber + + @property + def assembly_part_number(self): + return self._AssemblyPartNumber + + @property + def meta_pcba_part_number(self): + return self._MetaPCBAPartNumber + + @property + def meta_pcb_part_number(self): + return self._MetaPCBPartNumber + + @property + def odm_pcba_part_number(self): + return self._ODMPCBAPartNumber + + @property + def odm_pcba_serial_number(self): + return self._ODMPCBASerialNumber + + @property + def product_production_state(self): + return self._ProductProductionState + + @property + def product_version(self): + return self._ProductVersion + + @property + def product_sub_version(self): + return self._ProductSubVersion + + @property + def product_serial_number(self): + return self._ProductSerialNumber + + @property + def system_manufacturer(self): + return self._SystemManufacturer + + @property + def system_manufacturing_date(self): + return self._SystemManufacturingDate + + @property + def pcb_manufacturer(self): + return self._PCBManufacturer + + @property + def assembled_at(self): + return self._AssembledAt + + @property + def e2_location_on_fabric(self): + return self._E2LocationOnFabric + + @property + def x86_cpu_mac(self): + return self._X86_CPU_MAC + + @property + def x86_cpu_mac_size(self): + return self._X86_CPU_MAC_SIZE + + @property + def bmc_mac(self): + return self._BMC_MAC + + @property + def bmc_mac_size(self): + return self._BMC_MAC_SIZE + + @property + def switch_asic_mac(self): + return self._SWITCH_ASIC_MAC + + @property + def switch_asic_mac_size(self): + return self._SWITCH_ASIC_MAC_SIZE + + @property + def meta_reserved_mac(self): + return self._MetaReservedMAC + + @property + def meta_reserved_mac_size(self): + return self._MetaReservedMAC_SIZE + + @property + def crc16(self): + return self._crc16 + + + def __init__(self): + self._ProductName = "" + self._ProductPartNumber = "" + self._AssemblyPartNumber = "" + self._MetaPCBAPartNumber = "" + self._MetaPCBPartNumber = "" + self._ODMPCBAPartNumber = "" + self._ODMPCBASerialNumber = "" + self._ProductProductionState = "" + self._ProductVersion = "" + self._ProductSubVersion = "" + self._ProductSerialNumber = "" + self._SystemManufacturer = "" + self._SystemManufacturingDate = "" + self._PCBManufacturer = "" + self._AssembledAt = "" + self._E2LocationOnFabric = "" + self._X86_CPU_MAC = "" + self._X86_CPU_MAC_SIZE = "" + self._BMC_MAC = "" + self._BMC_MAC_SIZE = "" + self._SWITCH_ASIC_MAC = "" + self._SWITCH_ASIC_MAC_SIZE = "" + self._MetaReservedMAC = "" + self._MetaReservedMAC_SIZE = "" + self._crc16 = "" + + def crc_ccitt(self, data, crc_init=0xFFFF, poly=0x1021): + ''' + CRC-16-CCITT Algorithm + ''' + + data_array = bytearray() + for x in data: + data_array.append(ord(x)) + + crc = crc_init + for byte in data_array: + crc ^= byte << 8 + for _ in range(8): + if crc & 0x8000: + crc = (crc << 1) ^ poly + else: + crc <<= 1 + crc &= 0xFFFF + + return '0x%04X' % (crc & 0xFFFF) + + + def check_mac_addr(self, mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + def decoce_mac_and_size(self, value): + mac_addr = ":".join(['%02X' % ord(T) for T in value[0:6]]).upper() + ret = self.check_mac_addr(mac_addr) + if ret is False: + return False, "Invalid MAC address: [%s]" % mac_addr + + mac_size = ((ord(value[6]) << 8) | ord(value[7])) + if mac_size == 0: + return False, "Invalid MAC address size: %d" % mac_size + return True, "" + + def getTLV_BODY(self, tlv_type, value): + x = [] + temp_t = None + if tlv_type == self.FBWV5_ASSEMBLY_PART_NUMBER and len(value) != self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + if len(value) > self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + raise WedgeException("Invalid System Assembly Part Number length. value: %s, length: %d, length must less than %d" % + (value, len(value), self.FBWV5_ASSEMBLY_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_ASSEMBLY_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + if tlv_type == self.FBWV5_META_PCBA_PART_NUMBER and len(value) != self.FBWV5_META_PCBA_PART_NUMBER_LEN: + if len(value) > self.FBWV5_META_PCBA_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCBA Part Number length. value: %s, length: %d, length must be %d" % + (value, len(value), self.FBWV5_META_PCBA_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_META_PCBA_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + + if tlv_type == self.FBWV5_META_PCB_PART_NUMBER and len(value) != self.FBWV5_META_PCB_PART_NUMBER_LEN: + if len(value) > self.FBWV5_META_PCB_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCB Part Number length. value: %s, length: %d, length must be %d" % + (value, len(value), self.FBWV5_META_PCB_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_META_PCB_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + if (tlv_type == self.FBWV5_PRODUCT_PRODUCTION_STATE + or tlv_type == self.FBWV5_PRODUCT_VERSION + or tlv_type == self.FBWV5_PRODUCT_SUB_VERSION): + if not isinstance(value, int) or value > 0xff or value < 0: + raise WedgeException("Invalid Wedge EEPROM Format V5 Tlv type: %d, value: %s" % + (tlv_type, value), -1) + temp_t = chr(value) + + if tlv_type == self.FBWV5_SYSTEM_MANUFACTURING_DATE and len(value) != self.FBWV5_SYSTEM_MANUFACTURING_DATE_LEN: + raise WedgeException("Invalid System Manufacturing Date. value: %s, length: %d, format must YYYYMMDD" + % (value, len(value)), -1) + + if tlv_type == self.FBWV5_X86_CPU_MAC: + if len(value) != self.FBWV5_X86_CPU_MAC_LEN: + raise WedgeException("Invalid X86 CPU MAC length: %d, must be %d" + % (len(value), self.FBWV5_X86_CPU_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode X86 CPU MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_BMC_MAC: + if len(value) != self.FBWV5_BMC_MAC_LEN: + raise WedgeException("Invalid BMC MAC length: %d, must be %d" + % (len(value), self.FBWV5_BMC_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode BMC MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_SWITCH_ASIC_MAC: + if len(value) != self.FBWV5_SWITCH_ASIC_MAC_LEN: + raise WedgeException("Invalid Switch ASIC MAC length: %d, must be %d" + % (len(value), self.FBWV5_SWITCH_ASIC_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode Switch ASIC MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_META_RESERVED_MAC: + if len(value) != self.FBWV5_META_RESERVED_MAC_LEN: + raise WedgeException("Invalid META Reserved MAC length: %d, must be %d" + % (len(value), self.FBWV5_META_RESERVED_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode META Reserved MAC failed, msg: %s" % (value, msg), -1) + + if temp_t is None: + temp_t = value + + x.append(chr(tlv_type)) + x.append(chr(len(temp_t))) + for i in temp_t: + x.append(i) + return x + + def generate_value(self, _t, size=256): + ret = [] + ret.append(chr(0xfb)) + ret.append(chr(0xfb)) + ret.append(chr(self.VERSION)) + ret.append(chr(0xff)) + + key_list = sorted(_t.keys()) + for key in key_list: + x = self.getTLV_BODY(key, _t[key]) + ret += x + + crc16_str = self.crc_ccitt(ret) + crc16_val = int(crc16_str, 16) + + ret.append(chr(self.FBWV5_CRC16)) + ret.append(chr(0x02)) + ret.append(chr((crc16_val >> 8) & 0xff)) + ret.append(chr((crc16_val & 0xff))) + + totallen = len(ret) + if (totallen > size): + raise WedgeException("Generate Wedge EEPROM Format V5 failed, totallen: %d more than e2_size: %d" + % (totallen, size), -1) + if (totallen < size): + for left_t in range(0, size - totallen): + ret.append(chr(0x00)) + return ret + + def decoder(self, t): + ret = [] + if ord(t[0]) == self.FBWV5_PRODUCT_NAME: + name = "Product Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductName = value + elif ord(t[0]) == self.FBWV5_PRODUCT_PART_NUMBER: + name = "Product Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductPartNumber = value + elif ord(t[0]) == self.FBWV5_ASSEMBLY_PART_NUMBER: + name = "System Assembly Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + raise WedgeException("Invalid System Assembly Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._AssemblyPartNumber = value + elif ord(t[0]) == self.FBWV5_META_PCBA_PART_NUMBER: + name = "Meta PCBA Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_META_PCBA_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCBA Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._MetaPCBAPartNumber = value + elif ord(t[0]) == self.FBWV5_META_PCB_PART_NUMBER: + name = "Meta PCB Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_META_PCB_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCB Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._MetaPCBPartNumber = value + elif ord(t[0]) == self.FBWV5_ODM_PCBA_PART_NUMBER: + name = "ODM/JDM PCBA Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ODMPCBAPartNumber = value + elif ord(t[0]) == self.FBWV5_ODM_PCBA_SERIAL_NUMBER: + name = "ODM/JDM PCBA Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ODMPCBASerialNumber = value + elif ord(t[0]) == self.FBWV5_PRODUCT_PRODUCTION_STATE: + name = "Product Production State" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_PRODUCTION_STATE_LEN: + raise WedgeException("Invalid Product Production State len: %d" % _len, -1) + value = ord(t[2]) + self._ProductProductionState = value + elif ord(t[0]) == self.FBWV5_PRODUCT_VERSION: + name = "Product Version" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_VERSION_LEN: + raise WedgeException("Invalid Product Version len: %d" % _len, -1) + value = ord(t[2]) + self._ProductVersion = value + elif ord(t[0]) == self.FBWV5_PRODUCT_SUB_VERSION: + name = "Product Sub-Version" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_SUB_VERSION_LEN: + raise WedgeException("Invalid Product Sub-Version len: %d" % _len, -1) + value = ord(t[2]) + self._ProductSubVersion = value + elif ord(t[0]) == self.FBWV5_PRODUCT_SERIAL_NUMBER: + name = "Product Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductSerialNumber = value + elif ord(t[0]) == self.FBWV5_SYSTEM_MANUFACTURER: + name = "System Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._SystemManufacturer = value + elif ord(t[0]) == self.FBWV5_SYSTEM_MANUFACTURING_DATE: + name = "System Manufacturing Date" + _len = ord(t[1]) + if _len != self.FBWV5_SYSTEM_MANUFACTURING_DATE_LEN: + raise WedgeException("Invalid System Manufacturing Date len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._SystemManufacturingDate = value + elif ord(t[0]) == self.FBWV5_PCB_MANUFACTURER: + name = "PCB Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._PCBManufacturer = value + elif ord(t[0]) == self.FBWV5_ASSEMBLED_AT: + name = "Assembled at" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._AssembledAt = value + elif ord(t[0]) == self.FBWV5_E2_LOCATION_ON_FABRIC: + name = "EEPROM location on Fabric" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._E2LocationOnFabric = value + elif ord(t[0]) == self.FBWV5_X86_CPU_MAC: + name = "X86 CPU MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_X86_CPU_MAC_LEN: + raise WedgeException("Invalid X86 CPU MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._X86_CPU_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # X86 CPU MAC Address Size + name = "X86 CPU MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._X86_CPU_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_BMC_MAC: + name = "BMC MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_BMC_MAC_LEN: + raise WedgeException("Invalid BMC MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._BMC_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # BMC MAC Address Size + name = "BMC MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._BMC_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_SWITCH_ASIC_MAC: + name = "Switch ASIC MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_SWITCH_ASIC_MAC_LEN: + raise WedgeException("Invalid Switch ASIC MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._SWITCH_ASIC_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # Switch ASIC MAC Address Size + name = "Switch ASIC MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._SWITCH_ASIC_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_META_RESERVED_MAC: + name = "META Reserved MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_META_RESERVED_MAC_LEN: + raise WedgeException("Invalid META Reserved MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._MetaReservedMAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # META Reserved MAC Address Size + name = "META Reserved MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._MetaReservedMAC_SIZE = value + elif ord(t[0]) == self.FBWV5_CRC16 and len(t) == 4: + name = "CRC16" + _len = ord(t[1]) + value = "0x%04X" % ((ord(t[2]) << 8) | (ord(t[3]))) + self._crc16 = value + else: + name = "Unknown" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "0x%02X " % (ord(c),) + raise WedgeException("Unknown Wedge EEPROM Format V5 TLV type: 0x%02x, len: %d, value: %s" % (ord(t[0]), ord(t[1]), value), -1) + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": _len}) + return ret + + + def decode_tlv(self, e2): + tlv_index = 0 + tlv_end = len(e2) + ret = [] + while tlv_index < tlv_end: + rt = self.decoder(e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])]) + ret.extend(rt) + if ord(e2[tlv_index]) == self.FBWV5_CRC16: + break + tlv_index += ord(e2[tlv_index + 1]) + 2 + return ret, tlv_index + + def decode(self, e2): + e2_index = 0 + head = ord(e2[0]) | (ord(e2[1]) << 8) + if head != self.MAGIC_HEAD_INFO: + raise WedgeException("Wedge eeprom head info error, not Wedge eeprom type, head:0x%04x" % head, -10) + e2_index += 2 + + # E2 Version check + if ord(e2[e2_index]) != self.VERSION: + raise WedgeException("Wedge eeprom version: 0x%02x, not V5 format" % ord(e2[e2_index]), -10) + e2_index += 1 + + # one byte Reserved + e2_index += 1 + + ret, tlv_data_len = self.decode_tlv(e2[e2_index:]) + + # check crc + e2_crc_data_len = tlv_data_len + 4 # two byte Magic word + one byte Format Version + one byte Reserved + + crc_calc = self.crc_ccitt(e2[0:e2_crc_data_len]) + crc_read = self.crc16 + if crc_calc != crc_read: + print("Wedge EEPROM Format V5 crc error, calc value: %s, read value: %s" % (crc_calc, crc_read), -1) + + return ret + + def __str__(self): + formatstr = "Product Name : %s \n" \ + "Product Part Number : %s \n" \ + "System Assembly Part Number : %s \n" \ + "Meta PCBA Part Number : %s \n" \ + "Meta PCB Part Number : %s \n" \ + "ODM/JDM PCBA Part Number : %s \n" \ + "ODM/JDM PCBA Serial Number : %s \n" \ + "Product Production State : %s \n" \ + "Product Version : %s \n" \ + "Product Sub-Version : %s \n" \ + "Product Serial Number : %s \n" \ + "System Manufacturer : %s \n" \ + "System Manufacturing Date : %s \n" \ + "PCB Manufacturer : %s \n" \ + "Assembled at : %s \n" \ + "EEPROM location on Fabric : %s \n" \ + "X86 CPU MAC Base : %s \n" \ + "X86 CPU MAC Address Size : %s \n" \ + "BMC MAC Base : %s \n" \ + "BMC MAC Address Size : %s \n" \ + "Switch ASIC MAC Base : %s \n" \ + "Switch ASIC MAC Address Size : %s \n" \ + "META Reserved MAC Base : %s \n" \ + "META Reserved MAC Address Size : %s \n" \ + "CRC16 : %s \n" + return formatstr % (self.product_name, + self.product_part_number, + self.assembly_part_number, + self.meta_pcba_part_number, + self.meta_pcb_part_number, + self.odm_pcba_part_number, + self.odm_pcba_serial_number, + self.product_production_state, + self.product_version, + self.product_sub_version, + self.product_serial_number, + self.system_manufacturer, + self.system_manufacturing_date, + self.pcb_manufacturer, + self.assembled_at, + self.e2_location_on_fabric, + self.x86_cpu_mac, + self.x86_cpu_mac_size, + self.bmc_mac, + self.bmc_mac_size, + self.switch_asic_mac, + self.switch_asic_mac_size, + self.meta_reserved_mac, + self.meta_reserved_mac_size, + self.crc16) \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py index abf0ecf97d6b..12f9aa881daf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# baseutil.py -# Python implementation of the Class baseutil +# Copyright (C) 2024 Micas 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 +# 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 importlib.machinery import os import syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py index 767d6da34ba9..ea1ef4930a15 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py @@ -1,21 +1,31 @@ #!/usr/bin/env python3 -####################################################### # -# chassisbase.py -# Python implementation of the Class chassisbase +# Copyright (C) 2024 Micas 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 +# 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 from plat_hal.dcdc import dcdc from plat_hal.onie_e2 import onie_e2 from plat_hal.psu import psu from plat_hal.led import led -from plat_hal.temp import temp +from plat_hal.temp import temp, temp_s3ip from plat_hal.fan import fan from plat_hal.cpld import cpld from plat_hal.component import component from plat_hal.cpu import cpu from plat_hal.baseutil import baseutil - +from plat_hal.osutil import osutil class chassisbase(object): __onie_e2_list = [] @@ -89,6 +99,52 @@ def __init__(self, conftype=0, conf=None): temptemp.append(temp1) self.temp_list = temptemp + ''' + sensor print source select + ''' + self.__sensor_print_src = __confTemp.get("sensor_print_src", None) + + # temp_data_source. the following is example: + ''' + "temp_data_source": [ + { + "path": "/sys/s3ip/temp_sensor/", + "type": "temp", + "Unit": Unit.Temperature, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + ], + ''' + tmp_list = [] + temp_data_source_conf = __confTemp.get("temp_data_source", {}) + for item in temp_data_source_conf: + try: + path = item.get("path", None) + if path is None: + continue + sensor_type = item.get("type", None) + if sensor_type is None: + continue + number_path = "%s/%s" % (path, "number") + ret, number = osutil.readsysfs(number_path) + if ret is True: + for index in range(1, int(number) + 1): + sensor_dir = "%s%d" % (sensor_type, index) + # only monitored sensor add to list + monitor_flag_path = "%s/%s/%s" % (path, sensor_dir, "monitor_flag") + if os.path.exists(monitor_flag_path): + ret, monitor_flag = osutil.readsysfs(monitor_flag_path) + if ret is True and int(monitor_flag) == 0: + continue + s3ip_conf = item.copy() + s3ip_conf["sensor_dir"] = sensor_dir + obj = temp_s3ip(s3ip_conf) + tmp_list.append(obj) + except Exception: + pass + self.temp_list_s3ip = tmp_list + # fan fantemp = [] fanconfig = __confTemp.get('fans', []) @@ -105,6 +161,54 @@ def __init__(self, conftype=0, conf=None): dcdctemp.append(dcdc1) self.dcdc_list = dcdctemp + # dcdc_data_source. the following is example: + ''' + "dcdc_data_source": [ + { + "path": "/sys/s3ip/vol_sensor/", + "type": "vol", + "Unit": Unit.Voltage, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + { + "path": "/sys/s3ip/curr_sensor/", + "type": "curr", + "Unit": Unit.Current, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + ], + ''' + dcdc_data_source_conf = __confTemp.get("dcdc_data_source", {}) + tmp_list = [] + for item in dcdc_data_source_conf: + try: + path = item.get("path", None) + if path is None: + continue + sensor_type = item.get("type", None) + if sensor_type is None: + continue + number_path = "%s/%s" % (path, "number") + ret, number = osutil.readsysfs(number_path) + if ret is True: + for index in range(1, int(number) + 1): + sensor_dir = "%s%d" % (sensor_type, index) + # only monitored sensor add to list + monitor_flag_path = "%s/%s/%s" % (path, sensor_dir, "monitor_flag") + if os.path.exists(monitor_flag_path): + ret, monitor_flag = osutil.readsysfs(monitor_flag_path) + if ret is True and int(monitor_flag) == 0: + continue + s3ip_conf = item.copy() + s3ip_conf["sensor_dir"] = sensor_dir + dcdc_obj = dcdc(s3ip_conf = s3ip_conf) + tmp_list.append(dcdc_obj) + except Exception: + pass + self.dcdc_list.extend(tmp_list) + # cpld cpldtemp = [] cpldconfig = __confTemp.get('cplds', []) @@ -316,3 +420,7 @@ def cpu(self, val): def get_cpu_byname(self, name): return self.cpu + + @property + def sensor_print_src(self): + return self.__sensor_print_src diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py index 0f2ad2167485..e0cd231308fa 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# component.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase from plat_hal.osutil import osutil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py index 09eed5f975ee..b0abe6e9c302 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# fan.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py index c6bec1abd1c2..8fb1d70e57e0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py @@ -1,9 +1,20 @@ #!/usr/bin/env python3 -############################################################################### # -# Hardware Abstraction Layer APIs -- CPU APIs. +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py index ba604995043d..719680f878b6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py @@ -1,11 +1,30 @@ #!/usr/bin/env python3 -from plat_hal.devicebase import devicebase -from plat_hal.sensor import sensor +# +# Copyright (C) 2024 Micas 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 +# 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 . +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor, sensor_s3ip class dcdc(devicebase): - def __init__(self, conf=None): + def __init__(self, conf = None, s3ip_conf = None): if conf is not None: self.name = conf.get('name', None) self.dcdc_id = conf.get("dcdc_id", None) self.sensor = sensor(conf) + if s3ip_conf is not None: + self.sensor = sensor_s3ip(s3ip_conf) + self.name = self.sensor.name + self.dcdc_id = self.sensor.sensor_id diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py index 001b4ee239bf..4d8eb6dcf511 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# devicebase.py -# Python implementation of the Class devicebase +# Copyright (C) 2024 Micas 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 +# 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 subprocess import shlex import ast @@ -30,6 +40,8 @@ def get_op_value(self, node): value = node.n elif isinstance(node, ast.Str): # node is Str Constant value = node.s + elif isinstance(node, ast.List): # node is List Constant + value = [element.value for element in node.elts] else: raise NotImplementedError("Unsupport operand type: %s" % type(node)) return value @@ -78,7 +90,7 @@ def visit_Call(self, node): int support one or two parameters, eg: int(xxx) or int(xxx, 16) xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp ''' - calc_tuple = ("float", "int", "str") + calc_tuple = ("float", "int", "str", "max", "min") if node.func.id not in calc_tuple: raise NotImplementedError("Unsupport function call type: %s" % node.func.id) @@ -86,7 +98,10 @@ def visit_Call(self, node): args_val_list = [] for item in node.args: ret = self.get_op_value(item) - args_val_list.append(ret) + if isinstance(ret, list): + args_val_list.extend(ret) + else: + args_val_list.append(ret) if node.func.id == "str": if len(args_val_list) != 1: @@ -101,6 +116,16 @@ def visit_Call(self, node): value = float(args_val_list[0]) self.value = value return value + + if node.func.id == "max": + value = max(args_val_list) + self.value = value + return value + + if node.func.id == "min": + value = min(args_val_list) + self.value = value + return value # int if len(args_val_list) == 1: value = int(args_val_list[0]) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py index 5b33af02527c..80543bec83a2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py @@ -1,12 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# fan.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 +# 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 . + from eepromutil.fru import ipmifru from eepromutil.fantlv import fan_tlv +from eepromutil.wedge_v5 import WedgeV5 from plat_hal.devicebase import devicebase from plat_hal.rotor import rotor @@ -50,6 +61,7 @@ def __init__(self, conf=None): self.EnableWatchdogConf = conf.get('EnableWatchdogConf', None) self.led_attrs_config = conf.get('led_attrs', None) self.led_config = conf.get('led', None) + self.led_map = conf.get('led_map', None) self.Rotor_config = conf.get('Rotor', None) self.fan_display_name_conifg = conf.get("fan_display_name", None) rotor_tmp = [] @@ -228,6 +240,12 @@ def get_led(self): if ret is False or value is None: return False, 'N/A' ledval = int(value) & mask + if self.led_map is not None: + led_color = self.led_map.get(ledval, None) + if led_color is None: + return False, 'N/A' + return True, led_color + for key, val in self.led_attrs_config.items(): if (ledval == val) and (key != "mask"): return True, key @@ -256,7 +274,7 @@ def get_rotor_byname(self, rotor_index): def get_presence(self): ret, val = self.get_value(self.present) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) @@ -273,9 +291,10 @@ def get_speed_pwm(self, rotor_index): rotor_item = self.get_rotor_index(rotor_index) if rotor_item is None: return False - if rotor_item.i2c_speed is None: + speed_pwm = rotor_item.i2c_speed + if speed_pwm is None: return False - val = round(rotor_item.i2c_speed * 100 / 255) + val = round(speed_pwm * 100 / 255) return val def feed_watchdog(self): @@ -286,16 +305,39 @@ def feed_watchdog(self): return ret return ret - def get_fru_info(self): + def get_wedge_v5_info(self, eeprom): + try: + product_version = None + product_sub_version = None + wegdev5 = WedgeV5() + rets = wegdev5.decode(eeprom) + for item in rets: + if item["code"] == wegdev5.FBWV5_PRODUCT_NAME: + self.productName = item["value"].replace("\x00", "").strip() + elif item["code"] == wegdev5.FBWV5_PRODUCT_SERIAL_NUMBER: + self.productSerialNumber = item["value"].replace("\x00", "").strip() + elif item["code"] == wegdev5.FBWV5_PRODUCT_VERSION: + product_version = "%d" % item["value"] + elif item["code"] == wegdev5.FBWV5_PRODUCT_SUB_VERSION: + product_sub_version = "%02d" % item["value"] + if product_version is not None and product_sub_version is not None: + self.hw_version = product_version + "." + product_sub_version + elif product_version is not None: + self.hw_version = product_version + elif product_sub_version is not None: + self.hw_version = product_sub_version + else: + self.hw_version = None + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def get_fru_info(self, eeprom): try: - if self.get_presence() is False: - raise Exception("%s: not present" % self.name) - eeprom = self.get_eeprom_info(self.e2loc) - if eeprom is None: - raise Exception("%s: value is none" % self.name) fru = ipmifru() - if isinstance(eeprom, bytes): - eeprom = self.byteTostr(eeprom) fru.decodeBin(eeprom) self.productName = fru.productInfoArea.productName.strip() # PN self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip() # SN @@ -307,13 +349,8 @@ def get_fru_info(self): return False return True - def get_tlv_info(self): + def get_tlv_info(self, eeprom): try: - if self.get_presence() is False: - raise Exception("%s: not present" % self.name) - eeprom = self.get_eeprom_info(self.e2loc) - if eeprom is None: - raise Exception("%s: value is none" % self.name) tlv = fan_tlv() rets = tlv.decode(eeprom) for item in rets: @@ -330,14 +367,53 @@ def get_tlv_info(self): return False return True + def decode_eeprom_by_type(self, e2_type, eeprom): + if e2_type == "fru": + return self.get_fru_info(eeprom) + + if e2_type == "fantlv": + return self.get_tlv_info(eeprom) + + if e2_type == "wedge_v5": + return self.get_wedge_v5_info(eeprom) + return False + + def decode_eeprom_by_traverse(self, eeprom): + support_e2_type = ("fru", "fantlv", "wedge_v5") + for e2_type in support_e2_type: + status = self.decode_eeprom_by_type(e2_type, eeprom) + if status is True: + return True + return False + def decode_eeprom_info(self): '''get fan name, hw version, sn''' - if self.e2_type == "fru": - return self.get_fru_info() + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) - if self.e2_type == "fantlv": - return self.get_tlv_info() + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + if self.e2_type is None: + return self.decode_eeprom_by_traverse(eeprom) + + if isinstance(self.e2_type, str): + return self.decode_eeprom_by_type(self.e2_type, eeprom) + + if isinstance(self.e2_type, list): + for e2_type in self.e2_type: + status = self.decode_eeprom_by_type(e2_type, eeprom) + if status is True: + return True + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None return False def get_AirFlow(self): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py index 88873a029b64..e12c469e612b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py @@ -1,13 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# interface.py -# Python implementation of the Class interface +# Copyright (C) 2024 Micas 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 +# 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 collections from plat_hal.chassisbase import chassisbase -from plat_hal.baseutil import baseutil +from plat_hal.baseutil import baseutil, getplatform_name from plat_hal.osutil import osutil @@ -864,7 +874,7 @@ def get_dcdc_all_info(self): tmp = dcdc.sensor.Value if tmp is not None: dicttmp['Value'] = tmp - if tmp > dicttmp['Max'] or tmp < dicttmp['Min']: + if tmp > float(dicttmp['Max']) or tmp < float(dicttmp['Min']): dicttmp["Status"] = "NOT OK" else: dicttmp["Status"] = "OK" @@ -914,6 +924,8 @@ def get_monitor_temp_by_id(self, temp_id): dic["High"] = self.error_ret dic["Value"] = self.error_ret dic["Unit"] = self.error_ret + dic["Invalid"] = self.error_ret + dic["Error"] = self.error_ret else: dic["Name"] = temptmp.name dic["Api_name"] = temptmp.api_name @@ -924,6 +936,8 @@ def get_monitor_temp_by_id(self, temp_id): temp_value = temptmp.Value dic["Value"] = temp_value if (temp_value is not None) else self.error_ret dic["Unit"] = temptmp.Unit + dic["Invalid"] = temptmp.temp_invalid + dic["Error"] = temptmp.temp_error return dic def get_temp_info(self): @@ -942,6 +956,22 @@ def get_temp_info(self): val_list[temp.name] = dic return val_list + def get_temp_info_s3ip(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list_s3ip + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + return val_list + def get_sensor_info(self): val_list = collections.OrderedDict() # temp @@ -1337,3 +1367,10 @@ def get_cpu_reboot_cause(self): return "Unknown reboot cause" return cpu.get_cpu_reboot_cause() + def get_sensor_print_src(self): + """ + Get sensor data source + @return string of sensor data source + """ + return self.chas.sensor_print_src + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py index 7fb869c74d7f..0ae751b81e3d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# led.py -# Python implementation of the Class led +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase @@ -15,6 +25,7 @@ def __init__(self, conf=None): self.led_type = conf.get('led_type', None) self.led_attrs_config = conf.get('led_attrs', None) self.led_config = conf.get('led', None) + self.led_map = conf.get('led_map', None) def set_color(self, color): status = self.led_attrs_config.get(color, None) @@ -46,6 +57,11 @@ def get_color(self): if ret is False or value is None: return False, 'N/A' ledval = int(value) & mask + if self.led_map is not None: + led_color = self.led_map.get(ledval, None) + if led_color is None: + return False, 'N/A' + return True, led_color for key, val in self.led_attrs_config.items(): if (ledval == val) and (key != "mask"): return True, key diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py index 9ac32cace263..d09fa70973c7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# onie_e2.py -# Python implementation of the Class onie_e2 +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase from eepromutil.onietlv import onie_tlv diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py index 684e26bb9ecd..4501bcf5f29a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py @@ -1,10 +1,19 @@ #!/usr/bin/env python3 -####################################################### # -# osutil.py -# Python implementation of the Class osutil +# Copyright (C) 2024 Micas 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 +# 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 glob @@ -53,37 +62,31 @@ def wrapper(*args, **kwargs): return decorator -pidfile = None - - def file_rw_lock(file_path): - global pidfile pidfile = open(file_path, "r") try: fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) - platform_hal_debug("file_rw_lock success") - return True + platform_hal_debug("%s file_rw_lock success, pidfile: %s" % (file_path, pidfile)) + return True, pidfile except Exception: if pidfile is not None: pidfile.close() pidfile = None - return False + return False, pidfile -def file_rw_unlock(): +def file_rw_unlock(pidfile): try: - global pidfile - if pidfile is not None: fcntl.flock(pidfile, fcntl.LOCK_UN) pidfile.close() + platform_hal_debug("file_rw_unlock success, pidfile: %s" % pidfile) pidfile = None - platform_hal_debug("file_rw_unlock success") else: platform_hal_debug("pidfile is invalid, do nothing") return True except Exception as e: - platform_hal_debug("file_rw_unlock err, msg: %s" % (str(e))) + platform_hal_debug("file_rw_unlock err, pidfile: %s, msg: %s" % (pidfile, str(e))) return False @@ -91,11 +94,11 @@ def take_file_rw_lock(file_path): loop = 1000 ret = False for i in range(0, loop): - ret = file_rw_lock(file_path) + ret, pidfile = file_rw_lock(file_path) if ret is True: break time.sleep(0.001) - return ret + return ret, pidfile class osutil(object): @@ -252,6 +255,7 @@ def io_rd(reg_addr, read_len=1): @staticmethod def readsysfs(location, flock_path=None): flock_path_tmp = None + pidfile = None platform_hal_debug("readsysfs, location:%s, flock_path:%s" % (location, flock_path)) try: if flock_path is not None: @@ -259,7 +263,7 @@ def readsysfs(location, flock_path=None): if len(flock_paths) != 0: flock_path_tmp = flock_paths[0] platform_hal_debug("try to get file lock, path:%s" % flock_path_tmp) - ret = take_file_rw_lock(flock_path_tmp) + ret, pidfile = take_file_rw_lock(flock_path_tmp) if ret is False: platform_hal_debug("take file lock timeout, path:%s" % flock_path_tmp) return False, ("take file rw lock timeout, path:%s" % flock_path_tmp) @@ -270,14 +274,14 @@ def readsysfs(location, flock_path=None): with open(locations[0], 'rb') as fd1: retval = fd1.read() retval = osutil.byteTostr(retval) - if flock_path_tmp is not None: - file_rw_unlock() + if pidfile is not None: + file_rw_unlock(pidfile) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") except Exception as e: - if flock_path_tmp is not None: - file_rw_unlock() + if pidfile is not None: + file_rw_unlock(pidfile) platform_hal_debug("readsysfs error, msg:%s" % str(e)) return False, (str(e) + " location[%s]" % location) return True, retval diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py index a7fc90e0fe23..c62da1929d34 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# psu.py -# Python implementation of the Class psu +# Copyright (C) 2024 Micas 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 +# 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 . + from eepromutil.fru import ipmifru from eepromutil.cust_fru import CustFru from plat_hal.devicebase import devicebase @@ -428,7 +438,7 @@ def psu_not_present_pwm(self, val): @property def present(self): ret, val = self.get_value(self.__presentconfig) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False mask = self.__presentconfig.get("mask") if isinstance(val, str): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py index ff120cb474b2..0b96bf340ce3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# rotor.py -# Python implementation of the Class rotor +# Copyright (C) 2024 Micas 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 +# 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 . + from plat_hal.devicebase import devicebase from plat_hal.sensor import sensor @@ -32,7 +42,7 @@ def __init__(self, conf=None): def getRunning(self): ret, val = self.get_value(self.rotor_run_conf) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) @@ -120,7 +130,7 @@ def rotor_HwAlarm(self): ret, val = self.get_value(self.rotor_HwAlarm_conf) mask = self.rotor_HwAlarm_conf.get("mask") no_alarm_value = self.rotor_HwAlarm_conf.get("no_alarm") - if ret is False or val is None: + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py index af2a5384b618..99396923c41a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# sensor.py -# Python implementation of the Class sensor +# Copyright (C) 2024 Micas 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 +# 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 time from plat_hal.devicebase import devicebase @@ -103,9 +113,9 @@ def get_median(self, value_config, read_times): val_list = [] for i in range(0, read_times): ret, real_value = self.get_value(value_config) - if i != (read_times - 1): - time.sleep(0.01) if ret is False or real_value is None: + if i != (read_times - 1): + time.sleep(0.01) continue val_list.append(real_value) val_list.sort() @@ -272,3 +282,65 @@ def __str__(self): self.Max, self.Unit, self.format) return tmpstr + +class sensor_s3ip(sensor): + def __init__(self, s3ip_conf): + self.s3ip_conf = s3ip_conf + value_conf = {} + value_conf["loc"] = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "value") + value_conf["way"] = "sysfs" + conf = {} + conf["value"] = value_conf + conf["read_times"] = s3ip_conf.get("read_times", 1) + conf["Unit"] = unit = s3ip_conf.get("Unit", None) + conf["format"] = unit = s3ip_conf.get("format", None) + super(sensor_s3ip, self).__init__(conf) + self.min_path = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "min") + self.max_path = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "max") + self.alias = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "alias") + self.sensor_id = self.s3ip_conf.get("type").upper() + + @property + def Min(self): + try: + ret, val = self.get_sysfs(self.min_path) + if ret is True: + return val + except Exception: + pass + return None + + @Min.setter + def Min(self, val): + try: + return self.set_sysfs(self.min_path, val) + except Exception as e: + return False, (str(e) + " location[%s][%d]" % (self.min_path, val)) + + @property + def Max(self): + try: + ret, val = self.get_sysfs(self.max_path) + if ret is True: + return val + except Exception: + pass + return None + + @Max.setter + def Max(self, val): + try: + return self.set_sysfs(self.max_path, val) + except Exception as e: + return False, (str(e) + " location[%s][%d]" % (self.max_path, val)) + + @property + def name(self): + try: + ret, val = self.get_sysfs(self.alias) + if ret is True: + return val + except Exception: + pass + return None + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py index a202c20339c9..1dbd443f71c3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py @@ -1,14 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# temp.py -# Python implementation of the Class temp +# Copyright (C) 2024 Micas 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 +# 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 syslog -from plat_hal.sensor import sensor - +from plat_hal.sensor import sensor, sensor_s3ip PLATFORM_HAL_TEMP_DEBUG_FILE = "/etc/.platform_hal_temp_debug_flag" @@ -82,7 +91,7 @@ def get_max_value(self, conf): ret, val = self.get_value(conf) if ret is False or val is None: return None - return val + return float(val) except Exception: return None @@ -120,6 +129,25 @@ def Value(self): self.__Value = int(max_val) else: self.__Value = self.get_format_value(self.format % max_val) + elif isinstance(self.ValueConfig, dict) and self.ValueConfig.get("val_conf_list") is not None: + val_list = [] + fail_set = set() + for index, val_conf_item in enumerate(self.ValueConfig["val_conf_list"]): + val_tmp = self.get_max_value(val_conf_item) + if val_tmp is None: + fail_set.add(index) + fail_val = val_conf_item.get("fail_val") + if fail_val is None: + return None + val_tmp = fail_val + val_list.append(val_tmp) + # check fail set + fail_conf_set_list = self.ValueConfig.get("fail_conf_set_list",[]) + for item in fail_conf_set_list: + if item.issubset(fail_set): + return None + val_tuple = tuple(val_list) + self.__Value = self.get_format_value(self.ValueConfig["format"] % (val_tuple)) else: ret, val = self.get_value(self.ValueConfig) if ret is False or val is None: @@ -137,3 +165,8 @@ def Value(self): @Value.setter def Value(self, val): self.__Value = val + +class temp_s3ip(sensor_s3ip): + def __init__(self, s3ip_conf = None): + super(temp_s3ip, self).__init__(s3ip_conf) + self.temp_id = s3ip_conf.get("type").upper() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py index 2cb7f5273a44..86e102594cab 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py @@ -1,11 +1,26 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import requests + class RestfulApiClient(): Debug_file = "/tmp/restful_api_debug" BmcBaseUrl = 'http://240.1.1.2:8080' @@ -14,12 +29,13 @@ class RestfulApiClient(): HostnameUrl = '/api/v1.0/hostname' EventsUrl = '/api/v1.0/events' SensorsUrl = '/api/v1.0/sys_switch/sensors' + TempSensorsUrl = '/api/v1.0/sys_switch/temp_sensor' + VolSensorsUrl = '/api/v1.0/sys_switch/vol_sensor' + CurSensorsUrl = '/api/v1.0/sys_switch/cur_sensor' SyseepromUrl = '/api/v1.0/syseeprom' FansUrl = '/api/v1.0/sys_switch/fans' - # FanUrl = '/api/v1.0/sys_switch/fan/fan1' FanUrl = '/api/v1.0/sys_switch/fan/' PsusUrl = '/api/v1.0/sys_switch/psus' - # PsuUrl = '/api/v1.0/sys_switch/psu/psu1' PsuUrl = '/api/v1.0/sys_switch/psu/' LEDsUrl = '/api/v1.0/sys_switch/leds' FirmwaresUrl = '/api/v1.0/sys_switch/firmwares' @@ -28,7 +44,6 @@ class RestfulApiClient(): TimeUrl = '/api/v1.0/time' TimezoneUrl = '/api/v1.0/timezone' NtpUrl = '/api/v1.0/ntp' - PowerUrl = '/api/v1.0/power' def restful_api_error_log(self, msg): syslog.openlog("restful_api") diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py index 340a1f7a733f..fdc4410e2c20 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py index 5f1659b3bbf0..d474cffa2d35 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py @@ -1,25 +1,19 @@ #!/usr/bin/env python3 -# smbus2 - A drop-in replacement for smbus-cffi/smbus-python -# The MIT License (MIT) -# Copyright (c) 2017 Karl-Petter Lindegaard # -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: +# Copyright (C) 2024 Micas Networks Inc. # -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. +# 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. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. +# 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 sys diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile index e432430dba46..4e106f013819 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile @@ -8,9 +8,11 @@ module_out_put_dir := $(PWD)/build export module_out_put_dir PLAT_SYSFS_DIR = $(PWD)/plat_sysfs +S3IP_SYSFS_DIR = $(PWD)/s3ip_sysfs PINCTRL = $(PWD)/pinctrl export PLAT_SYSFS_DIR +export S3IP_SYSFS_DIR platform_common-objs := platform_common_module.o dfd_tlveeprom.o obj-m += platform_common.o @@ -39,9 +41,14 @@ obj-m += wb_i2c_mux_pca9641.o obj-m += wb_i2c_mux_pca954x.o obj-m += wb_xdpe132g5c_pmbus.o obj-m += wb_i2c_gpio_device.o +obj-m += ct7148.o +obj-m += wb_ucd9081.o +obj-m += wb_indirect_dev.o + all : $(MAKE) -C $(PLAT_SYSFS_DIR) + $(MAKE) -C $(S3IP_SYSFS_DIR) $(MAKE) -C $(PINCTRL) $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c new file mode 100644 index 000000000000..fff4b0e0eecc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c @@ -0,0 +1,237 @@ +/* + * An ct7148 driver for tmp ct7148 function + * + * Copyright (C) 2024 Micas 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 + * 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 + +/* debug switch level */ +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +static int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +#define CT7318_DEBUG(fmt, arg...) do { \ + if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if (debuglevel >= DBG_ERROR) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define CT7318_ERROR(fmt, arg...) do { \ + if (debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +enum chips { ct7318 }; + +/* The CT7318 registers */ +#define CT7318_CONFIG_REG_1 0x09 +#define CT7318_CONVERSION_RATE_REG 0x0A +#define CT7318_MANUFACTURER_ID_REG 0xFE +#define CT7318_DEVICE_ID_REG 0xFF + +static const u8 CT7318_TEMP_MSB[2] = { 0x00, 0x01 }; +static const u8 CT7318_TEMP_LSB[2] = { 0x15, 0x10 }; + +/* Flags */ +#define CT7318_CONFIG_SHUTDOWN 0x40 +#define CT7318_CONFIG_RANGE 0x04 + +/* Manufacturer / Device ID's */ +#define CT7318_MANUFACTURER_ID 0x59 +#define CT7318_DEVICE_ID 0x8D + +static const struct i2c_device_id ct7318_id[] = { + { "ct7318", 2 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ct7318_id); + +static const struct of_device_id ct7318_of_match[] = { + {.compatible = "sensylink,ct7318"}, + { }, +}; +MODULE_DEVICE_TABLE(of, ct7318_of_match); + +struct ct7318_data { + struct i2c_client *client; + struct mutex update_lock; + u32 temp_config[5]; + struct hwmon_channel_info temp_info; + const struct hwmon_channel_info *info[2]; + struct hwmon_chip_info chip; + char valid; + unsigned long last_updated; + unsigned long channels; + u8 config; + s16 temp[4]; +}; + +static int ct7318_register_to_temp(s16 reg) +{ + s16 tmp_val; + int val; + + CT7318_DEBUG("reg_data, data=0x%04x \n", reg); + + /* Positive number:reg*0.125 */ + if (!(reg & 0x400)) { + val = reg * 125; + /* Negative number: The first bit is the sign bit, and the rest is inverted +1 */ + } else { + tmp_val = ((~((s16)reg)) & 0x7ff) + 1; + CT7318_DEBUG("ct7318, tmp_val=0x%08x -- %d\n", tmp_val, tmp_val); + val = -(tmp_val * 125); + } + + CT7318_DEBUG("ct7318 reg2data, val=0x%08x -- %d \n", val, val); + + return val; +} + +static struct ct7318_data *ct7318_update_device(struct device *dev) +{ + struct ct7318_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + (HZ / 16)) || !data->valid) { + + for (i = 0; i < data->channels; i++) { + data->temp[i] = i2c_smbus_read_byte_data(client, CT7318_TEMP_MSB[i]) << 3; + data->temp[i] |= (i2c_smbus_read_byte_data(client, CT7318_TEMP_LSB[i]) >> 5); + } + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int ct7318_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct ct7318_data *ct7318 = ct7318_update_device(dev); + + switch (attr) { + case hwmon_temp_input: + *val = ct7318_register_to_temp(ct7318->temp[channel]); + return 0; + case hwmon_temp_fault: + /* + * The OPEN bit signals a fault. This is bit 0 of the temperature + * register (low byte). + */ + return 0; + default: + return -EOPNOTSUPP; + } +} + +static umode_t ct7318_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel) +{ + switch (attr) { + case hwmon_temp_fault: + if (channel == 0) { + return 0; + } + return 0444; + case hwmon_temp_input: + return 0444; + default: + return 0; + } +} + +static const struct hwmon_ops ct7318_ops = { + .read = ct7318_read, + .is_visible = ct7318_is_visible, +}; + +static int ct7318_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct ct7318_data *data; + int i; + + data = devm_kzalloc(dev, sizeof(struct ct7318_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + mutex_init(&data->update_lock); + + data->channels = i2c_match_id(ct7318_id, client)->driver_data; + data->client = client; + + for (i = 0; i < data->channels; i++) { + data->temp_config[i] = HWMON_T_INPUT; + } + + data->chip.ops = &ct7318_ops; + data->chip.info = data->info; + + data->info[0] = &data->temp_info; + + data->temp_info.type = hwmon_temp; + data->temp_info.config = data->temp_config; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &data->chip, NULL); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static struct i2c_driver ct7318_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ct7318", + .of_match_table = of_match_ptr(ct7318_of_match), + }, + .probe_new = ct7318_probe, + .id_table = ct7318_id, +}; + +module_i2c_driver(ct7318_driver); + +MODULE_AUTHOR("sonic_rd@whitebox"); +MODULE_DESCRIPTION("Sensylink CT7318 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c index 0d6f38ecc551..7469c760a568 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c @@ -1,9 +1,11 @@ /* - * Copyright (C) 2003-2014 FreeIPMI Core Team + * An dfd_tlveeprom driver for dfd rlveeprom function * - * This program is free software: you can redistribute it and/or modify + * Copyright (C) 2024 Micas 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 - * the Free Software Foundation, either version 3 of the License, or + * 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, @@ -12,33 +14,10 @@ * 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 . - * + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/*****************************************************************************\ - * Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC. - * Copyright (C) 2007 The Regents of the University of California. - * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). - * Written by Albert Chu - * UCRL-CODE-232183 - * - * This file is part of Ipmi-fru, a tool used for retrieving - * motherboard field replaceable unit (FRU) information. For details, - * see http://www.llnl.gov/linux/. - * - * Ipmi-fru 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. - * - * Ipmi-fru 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 Ipmi-fru. If not, see . -\*****************************************************************************/ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h index 6eaac5848223..30991eca5bc8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_tlveeprom driver + * + * Copyright (C) 2024 Micas 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 + * 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 DFD_OPENBMC_TLVEEPROM_H #define DFD_OPENBMC_TLVEEPROM_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h index 649a8452debe..293484605cf7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h @@ -1,3 +1,23 @@ +/* + * A header definition for fpga_i2c driver + * + * Copyright (C) 2024 Micas 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 + * 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 _FPGA_I2C_H #define _FPGA_I2C_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c index e74f4e800582..84d3f54943fd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c @@ -1,9 +1,21 @@ /* - * hw_test.c - * Original Author : support, 2020-10-15 + * An hw_test driver for hw test read/write function * - * History - * v1.0 support 2020-10-15 Initial version. + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h index 695fa336c4ff..231396390272 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h @@ -1,3 +1,22 @@ +/* + * A header definition for hw_test driver + * + * Copyright (C) 2024 Micas 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 + * 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 _LINUX_DRAM_DRIVER_H #define _LINUX_DRAM_DRIVER_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h index 840103c40c14..81655ead6007 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h @@ -1,11 +1,24 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ /* - * Core private header for the pin control subsystem + * A header definition for pin control subsystem * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on core.h * Copyright (C) 2011 ST-Ericsson SA - * Written on behalf of Linaro for ST-Ericsson * - * Author: Linus Walleij + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c index 753c8a061a86..7689ba1371bf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c @@ -1,9 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * Intel Denverton SoC pinctrl/GPIO driver + * An wb_gpio_c3000 driver for gpio c3000 function * - * Copyright (C) 2017, Intel Corporation - * Author: Mika Westerberg + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c index 33ab19a5ac44..ddfc5791b706 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c @@ -1,3 +1,23 @@ +/* + * An wb_gpio_c3000_device driver for gpio c3000 device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c index 7a52f17ac8f9..98d735ea6a1a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c @@ -1,10 +1,24 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * Intel pinctrl/GPIO core driver. + * An wb_pinctrl_intel driver for pinctrl intel function * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on pinctrl-intel.c * Copyright (C) 2015, Intel Corporation - * Authors: Mathias Nyman - * Mika Westerberg + * + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h index 5ed0cc0651a5..111edabacfcc 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h @@ -1,10 +1,24 @@ -/* SPDX-License-Identifier: GPL-2.0 */ /* - * Core pinctrl/GPIO driver for Intel GPIO controllers + * A header definition for pinctrl_intel driver * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on pinctrl-intel.h * Copyright (C) 2015, Intel Corporation - * Authors: Mathias Nyman - * Mika Westerberg + * + * 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 PINCTRL_INTEL_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c index 22962556eb0d..44bfe8e95b6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg driver for cfg function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c index 9c8dc6aa098e..cd26851725cc 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_adapter driver for cfg adapter function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c index ac1c22ff1c51..eaf58f6bc519 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_file driver for cfg file function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c index c1ad958bc8bb..26a7fab2c967 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_info driver for cfg information function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -551,6 +571,22 @@ static int dfd_info_reg2data_mac_th5(int data, int *temp_value) return DFD_RV_OK; } +static int dfd_info_reg2data_mac_th4(int data, int *temp_value) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, data=%d\n", data); + + tmp_val = data >> 4; + val = 356070 - (((tmp_val - 2) * 237340) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, val=%d\n", val); + *temp_value = val; + + return DFD_RV_OK; +} + static int dfd_info_reg2data_mac_td3(int data, int *temp_value) { int val; @@ -658,6 +694,9 @@ static int dfd_info_get_cpld_temperature(int key, int *value) case MAC_TD3: rv = dfd_info_reg2data_mac_td3(temp_reg, &temp_value); break; + case MAC_TH4: + rv = dfd_info_reg2data_mac_th4(temp_reg, &temp_value); + break; default: temp_value = temp_reg; rv = DFD_RV_OK; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c index d6fd7e104c9f..450d8a360173 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_listnode driver for cfg listnode function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c index d8965d75c9c0..203a8cc0d637 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_fan_driver driver for dfd fan function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c index 9e5b00b795de..c937cb790fd1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c @@ -1,3 +1,23 @@ +/* + * An dfd_module driver for dfd module function + * + * Copyright (C) 2024 Micas 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 + * 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 "../dev_sysfs/include/sysfs_common.h" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c index 55e2e4339ae7..bb0eba0bfa05 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_psu_driver driver for dfd psu function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c index bfca20290efb..433a51dc75ff 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_sensor_driver driver for dfd sensor function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c index 5c1faff975b1..f768c5640e76 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_sff_driver driver for dfd sff function + * + * Copyright (C) 2024 Micas 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 + * 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/dfd_module.h" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c index 69c82adabef0..6e3c70abea6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_slot_driver driver for dfd slot function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h index af3de1ca9938..2b698f37af61 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_H__ #define __DFD_CFG_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h index 70d8b536c437..c599250dd225 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_adapter driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_ADAPTER_H__ #define __DFD_CFG_ADAPTER_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h index 50d7a42d5564..d74bfae0d697 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_file driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_FILE_H__ #define __DFD_CFG_FILE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h index 88e8f92c10fe..def93cd51353 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_info driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_INFO_H__ #define __DFD_CFG_INFO_H__ @@ -97,7 +117,8 @@ typedef enum sensor_format_mem_s { LINEAR16, TMP464, MAC_TH5, - MAC_TD3 + MAC_TD3, + MAC_TH4 } sensor_format_mem_t; typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h index 955dfa96e42e..9c4bb057beb8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_listnode driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_LISTNODE_H__ #define __DFD_CFG_LISTNODE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h index 1065fd9eed3f..e1987b0f06cd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_fan_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_FAN_DRIVER_H_ #define _DFD_FAN_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h index a547255cf3ab..8ed110e7ae69 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_module driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_MODULE_H__ #define __DFD_MODULE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h index ce7199660557..a9d7f465915e 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_psu_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_PSU_DRIVER_H_ #define _DFD_PSU_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h index 16733b26029f..25998164ab36 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_sensor_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_SENSORS_DRIVER_H_ #define _DFD_SENSORS_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h index 7107b72ee4b2..3e9305d6647c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_aff_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_SFF_DRIVER_H_ #define _DFD_SFF_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h index c68caecd2e66..1e628c0e9754 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_slot_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_SLOT_DRIVER_H_ #define _DFD_SLOT_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h index bbd813e87114..b862ef7121cf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h @@ -1,3 +1,23 @@ +/* + * A header definition for plat_switch driver + * + * Copyright (C) 2024 Micas 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 + * 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 _PLAT_SWITCH_H_ #define _PLAT_SWITCH_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h index 5b73731e1fbf..4ac0cee1a4a6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h @@ -1,3 +1,23 @@ +/* + * A header definition for sysfs_common driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SYSFS_COMMON_H_ #define _SYSFS_COMMON_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c index 931c7c243a21..3809da9ec1a1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c @@ -1,8 +1,21 @@ /* - * plat_fan.c + * An plat_fan driver for plat fan function * - * This module create fan kobjects and attributes in /sys/wb_plat/fan + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c index 197f94b64991..4207b9bc8ca7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c @@ -1,8 +1,21 @@ /* - * plat_psu.c + * An plat_psu driver for plat psu function * - * This module create psu kobjects and attributes in /sys/wb_plat/psu + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c index aaf62f4c1a3c..da7d5a872350 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c @@ -1,7 +1,21 @@ /* - * plat_sensor.c + * An plat_sensor driver for plat sensor function * - * This module create sensor kobjects and attributes in /sys/wb_plat/sensor + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c index 50c0f78aede9..cf2cd5181f01 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c @@ -1,8 +1,21 @@ /* - * plat_sff.c + * An plat_sff driver for plat sff function * - * This module create sff kobjects and attributes in /sys/wb_plat/sff + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c index 7c50f283bd06..979de7418475 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c @@ -1,8 +1,21 @@ /* - * plat_slot.c + * An plat_slot driver for plat slot function * - * This module create sff kobjects and attributes in /sys/wb_plat/slot + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c index fea008b41bfe..e36ff6657c90 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c @@ -1,11 +1,23 @@ /* - * plat_switch.c + * An plat_switch driver for plat switch function * - * This module create a kset in sysfs called /sys/wb_plat - * Then other switch kobjects are created and assigned to this kset, - * such as "board", "cpld", "fan", "psu", "sff", ... + * Copyright (C) 2024 Micas 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 + * 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/plat_switch.h" #define SWITCH_INFO(fmt, args...) LOG_INFO("switch: ", fmt, ##args) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h index 9e4a4fae00c1..ffd752204e4f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h @@ -1,3 +1,23 @@ +/* + * A header definition for platfrom_common driver + * + * Copyright (C) 2024 Micas 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 + * 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 __PLATFORM_COMMON_H__ #define __PLATFORM_COMMON_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c index 189a3aa056b2..57f436e5b8af 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c @@ -1,3 +1,23 @@ +/* + * An platform_common_module driver for platform common modules function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h index 10fb17879f8e..853dba4333e3 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h @@ -1,9 +1,25 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * pmbus.h - Common defines and structures for PMBus devices + * A header definition for pmbus driver * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on kernel pmbus.h * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile new file mode 100644 index 000000000000..c4e5d6928bb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile @@ -0,0 +1,19 @@ +PWD = $(shell pwd) +SYSFS_OUT_PUT := $(PWD)/build +sysfs_out_put_dir := $(SYSFS_OUT_PUT)/S3IP_sysfs/ +sysfs_cfg_dir := $(SYSFS_OUT_PUT)/dfd_cfg/ +export sysfs_out_put_dir sysfs_cfg_dir + +SYSFS_DRIVER_DIR = $(PWD)/sysfs_driver +SWITCH_DRIVER_DIR = $(PWD)/switch_driver +DEVICE_DRIVER_DIR = $(PWD)/device_driver + +export SYSFS_DRIVER_DIR SWITCH_DRIVER_DIR + +all : + $(MAKE) -C $(SYSFS_DRIVER_DIR) + $(MAKE) -C $(SWITCH_DRIVER_DIR) + $(MAKE) -C $(DEVICE_DRIVER_DIR) + +clean : + -rm -rf $(SYSFS_OUT_PUT) \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile new file mode 100644 index 000000000000..a971e0bf3844 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile @@ -0,0 +1,36 @@ +PWD = $(shell pwd) + +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +DEV_SYSFS_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../sysfs_driver/include) +SWITCH_DVR_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../switch_driver/include) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -I$(DEV_SYSFS_HEADER_DIR) +EXTRA_CFLAGS+= -I$(SWITCH_DVR_HEADER_DIR) +EXTRA_CFLAGS+= -Wall + +KBUILD_EXTRA_SYMBOLS += $(SYSFS_DRIVER_DIR)/Module.symvers +KBUILD_EXTRA_SYMBOLS += $(SWITCH_DRIVER_DIR)/Module.symvers + +obj-m := syseeprom_device_driver.o +obj-m += fan_device_driver.o +obj-m += cpld_device_driver.o +obj-m += sysled_device_driver.o +obj-m += slot_device_driver.o +obj-m += psu_device_driver.o +obj-m += transceiver_device_driver.o +obj-m += temp_sensor_device_driver.o +obj-m += vol_sensor_device_driver.o +obj-m += curr_sensor_device_driver.o +obj-m += fpga_device_driver.o +obj-m += watchdog_device_driver.o +obj-m += system_device_driver.o +obj-m += eeprom_device_driver.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c new file mode 100644 index 000000000000..de760b7bc775 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c @@ -0,0 +1,217 @@ +/* + * An cpld_device_driver driver for cpld devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "cpld_sysfs.h" +#include "dfd_sysfs_common.h" + +#define CPLD_INFO(fmt, args...) LOG_INFO("cpld: ", fmt, ##args) +#define CPLD_ERR(fmt, args...) LOG_ERR("cpld: ", fmt, ##args) +#define CPLD_DBG(fmt, args...) LOG_DBG("cpld: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************CPLD***********************************************/ +static int wb_get_main_board_cpld_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_number); + + ret = g_drv->get_main_board_cpld_number(); + return ret; +} + +/* + * wb_get_main_board_cpld_alias - Used to identify the location of cpld, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_alias(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_alias); + + ret = g_drv->get_main_board_cpld_alias(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_type - Used to get cpld model name + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_type(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_type); + + ret = g_drv->get_main_board_cpld_type(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_firmware_version - Used to get cpld firmware version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_firmware_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_firmware_version); + + ret = g_drv->get_main_board_cpld_firmware_version(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_board_version - Used to get cpld board version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_board_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_board_version); + + ret = g_drv->get_main_board_cpld_board_version(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_test_reg - Used to test cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_test_reg(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_test_reg); + + ret = g_drv->get_main_board_cpld_test_reg(cpld_index, buf, count); + return ret; +} + +/* + * wb_set_main_board_cpld_test_reg - Used to test cpld register write + * @cpld_index: start with 1 + * @value: value write to cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_main_board_cpld_test_reg(unsigned int cpld_index, unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_main_board_cpld_test_reg); + + ret = g_drv->set_main_board_cpld_test_reg(cpld_index, value); + return ret; +} +/***************************************end of CPLD*******************************************/ + +static struct s3ip_sysfs_cpld_drivers_s drivers = { + /* + * set ODM CPLD drivers to /sys/s3ip/cpld, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_cpld_number = wb_get_main_board_cpld_number, + .get_main_board_cpld_alias = wb_get_main_board_cpld_alias, + .get_main_board_cpld_type = wb_get_main_board_cpld_type, + .get_main_board_cpld_firmware_version = wb_get_main_board_cpld_firmware_version, + .get_main_board_cpld_board_version = wb_get_main_board_cpld_board_version, + .get_main_board_cpld_test_reg = wb_get_main_board_cpld_test_reg, + .set_main_board_cpld_test_reg = wb_set_main_board_cpld_test_reg, +}; + +static int __init cpld_device_driver_init(void) +{ + int ret; + + CPLD_INFO("cpld_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_cpld_drivers_register(&drivers); + if (ret < 0) { + CPLD_ERR("cpld drivers register err, ret %d.\n", ret); + return ret; + } + + CPLD_INFO("cpld_init success.\n"); + return 0; +} + +static void __exit cpld_device_driver_exit(void) +{ + s3ip_sysfs_cpld_drivers_unregister(); + CPLD_INFO("cpld_exit success.\n"); + return; +} + +module_init(cpld_device_driver_init); +module_exit(cpld_device_driver_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("cpld device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c new file mode 100644 index 000000000000..1c2a1e25f6de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c @@ -0,0 +1,220 @@ +/* + * An curr_sensor_device_driver driver for current devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "curr_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define CURR_SENSOR_INFO(fmt, args...) LOG_INFO("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_ERR(fmt, args...) LOG_ERR("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_DBG(fmt, args...) LOG_DBG("curr_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*************************************main board current***************************************/ +static int wb_get_main_board_curr_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_number); + + ret = g_drv->get_main_board_curr_number(); + return ret; +} + +/* + * wb_get_main_board_curr_alias - Used to identify the location of the current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_alias(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_alias); + + ret = g_drv->get_main_board_curr_alias(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_type - Used to get the model of current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_type(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_type); + + ret = g_drv->get_main_board_curr_type(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_max - Used to get the maximum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_max(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_max); + + ret = g_drv->get_main_board_curr_max(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_min - Used to get the minimum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_min(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_min); + + ret = g_drv->get_main_board_curr_min(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_value - Used to get the input value of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_value(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_value); + + ret = g_drv->get_main_board_curr_value(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_monitor_flag - Used to get the monitor flag of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_monitor_flag(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_monitor_flag); + + ret = g_drv->get_main_board_curr_monitor_flag(curr_index, buf, count); + return ret; +} +/*********************************end of main board current************************************/ + +static struct s3ip_sysfs_curr_sensor_drivers_s drivers = { + /* + * set ODM current sensor drivers to /sys/s3ip/curr_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_curr_number = wb_get_main_board_curr_number, + .get_main_board_curr_alias = wb_get_main_board_curr_alias, + .get_main_board_curr_type = wb_get_main_board_curr_type, + .get_main_board_curr_max = wb_get_main_board_curr_max, + .get_main_board_curr_min = wb_get_main_board_curr_min, + .get_main_board_curr_value = wb_get_main_board_curr_value, + .get_main_board_curr_monitor_flag = wb_get_main_board_curr_monitor_flag, +}; + +static int __init curr_sensor_dev_drv_init(void) +{ + int ret; + + CURR_SENSOR_INFO("curr_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_curr_sensor_drivers_register(&drivers); + if (ret < 0) { + CURR_SENSOR_ERR("curr sensor drivers register err, ret %d.\n", ret); + return ret; + } + + CURR_SENSOR_INFO("curr_sensor_init success.\n"); + return 0; +} + +static void __exit curr_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_curr_sensor_drivers_unregister(); + CURR_SENSOR_INFO("curr_sensor_exit success.\n"); + return; +} + +module_init(curr_sensor_dev_drv_init); +module_exit(curr_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("current sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c new file mode 100644 index 000000000000..ee5d3495ed19 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c @@ -0,0 +1,209 @@ +/* + * An eeprom_device_driver driver for eeprom devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "eeprom_sysfs.h" +#include "dfd_sysfs_common.h" + +#define EEPROM_INFO(fmt, args...) LOG_INFO("eeprom: ", fmt, ##args) +#define EEPROM_ERR(fmt, args...) LOG_ERR("eeprom: ", fmt, ##args) +#define EEPROM_DBG(fmt, args...) LOG_DBG("eeprom: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************eeprom*******************************************/ + +/* + * wb_get_eeprom_number - Used to get eeprom number + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eeprom_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_number); + + ret = g_drv->get_eeprom_number(); + return ret; +} + +/* + * wb_get_eeprom_size - Used to get eeprom size + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eeprom_size(unsigned int e2_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_size); + + ret = g_drv->get_eeprom_size(e2_index); + return ret; +} + +/* + * wb_get_eeprom_alias - Used to get eeprom alias + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_alias(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_alias); + + ret = g_drv->get_eeprom_alias(e2_index, buf, count); + return ret; +} + +/* + * wb_get_eeprom_tag - Used to get eeprom tag + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_tag(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_tag); + + ret = g_drv->get_eeprom_tag(e2_index, buf, count); + return ret; +} + +/* + * wb_get_eeprom_type - Used to get eeprom type + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_type(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_type); + + ret = g_drv->get_eeprom_type(e2_index, buf, count); + return ret; +} + + +/* + * wb_read_eeprom_data - Used to read eeprom data, + * @buf: Data read buffer + * @offset: offset address to read eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_eeprom_data); + + ret = g_drv->read_eeprom_data(e2_index, buf, offset, count); + return ret; +} + +/* + * wb_write_eeprom_data - Used to write eeprom data + * @buf: Data write buffer + * @offset: offset address to write eeprom data + * @count: length of buf + * + * This function returns the written length of eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_eeprom_data); + + ret = g_drv->write_eeprom_data(e2_index, buf, offset, count); + return ret; +} +/*************************************end of eeprom****************************************/ + +static struct s3ip_sysfs_eeprom_drivers_s drivers = { + /* + * set ODM eeprom drivers to /sys/s3ip/eeprom, + * if not support the function, set corresponding hook to NULL. + */ + .get_eeprom_number = wb_get_eeprom_number, + .get_eeprom_alias = wb_get_eeprom_alias, + .get_eeprom_tag = wb_get_eeprom_tag, + .get_eeprom_type = wb_get_eeprom_type, + .get_eeprom_size = wb_get_eeprom_size, + .read_eeprom_data = wb_read_eeprom_data, + .write_eeprom_data = wb_write_eeprom_data, +}; + +static int __init eeprom_dev_drv_init(void) +{ + int ret; + + EEPROM_INFO("eeprom_dev_drv_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_eeprom_drivers_register(&drivers); + if (ret < 0) { + EEPROM_ERR("eeprom drivers register err, ret %d.\n", ret); + return ret; + } + EEPROM_INFO("eeprom_dev_drv_init success.\n"); + return 0; +} + +static void __exit eeprom_dev_drv_exit(void) +{ + s3ip_sysfs_eeprom_drivers_unregister(); + EEPROM_INFO("eeprom_exit success.\n"); + return; +} + +module_init(eeprom_dev_drv_init); +module_exit(eeprom_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("eeprom device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c new file mode 100644 index 000000000000..5360043678db --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c @@ -0,0 +1,542 @@ +/* + * An fan_device_driver driver for fan devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "fan_sysfs.h" +#include "dfd_sysfs_common.h" + +#define FAN_INFO(fmt, args...) LOG_INFO("fan: ", fmt, ##args) +#define FAN_ERR(fmt, args...) LOG_ERR("fan: ", fmt, ##args) +#define FAN_DBG(fmt, args...) LOG_DBG("fan: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/********************************************fan**********************************************/ +static int wb_get_fan_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_number); + + ret = g_drv->get_fan_number(); + return ret; +} + +static int wb_get_fan_motor_number(unsigned int fan_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_number); + + ret = g_drv->get_fan_motor_number(fan_index); + return ret; +} + +/* + * wb_get_fan_model_name - Used to get fan model name, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_model_name(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_model_name); + + ret = g_drv->get_fan_model_name(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_vendor - Used to get vendor, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_vendor(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_vendor); + + ret = g_drv->get_fan_vendor(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_serial_number - Used to get fan serial number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_serial_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_serial_number); + + ret = g_drv->get_fan_serial_number(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_part_number - Used to get fan part number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_part_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_part_number); + + ret = g_drv->get_fan_part_number(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_hardware_version - Used to get fan hardware version, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_hardware_version(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_hardware_version); + + ret = g_drv->get_fan_hardware_version(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_status - Used to get fan status, + * filled the value to buf, fan status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_status); + + ret = g_drv->get_fan_status(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_present - Used to get fan present status, + * filled the value to buf, fan status define as below: + * 0: ABSENT + * 1: PRESENT + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_present(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_present); + + ret = g_drv->get_fan_present(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_led_status - Used to get fan led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_led_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_led_status); + + ret = g_drv->get_fan_led_status(fan_index, buf, count); + return ret; +} + +/* + * wb_set_fan_led_status - Used to set fan led status + * @fan_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_fan_led_status(unsigned int fan_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_fan_led_status); + + ret = g_drv->set_fan_led_status(fan_index, status); + return ret; +} + +/* + * wb_get_fan_direction - Used to get fan air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_direction(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_direction); + + ret = g_drv->get_fan_direction(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_status - Used to get fan motor status + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_status(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_status); + + ret = g_drv->get_fan_motor_status(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed - Used to get fan motor speed + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed); + + ret = g_drv->get_fan_motor_speed(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_tolerance - Used to get fan motor speed tolerance + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_tolerance); + + ret = g_drv->get_fan_motor_speed_tolerance(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_target - Used to get fan motor speed target + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_target(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_target); + + ret = g_drv->get_fan_motor_speed_target(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_max - Used to get the maximum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_max); + + ret = g_drv->get_fan_motor_speed_max(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_min - Used to get the minimum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_min); + + ret = g_drv->get_fan_motor_speed_min(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_ratio - Used to get the ratio of fan + * filled the value to buf + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_ratio(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_ratio); + + ret = g_drv->get_fan_ratio(fan_index, buf, count); + return ret; +} + +/* + * wb_set_fan_ratio - Used to set the ratio of fan + * @fan_index: start with 1 + * @ratio: motor speed ratio, from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_fan_ratio(unsigned int fan_index, int ratio) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_fan_ratio); + + ret = g_drv->set_fan_ratio(fan_index, ratio); + return ret; +} +/****************************************end of fan*******************************************/ + +static struct s3ip_sysfs_fan_drivers_s drivers = { + /* + * set ODM fan drivers to /sys/s3ip/fan, + * if not support the function, set corresponding hook to NULL. + */ + .get_fan_number = wb_get_fan_number, + .get_fan_motor_number = wb_get_fan_motor_number, + .get_fan_model_name = wb_get_fan_model_name, + .get_fan_vendor = wb_get_fan_vendor, + .get_fan_serial_number = wb_get_fan_serial_number, + .get_fan_part_number = wb_get_fan_part_number, + .get_fan_hardware_version = wb_get_fan_hardware_version, + .get_fan_status = wb_get_fan_status, + .get_fan_present = wb_get_fan_present, + .get_fan_led_status = wb_get_fan_led_status, + .set_fan_led_status = wb_set_fan_led_status, + .get_fan_direction = wb_get_fan_direction, + .get_fan_motor_status = wb_get_fan_motor_status, + .get_fan_motor_speed = wb_get_fan_motor_speed, + .get_fan_motor_speed_tolerance = wb_get_fan_motor_speed_tolerance, + .get_fan_motor_speed_target = wb_get_fan_motor_speed_target, + .get_fan_motor_speed_max = wb_get_fan_motor_speed_max, + .get_fan_motor_speed_min = wb_get_fan_motor_speed_min, + .get_fan_ratio = wb_get_fan_ratio, + .set_fan_ratio = wb_set_fan_ratio +}; + +static int __init fan_dev_drv_init(void) +{ + int ret; + + FAN_INFO("fan_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_fan_drivers_register(&drivers); + if (ret < 0) { + FAN_ERR("fan drivers register err, ret %d.\n", ret); + return ret; + } + + FAN_INFO("fan_init success.\n"); + return 0; +} + +static void __exit fan_dev_drv_exit(void) +{ + s3ip_sysfs_fan_drivers_unregister(); + FAN_INFO("fan_exit success.\n"); + return; +} + +module_init(fan_dev_drv_init); +module_exit(fan_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fan device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c new file mode 100644 index 000000000000..7fda8b9b7184 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c @@ -0,0 +1,216 @@ +/* + * An fpga_device_driver driver for fpga devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "fpga_sysfs.h" +#include "dfd_sysfs_common.h" + +#define FPGA_INFO(fmt, args...) LOG_INFO("fpga: ", fmt, ##args) +#define FPGA_ERR(fmt, args...) LOG_ERR("fpga: ", fmt, ##args) +#define FPGA_DBG(fmt, args...) LOG_DBG("fpga: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************FPGA***********************************************/ +static int wb_get_main_board_fpga_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_number); + + ret = g_drv->get_main_board_fpga_number(); + return ret; +} + +/* + * wb_get_main_board_fpga_alias - Used to identify the location of fpga, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_alias(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_alias); + + ret = g_drv->get_main_board_fpga_alias(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_type - Used to get fpga model name + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_type(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_type); + + ret = g_drv->get_main_board_fpga_type(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_firmware_version - Used to get fpga firmware version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_firmware_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_firmware_version); + + ret = g_drv->get_main_board_fpga_firmware_version(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_board_version - Used to get fpga board version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_board_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_board_version); + + ret = g_drv->get_main_board_fpga_board_version(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_test_reg - Used to test fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_test_reg(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_test_reg); + + ret = g_drv->get_main_board_fpga_test_reg(fpga_index, buf, count); + return ret; +} + +/* + * wb_set_main_board_fpga_test_reg - Used to test fpga register write + * @fpga_index: start with 1 + * @value: value write to fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_main_board_fpga_test_reg(unsigned int fpga_index, unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_main_board_fpga_test_reg); + + ret = g_drv->set_main_board_fpga_test_reg(fpga_index, value); + return ret; +} +/***************************************end of FPGA*******************************************/ + +static struct s3ip_sysfs_fpga_drivers_s drivers = { + /* + * set ODM FPGA drivers to /sys/s3ip/fpga, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_fpga_number = wb_get_main_board_fpga_number, + .get_main_board_fpga_alias = wb_get_main_board_fpga_alias, + .get_main_board_fpga_type = wb_get_main_board_fpga_type, + .get_main_board_fpga_firmware_version = wb_get_main_board_fpga_firmware_version, + .get_main_board_fpga_board_version = wb_get_main_board_fpga_board_version, + .get_main_board_fpga_test_reg = wb_get_main_board_fpga_test_reg, + .set_main_board_fpga_test_reg = wb_set_main_board_fpga_test_reg, +}; + +static int __init fpga_dev_drv_init(void) +{ + int ret; + + FPGA_INFO("fpga_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_fpga_drivers_register(&drivers); + if (ret < 0) { + FPGA_ERR("fpga drivers register err, ret %d.\n", ret); + return ret; + } + FPGA_INFO("fpga_init success.\n"); + return 0; +} + +static void __exit fpga_dev_drv_exit(void) +{ + s3ip_sysfs_fpga_drivers_unregister(); + FPGA_INFO("fpga_exit success.\n"); + return; +} + +module_init(fpga_dev_drv_init); +module_exit(fpga_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fpga device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h new file mode 100644 index 000000000000..5628c298b9c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h @@ -0,0 +1,69 @@ +/* + * A header definition for devcie_driver_common driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DEVICE_DRIVER_COMMON_H_ +#define _DEVICE_DRIVER_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum LOG_LEVEL { + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +#define LOG_INFO(_prefix, fmt, args...) do { \ + if (g_loglevel & INFO) { \ + printk(KERN_INFO _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_ERR(_prefix, fmt, args...) do { \ + if (g_loglevel & ERR) { \ + printk(KERN_ERR _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_DBG(_prefix, fmt, args...) do { \ + if (g_loglevel & DBG) { \ + printk(KERN_DEBUG _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_loglevel & ERR) { \ + printk(KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -ENOSYS; \ + } \ +} while (0) + +#define check_p(p) check_pfun(p) + +#endif /* _DEVICE_DRIVER_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c new file mode 100644 index 000000000000..c97f4814523d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c @@ -0,0 +1,1025 @@ +/* + * An psu_device_driver driver for psu devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "psu_sysfs.h" +#include "dfd_sysfs_common.h" + +#define PSU_INFO(fmt, args...) LOG_INFO("psu: ", fmt, ##args) +#define PSU_ERR(fmt, args...) LOG_ERR("psu: ", fmt, ##args) +#define PSU_DBG(fmt, args...) LOG_DBG("psu: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/********************************************psu**********************************************/ +static int wb_get_psu_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_number); + + ret = g_drv->get_psu_number(); + return ret; +} + +static int wb_get_psu_temp_number(unsigned int psu_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_number); + + ret = g_drv->get_psu_temp_number(psu_index); + return ret; +} + +/* + * wb_get_psu_model_name - Used to get psu model name, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_model_name(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_model_name); + + ret = g_drv->get_psu_model_name(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_vendor - Used to get psu model name, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_vendor(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_vendor); + + ret = g_drv->get_psu_vendor(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_date - Used to get psu date, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_date(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_date); + + ret = g_drv->get_psu_date(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_status - Used to get psu status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_status); + + ret = g_drv->get_psu_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_hw_status - Used to get psu status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_hw_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_hw_status); + + ret = g_drv->get_psu_hw_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_alarm - Used to get psu alarm status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_alarm(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_alarm); + + ret = g_drv->get_psu_alarm(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_serial_number - Used to get psu serial number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_serial_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_serial_number); + + ret = g_drv->get_psu_serial_number(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_part_number - Used to get psu part number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_part_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_part_number); + + ret = g_drv->get_psu_part_number(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_hardware_version - Used to get psu hardware version, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_hardware_version(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_hardware_version); + + ret = g_drv->get_psu_hardware_version(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_type - Used to get the input type of psu + * filled the value to buf, input type value define as below: + * 0: DC + * 1: AC + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_type(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_type); + + ret = g_drv->get_psu_type(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_curr - Used to get the input current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_curr); + + ret = g_drv->get_psu_in_curr(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_vol - Used to get the input voltage of psu + * filled the value to bu, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_vol); + + ret = g_drv->get_psu_in_vol(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_power - Used to get the input power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_power); + + ret = g_drv->get_psu_in_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_curr - Used to get the output current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_curr); + + ret = g_drv->get_psu_out_curr(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_vol - Used to get the output voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_vol); + + ret = g_drv->get_psu_out_vol(psu_index, buf, count); + return ret; +} + +static ssize_t wb_get_psu_attr_threshold(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_attr_threshold); + + ret = g_drv->get_psu_attr_threshold(psu_index, type, buf, count); + return ret; +} + +/* + * wb_get_psu_out_power - Used to get the output power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_power); + + ret = g_drv->get_psu_out_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_max_power - Used to get the output max power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_max_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_max_power); + + ret = g_drv->get_psu_out_max_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_present_status - Used to get psu present status + * filled the value to buf, psu present status define as below: + * 0: ABSENT + * 1: PRESENT + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_present_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_present_status); + + ret = g_drv->get_psu_present_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_status - Used to get psu input status + * filled the value to buf, psu input status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_status); + + ret = g_drv->get_psu_in_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_status_pmbus - Used to get psu status from pmbus + * filled the value to buf, psu output status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_status_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_status_pmbus); + + ret = g_drv->get_psu_status_pmbus(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_status - Used to get psu output status + * filled the value to buf, psu output status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_status); + + ret = g_drv->get_psu_out_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_speed_cal - Used to get psu fan speed cal + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_speed_cal(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_speed_cal); + + ret = g_drv->get_psu_fan_speed_cal(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_speed - Used to get psu fan speed + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_speed(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_speed); + + ret = g_drv->get_psu_fan_speed(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_ratio - Used to get the ratio of psu fan + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_ratio(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_ratio); + + ret = g_drv->get_psu_fan_ratio(psu_index, buf, count); + return ret; +} + +/* + * wb_set_psu_fan_ratio - Used to set the ratio of psu fan + * @psu_index: start with 1 + * @ratio: from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_fan_ratio(unsigned int psu_index, int ratio) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_fan_ratio); + + ret = g_drv->set_psu_fan_ratio(psu_index, ratio); + return ret; +} + +/* + * wb_get_psu_fan_direction - Used to get psu air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_direction(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_direction); + + ret = g_drv->get_psu_fan_direction(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_led_status - Used to get psu led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_led_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_led_status); + + ret = g_drv->get_psu_led_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_alias - Used to identify the location of the temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_alias(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_alias); + + ret = g_drv->get_psu_temp_alias(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_type - Used to get the model of temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_type(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_type); + + ret = g_drv->get_psu_temp_type(psu_index, temp_index, buf, count); + return ret; + +} + +/* + * wb_get_psu_temp_max - Used to get the maximum threshold of temperature sensor of psu, + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_max); + + ret = g_drv->get_psu_temp_max(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_set_psu_temp_max - Used to set the maximum threshold of temperature sensor of psu, + * get value from buf and set it to maximum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '80.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_temp_max); + + ret = g_drv->set_psu_temp_max(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_min - Used to get the minimum threshold of temperature sensor of psu, + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_min); + + ret = g_drv->get_psu_temp_min(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_set_psu_temp_min - Used to set the minimum threshold of temperature sensor of psu, + * get value from buf and set it to minimum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_temp_min); + + ret = g_drv->set_psu_temp_min(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_value - Used to get the input value of temperature sensor of psu + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_value(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_value); + + ret = g_drv->get_psu_temp_value(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_eeprom_size - Used to get psu eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int wb_get_psu_eeprom_size(unsigned int psu_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_eeprom_size); + + ret = g_drv->get_psu_eeprom_size(psu_index); + return ret; +} + +/* + * wb_read_psu_eeprom_data - Used to read psu eeprom data, + * @buf: Data read buffer + * @offset: offset address to read psu eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_psu_eeprom_data(unsigned int psu_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_psu_eeprom_data); + + ret = g_drv->read_psu_eeprom_data(psu_index, buf, offset, count); + return ret; +} + +/* + * wb_get_psu_blackbox_info - Used to get psu blackbox information, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_blackbox_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_blackbox_info); + + ret = g_drv->get_psu_blackbox_info(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_pmbus_info - Used to get psu pmbus information, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_pmbus_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_pmbus_info); + + ret = g_drv->get_psu_pmbus_info(psu_index, buf, count); + return ret; +} + +/* + * wb_clear_psu_blackbox - Used to clear psu blackbox information + * @psu_index: start with 1 + * @value: 1 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_clear_psu_blackbox(unsigned int psu_index, uint8_t value) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->clear_psu_blackbox); + + ret = g_drv->clear_psu_blackbox(psu_index, value); + return ret; +} + +/****************************************end of psu*******************************************/ + +static struct s3ip_sysfs_psu_drivers_s drivers = { + /* + * set ODM psu drivers to /sys/s3ip/psu, + * if not support the function, set corresponding hook to NULL. + */ + .get_psu_number = wb_get_psu_number, + .get_psu_temp_number = wb_get_psu_temp_number, + .get_psu_model_name = wb_get_psu_model_name, + .get_psu_vendor = wb_get_psu_vendor, + .get_psu_date = wb_get_psu_date, + .get_psu_status = wb_get_psu_status, + .get_psu_hw_status = wb_get_psu_hw_status, + .get_psu_alarm = wb_get_psu_alarm, + .get_psu_serial_number = wb_get_psu_serial_number, + .get_psu_part_number = wb_get_psu_part_number, + .get_psu_hardware_version = wb_get_psu_hardware_version, + .get_psu_type = wb_get_psu_type, + .get_psu_in_curr = wb_get_psu_in_curr, + .get_psu_in_vol = wb_get_psu_in_vol, + .get_psu_in_power = wb_get_psu_in_power, + .get_psu_out_curr = wb_get_psu_out_curr, + .get_psu_out_vol = wb_get_psu_out_vol, + .get_psu_out_power = wb_get_psu_out_power, + .get_psu_out_max_power = wb_get_psu_out_max_power, + .get_psu_present_status = wb_get_psu_present_status, + .get_psu_status_pmbus = wb_get_psu_status_pmbus, + .get_psu_in_status = wb_get_psu_in_status, + .get_psu_out_status = wb_get_psu_out_status, + .get_psu_fan_speed = wb_get_psu_fan_speed, + .get_psu_fan_ratio = wb_get_psu_fan_ratio, + .set_psu_fan_ratio = wb_set_psu_fan_ratio, + .get_psu_fan_direction = wb_get_psu_fan_direction, + .get_psu_led_status = wb_get_psu_led_status, + .get_psu_temp_alias = wb_get_psu_temp_alias, + .get_psu_temp_type = wb_get_psu_temp_type, + .get_psu_temp_max = wb_get_psu_temp_max, + .set_psu_temp_max = wb_set_psu_temp_max, + .get_psu_temp_min = wb_get_psu_temp_min, + .set_psu_temp_min = wb_set_psu_temp_min, + .get_psu_temp_value = wb_get_psu_temp_value, + .get_psu_fan_speed_cal = wb_get_psu_fan_speed_cal, + .get_psu_attr_threshold = wb_get_psu_attr_threshold, + .get_psu_eeprom_size = wb_get_psu_eeprom_size, + .read_psu_eeprom_data = wb_read_psu_eeprom_data, + .get_psu_blackbox_info = wb_get_psu_blackbox_info, + .get_psu_pmbus_info = wb_get_psu_pmbus_info, + .clear_psu_blackbox = wb_clear_psu_blackbox, +}; + +static int __init psu_dev_drv_init(void) +{ + int ret; + + PSU_INFO("psu_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_psu_drivers_register(&drivers); + if (ret < 0) { + PSU_ERR("psu drivers register err, ret %d.\n", ret); + return ret; + } + PSU_INFO("psu_init success.\n"); + return 0; +} + +static void __exit psu_dev_drv_exit(void) +{ + s3ip_sysfs_psu_drivers_unregister(); + PSU_INFO("psu_exit ok.\n"); + + return; +} + +module_init(psu_dev_drv_init); +module_exit(psu_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("psu device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c new file mode 100644 index 000000000000..f22e51e1613e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c @@ -0,0 +1,1100 @@ +/* + * An slot_device_driver driver for slot devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "slot_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SLOT_INFO(fmt, args...) LOG_INFO("slot: ", fmt, ##args) +#define SLOT_ERR(fmt, args...) LOG_ERR("slot: ", fmt, ##args) +#define SLOT_DBG(fmt, args...) LOG_DBG("slot: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************slot***********************************************/ +static int wb_get_slot_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_number); + + ret = g_drv->get_slot_number(); + return ret; +} + +static int wb_get_slot_temp_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_number); + + ret = g_drv->get_slot_temp_number(slot_index); + return ret; +} + +static int wb_get_slot_vol_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_number); + + ret = g_drv->get_slot_vol_number(slot_index); + return ret; +} + +static int wb_get_slot_curr_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_number); + + ret = g_drv->get_slot_curr_number(slot_index); + return ret; +} + +static int wb_get_slot_fpga_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_number); + + ret = g_drv->get_slot_fpga_number(slot_index); + return ret; +} + +static int wb_get_slot_cpld_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_number); + + ret = g_drv->get_slot_cpld_number(slot_index); + return ret; +} + +/* + * wb_get_slot_model_name - Used to get slot model name, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_model_name(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_model_name); + + ret = g_drv->get_slot_model_name(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vendor - Used to get slot model name, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vendor(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vendor); + + ret = g_drv->get_slot_vendor(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_serial_number - Used to get slot serial number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_serial_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_serial_number); + + ret = g_drv->get_slot_serial_number(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_part_number - Used to get slot part number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_part_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_part_number); + + ret = g_drv->get_slot_part_number(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_hardware_version - Used to get slot hardware version, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_hardware_version(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_hardware_version); + + ret = g_drv->get_slot_hardware_version(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_status - Used to get slot status, + * filled the value to buf, slot status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_status); + + ret = g_drv->get_slot_status(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_led_status - Used to get slot led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_led_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_led_status); + + ret = g_drv->get_slot_led_status(slot_index, buf, count); + return ret; +} + +/* + * wb_set_slot_led_status - Used to set slot led status + * @slot_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_led_status(unsigned int slot_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_led_status); + + ret = g_drv->set_slot_led_status(slot_index, status); + return ret; +} + +/* + * wb_set_slot_power_status - Used to set slot power status, + * filled the value to buf, slot status define as below: + * 0: OFF + * 1: ON + * + * @slot_index: start with 1 + * @status: power status + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_power_status(unsigned int slot_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_power_status); + + ret = g_drv->set_slot_power_status(slot_index, status); + return ret; +} + +/* + * wb_get_slot_power_status - Used to get slot power status, + * filled the value to buf, slot status define as below: + * 0: OFF + * 1: ON + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_power_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_power_status); + + ret = g_drv->get_slot_power_status(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_alias - Used to identify the location of the temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_alias(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_alias); + + ret = g_drv->get_slot_temp_alias(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_type - Used to get the model of temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_type(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_type); + + ret = g_drv->get_slot_temp_type(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_max - Used to get the maximum threshold of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_max); + + ret = g_drv->get_slot_temp_max(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_min - Used to get the minimum threshold of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_min); + + ret = g_drv->get_slot_temp_min(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_value - Used to get the input value of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_value(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_value); + + ret = g_drv->get_slot_temp_value(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_alias - Used to identify the location of the voltage sensor of slot, + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_alias(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_alias); + + ret = g_drv->get_slot_vol_alias(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_type - Used to get the model of voltage sensor of slot, + * such as udc90160, tps53622 and so on + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_type(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_type); + + ret = g_drv->get_slot_vol_type(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_max - Used to get the maximum threshold of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_max); + + ret = g_drv->get_slot_vol_max(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_min - Used to get the minimum threshold of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_min); + + ret = g_drv->get_slot_vol_min(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_range - Used to get the output error value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_range(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_range); + + ret = g_drv->get_slot_vol_range(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_nominal_value - Used to get the nominal value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_nominal_value(unsigned int slot_index, + unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_nominal_value); + + ret = g_drv->get_slot_vol_nominal_value(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_value - Used to get the input value of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_value(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_value); + + ret = g_drv->get_slot_vol_value(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_alias - Used to identify the location of the current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_alias(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_alias); + + ret = g_drv->get_slot_curr_alias(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_type - Used to get the model of current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_type(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_type); + + ret = g_drv->get_slot_curr_type(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_max - Used to get the maximum threshold of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_max); + + ret = g_drv->get_slot_curr_max(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_min - Used to get the minimum threshold of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_min); + + ret = g_drv->get_slot_curr_min(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_value - Used to get the input value of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_value(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_value); + + ret = g_drv->get_slot_curr_value(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_alias - Used to identify the location of slot fpga, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_alias(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_alias); + + ret = g_drv->get_slot_fpga_alias(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_type - Used to get slot fpga model name + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_type(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_type); + + ret = g_drv->get_slot_fpga_type(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_firmware_version - Used to get slot fpga firmware version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_firmware_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_firmware_version); + + ret = g_drv->get_slot_fpga_firmware_version(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_board_version - Used to get slot fpga board version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_board_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_board_version); + + ret = g_drv->get_slot_fpga_board_version(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_test_reg - Used to test slot fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_test_reg); + + ret = g_drv->get_slot_fpga_test_reg(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_set_slot_fpga_test_reg - Used to test slot fpga register write + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @value: value write to slot fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_fpga_test_reg); + + ret = g_drv->set_slot_fpga_test_reg(slot_index, fpga_index, value); + return ret; +} + +/* + * wb_get_slot_cpld_alias - Used to identify the location of slot cpld, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_alias(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_alias); + + ret = g_drv->get_slot_cpld_alias(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_type - Used to get slot cpld model name + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_type(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_type); + + ret = g_drv->get_slot_cpld_type(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_firmware_version - Used to get slot cpld firmware version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_firmware_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_firmware_version); + + ret = g_drv->get_slot_cpld_firmware_version(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_board_version - Used to get slot cpld board version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_board_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_board_version); + + ret = g_drv->get_slot_cpld_board_version(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_test_reg - Used to test slot cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_test_reg); + + ret = g_drv->get_slot_cpld_test_reg(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_set_slot_cpld_test_reg - Used to test slot cpld register write + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @value: value write to slot cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_cpld_test_reg); + + ret = g_drv->set_slot_cpld_test_reg(slot_index, cpld_index, value); + return ret; +} +/***************************************end of slot*******************************************/ + +static struct s3ip_sysfs_slot_drivers_s drivers = { + /* + * set ODM slot drivers to /sys/s3ip/slot, + * if not support the function, set corresponding hook to NULL. + */ + .get_slot_number = wb_get_slot_number, + .get_slot_temp_number = wb_get_slot_temp_number, + .get_slot_vol_number = wb_get_slot_vol_number, + .get_slot_curr_number = wb_get_slot_curr_number, + .get_slot_cpld_number = wb_get_slot_cpld_number, + .get_slot_fpga_number = wb_get_slot_fpga_number, + .get_slot_model_name = wb_get_slot_model_name, + .get_slot_vendor = wb_get_slot_vendor, + .get_slot_serial_number = wb_get_slot_serial_number, + .get_slot_part_number = wb_get_slot_part_number, + .get_slot_hardware_version = wb_get_slot_hardware_version, + .get_slot_status = wb_get_slot_status, + .get_slot_led_status = wb_get_slot_led_status, + .set_slot_led_status = wb_set_slot_led_status, + .get_slot_power_status = wb_get_slot_power_status, + .set_slot_power_status = wb_set_slot_power_status, + .get_slot_temp_alias = wb_get_slot_temp_alias, + .get_slot_temp_type = wb_get_slot_temp_type, + .get_slot_temp_max = wb_get_slot_temp_max, + .get_slot_temp_min = wb_get_slot_temp_min, + .get_slot_temp_value = wb_get_slot_temp_value, + .get_slot_vol_alias = wb_get_slot_vol_alias, + .get_slot_vol_type = wb_get_slot_vol_type, + .get_slot_vol_max = wb_get_slot_vol_max, + .get_slot_vol_min = wb_get_slot_vol_min, + .get_slot_vol_range = wb_get_slot_vol_range, + .get_slot_vol_nominal_value = wb_get_slot_vol_nominal_value, + .get_slot_vol_value = wb_get_slot_vol_value, + .get_slot_curr_alias = wb_get_slot_curr_alias, + .get_slot_curr_type = wb_get_slot_curr_type, + .get_slot_curr_max = wb_get_slot_curr_max, + .get_slot_curr_min = wb_get_slot_curr_min, + .get_slot_curr_value = wb_get_slot_curr_value, + .get_slot_fpga_alias = wb_get_slot_fpga_alias, + .get_slot_fpga_alias = wb_get_slot_fpga_alias, + .get_slot_fpga_type = wb_get_slot_fpga_type, + .get_slot_fpga_firmware_version = wb_get_slot_fpga_firmware_version, + .get_slot_fpga_board_version = wb_get_slot_fpga_board_version, + .get_slot_fpga_test_reg = wb_get_slot_fpga_test_reg, + .set_slot_fpga_test_reg = wb_set_slot_fpga_test_reg, + .get_slot_cpld_alias = wb_get_slot_cpld_alias, + .get_slot_cpld_type = wb_get_slot_cpld_type, + .get_slot_cpld_firmware_version = wb_get_slot_cpld_firmware_version, + .get_slot_cpld_board_version = wb_get_slot_cpld_board_version, + .get_slot_cpld_test_reg = wb_get_slot_cpld_test_reg, + .set_slot_cpld_test_reg = wb_set_slot_cpld_test_reg, +}; + +static int __init slot_dev_drv_init(void) +{ + int ret; + + SLOT_INFO("slot_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_slot_drivers_register(&drivers); + if (ret < 0) { + SLOT_ERR("slot drivers register err, ret %d.\n", ret); + return ret; + } + SLOT_INFO("slot_init success.\n"); + return 0; +} + +static void __exit slot_dev_drv_exit(void) +{ + s3ip_sysfs_slot_drivers_unregister(); + SLOT_INFO("slot_exit success.\n"); + return; +} + +module_init(slot_dev_drv_init); +module_exit(slot_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("slot device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c new file mode 100644 index 000000000000..c431c5dbb703 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c @@ -0,0 +1,136 @@ +/* + * An syseeprom_device_driver driver for syseeprom devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "syseeprom_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SYSE2_INFO(fmt, args...) LOG_INFO("syseeprom: ", fmt, ##args) +#define SYSE2_ERR(fmt, args...) LOG_ERR("syseeprom: ", fmt, ##args) +#define SYSE2_DBG(fmt, args...) LOG_DBG("syseeprom: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************syseeprom*******************************************/ +/* + * wb_get_syseeprom_size - Used to get syseeprom size + * + * This function returns the size of syseeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_syseeprom_size(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_syseeprom_size); + + ret = g_drv->get_syseeprom_size(); + return ret; +} + +/* + * wb_read_syseeprom_data - Used to read syseeprom data, + * @buf: Data read buffer + * @offset: offset address to read syseeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_syseeprom_data); + + ret = g_drv->read_syseeprom_data(buf, offset, count); + return ret; +} + +/* + * wb_write_syseeprom_data - Used to write syseeprom data + * @buf: Data write buffer + * @offset: offset address to write syseeprom data + * @count: length of buf + * + * This function returns the written length of syseeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_syseeprom_data); + + ret = g_drv->write_syseeprom_data(buf, offset, count); + return ret; +} +/*************************************end of syseeprom****************************************/ + +static struct s3ip_sysfs_syseeprom_drivers_s drivers = { + /* + * set ODM syseeprom drivers to /sys/s3ip/syseeprom, + * if not support the function, set corresponding hook to NULL. + */ + .get_syseeprom_size = wb_get_syseeprom_size, + .read_syseeprom_data = wb_read_syseeprom_data, + .write_syseeprom_data = wb_write_syseeprom_data, +}; + +static int __init syseeprom_dev_drv_init(void) +{ + int ret; + + SYSE2_INFO("syseeprom_dev_drv_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_syseeprom_drivers_register(&drivers); + if (ret < 0) { + SYSE2_ERR("syseeprom drivers register err, ret %d.\n", ret); + return ret; + } + SYSE2_INFO("syseeprom_dev_drv_init success.\n"); + return 0; +} + +static void __exit syseeprom_dev_drv_exit(void) +{ + s3ip_sysfs_syseeprom_drivers_unregister(); + SYSE2_INFO("syseeprom_exit success.\n"); + return; +} + +module_init(syseeprom_dev_drv_init); +module_exit(syseeprom_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("syseeprom device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c new file mode 100644 index 000000000000..05da8b680084 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c @@ -0,0 +1,240 @@ +/* + * An sysled_device_driver driver for sysled devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "sysled_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SYSLED_INFO(fmt, args...) LOG_INFO("sysled: ", fmt, ##args) +#define SYSLED_ERR(fmt, args...) LOG_ERR("sysled: ", fmt, ##args) +#define SYSLED_DBG(fmt, args...) LOG_DBG("sysled: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************sysled**********************************************/ +/* + * wb_get_sys_led_status - Used to get sys led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_sys_led_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_sys_led_status); + + ret = g_drv->get_sys_led_status(buf, count); + return ret; +} + +/* + * wb_set_sys_led_status - Used to set sys led status + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_sys_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_led_status); + + ret = g_drv->set_sys_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_bmc_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_bmc_led_status); + + ret = g_drv->get_bmc_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_bmc_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_bmc_led_status); + + ret = g_drv->set_bmc_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_sys_fan_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_sys_fan_led_status); + + ret = g_drv->get_sys_fan_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_sys_fan_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_fan_led_status); + + ret = g_drv->set_sys_fan_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_sys_psu_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_sys_psu_led_status); + + ret = g_drv->get_sys_psu_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_sys_psu_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_psu_led_status); + + ret = g_drv->set_sys_psu_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_id_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_id_led_status); + + ret = g_drv->get_id_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_id_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_id_led_status); + + ret = g_drv->set_id_led_status(status); + return ret; +} + +/**************************************end of sysled******************************************/ + +static struct s3ip_sysfs_sysled_drivers_s drivers = { + /* + * set ODM sysled drivers to /sys/s3ip/sysled, + * if not support the function, set corresponding hook to NULL. + */ + .get_sys_led_status = wb_get_sys_led_status, + .set_sys_led_status = wb_set_sys_led_status, + .get_bmc_led_status = wb_get_bmc_led_status, + .set_bmc_led_status = wb_set_bmc_led_status, + .get_sys_fan_led_status = wb_get_sys_fan_led_status, + .set_sys_fan_led_status = wb_set_sys_fan_led_status, + .get_sys_psu_led_status = wb_get_sys_psu_led_status, + .set_sys_psu_led_status = wb_set_sys_psu_led_status, + .get_id_led_status = wb_get_id_led_status, + .set_id_led_status = wb_set_id_led_status, +}; + +static int __init sysled_init(void) +{ + int ret; + + SYSLED_INFO("sysled_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_sysled_drivers_register(&drivers); + if (ret < 0) { + SYSLED_ERR("sysled drivers register err, ret %d.\n", ret); + return ret; + } + + SYSLED_INFO("sysled create success.\n"); + return 0; +} + +static void __exit sysled_exit(void) +{ + s3ip_sysfs_sysled_drivers_unregister(); + SYSLED_INFO("sysled_exit ok.\n"); + return; +} + +module_init(sysled_init); +module_exit(sysled_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("sysled device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c new file mode 100644 index 000000000000..65013163cb90 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c @@ -0,0 +1,109 @@ +/* + * An system_device_driver driver for system devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "system_sysfs.h" +#include "dfd_sysfs_common.h" + +#define TEMP_SENSOR_INFO(fmt, args...) LOG_INFO("system: ", fmt, ##args) +#define TEMP_SENSOR_ERR(fmt, args...) LOG_ERR("system: ", fmt, ##args) +#define TEMP_SENSOR_DBG(fmt, args...) LOG_DBG("system: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +static ssize_t wb_set_system_value(unsigned int type, int value) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_system_value); + + ret = g_drv->set_system_value(type, value); + return ret; +} + +static ssize_t wb_get_system_value(unsigned int type, int *value, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_system_value); + + ret = g_drv->get_system_value(type, value, buf, count); + return ret; +} + +static ssize_t wb_get_system_port_power_status(unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_system_port_power_status); + + ret = g_drv->get_system_port_power_status(type, buf, count); + return ret; +} +/***********************************end of main board temp*************************************/ + +static struct s3ip_sysfs_system_drivers_s drivers = { + /* + * set ODM system drivers to /sys/s3ip/system, + * if not support the function, set corresponding hook to NULL. + */ + .get_system_value = wb_get_system_value, + .set_system_value = wb_set_system_value, + .get_system_port_power_status = wb_get_system_port_power_status, +}; + +static int __init system_dev_drv_init(void) +{ + int ret; + + TEMP_SENSOR_INFO("system_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_system_drivers_register(&drivers); + if (ret < 0) { + TEMP_SENSOR_ERR("temp sensor drivers register err, ret %d.\n", ret); + return ret; + } + TEMP_SENSOR_INFO("system_init success.\n"); + return 0; +} + +static void __exit system_dev_drv_exit(void) +{ + s3ip_sysfs_system_drivers_unregister(); + TEMP_SENSOR_INFO("system_exit success.\n"); + return; +} + +module_init(system_dev_drv_init); +module_exit(system_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("system device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c new file mode 100644 index 000000000000..afd0bc25c8d0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c @@ -0,0 +1,275 @@ +/* + * An temp_sensor_device_driver driver for temperature devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "temp_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define TEMP_SENSOR_INFO(fmt, args...) LOG_INFO("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_ERR(fmt, args...) LOG_ERR("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_DBG(fmt, args...) LOG_DBG("temp_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/***************************************main board temp*****************************************/ +/* + * wb_get_main_board_temp_number - Used to get main board temperature sensors number, + * + * This function returns main board temperature sensors by your switch, + * If there is no main board temperature sensors, returns 0, + * otherwise it returns a negative value on failed. + */ +static int wb_get_main_board_temp_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_number); + + ret = g_drv->get_main_board_temp_number(); + return ret; +} + +/* + * wb_get_main_board_temp_alias - Used to identify the location of the temperature sensor, + * such as air_inlet, air_outlet and so on. + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_alias(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_alias); + + ret = g_drv->get_main_board_temp_alias(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_type - Used to get the model of temperature sensor, + * such as lm75, tmp411 and so on + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_type(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_type); + + ret = g_drv->get_main_board_temp_type(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_max - Used to get the maximum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_max(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_max); + + ret = g_drv->get_main_board_temp_max(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_min - Used to get the minimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_min(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_min); + + ret = g_drv->get_main_board_temp_min(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_high - Used to get the highimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_high(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_high); + + ret = g_drv->get_main_board_temp_high(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_low - Used to get the lowimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_low(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_low); + + ret = g_drv->get_main_board_temp_low(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_value - Used to get the input value of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_value(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_value); + + ret = g_drv->get_main_board_temp_value(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_monitor_flag - Used to get the monitor flag of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_monitor_flag(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_monitor_flag); + + ret = g_drv->get_main_board_temp_monitor_flag(temp_index, buf, count); + return ret; +} +/***********************************end of main board temp*************************************/ + +static struct s3ip_sysfs_temp_sensor_drivers_s drivers = { + /* + * set ODM temperature sensor drivers to /sys/s3ip/temp_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_temp_number = wb_get_main_board_temp_number, + .get_main_board_temp_alias = wb_get_main_board_temp_alias, + .get_main_board_temp_type = wb_get_main_board_temp_type, + .get_main_board_temp_max = wb_get_main_board_temp_max, + .get_main_board_temp_min = wb_get_main_board_temp_min, + .get_main_board_temp_value = wb_get_main_board_temp_value, + .get_main_board_temp_high = wb_get_main_board_temp_high, + .get_main_board_temp_low = wb_get_main_board_temp_low, + .get_main_board_temp_monitor_flag = wb_get_main_board_temp_monitor_flag, +}; + +static int __init temp_sensor_dev_drv_init(void) +{ + int ret; + + TEMP_SENSOR_INFO("temp_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_temp_sensor_drivers_register(&drivers); + if (ret < 0) { + TEMP_SENSOR_ERR("temp sensor drivers register err, ret %d.\n", ret); + return ret; + } + TEMP_SENSOR_INFO("temp_sensor_init success.\n"); + return 0; +} + +static void __exit temp_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_temp_sensor_drivers_unregister(); + TEMP_SENSOR_INFO("temp_sensor_exit success.\n"); + return; +} + +module_init(temp_sensor_dev_drv_init); +module_exit(temp_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("temperature sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c new file mode 100644 index 000000000000..1aad05fea3f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c @@ -0,0 +1,481 @@ +/* + * An transceiver_device_driver driver for sff devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "transceiver_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SFF_INFO(fmt, args...) LOG_INFO("sff: ", fmt, ##args) +#define SFF_ERR(fmt, args...) LOG_ERR("sff: ", fmt, ##args) +#define SFF_DBG(fmt, args...) LOG_DBG("sff: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/****************************************transceiver******************************************/ +static int wb_get_eth_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eth_number); + + ret = g_drv->get_eth_number(); + return ret; +} + +/* + * wb_get_transceiver_power_on_status - Used to get the whole machine port power on status, + * filled the value to buf, 0: power off, 1: power on + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_transceiver_power_on_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_transceiver_power_on_status); + + ret = g_drv->get_transceiver_power_on_status(buf, count); + return ret; +} + +/* + * wb_set_transceiver_power_on_status - Used to set the whole machine port power on status, + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_transceiver_power_on_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_transceiver_power_on_status); + + ret = g_drv->set_transceiver_power_on_status(status); + return ret; +} + +/* + * wb_get_transceiver_present_status - Used to get the whole machine port present status, + * filled the value to buf, 0: absent, 1: present + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_transceiver_present_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_transceiver_present_status); + + ret = g_drv->get_transceiver_present_status(buf, count); + return ret; +} + +/* + * wb_get_eth_power_on_status - Used to get single port power on status, + * filled the value to buf, 0: power off, 1: power on + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_power_on_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_power_on_status); + + ret = g_drv->get_eth_power_on_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_power_on_status - Used to set single port power on status, + * @eth_index: start with 1 + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_power_on_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_power_on_status); + + ret = g_drv->set_eth_power_on_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_tx_fault_status - Used to get port tx_fault status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_tx_fault_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_tx_fault_status); + + ret = g_drv->get_eth_tx_fault_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_tx_disable_status - Used to get port tx_disable status, + * filled the value to buf, 0: tx_enable, 1: tx_disable + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_tx_disable_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_tx_disable_status); + + ret = g_drv->get_eth_tx_disable_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_tx_disable_status - Used to set port tx_disable status, + * @eth_index: start with 1 + * @status: tx_disable status, 0: tx_enable, 1: tx_disable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_tx_disable_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_tx_disable_status); + + ret = g_drv->set_eth_tx_disable_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_present_status - Used to get port present status, + * filled the value to buf, 1: present, 0: absent + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_present_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_present_status); + + ret = g_drv->get_eth_present_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_rx_los_status - Used to get port rx_los status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_rx_los_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_rx_los_status); + + ret = g_drv->get_eth_rx_los_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_reset_status - Used to get port reset status, + * filled the value to buf, 0: unreset, 1: reset + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_reset_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_reset_status); + + ret = g_drv->get_eth_reset_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_reset_status - Used to set port reset status, + * @eth_index: start with 1 + * @status: reset status, 0: unreset, 1: reset + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_reset_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_reset_status); + + ret = g_drv->set_eth_reset_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_low_power_mode_status - Used to get port low power mode status, + * filled the value to buf, 0: high power mode, 1: low power mode + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_low_power_mode_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_low_power_mode_status); + + ret = g_drv->get_eth_low_power_mode_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_interrupt_status - Used to get port interruption status, + * filled the value to buf, 0: no interruption, 1: interruption + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_interrupt_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_interrupt_status); + + ret = g_drv->get_eth_interrupt_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_eeprom_size - Used to get port eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eth_eeprom_size(unsigned int eth_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eth_eeprom_size); + + ret = g_drv->get_eth_eeprom_size(eth_index); + return ret; +} + +/* + * wb_read_eth_eeprom_data - Used to read port eeprom data, + * @buf: Data read buffer + * @offset: offset address to read port eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_eth_eeprom_data); + + ret = g_drv->read_eth_eeprom_data(eth_index, buf, offset, count); + return ret; +} + +/* + * wb_write_eth_eeprom_data - Used to write port eeprom data + * @buf: Data write buffer + * @offset: offset address to write port eeprom data + * @count: length of buf + * + * This function returns the written length of port eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_eth_eeprom_data); + + ret = g_drv->write_eth_eeprom_data(eth_index, buf, offset, count); + return ret; +} + +static ssize_t wb_get_eth_optoe_type(unsigned int sff_index, int *optoe_type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_optoe_type); + + ret = g_drv->get_eth_optoe_type(sff_index, optoe_type, buf, count); + return ret; +} + +static ssize_t wb_set_eth_optoe_type(unsigned int sff_index, int optoe_type) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_eth_optoe_type); + + ret = g_drv->set_eth_optoe_type(sff_index, optoe_type); + return ret; +} + +/************************************end of transceiver***************************************/ + +static struct s3ip_sysfs_transceiver_drivers_s drivers = { + /* + * set ODM transceiver drivers to /sys/s3ip/transceiver, + * if not support the function, set corresponding hook to NULL. + */ + .get_eth_number = wb_get_eth_number, + .get_transceiver_power_on_status = wb_get_transceiver_power_on_status, + .set_transceiver_power_on_status = wb_set_transceiver_power_on_status, + .get_transceiver_present_status = wb_get_transceiver_present_status, + .get_eth_power_on_status = wb_get_eth_power_on_status, + .set_eth_power_on_status = wb_set_eth_power_on_status, + .get_eth_tx_fault_status = wb_get_eth_tx_fault_status, + .get_eth_tx_disable_status = wb_get_eth_tx_disable_status, + .set_eth_tx_disable_status = wb_set_eth_tx_disable_status, + .get_eth_present_status = wb_get_eth_present_status, + .get_eth_rx_los_status = wb_get_eth_rx_los_status, + .get_eth_reset_status = wb_get_eth_reset_status, + .set_eth_reset_status = wb_set_eth_reset_status, + .get_eth_low_power_mode_status = wb_get_eth_low_power_mode_status, + .get_eth_interrupt_status = wb_get_eth_interrupt_status, + .get_eth_eeprom_size = wb_get_eth_eeprom_size, + .read_eth_eeprom_data = wb_read_eth_eeprom_data, + .write_eth_eeprom_data = wb_write_eth_eeprom_data, + .get_eth_optoe_type = wb_get_eth_optoe_type, + .set_eth_optoe_type = wb_set_eth_optoe_type, +}; + +static int __init sff_dev_drv_init(void) +{ + int ret; + + SFF_INFO("sff_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_sff_drivers_register(&drivers); + if (ret < 0) { + SFF_ERR("transceiver drivers register err, ret %d.\n", ret); + return ret; + } + SFF_INFO("sff_init success.\n"); + return 0; +} + +static void __exit sff_dev_drv_exit(void) +{ + s3ip_sysfs_sff_drivers_unregister(); + SFF_INFO("sff_exit success.\n"); + return; +} + +module_init(sff_dev_drv_init); +module_exit(sff_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("transceiver device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c new file mode 100644 index 000000000000..a2fc96551235 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c @@ -0,0 +1,267 @@ +/* + * An vol_sensor_device_driver driver for voltage devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "vol_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define VOL_SENSOR_INFO(fmt, args...) LOG_INFO("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_ERR(fmt, args...) LOG_ERR("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_DBG(fmt, args...) LOG_DBG("vol_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*************************************main board voltage***************************************/ +static int wb_get_main_board_vol_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_number); + + ret = g_drv->get_main_board_vol_number(); + return ret; +} + +/* + * wb_get_main_board_vol_alias - Used to identify the location of the voltage sensor, + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_alias(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_alias); + + ret = g_drv->get_main_board_vol_alias(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_type - Used to get the model of voltage sensor, + * such as udc90160, tps53622 and so on + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_type(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_type); + + ret = g_drv->get_main_board_vol_type(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_max - Used to get the maximum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_max(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_max); + + ret = g_drv->get_main_board_vol_max(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_min - Used to get the minimum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_min(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_min); + + ret = g_drv->get_main_board_vol_min(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_range - Used to get the output error value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_range(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_range); + + ret = g_drv->get_main_board_vol_range(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_nominal_value - Used to get the nominal value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_nominal_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_nominal_value); + + ret = g_drv->get_main_board_vol_nominal_value(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_value - Used to get the input value of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_value); + + ret = g_drv->get_main_board_vol_value(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_monitor_flag - Used to get the monitor flag of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_monitor_flag(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_monitor_flag); + + ret = g_drv->get_main_board_vol_monitor_flag(vol_index, buf, count); + return ret; +} +/*********************************end of main board voltage************************************/ + +static struct s3ip_sysfs_vol_sensor_drivers_s drivers = { + /* + * set ODM voltage sensor drivers to /sys/s3ip/vol_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_vol_number = wb_get_main_board_vol_number, + .get_main_board_vol_alias = wb_get_main_board_vol_alias, + .get_main_board_vol_type = wb_get_main_board_vol_type, + .get_main_board_vol_max = wb_get_main_board_vol_max, + .get_main_board_vol_min = wb_get_main_board_vol_min, + .get_main_board_vol_range = wb_get_main_board_vol_range, + .get_main_board_vol_nominal_value = wb_get_main_board_vol_nominal_value, + .get_main_board_vol_value = wb_get_main_board_vol_value, + .get_main_board_vol_monitor_flag = wb_get_main_board_vol_monitor_flag, +}; + +static int __init vol_sensor_dev_drv_init(void) +{ + int ret; + + VOL_SENSOR_INFO("vol_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_vol_sensor_drivers_register(&drivers); + if (ret < 0) { + VOL_SENSOR_ERR("vol sensor drivers register err, ret %d.\n", ret); + return ret; + } + VOL_SENSOR_INFO("vol_sensor_init success.\n"); + return 0; +} + +static void __exit vol_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_vol_sensor_drivers_unregister(); + VOL_SENSOR_INFO("vol_sensor_exit success.\n"); + return; +} + +module_init(vol_sensor_dev_drv_init); +module_exit(vol_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("voltage sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c new file mode 100644 index 000000000000..b2075afe1081 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c @@ -0,0 +1,214 @@ +/* + * An watchdog_device_driver driver for watchdog devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "device_driver_common.h" +#include "watchdog_sysfs.h" +#include "dfd_sysfs_common.h" + +#define WDT_INFO(fmt, args...) LOG_INFO("watchdog: ", fmt, ##args) +#define WDT_ERR(fmt, args...) LOG_ERR("watchdog: ", fmt, ##args) +#define WDT_DBG(fmt, args...) LOG_DBG("watchdog: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/****************************************watchdog*********************************************/ +/* + * wb_get_watchdog_identify - Used to get watchdog identify, such as iTCO_wdt + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_identify(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_identify); + + ret = g_drv->get_watchdog_identify(buf, count); + return ret; +} + +/* + * wb_get_watchdog_timeleft - Used to get watchdog timeleft, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_timeleft(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_timeleft); + + ret = g_drv->get_watchdog_timeleft(buf, count); + return ret; +} + +/* + * wb_get_watchdog_timeout - Used to get watchdog timeout, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_timeout(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_timeout); + + ret = g_drv->get_watchdog_timeout(buf, count); + return ret; +} + +/* + * wb_set_watchdog_timeout - Used to set watchdog timeout, + * @value: timeout value + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_timeout(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_timeout); + + ret = g_drv->set_watchdog_timeout(value); + return ret; +} + +/* + * wb_get_watchdog_enable_status - Used to get watchdog enable status, + * filled the value to buf, 0: disable, 1: enable + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_enable_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_enable_status); + + ret = g_drv->get_watchdog_enable_status(buf, count); + return ret; +} + +/* + * wb_set_watchdog_enable_status - Used to set watchdog enable status, + * @value: enable status value, 0: disable, 1: enable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_enable_status(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_enable_status); + + ret = g_drv->set_watchdog_enable_status(value); + return ret; +} + +/* + * wb_set_watchdog_reset - Used to feed watchdog, + * @value: any value to feed watchdog + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_reset(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_reset); + + ret = g_drv->set_watchdog_reset(value); + return ret; +} + +/*************************************end of watchdog*****************************************/ + +static struct s3ip_sysfs_watchdog_drivers_s drivers = { + /* + * set ODM watchdog sensor drivers to /sys/s3ip/watchdog, + * if not support the function, set corresponding hook to NULL. + */ + .get_watchdog_identify = wb_get_watchdog_identify, + .get_watchdog_timeleft = wb_get_watchdog_timeleft, + .get_watchdog_timeout = wb_get_watchdog_timeout, + .set_watchdog_timeout = wb_set_watchdog_timeout, + .get_watchdog_enable_status = wb_get_watchdog_enable_status, + .set_watchdog_enable_status = wb_set_watchdog_enable_status, + .set_watchdog_reset = wb_set_watchdog_reset, +}; + +static int __init watchdog_dev_drv_init(void) +{ + int ret; + + WDT_INFO("watchdog_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_watchdog_drivers_register(&drivers); + if (ret < 0) { + WDT_ERR("watchdog drivers register err, ret %d.\n", ret); + return ret; + } + WDT_INFO("watchdog create success.\n"); + return 0; +} + +static void __exit watchdog_dev_drv_exit(void) +{ + s3ip_sysfs_watchdog_drivers_unregister(); + WDT_INFO("watchdog_exit success.\n"); + return; +} + +module_init(watchdog_dev_drv_init); +module_exit(watchdog_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("watchdog device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile new file mode 100644 index 000000000000..98b0d0db75c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile @@ -0,0 +1,35 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall + +SUBDIR_CFG = cfg +wb_switch_driver-objs := switch_driver.o wb_module.o \ +wb_fan_driver.o \ +wb_eeprom_driver.o \ +wb_cpld_driver.o \ +wb_fpga_driver.o \ +wb_led_driver.o \ +wb_slot_driver.o \ +wb_sensors_driver.o \ +wb_psu_driver.o \ +wb_sff_driver.o \ +wb_watchdog_driver.o \ +wb_system_driver.o \ +$(SUBDIR_CFG)/dfd_cfg.o \ +$(SUBDIR_CFG)/dfd_cfg_adapter.o \ +$(SUBDIR_CFG)/dfd_cfg_file.o \ +$(SUBDIR_CFG)/dfd_cfg_info.o \ +$(SUBDIR_CFG)/dfd_cfg_listnode.o \ +$(SUBDIR_CFG)/dfd_frueeprom.o \ +$(SUBDIR_CFG)/dfd_tlveeprom.o \ + +obj-m := wb_switch_driver.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/$(SUBDIR_CFG)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/$(SUBDIR_CFG)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c new file mode 100644 index 000000000000..0637d8566aa2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c @@ -0,0 +1,1169 @@ +/* + * An dfd_cfg driver for cfg devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg_file.h" +#include "dfd_cfg_listnode.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg.h" + +/* Configuration item name */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _name, +static char *dfd_cfg_item_name[] = { + DFD_CFG_ITEM_ALL +}; + +/* The index range of the item is specified */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) {_index_min, _index_max}, +static index_range_t dfd_cfg_item_index_range[] = { + DFD_CFG_ITEM_ALL +}; + +/* led status register value conversion level list header */ +LIST_HEAD(dfd_lib_cfg_led_status_decode_conv_lst); + +/* Fan name Convert Air duct type chain head */ +LIST_HEAD(dfd_lib_cfg_fan_name_conv_dir_lst); + +/* Fan name Convert Air duct type chain head */ +LIST_HEAD(dfd_lib_cfg_power_name_conv_lst); + +/* Configure the root node of the necklace watch */ +static lnode_root_t dfd_ko_cfg_list_root; + +/* input key,and then get configuration string */ +char *key_to_name(uint64_t key) +{ + return dfd_cfg_item_name[key]; +} + +/* Strip out Spaces and carriage returns */ +void dfd_ko_cfg_del_space_lf_cr(char *str) +{ + int i, j; + int len; + + if (str == NULL) { + DBG_DEBUG(DBG_ERROR, "param error, str is NULL\n"); + return; + } + /* Remove all Spaces from the configuration line */ + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ') { + for (j = i; j < len - 1; j++) { + str[j] = str[j + 1]; + } + str[j] = '\0'; + len--; + i--; + } + } +} + +void dfd_ko_cfg_del_lf_cr(char *str) +{ + int i, len; + + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n') { + str[i] = '\0'; + } + } +} + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void val_convert_node_lst_free(struct list_head *root) +{ + val_convert_node_t *node, *node_next; + + if (root == NULL) { + return; + } + + /* Iterate to delete the linked list */ + list_for_each_entry_safe(node, node_next, root, lst) { + list_del(&node->lst); + kfree(node); + node = NULL; + } + + return; + +} + +/* Register value conversion node added */ +static void dfd_ko_cfg_regval_conv_lst_add(struct list_head *root, int val, char *str, + int index1, int index2) +{ + val_convert_node_t *val_convert; + + val_convert = (val_convert_node_t *)kmalloc(sizeof(val_convert_node_t), GFP_KERNEL); + if (val_convert == NULL) { + DBG_DEBUG(DBG_ERROR, "kmalloc val_convert_node_t fail\n"); + return; + } + mem_clear(val_convert, sizeof(val_convert_node_t)); + + val_convert->int_val = val; + val_convert->index1 = index1; + val_convert->index2 = index2; + if (str != NULL) { + strlcpy(val_convert->str_val, str, sizeof(val_convert->str_val)); + } + + /* After initialization, the list does not change and does not need to be locked */ + list_add_tail(&(val_convert->lst), root); +} + +/* Get an index value from an integer value */ +static int dfd_ko_cfg_get_index2_by_intval(struct list_head *root, int val, int index1, + int *index2) +{ + val_convert_node_t *val_convert; + + /* The list does not change after initialization and does not need to be locked */ + list_for_each_entry(val_convert, root, lst) { + if ((val_convert->int_val == val) && (index1 == val_convert->index1)) { + *index2 = val_convert->index2; + return 0; + } + } + + return -1; +} + +/* Gets an index value from a string value */ +static int dfd_ko_cfg_get_index_by_strval(struct list_head *root, char *str, int *index1, int *index2) +{ + val_convert_node_t *val_convert; + + /* The list does not change after initialization and does not need to be locked */ + list_for_each_entry(val_convert, root, lst) { + if (strncmp(val_convert->str_val, str, strlen(val_convert->str_val)) == 0) { + *index1 = val_convert->index1; + *index2 = val_convert->index2; + return 0; + } + } + + return -1; +} + +/* Create a message lookup table */ +static void dfd_ko_cfg_convert_list_build(dfd_cfg_item_id_t cfg_item_id, int val, char *str, + int index1, int index2) +{ + if (cfg_item_id == DFD_CFG_ITEM_LED_STATUS_DECODE) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_led_status_decode_conv_lst, val, str, index1, index2); + } else if (cfg_item_id == DFD_CFG_ITEM_FAN_NAME) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_fan_name_conv_dir_lst, val, str, index1, index2); + } else if (cfg_item_id == DFD_CFG_ITEM_POWER_NAME) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_power_name_conv_lst, val, str, index1, index2); + } + return; +} + +/** + * dfd_ko_cfg_get_led_status_decode2_by_regval - Reverse check the register value of the led status + * @regval: Defined led values + * @index1: led type + * @*value: Gets the register value of the led status + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_led_status_decode2_by_regval(int regval, int index1, int *value) +{ + int rv; + + if (value == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index2_by_intval(&dfd_lib_cfg_led_status_decode_conv_lst, regval, + index1, value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get led status decode by regval[0x%x] index1[%d] fail\n", + regval, index1); + return -DFD_RV_INVALID_VALUE; + } + + return 0; +} + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the air duct type by fan name + * @fan_name: Fan name + * @fan_direction: Duct type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_direction_by_name(char *fan_name, int *fan_direction) +{ + int rv; + int index1, index2; + + if ((fan_name == NULL) || (fan_direction == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_fan_name_conv_dir_lst, fan_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get fan direction by name[%s] fail\n", fan_name); + return -DFD_RV_NODE_FAIL; + } + + *fan_direction = index1; + + return 0; +} + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the fan type by fan name + * @fan_name: Fan name + * @fan_type: Fan type + * @sub_type: Fan sub-type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_type_by_name(char *fan_name, int *fan_type, int *sub_type) +{ + int rv; + int index1, index2; + + if ((fan_name == NULL) || (fan_type == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_fan_name_conv_dir_lst, fan_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get fan direction by name[%s] fail\n", fan_name); + return -DFD_RV_NODE_FAIL; + } + + *fan_type = index1; + *sub_type = index2; + + return 0; +} + +/** + * dfd_ko_cfg_get_power_type_by_name - obtain the power supply type by power supply name + * @name: PSU name + * @power_type: PSU type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_power_type_by_name(char *power_name, int *power_type) +{ + int rv; + int index1, index2; + + if ((power_name == NULL) || (power_type == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -1; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_power_name_conv_lst, power_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get power type by name[%s] fail\n", power_name); + return -1; + } + + *power_type = index1; + + return 0; +} + +/* Convert a string to a value */ +static int dfd_ko_cfg_get_value_from_char(char *value_str, int32_t *value, int line_num) +{ + int value_tmp = 0; + + if (strlen(value_str) == 0) { + DBG_DEBUG(DBG_WARN, "line%d: value str is empty\n", line_num); + *value = DFD_CFG_EMPTY_VALUE; + return 0; + } + + /* Format processing data */ + if ((strlen(value_str) > 2) && (value_str[0] == '0') + && (value_str[1] == 'x' || value_str[1] == 'X')) { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 16); /* hexadecimal */ + } else { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 10); /* decimalism */ + } + + *value = value_tmp; + return 0; +} + +/* Get an index value,index2=NULL indicates that there is only one level index */ +static int dfd_ko_cfg_analyse_index(char *index_str, int *index1, int *index2, int line_num) +{ + int rv; + char *index1_begin_char, *index2_begin_char; + + /* first character should be'_' */ + if (index_str[0] != '_') { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between name and index1\n", line_num); + return -1; + } + + /* Gets the first-level index value */ + index1_begin_char = index_str; + rv = dfd_ko_cfg_get_value_from_char(++index1_begin_char, index1, line_num); + if (rv < 0) { + return -1; + } + + /* No secondary index exists */ + if (index2 == NULL) { + return 0; + } + + /* Gets the secondary index value */ + index2_begin_char = strchr(index1_begin_char, '_'); + if (index2_begin_char == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between index1 and index2\n", line_num); + return -1; + } else { + rv = dfd_ko_cfg_get_value_from_char(++index2_begin_char, index2, line_num); + if (rv < 0) { + return -1; + } + } + + return 0; +} + +/* The index value of the array is checked. index2=NULL indicates that it is not checked */ +static int dfd_ko_cfg_check_array_index(index_range_t *index_range, int *index1, int *index2, + int line_num) +{ + /* Level 1 index value check */ + if ((*index1 < 0) || (*index1 > index_range->index1_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index1[%d] invalid, max=%d\n", line_num, *index1, + index_range->index1_max); + return -1; + } + + /* The secondary index does not exist */ + if (index2 == NULL) { + return 0; + } + + /* Secondary index value check */ + if ((*index2 < 0) || (*index2 > index_range->index2_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index2[%d] invalid, max=%d\n", line_num, *index2, + index_range->index2_max); + return -1; + } + + return 0; +} + +/* Get index value */ +static int dfd_ko_cfg_get_index(char *index_str, index_range_t *index_range, int *index1, + int *index2, int line_num) +{ + int rv; + + /* No secondary index value exists */ + if (index_range->index2_max == INDEX_NOT_EXIST) { + index2 = NULL; + } + + /* Analytic index value */ + rv = dfd_ko_cfg_analyse_index(index_str, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + /* Check the index value for valid values */ + rv = dfd_ko_cfg_check_array_index(index_range, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_int_item(uint64_t key, int value, int line_num) +{ + int rv; + int *int_cfg; + + int_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (int_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + int_cfg = (int *)kmalloc(sizeof(int), GFP_KERNEL); + if (int_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc int fail\n", line_num); + return -1; + } + + /* Add to linked list */ + *int_cfg = value; + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, int_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add int item[%d] success, key=0x%08llx\n", + line_num, value, key); + } else { + kfree(int_cfg); + int_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add int item[%d] fail, key=0x%08llx rv=%d \n", + line_num, value, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_WARN, "line%d: replace int item[%d->%d], key=0x%08llx\n", + line_num, *int_cfg, value, key); + *int_cfg = value; + } + + return 0; +} + +/* Parse int type configuration */ +static int dfd_ko_cfg_analyse_int_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Get configuration value */ + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + /* Add a configuration item */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_int_item(key, value, line_num); + if (rv < 0) { + return -1; + } + + /* Some data needs to be backtracked, and an int type backtracked linked list is created */ + dfd_ko_cfg_convert_list_build(cfg_item_id, value, NULL, index1, index2); + return 0; +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_str_item(uint64_t key, char *str, int line_num) +{ + int rv; + char *str_cfg; + + str_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (str_cfg == NULL) { + /* kmalloc new node */ + str_cfg = (char *)kmalloc(DFD_CFG_STR_MAX_LEN, GFP_KERNEL); + if (str_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc str[%lu] fail\n", line_num, strlen(str)); + return -1; + } + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); + + /* Add to linked list */ + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add string item[%s] success, key=0x%08llx\n", + line_num, str_cfg, key); + } else { + kfree(str_cfg); + str_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add string item[%s] fail, key=0x%08llx rv=%d \n", + line_num, str_cfg, key, rv); + return -1; + } + } else { + DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08llx\n", + line_num, str_cfg, str, key); + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); + } + + return 0; +} + +/* Parse the str type configuration */ +static int dfd_ko_cfg_analyse_str_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int btree_key; + char *arg_name_tmp; + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Length check */ + if (strlen(arg_value) >= DFD_CFG_STR_MAX_LEN) { + DBG_DEBUG(DBG_ERROR, "line%d: string item[%s] is too long \n", line_num, arg_value); + return -1; + } + + /* Add a configuration item */ + btree_key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_str_item(btree_key, arg_value, line_num); + if (rv < 0) { + return -1; + } + + /* Part of the data need to reverse lookup, create a string type reverse lookup list */ + dfd_ko_cfg_convert_list_build(cfg_item_id, 0, arg_value, index1, index2); + return 0; +} + +/* Gets the dfd_i2c_dev_t member */ +static int dfd_ko_cfg_get_i2c_dev_member(char *member_str, dfd_i2c_dev_mem_t *member, int line_num) +{ + dfd_i2c_dev_mem_t mem_index; + + for (mem_index = DFD_I2C_DEV_MEM_BUS; mem_index < DFD_I2C_DEV_MEM_END; mem_index++) { + if (memcmp(member_str, g_dfd_i2c_dev_mem_str[mem_index], + strlen(g_dfd_i2c_dev_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: i2c dev member[%s] invalid\n", line_num, member_str); + return -1; +} + +/* Set the i2c_dev member value */ +static void dfd_ko_cfg_set_i2c_dev_mem_value(dfd_i2c_dev_t *i2c_dev, dfd_i2c_dev_mem_t member, + int value) +{ + switch (member) { + case DFD_I2C_DEV_MEM_BUS: + i2c_dev->bus = value; + break; + case DFD_I2C_DEV_MEM_ADDR: + i2c_dev->addr = value; + break; + default: + break; + } +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_i2c_dev_item(uint64_t key, dfd_i2c_dev_mem_t member, int value, int line_num) +{ + int rv; + dfd_i2c_dev_t *i2c_dev_cfg; + + i2c_dev_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (i2c_dev_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + i2c_dev_cfg = (dfd_i2c_dev_t *)kmalloc(sizeof(dfd_i2c_dev_t), GFP_KERNEL); + if (i2c_dev_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc i2c_dev fail\n", line_num); + return -1; + } + mem_clear(i2c_dev_cfg, sizeof(dfd_i2c_dev_t)); + + /* Add to linked list */ + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, i2c_dev_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add i2c_dev item[%s=%d] success, key=0x%08llx\n", + line_num, g_dfd_i2c_dev_mem_str[member], value, key); + } else { + kfree(i2c_dev_cfg); + i2c_dev_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add i2c_dev item[%s=%d] fail, key=0x%08llx rv=%d\n", + line_num, g_dfd_i2c_dev_mem_str[member], value, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_VERBOSE, "line%d: replace i2c_dev item[%s=%d], key=0x%08llx\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + } + + return 0; +} + +/* Parse the dfd_i2c_dev_t type configuration */ +static int dfd_ko_cfg_analyse_i2c_dev_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + dfd_i2c_dev_mem_t member; + + /* Parsing structure member */ + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_i2c_dev_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_dfd_i2c_dev_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Value acquisition */ + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + /* Add a configuration item */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_i2c_dev_item(key, member, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* String to enumeration value */ +static int dfd_ko_cfg_get_enum_value_by_str(char *enum_val_str[], int enum_val_end, char *buf) +{ + int i; + int enum_val; + + enum_val = DFD_CFG_INVALID_VALUE; + for (i = 0; i < enum_val_end; i++) { + if (memcmp(buf, enum_val_str[i], strlen(enum_val_str[i])) == 0) { + enum_val = i; + break; + } + } + + return enum_val; +} + +/* Obtain the info_ctrl_t member */ +static int dfd_ko_cfg_get_info_ctrl_member(char *member_str, info_ctrl_mem_t *member, int line_num) +{ + info_ctrl_mem_t mem_index; + + for (mem_index = INFO_CTRL_MEM_MODE; mem_index < INFO_CTRL_MEM_END; mem_index++) { + if (memcmp(member_str, g_info_ctrl_mem_str[mem_index], + strlen(g_info_ctrl_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: info ctrl member[%s] invalid\n", line_num, member_str); + return -1; +} + +/* Set the info_ctrl member value */ +static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl_mem_t member, + char *buf_val, int line_num) +{ + switch (member) { + case INFO_CTRL_MEM_MODE: + info_ctrl->mode = dfd_ko_cfg_get_enum_value_by_str(g_info_ctrl_mode_str, + INFO_CTRL_MODE_END, buf_val); + break; + case INFO_CTRL_MEM_INT_CONS: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_cons), line_num); + break; + case INFO_CTRL_MEM_SRC: + info_ctrl->src = dfd_ko_cfg_get_enum_value_by_str(g_info_src_str, INFO_SRC_END, buf_val); + break; + case INFO_CTRL_MEM_FRMT: + info_ctrl->frmt = dfd_ko_cfg_get_enum_value_by_str(g_info_frmt_str, INFO_FRMT_END, buf_val); + break; + case INFO_CTRL_MEM_POLA: + info_ctrl->pola = dfd_ko_cfg_get_enum_value_by_str(g_info_pola_str, INFO_POLA_END, buf_val); + break; + case INFO_CTRL_MEM_FPATH: + mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); + strlcpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); + break; + case INFO_CTRL_MEM_ADDR: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); + break; + case INFO_CTRL_MEM_LEN: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->len), line_num); + break; + case INFO_CTRL_MEM_BIT_OFFSET: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->bit_offset), line_num); + break; + case INFO_CTRL_MEM_STR_CONS: + mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); + strlcpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); + break; + case INFO_CTRL_MEM_INT_EXTRA1: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA2: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra2), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA3: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra3), line_num); + break; + default: + break; + } +} + +/* ADD A CONFIGURATION ITEM */ +static int dfd_ko_cfg_add_info_ctrl_item(uint64_t key, info_ctrl_mem_t member, char *buf_val, + int line_num) +{ + int rv; + info_ctrl_t *info_ctrl_cfg; + + info_ctrl_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (info_ctrl_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + info_ctrl_cfg = (info_ctrl_t *)kmalloc(sizeof(info_ctrl_t), GFP_KERNEL); + if (info_ctrl_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc info_ctrl fail\n", line_num); + return -1; + } + mem_clear(info_ctrl_cfg, sizeof(info_ctrl_t)); + + /* Add to linked list */ + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, info_ctrl_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add info_ctrl item[%s=%s] success, key=0x%08llx\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key); + } else { + kfree(info_ctrl_cfg); + info_ctrl_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add info_ctrl item[%s=%s] fail, key=0x%08llx rv=%d\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_VERBOSE, "line%d: replace info_ctrl item[%s=%s], key=0x%08llx\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key); + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + } + + return 0; +} + +/* Parse the configuration of info_ctrl_t */ +static int dfd_ko_cfg_analyse_info_ctrl_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + uint64_t key; + char *arg_name_tmp; + info_ctrl_mem_t member; + + /* Parsing structure member */ + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_info_ctrl_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_info_ctrl_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* ADD A CONFIGURATION ITEM */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_info_ctrl_item(key, member, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* Parsing configuration */ +static int dfd_ko_cfg_analyse_config(char *arg_name, char*arg_value, int line_num) +{ + int i, rv = 0; + int cfg_item_num; + + cfg_item_num = sizeof(dfd_cfg_item_name) / sizeof(dfd_cfg_item_name[0]); + for (i = 0; i < cfg_item_num; i++) { + if (memcmp(arg_name, dfd_cfg_item_name[i], strlen(dfd_cfg_item_name[i])) == 0){ + if (DFD_CFG_ITEM_IS_INT(i)) { + rv = dfd_ko_cfg_analyse_int_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_STRING(i)) { + rv = dfd_ko_cfg_analyse_str_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(i)) { + rv = dfd_ko_cfg_analyse_i2c_dev_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(i)) { + rv = dfd_ko_cfg_analyse_info_ctrl_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else { + rv = -1; + } + break; + } + } + + return rv; +} + +/* Cut the configuration row with '=' */ +static int dfd_ko_cfg_cut_config_line(char *config_line, char *arg_name, char *arg_value) +{ + int i, j = 0, k = 0; + int len, name_value_flag = 0; + + len = strlen(config_line); + for (i = 0; i < len; i++) { + if (config_line[i] == '=') { + name_value_flag = 1; + continue; + } + + /* Data before and after cutting equal sign */ + if (name_value_flag == 0) { + arg_name[j++] = config_line[i]; + } else { + arg_value[k++] = config_line[i]; + } + } + + /* Failed to return if the equal sign does not exist */ + if (name_value_flag == 0) { + return -1; + } else { + return 0; + } +} + +/* Parse configuration row */ +static int dfd_ko_cfg_analyse_config_line(char *config_line, int line_num) +{ + int rv; + char arg_name[DFD_CFG_NAME_MAX_LEN] = {0}; + char arg_value[DFD_CFG_VALUE_MAX_LEN] = {0}; + + /* Remove all Spaces from the configuration line */ + dfd_ko_cfg_del_space_lf_cr(config_line); + + /* Blank line */ + if (strlen(config_line) == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: space line\n", line_num); + return 0; + } + + /* Comment line */ + if (config_line[0] == '#') { + DBG_DEBUG(DBG_VERBOSE, "line%d: comment line[%s]\n", line_num, config_line); + return 0; + } + + /* Look for the '=' character after the line argument and record its position */ + rv = dfd_ko_cfg_cut_config_line(config_line, arg_name, arg_value); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: [%s]no '=' between name and value\n", + line_num, config_line); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "line%d: config_line[%s] name[%s] value[%s]\n", + line_num, config_line, arg_name, arg_value); + return dfd_ko_cfg_analyse_config(arg_name, arg_value, line_num); +} + +/* Parse configuration file */ +static int dfd_ko_cfg_analyse_config_file(char *fpath) +{ + int rv; + int line_num = 1; + kfile_ctrl_t kfile_ctrl; + char config_line[DFD_CFG_CMDLINE_MAX_LEN] = {0}; + + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + /* Parse the configuration rows line by line */ + while (kfile_gets(config_line, sizeof(config_line), &kfile_ctrl) > 0) { + rv = dfd_ko_cfg_analyse_config_line(config_line, line_num++); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "!!!!file[%s] config line[%d %s] analyse fail\n", + fpath, line_num - 1, config_line); + break; + } + + (void)mem_clear(config_line, sizeof(config_line)); + + } + kfile_close(&kfile_ctrl); + + return rv; +} + +/** + * dfd_ko_cfg_get_item - Get configuration item + * @key: node key + * + * @returns: NULL configuration item does not exist, other configuration items are successful + */ +void *dfd_ko_cfg_get_item(uint64_t key) +{ + return lnode_find_node(&dfd_ko_cfg_list_root, key); +} + +/* Print configuration item */ +static void dfd_ko_cfg_print_item(uint64_t key, const void *cfg) +{ + int item_id; + dfd_i2c_dev_t *i2c_dev; + info_ctrl_t *info_ctrl; + + if (cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return; + } + printk(KERN_INFO "**************************\n"); + printk(KERN_INFO "key=0x%08llx\n", key); + + item_id = DFD_CFG_ITEM_ID(key); + if (DFD_CFG_ITEM_IS_INT(item_id)) { + printk(KERN_INFO "int=%d\n", *((int *)cfg)); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(item_id)) { + i2c_dev = (dfd_i2c_dev_t *)cfg; + printk(KERN_INFO ".bus=0x%02x\n", i2c_dev->bus); + printk(KERN_INFO ".addr=0x%02x\n", i2c_dev->addr); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(item_id)) { + info_ctrl = (info_ctrl_t *)cfg; + printk(KERN_INFO ".mode=%s\n", g_info_ctrl_mode_str[info_ctrl->mode]); + printk(KERN_INFO ".int_cons=%d\n", info_ctrl->int_cons); + printk(KERN_INFO ".src=%s\n", g_info_src_str[info_ctrl->src]); + printk(KERN_INFO ".frmt=%s\n", g_info_frmt_str[info_ctrl->frmt]); + printk(KERN_INFO ".pola=%s\n", g_info_pola_str[info_ctrl->pola]); + printk(KERN_INFO ".fpath=%s\n", info_ctrl->fpath); + printk(KERN_INFO ".addr=0x%02x\n", info_ctrl->addr); + printk(KERN_INFO ".len=%d\n", info_ctrl->len); + printk(KERN_INFO ".bit_offset=%d\n", info_ctrl->bit_offset); + } else { + printk(KERN_INFO "item[%d] error!\n", item_id); + } +} + +/** + * dfd_ko_cfg_show_item - Display configuration items + * @key: node key + */ +void dfd_ko_cfg_show_item(uint64_t key) +{ + void *cfg; + + cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (cfg == 0) { + printk(KERN_INFO "item[0x%08llx] not exist\n", key); + return; + } + + dfd_ko_cfg_print_item(key, cfg); +} + +/* x86 devices get the card type method */ +static int dfd_get_my_dev_type_by_file(void) +{ + struct file *fp; + loff_t pos; + int card_type; + char buf[DFD_PID_BUF_LEN]; + int ret; + + fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_VERBOSE, "open file fail!\n"); + return -1; + } + + mem_clear(buf, DFD_PID_BUF_LEN); + pos = 0; + ret = kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_VERBOSE, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + DFD_PUB_CARDTYPE_FILE, DFD_PRODUCT_ID_LENGTH + 1, ret); + filp_close(fp, NULL); + return -1; + } + + card_type = simple_strtoul(buf, NULL, 0); + DBG_DEBUG(DBG_VERBOSE, "card_type 0x%x.\n", card_type); + + filp_close(fp, NULL); + return card_type; +} + +/** + * drv_get_my_dev_type - Get device type + * + * return: Return the corresponding value + * + */ +static int drv_get_my_dev_type(void) +{ + static int type = -1; + + if (type > 0) { + return type; + } + type = dfd_get_my_dev_type_by_file(); + DBG_DEBUG(DBG_VERBOSE, "ko board type %d\n", type); + return type; +} + +static int dfd_ko_cfg_init(void) +{ + int rv; + int card_type; + char file_name[32] = {0}; + char fpath[128] = {0}; + kfile_ctrl_t kfile_ctrl; + + /* Initializes the list root node */ + rv = lnode_init_root(&dfd_ko_cfg_list_root); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "init list root fail, rv=%d\n", rv); + return -1; + } + + /* Gets the card type */ + card_type = drv_get_my_dev_type(); + if (card_type < 0) { + DBG_DEBUG(DBG_ERROR, "get my dev type fail, rv=%d\n", card_type); + return -1; + } + + /* Read the required profile name for the corresponding board type */ + snprintf(fpath, sizeof(fpath), "%s0x%x", DFD_KO_FILE_NAME_DIR, card_type); + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + /* Multiple profiles are supported */ + while (kfile_gets(file_name, sizeof(file_name), &kfile_ctrl) > 0) { + /* Read configuration file */ + dfd_ko_cfg_del_space_lf_cr(file_name); + snprintf(fpath, sizeof(fpath), "%s%s.cfg", DFD_KO_CFG_FILE_DIR, file_name); + DBG_DEBUG(DBG_VERBOSE, ">>>>start parsing config file[%s]\n", fpath); + + /* Description Failed to parse the configuration file */ + rv = dfd_ko_cfg_analyse_config_file(fpath); + if (rv < 0) { + break; + } + } + kfile_close(&kfile_ctrl); + + /* todo Configure data validity check */ + return 0; +} + +/** + * dfd_dev_cfg_init - Module initialization + * + * @returns: <0 Fail, or succeed + */ +int32_t dfd_dev_cfg_init(void) +{ + return dfd_ko_cfg_init(); +} + +/** + * dfd_dev_cfg_init - Module exit + * + * @returns: void + */ + +void dfd_dev_cfg_exit(void) +{ + lnode_free_list(&dfd_ko_cfg_list_root); + val_convert_node_lst_free(&dfd_lib_cfg_led_status_decode_conv_lst); + val_convert_node_lst_free(&dfd_lib_cfg_fan_name_conv_dir_lst); + val_convert_node_lst_free(&dfd_lib_cfg_power_name_conv_lst); + return; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c new file mode 100644 index 000000000000..c4c273059b11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c @@ -0,0 +1,654 @@ +/* + * An dfd_cfg_adapter driver for cfg of adapter devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg_file.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" + +/* dfd_i2c_dev_t member string */ +char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END] = { + ".bus", + ".addr", +}; + +static dfd_i2c_dev_t* dfd_ko_get_cpld_i2c_dev(int sub_slot, int cpld_id) +{ + uint64_t key; + dfd_i2c_dev_t *i2c_dev; + + /* Read configuration value */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_I2C_DEV, sub_slot, cpld_id); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] i2c dev config fail, key_name=%s\n", + cpld_id, key_to_name(DFD_CFG_ITEM_CPLD_I2C_DEV)); + return NULL; + } + + return i2c_dev; +} + +static int dfd_ko_i2c_block_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + int i; + int rv = 0; + char i2c_path[32]; + + mem_clear(i2c_path, 32); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_ERROR, "i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + + if (i2c_check_functionality(client.adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + for (i = 0; i < size; i += 32) { + rv = i2c_smbus_read_i2c_block_data(&client, offset + i, WB_MIN(32, size-i), buf + i); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c_block read failed, rv = %d\n", rv); + rv = -DFD_RV_DEV_FAIL; + goto out; + } + if (rv != 32) { + break; + } + } + rv = DFD_RV_OK; + } else { + rv = -DFD_RV_DEV_NOTSUPPORT; + } + +out: + filp_close(fp, NULL); + return rv; +} + +static int32_t dfd_ko_i2c_smbus_transfer(int read_write, int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int rv; + struct i2c_adapter *i2c_adap; + union i2c_smbus_data data; + + i2c_adap = i2c_get_adapter(bus); + if (i2c_adap == NULL) { + DBG_DEBUG(DBG_ERROR, "get i2c bus[%d] adapter fail\n", bus); + return -DFD_RV_DEV_FAIL; + } + + /* Operation i2c */ + if (read_write == I2C_SMBUS_WRITE) { + data.byte = *buf; + } else { + data.byte = 0; + } + rv = i2c_smbus_xfer(i2c_adap, addr, 0, read_write, offset, I2C_SMBUS_BYTE_DATA, &data); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer fail, rv=%d\n", + bus, addr, offset, size, read_write, rv); + rv = -DFD_RV_DEV_FAIL; + } else { + DBG_DEBUG(DBG_VERBOSE, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer success\n", + bus, addr, offset, size, read_write); + rv = DFD_RV_OK; + } + + if (read_write == I2C_SMBUS_READ) { + if (rv == DFD_RV_OK) { + *buf = data.byte; + } else { + *buf = 0; + } + } + + i2c_put_adapter(i2c_adap); + return rv; +} + +static int32_t dfd_ko_i2c_read_bulk_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_block_read(bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d] read[offset=0x%x] fail, rv %d\r\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d] read[offset=0x%x] success\r\n", + i, addr); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_read_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_READ, bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld read[offset=0x%x] fail, rv %d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld read[offset=0x%x] success, value=0x%x\n", + i, addr, *buf); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_write_data(int bus, int addr, int offset, uint8_t data, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_WRITE, bus, addr, offset, &data, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld write[offset=0x%x] fail, rv=%d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld write[offset=0x%x, data=%d] success\n", i, addr, data); + break; + } + } + + return rv; +} + +/** + * dfd_ko_cpld_i2c_read - cpld read operation + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_i2c_read(int32_t addr, uint8_t *buf) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INDEX_INVALID; + } + + /* Obtain the i2c device bus addr */ + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_ko_i2c_read_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, buf, sizeof(uint8_t)); + + return rv; +} + +/** + * dfd_ko_cpld_i2c_write - cpld WRITE OPERATION + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_i2c_write(int32_t addr, uint8_t data) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + /* Obtain the i2c device bus addr */ + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_ko_i2c_write_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, data, sizeof(uint8_t)); + + return rv; +} + +#ifdef CONFIG_X86 +/** + * dfd_ko_cpld_io_read - cpld io spatial read operation + * @offset: address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_io_read(int32_t addr, uint8_t *buf) +{ + uint64_t key; + int cpld_id, sub_slot, offset; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + /* int Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR,"get cpld io base config fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_CPLD_LPC_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + io_port = (u16)(*tmp) + offset; + *buf = inb(io_port); + DBG_DEBUG(DBG_VERBOSE, "read cpld io port addr 0x%x, data 0x%x\n", io_port, *buf); + + return DFD_RV_OK; + +} +#endif + +#ifdef CONFIG_X86 +/** + * dfd_ko_cpld_io_write - cpld io space WRITE OPERATION + * @addr: address + * @data: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_io_write(int32_t addr, uint8_t data) +{ + uint64_t key; + int cpld_id, sub_slot, offset; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + /* int Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld io base config fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_CPLD_LPC_DEV)); + return -1; + } + + io_port = (u16)(*tmp) + offset; + DBG_DEBUG(DBG_VERBOSE, "write cpld io port addr 0x%x, data 0x%x\n", io_port, data); + outb(data, (u16)io_port); + + return DFD_RV_OK; +} +#endif + +static int dfd_cfg_get_cpld_mode(int sub_slot, int cpld_id, int *mode) +{ + uint64_t key; + char *name; + + if (mode == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_TYPE_ERR; + } + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_MODE, sub_slot, cpld_id); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] mode info ctrl fail, key_name=%s\n", + cpld_id, key_to_name(DFD_CFG_ITEM_CPLD_MODE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode_name %s.\n", cpld_id, name); + if (!strncmp(name, DFD_KO_CPLD_MODE_I2C_STRING, strlen(DFD_KO_CPLD_MODE_I2C_STRING))) { + *mode = DFD_CPLD_MODE_I2C; + } else if (!strncmp(name, DFD_KO_CPLD_MODE_LPC_STRING, strlen(DFD_KO_CPLD_MODE_LPC_STRING))) { + *mode = DFD_CPLD_MODE_LPC; + } else { + /* The default mode is I2C */ + *mode = DFD_CPLD_MODE_I2C; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode %d.\n", cpld_id, *mode); + return 0; +} + +/** + * dfd_ko_cpld_read - cpld read operation, read only one byte + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf) +{ + int ret; + int sub_slot, cpld_id; + int cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + /* cpld mode, including I2C and LPC. Other modes are not supported */ + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_WARN, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default i2c mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_read(addr, buf); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { +#ifdef CONFIG_X86 + ret = dfd_ko_cpld_io_read(addr, buf); +#else + DBG_DEBUG(DBG_ERROR, "ERROR:only x86 arch support cpld_mode %d.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; +#endif + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, *buf, ret); + return ret; +} + +/** + * dfd_ko_cpld_write - cpld WRITE OPERATION Write a byte + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val) +{ + int ret; + int sub_slot, cpld_id, cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_ERROR, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default local_bus mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_write(addr, val); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { +#ifdef CONFIG_X86 + ret = dfd_ko_cpld_io_write(addr, val); +#else + DBG_DEBUG(DBG_ERROR, "ERROR:only x86 arch support cpld_mode %d.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; +#endif + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_MODE_INVALID; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, val, ret); + return ret; +} + +/** + * dfd_ko_i2c_read_tmp - I2C read operation + * @bus: I2C BUS Device address + * @offset:Register offset + * @buf:Read buffer + * @size:Read length + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_i2c_read_tmp(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_read_data(bus, addr, offset, &buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read_data[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; +} + +/** + * dfd_ko_i2c_write - I2C WRITE OPERATION + * @bus: I2C BUS + * @addr: I2C Device address + * @offset:Register offset + * @buf: Write buffer + * @size:Write length + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_write_data(bus, addr, offset, buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_write[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; + +} + +/** + * dfd_ko_read_file - File read operation + * @fpath: File path + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, read_bytes, MAX_RW_COUNT), + }; + struct iov_iter iter; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (read_bytes < 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d read_bytes=%d\n", addr, read_bytes); + return -DFD_RV_INDEX_INVALID; + } + + /* Open file */ + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + /* Location file */ + pos = addr; + iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); + ret = vfs_iter_read(filp, &iter, &pos, 0); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR, "vfs_iter_read failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, read_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + filp_close(filp, NULL); + return ret; +} + +/** + * dfd_ko_other_i2c_dev_read - other_i2c read operation + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_other_i2c_dev_read(int32_t addr, uint8_t *value, int32_t read_len) +{ + uint64_t key; + int rv; + int e2p_main_id, e2p_index, e2p_addr; + dfd_i2c_dev_t *i2c_dev; + + if ((value == NULL) || (read_len <= 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, read_len=%d\r\n", read_len); + return -1; + } + + e2p_main_id = DFD_KO_OTHER_I2C_GET_MAIN_ID(addr); + e2p_index = DFD_KO_OTHER_I2C_GET_INDEX(addr); + e2p_addr = DFD_KO_OTHER_I2C_GET_OFFSET(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, e2p_main_id, e2p_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "psu i2c dev config error, key_name: %s\r\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_NODE_FAIL; + } + + rv = dfd_ko_i2c_read_bulk_data(i2c_dev->bus, i2c_dev->addr, e2p_addr, value, read_len); + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_other_i2c_dev_read, value[0] = 0x%x\n", value[0]); + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_other_i2c_dev_read, value[1] = 0x%x\n", value[1]); + return rv; +} + +/** + * dfd_ko_i2c_read - I2C read operation + * @bus: I2C BUS + * @addr: I2C Device address + * @offset:Register offset + * @buf:Read buffer + * @size:Read length + * @sysfs_name:sysfs attribute name + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size, const char *sysfs_name) +{ + int rv; + char sysfs_path[DFD_SYSFS_PATH_MAX_LEN]; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "params error, buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + if (sysfs_name == NULL) { /* Read in i2c mode */ + DBG_DEBUG(DBG_VERBOSE, "using i2c_smbus_xfer, bus:%d, addr:0x%x, offset:0x%x, read size:%d.\n", + bus, addr, offset, size); + rv = dfd_ko_i2c_read_tmp(bus, addr, offset, buf, size); + } else { /* Read by sysfs */ + mem_clear(sysfs_path, sizeof(sysfs_path)); + snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/i2c/devices/%d-%04x/%s", + bus, addr, sysfs_name); + DBG_DEBUG(DBG_VERBOSE, "using sysfs, sysfs_path:%s, offset:0x%x, read size:%d.\n", + sysfs_path, offset, size); + rv = dfd_ko_read_file(sysfs_path, offset, buf, size); + } + + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read failed.\n"); + } else { + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_i2c_read success.\n"); + } + + return rv; +} + +/** + * dfd_ko_write_file - file WRITE OPERATION + * @fpath: file path + * @addr: address + * @val: data + * @write_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_write_file(char *fpath, int32_t addr, uint8_t *val, int32_t write_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, write_bytes, MAX_RW_COUNT), + }; + struct iov_iter iter; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (write_bytes <= 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d write_bytes=%d\n", addr, write_bytes); + return -DFD_RV_INDEX_INVALID; + } + + /* Open file */ + filp = filp_open(fpath, O_RDWR, 777); + if (IS_ERR(filp)) { + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + /* Location file */ + pos = addr; + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); + ret = vfs_iter_write(filp, &iter, &pos, 0); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR,"vfs_iter_write failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, write_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c new file mode 100644 index 000000000000..7164e02d90f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c @@ -0,0 +1,305 @@ +/* + * An dfd_cfg_file driver for cfg of file devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "dfd_cfg_file.h" +#include "wb_module.h" + +struct getdents_callback { + struct dir_context ctx; + const char *obj_name; /* Name to be matched */ + char *match_name; /* Matching result */ + int dir_len; /* Directory name length */ + int found; /* Configuration flag */ +}; + +/* + * Open file + * @fname: filename + * @kfile_ctrl: File control variable + * + * @returns: 0 Success, other failure + */ +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl) +{ + int ret; + struct file *filp; + loff_t pos; + + if ((fname == NULL) || (kfile_ctrl == NULL)) { + return KFILE_RV_INPUT_ERR; + } + + /* Open file */ + filp = filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filp)) { + return KFILE_RV_OPEN_FAIL; + } + + kfile_ctrl->size = filp->f_inode->i_size; + + /* Request file size memory */ + kfile_ctrl->buf = kmalloc(kfile_ctrl->size, GFP_KERNEL); + if (kfile_ctrl->buf == NULL) { + ret = KFILE_RV_MALLOC_FAIL; + goto close_fp; + } + mem_clear(kfile_ctrl->buf, kfile_ctrl->size); + /* Read file contents */ + pos = 0; + ret = kernel_read(filp, kfile_ctrl->buf, kfile_ctrl->size, &pos); + if (ret < 0) { + ret = KFILE_RV_RD_FAIL; + goto free_buf; + } + /* Set current position */ + kfile_ctrl->pos = 0; + + ret = KFILE_RV_OK; + goto close_fp; + +free_buf: + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + +close_fp: + filp_close(filp, NULL); + return ret; +} + +/* + * Close file + * @kfile_ctrl: File control variable + */ +void kfile_close(kfile_ctrl_t *kfile_ctrl) +{ + if (kfile_ctrl == NULL) { + return; + } + + /* Set the file size to 0 to free memory */ + kfile_ctrl->size = 0; + kfile_ctrl->pos = 0; + if (kfile_ctrl->buf) { + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + } +} + +/* + * Get a row + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + int has_cr = 0; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Clear the buf first */ + mem_clear(buf, buf_size); + for (i = 0; i < buf_size; i++) { + /* It's at the end of the file */ + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + /* The previous data is a newline character, and a line has been copied */ + if (has_cr) { + break; + } + + /* Search for a newline */ + if (IS_CR(kfile_ctrl->buf[kfile_ctrl->pos])) { + has_cr = 1; + } + + /* Copy data */ + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Address check */ + if ((addr < 0) || (addr >= kfile_ctrl->size)) { + return KFILE_RV_ADDR_ERR; + } + + /* Clear the buf first */ + mem_clear(buf, buf_size); + + kfile_ctrl->pos = addr; + for (i = 0; i < buf_size; i++) { + /* It's at the end of the file */ + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + /* Copy data */ + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +static bool kfile_filldir_one(struct dir_context *ctx, const char * name, int len, + loff_t pos, u64 ino, unsigned int d_type) +{ + struct getdents_callback *buf; + bool result; + buf = container_of(ctx, struct getdents_callback, ctx); + result = 1; + if (strncmp(buf->obj_name, name, strlen(buf->obj_name)) == 0) { + if (buf->dir_len < len) { + DBG_DEBUG(DBG_ERROR, "match ok. dir name:%s, but buf_len %d small than dir len %d.\n", + name, buf->dir_len, len); + buf->found = 0; + return 0; + } + mem_clear(buf->match_name, buf->dir_len); + memcpy(buf->match_name, name, len); + buf->found = 1; + result = 0; + } + return result; +} + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len) +{ + int ret; + struct file *dir; + struct getdents_callback buffer = { + .ctx.actor = kfile_filldir_one, + }; + + if (!dir_path || !obj_name || !match_name) { + DBG_DEBUG(DBG_ERROR, "params error. \n"); + return KFILE_RV_INPUT_ERR; + } + buffer.obj_name = obj_name; + buffer.match_name = match_name; + buffer.dir_len = len; + buffer.found = 0; + /* Open folde */ + dir = filp_open(dir_path, O_RDONLY, 0); + if (IS_ERR(dir)) { + DBG_DEBUG(DBG_ERROR, "filp_open error, dir path:%s\n", dir_path); + return KFILE_RV_OPEN_FAIL; + } + ret = iterate_dir(dir, &buffer.ctx); + if (buffer.found) { + DBG_DEBUG(DBG_VERBOSE, "match ok, dir name:%s\n", match_name); + filp_close(dir, NULL); + return DFD_RV_OK; + } + filp_close(dir, NULL); + return -DFD_RV_NODE_FAIL; +} + +#if 0 +/* + * Write data + * @fname: indicates the file name + * @addr: offset address of the file to be written + * @buf: Writes data + * @buf_size: indicates the data size + * + * @returns: >=0 Success, others fail + */ +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size) +{ + int ret = KFILE_RV_OK; + struct file *filp; + int wlen; + + if ((fpath == NULL) || (buf == NULL) || (buf_size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Address check */ + if (addr < 0) { + return KFILE_RV_ADDR_ERR; + } + + /* Open file */ + filp = filp_open(fpath, O_RDWR, 0); + if (IS_ERR(filp)) { + return KFILE_RV_OPEN_FAIL; + } + + filp->f_op->llseek(filp,0,0); + filp->f_pos = addr; + /* Write file content */ + wlen = filp->f_op->write(filp, buf, buf_size, &(filp->f_pos)); + if (wlen < 0) { + ret = KFILE_RV_WR_FAIL; + } + + filp->f_op->llseek(filp,0,0); + filp_close(filp, NULL); + + return ret; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c new file mode 100644 index 000000000000..615285d1c326 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c @@ -0,0 +1,929 @@ +/* + * An dfd_cfg_info driver for cfg of information devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_file.h" + +#define DFD_HWMON_NAME "hwmon" + +/* CPLD_VOLATGE_VALUE_MODE1 */ +/* high 8 bit + high 4 bit(bit4-bit7) */ +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE(value) ((value >> 4)& 0xfff) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE(code_val, k) ((code_val * 16 * 33 * k) / ((65536 - 5000) * 10)) + +/* CPLD_VOLATGE_VALUE_MODE2 */ +/* high 8 bit + low 4 bit(bit0-bit3) */ +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE2(value) (((value & 0xff00) >> 4) + (value & 0xf)) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE2(code_val, k) ((code_val * 33 * k) / 40950) + +typedef enum cpld_volatge_value_s { + CPLD_VOLATGE_VALUE_MODE1, + CPLD_VOLATGE_VALUE_MODE2, +} cpld_volatge_value_t; + +#define VALID_MAC_TEMP_MAX (120) +#define VALID_MAC_TEMP_MIN (-40) +#define MAC_TEMP_INVALID (-99999999) + +/* info_ctrl_t member string */ +char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = { + ".mode", + ".int_cons", + ".src", + ".frmt", + ".pola", + ".fpath", + ".addr", + ".len", + ".bit_offset", + ".str_cons", + ".int_extra1", + ".int_extra2", + ".int_extra3", +}; + +/* info_ctrl_mode_t enumeration string */ +char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END] = { + "none", + "config", + "constant", + "tlv", + "str_constant", +}; + +/* info_src_t enumeration string */ +char *g_info_src_str[INFO_SRC_END] = { + "none", + "cpld", + "fpga", + "other_i2c", + "file", +}; + +/* info_frmt_t enumeration string */ +char *g_info_frmt_str[INFO_FRMT_END] = { + "none", + "bit", + "byte", + "num_bytes", + "num_str", + "num_buf", + "buf", +}; + +/* info_pola_t enumeration string */ +char *g_info_pola_str[INFO_POLA_END] = { + "none", + "positive", + "negative", +}; + +/* Read information from the cpld */ +static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val) +{ + int i, rv; + + for (i = 0; i < read_bytes; i++) { + rv = dfd_ko_cpld_read(addr, &(val[i])); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from cpld fail, reading_byte=%d rv=%d\n", + addr, read_bytes, i, rv); + return rv; + } + addr++; + } + + return read_bytes; +} + +/* Write information to the cpld */ +static int dfd_write_info_to_cpld(int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv; + uint8_t val_tmp; + + val_tmp = val[0]; + rv = dfd_ko_cpld_write(addr, val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write info[addr=0x%x val=0x%x] to cpld fail, rv=%d\n", addr, val_tmp, rv); + return -1; + } + + return 0; +} + +/* Read information from other_i2c */ +static int dfd_read_info_from_other_i2c(int32_t addr, int read_bytes, uint8_t *val) +{ + int rv; + + rv = dfd_ko_other_i2c_dev_read(addr, val, read_bytes); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from othre i2c fail, rv=%d\r\n", + addr, read_bytes, rv); + return rv; + } + + return read_bytes; +} + +/* Read information */ +static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_bytes, uint8_t *val) +{ + int rv = 0; + + /* Read data from different sources */ + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_read_info_from_cpld(addr, read_bytes, val); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = dfd_read_info_from_other_i2c(addr, read_bytes, val); + break; + case INFO_SRC_FILE: + rv = dfd_ko_read_file(fpath, addr, val, read_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +/* Write message */ +static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv = 0; + + /* Write data to separate sources */ + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_write_info_to_cpld(addr, write_bytes, val, bit_mask); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n"); + break; + case INFO_SRC_FILE: + rv = dfd_ko_write_file(fpath, addr, val, write_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +static int dfd_get_info_value(info_ctrl_t *info_ctrl, int *ret, info_num_buf_to_value_f pfun) +{ + int i, rv; + int read_bytes, readed_bytes, int_tmp; + uint8_t byte_tmp, val[INFO_INT_MAX_LEN + 1] = {0}; + + if (info_ctrl->mode == INFO_CTRL_MODE_CONS) { + *ret = info_ctrl->int_cons; + return DFD_RV_OK; + } + if (info_ctrl->mode == INFO_CTRL_MODE_TLV) { + return INFO_CTRL_MODE_TLV; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl bit_offsest[%d] invalid\n", + info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + read_bytes = 1; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt) || IS_INFO_FRMT_NUM_STR(info_ctrl->frmt) + || IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl len[%d] invalid\n", info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + read_bytes = info_ctrl->len; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl info format[%d] error\n", info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + readed_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, read_bytes, &(val[0])); + if (readed_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read int info[src=%s frmt=%s fpath=%s addr=0x%x read_bytes=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, read_bytes, readed_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + val[0] = ~val[0]; + } + byte_tmp = (val[0] >> info_ctrl->bit_offset) & (~(0xff << info_ctrl->len)); + if (pfun) { + rv = pfun(&byte_tmp, sizeof(byte_tmp), &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl bit process fail, rv=%d\n", rv); + return rv; + } + } else { + int_tmp = (int)byte_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + int_tmp = 0; + for (i = 0; i < info_ctrl->len; i++) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + int_tmp |= val[info_ctrl->len - i - 1]; + } else { + int_tmp |= val[i]; + } + if (i != (info_ctrl->len - 1)) { + int_tmp <<= 8; + } + } + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + val[readed_bytes] = '\0'; + int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10); + } else { + if (pfun == NULL) { + DBG_DEBUG(DBG_ERROR, "info ctrl number buf process function is null\n"); + return -DFD_RV_INDEX_INVALID; + } + rv = pfun(val, readed_bytes, &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl number buf process fail, rv=%d\n", rv); + return rv; + } + } + + *ret = int_tmp; + DBG_DEBUG(DBG_VERBOSE, "read int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d] success, ret=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, *ret); + return DFD_RV_OK; +} + +/** + * dfd_info_get_int - Get int type information + * @key: Search keyword of the configuration item + * @ret: int type information + * @pfun: num buf type data conversion function + * + * @returns: 0 Success, <0 failure + */ +int dfd_info_get_int(uint64_t key, int *ret, info_num_buf_to_value_f pfun) +{ + int rv; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (ret == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "get info ctrl value, key=0x%08llx\n", key); + rv = dfd_get_info_value(info_ctrl, ret, pfun); + return rv; +} + +/** + * dfd_info_get_buf - Get buf type information + * @key: Search keyword of the configuration item + * @buf: information buf + * @buf_len: buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: <0 Success, <0 failure + */ +int dfd_info_get_buf(uint64_t key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (buf == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Failed to return the non-configured mode */ + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] mode[%d] invalid\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + /* Parameter check */ + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] format=%d or len=%d invlaid, buf_len=%d\n", + key, info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + /* Read information */ + read_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[key=0x%08llx src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + /* Data conversion processing */ + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] buf process fail, rv=%d\n", key, rv); + return -DFD_RV_DEV_FAIL; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, read_bytes); + } + + return buf_real_len; +} + +/** + * dfd_2key_info_get_buf - Get buf type information + * @key: indicates the search keyword of the configuration item + * @buf: Message buf + * @buf_len: indicates the buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: <0 fails, others succeed + */ +static int dfd_2key_info_get_buf(info_ctrl_t *info_ctrl, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + char fpath[INFO_FPATH_MAX_LEN]; + int coefficient, addend; + + /* Parameter check */ + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "key_path info ctrl format=%d or len=%d invlaid, buf_len=%d\n", + info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + rv = kfile_iterate_dir(info_ctrl->fpath, DFD_HWMON_NAME, buf_tmp, INFO_BUF_MAX_LEN); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dir patch:%s, can find name %s dir \n", + info_ctrl->fpath, DFD_HWMON_NAME); + return -DFD_RV_NO_NODE; + } + mem_clear(fpath, sizeof(fpath)); + snprintf(fpath, sizeof(fpath), "%s%s/%s", + info_ctrl->fpath, buf_tmp, info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "match ok path: %s\n", fpath); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + /* Read information */ + read_bytes = dfd_read_info(info_ctrl->src, fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[src: %s frmt: %s fpath: %s addr: 0x%x len: %d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_src_str[info_ctrl->frmt], fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + /* Data conversion processing */ + if (pfun) { + buf_real_len = buf_len; + coefficient = info_ctrl->int_extra1; + addend = info_ctrl->int_extra2; + if (coefficient != 0) { + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl, coefficient, addend); + } else { + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl, 1, addend); + } + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl buf process fail, rv=%d\n", rv); + return -DFD_RV_DEV_FAIL; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; +} + +/** + * dfd_info_set_int - Set the int type information + * @key: Search keyword of the configuration item + * @val: int type information + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_set_int(uint64_t key, int val) +{ + int rv; + int write_bytes; + uint8_t byte_tmp, bit_mask, val_tmp; + info_ctrl_t *info_ctrl; + uint8_t *val_buf; + + val_buf = &byte_tmp; + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key))) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Non-configuration is not processed */ + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] mode[%d] warnning\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + /* Information conversion */ + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + /* Bit offset check */ + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); /* The minimum 8 bits of data in bit format is valid */ + byte_tmp <<= info_ctrl->bit_offset; /* The value is shifted to the corresponding bit */ + if (info_ctrl->pola == INFO_POLA_NEGA) { /* Negative polarity data is reversed */ + byte_tmp = ~byte_tmp; + } + + write_bytes = 1; + /* Information valid mask */ + bit_mask = (~(0xff << info_ctrl->len)) << info_ctrl->bit_offset; + if (bit_mask != 0xff) { + rv = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + &val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, + "read original info[src=%d][fpath=%s][addr=0x%x] fail. rv = %d\n", + info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, rv); + return -DFD_RV_DEV_FAIL; + } + val_tmp = (val_tmp & (~bit_mask)) | ((uint8_t)byte_tmp & bit_mask); + byte_tmp = val_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + /* Length check */ + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + /* XXX There is currently no requirement to set multi-byte int data */ + write_bytes = 1; + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); + + /* Information valid mask */ + bit_mask = 0xff; + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + val_buf = info_ctrl->str_cons; + write_bytes = strlen(info_ctrl->str_cons); + if (write_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] write num_str: fpath: %s, len[%d] invalid\n", + key, info_ctrl->fpath, write_bytes); + return -DFD_RV_INVALID_VALUE; + } + bit_mask = 0xff; + DBG_DEBUG(DBG_VERBOSE, "info ctrl[key=0x%08llx], write num_str: fpath: %s, write val: %s, len: %d\n", + key, info_ctrl->fpath, val_buf, write_bytes); + } else if (IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + /* Length check */ + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + /* num is converted before buf is set. XXX does not need to set multi-byte int data */ + write_bytes = 1; + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); + + /* Information valid mask */ + bit_mask = 0xff; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + /* Write message */ + rv = dfd_write_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + val_buf, bit_mask); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write int info[src=%s frmt=%s fpath=%s addr=0x%x len=%d val=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, val, rv); + return -DFD_RV_DEV_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "write int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d val=%d] success\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, val); + return DFD_RV_OK; +} + +static long dfd_info_reg2data_linear(uint64_t key, int data) +{ + s16 exponent; + s32 mantissa; + long val; + info_ctrl_t *info_ctrl; + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + switch (info_ctrl->int_extra1) { + case LINEAR11: + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + val = mantissa; + val = val * 1000L; + break; + case LINEAR16: + break; + default: + break; + } + + if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_POWER) { + val = val * 1000L; + } + + if (exponent >= 0) { + val <<= exponent; + } else { + val >>= -exponent; + } + + return val; +} + +static long dfd_info_reg2data_tmp464(uint64_t key, int data) +{ + s16 tmp_val; + long val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_tmp464, data=%d\n", data); + + /* Positive number:data/8*0.0625 */ + if (data >= 0) { + val = data*625/80; + /* Negative number: The first bit is the sign bit and the rest is inverted +1 */ + } else { + tmp_val = ~(data & 0x7ff) + 1; + val = tmp_val*625/80; + } + + return val; +} + +static long dfd_info_reg2data_mac_th5(uint64_t key, int data) +{ + int tmp_val; + long val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th5, data=0x%d\n", data); + + tmp_val = data >> 4; + val = 476359 - (((tmp_val - 2) * 317704) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th5, val=0x%ld\n", val); + return val; +} + +static long dfd_info_reg2data_mac_th4(uint64_t key, int data) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, data=%d\n", data); + + tmp_val = data >> 4; + val = 356070 - (((tmp_val - 2) * 237340) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, val=%d\n", val); + return val; +} + + +static int dfd_info_get_cpld_voltage(uint64_t key, uint32_t *value) +{ + int rv; + uint32_t vol_ref_tmp, vol_ref; + uint32_t vol_curr_tmp, vol_curr; + info_ctrl_t *info_ctrl; + info_ctrl_t info_ctrl_tmp; + uint32_t vol_coefficient; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + vol_coefficient = (uint32_t)info_ctrl->int_extra2; + + rv = dfd_get_info_value(info_ctrl, &vol_curr_tmp, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current voltage error, addr:0x%x, rv = %d\n", info_ctrl->addr, rv); + return rv; + } + if (info_ctrl->int_extra3 == CPLD_VOLATGE_VALUE_MODE2) { + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE2(vol_curr_tmp); + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE2(vol_curr_tmp, info_ctrl->int_extra2); + DBG_DEBUG(DBG_VERBOSE, "vol_curr_tmp = 0x%x, vol_curr = 0x%x, is same.\n", vol_curr_tmp, vol_curr); + } else { + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_curr_tmp); + if (info_ctrl->addr == info_ctrl->int_extra1) { + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE(vol_curr_tmp, vol_coefficient); + DBG_DEBUG(DBG_VERBOSE, "current voltage is reference voltage, vol_curr_tmp: 0x%x, coefficient: %u, vol_curr: %u\n", + vol_curr_tmp, vol_coefficient, vol_curr); + } else { + memcpy(&info_ctrl_tmp, info_ctrl, sizeof(info_ctrl_t)); + info_ctrl_tmp.addr = info_ctrl->int_extra1; + rv = dfd_get_info_value(&info_ctrl_tmp, &vol_ref_tmp, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld reference voltage error, addr: 0x%x, rv: %d\n", info_ctrl_tmp.addr, rv); + return rv; + } + vol_ref = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_ref_tmp); + DBG_DEBUG(DBG_VERBOSE, "vol_ref_tmp: 0x%x, vol_ref: 0x%x\n", vol_ref_tmp, vol_ref); + vol_curr = (vol_curr_tmp * vol_coefficient) / vol_ref; + DBG_DEBUG(DBG_VERBOSE, "vol_curr_tmp: 0x%x, vol_ref: 0x%x, coefficient: %u, vol_curr: %u\n", + vol_curr_tmp, vol_ref, vol_coefficient, vol_curr); + } + } + *value = vol_curr; + return DFD_RV_OK; +} + +static int dfd_info_get_cpld_temperature(uint64_t key, int *value) +{ + int rv; + int temp_reg; + info_ctrl_t *info_ctrl; + long val; + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Read the temperature value */ + rv = dfd_info_get_int(key, &temp_reg, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current temperature error, addr:0x%x, rv =%d\n", info_ctrl->addr, rv); + return rv; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld temp:0x%08x, extra1 0x%x\n", temp_reg, info_ctrl->int_extra1); + + switch (info_ctrl->int_extra1) { + case LINEAR11: + val = dfd_info_reg2data_linear(key, temp_reg); + break; + case TMP464: + val = dfd_info_reg2data_tmp464(key, temp_reg); + break; + case MAC_TH5: + val = dfd_info_reg2data_mac_th5(key, temp_reg); + break; + case MAC_TH4: + val = dfd_info_reg2data_mac_th4(key, temp_reg); + break; + default: + val = temp_reg; + break; + } + + if ((val / 1000 < VALID_MAC_TEMP_MIN) || (val / 1000 > VALID_MAC_TEMP_MAX)) { + DBG_DEBUG(DBG_ERROR, "mac temp invalid, temp = %ld\n", val); + val = MAC_TEMP_INVALID; + } + DBG_DEBUG(DBG_VERBOSE, "calc temp:%ld \n", val); + *value = val; + + return DFD_RV_OK; +} + +static int dfd_info_get_sensor_value(uint64_t key, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv, buf_real_len; + uint32_t value; + int temp_value; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) { + rv = dfd_info_get_cpld_voltage(key, &value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08llx, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld voltage ok, value:%u\n", value); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%u\n", value); + buf_real_len = strlen(buf_tmp); + if (buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, strlen(buf_tmp), buf, &buf_real_len, info_ctrl, 1, 0); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "deal date error.org value:%s, buf_len:%d, rv=%d\n", + buf_tmp, buf_len, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; + } else if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_TEMP && info_ctrl->src == INFO_SRC_CPLD) { + rv = dfd_info_get_cpld_temperature(key, &temp_value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld temperature failed.key=0x%08llx, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld temperature ok, value:%d buf_len %d\n", temp_value, buf_len); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%d\n", temp_value); + buf_real_len = strlen(buf_tmp); + if (buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + DBG_DEBUG(DBG_VERBOSE, "buf_real_len %d\n", buf_real_len); + memcpy(buf, buf_tmp, buf_real_len); + return buf_real_len; + } + + DBG_DEBUG(DBG_ERROR, "not support mode. key:0x%08llx\n", key); + return -DFD_RV_MODE_NOTSUPPORT; +} + +/** + * dfd_info_get_sensor - Get sensors + * @key: HWMON Configures the key + * @buf:Result storage + * @buf_len: buf Length + * + * @returns: <0 Failure, other success + */ +int dfd_info_get_sensor(uint64_t key, char *buf, int buf_len, info_hwmon_buf_f pfun) +{ + info_ctrl_t *key_info_ctrl; + int rv; + + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || + (buf == NULL) || buf_len <= 0) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key: 0x%08llx, buf_len: %d\n", + key, buf_len); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, buf_len); + /* Get the configuration item read and write control variables */ + key_info_ctrl = dfd_ko_cfg_get_item(key); + if (key_info_ctrl == NULL) { + DBG_DEBUG(DBG_VERBOSE, "can't find dfd config, key: 0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + /* String type */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_SRT_CONS) { + snprintf(buf, buf_len, "%s\n", key_info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through string config, key: 0x%08llx, value: %s\n", key, buf); + return strlen(buf); + } + /* int constant type */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_CONS) { + snprintf(buf, buf_len, "%d\n", key_info_ctrl->int_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through int config, key: 0x%08llx, value: %d\n", key, key_info_ctrl->int_cons); + return strlen(buf); + } + + /* Read from the hwmon file */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_CFG && key_info_ctrl->src == INFO_SRC_FILE) { + if (strstr(key_info_ctrl->fpath, "hwmon") != NULL) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon, key: 0x%08llx\n", key); + rv = dfd_2key_info_get_buf(key_info_ctrl, buf, buf_len, pfun); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon failed, key: 0x%08llx, rv: %d\n", key, rv); + } + return rv; + } else { + DBG_DEBUG(DBG_VERBOSE, "get sensor value, key:0x%08llx\n", key); + rv = dfd_info_get_buf(key, buf, buf_len, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value failed, key:0x%08llx, rv:%d\n", key, rv); + } + return rv; + } + } + rv = dfd_info_get_sensor_value(key, buf, buf_len, pfun); + if ( rv < 0) { + DBG_DEBUG(DBG_ERROR, "get sensor value failed, key: 0x%08llx, rv: %d\n", key, rv); + } + return rv; +} + +/** + * @buf:Input and result store + * + */ +void dfd_info_del_no_print_string(char *buf) +{ + int i, len; + + len = strlen(buf); + /* Culling noncharacter */ + for (i = 0; i < len; i++) { + if ((buf[i] < 0x21) || (buf[i] > 0x7E)) { + buf[i] = '\0'; + break; + } + } + return; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c new file mode 100644 index 000000000000..888cfe8b05f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c @@ -0,0 +1,133 @@ +/* + * An dfd_cfg_listnode driver for cfg of listnode devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "dfd_cfg_listnode.h" + +/** + * Find node + * @root: Root node pointer + * @key: Node index value + * + * @return : Node data pointer, NULL failed + */ +void *lnode_find_node(lnode_root_t *root, uint64_t key) +{ + lnode_node_t *lnode; + + if (root == NULL) { + return NULL; + } + + /* Traversal query */ + list_for_each_entry(lnode, &(root->root), lst) { + if (lnode->key == key) { + return lnode->data; + } + } + + return NULL; +} + +/** + * Insert node + * @root: Root node pointer + * @key: Node index value + * @data: data + * + * @return : 0-- success, other failures + */ +int lnode_insert_node(lnode_root_t *root, uint64_t key, void *data) +{ + lnode_node_t *lnode; + void *data_tmp; + + if ((root == NULL) || (data == NULL)) { + return LNODE_RV_INPUT_ERR; + } + + /* Check whether the node exists */ + data_tmp = lnode_find_node(root, key); + if (data_tmp != NULL) { + return LNODE_RV_NODE_EXIST; + } + + /* Node memory request */ + lnode = kmalloc(sizeof(lnode_node_t), GFP_KERNEL); + if (lnode == NULL) { + return LNODE_RV_NOMEM; + } + + /* Add to list */ + lnode->key = key; + lnode->data = data; + list_add_tail(&(lnode->lst), &(root->root)); + + return LNODE_RV_OK; +} + +/** + * Example Initialize the root node + * @root: Root node pointer + * + * @return : 0 Succeeded, others failed + */ +int lnode_init_root(lnode_root_t *root) +{ + if (root == NULL) { + return LNODE_RV_INPUT_ERR; + } + + INIT_LIST_HEAD(&(root->root)); + + return LNODE_RV_OK; +} + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void lnode_free_list(lnode_root_t *root) +{ + lnode_node_t *lnode, *lnode_next; + + if (root == NULL) { + return; + } + + /* Iterate to delete the linked list */ + list_for_each_entry_safe(lnode, lnode_next, &(root->root), lst) { + if (lnode->data) { + kfree(lnode->data); + lnode->data = NULL; + lnode->key = 0; + } + list_del(&lnode->lst); + kfree(lnode); + lnode = NULL; + } + + return; + +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c new file mode 100644 index 000000000000..ded8eb8a8db8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c @@ -0,0 +1,534 @@ +/* + * An dfd_frueeprom driver for frueeprom devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "dfd_frueeprom.h" +#include "dfd_cfg_adapter.h" +#include "wb_module.h" + +int g_dfd_fru_dbg_level = 0; +module_param(g_dfd_fru_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * Takes the pointer to stream of bytes and length + * and returns the 8 bit checksum + * This algo is per IPMI V2.0 spec + */ +static unsigned char ipmi_calculate_crc(const unsigned char *data, size_t len) +{ + char crc = 0; + size_t byte = 0; + + for (byte = 0; byte < len; byte++) { + crc += *data++; + } + + return(-crc); +} + +/* Validates the data for crc and mandatory fields */ +static int ipmi_verify_fru_data(const uint8_t *data, const size_t len) +{ + uint8_t checksum = 0; + int rc = -DFD_RV_TYPE_ERR; + + /* Validate for first byte to always have a value of [1] */ + if (data[0] != IPMI_FRU_HDR_BYTE_ZERO) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid entry:[%d] in byte-0\n",data[0]); + return rc; + } else { + DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Validated [0x%X] in entry_1 of fru_data\n",data[0]); + } + + /* See if the calculated CRC matches with the embedded one. + * CRC to be calculated on all except the last one that is CRC itself.*/ + checksum = ipmi_calculate_crc(data, len - 1); + if (checksum != data[len-1]) { + DBG_FRU_DEBUG(DBG_ERROR, "Checksum mismatch." + " Calculated:[0x%X], Embedded:[0x%X]\n", + checksum, data[len - 1]); + return rc; + } else { + DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Checksum matches:[0x%X]\n",checksum); + } + + return 0; +} + +/* private method to parse type/length */ +static int ipmi_parse_type_length (const void *areabuf, + unsigned int areabuflen, + unsigned int current_area_offset, + uint8_t *number_of_data_bytes, + ipmi_fru_field_t *field) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + uint8_t type_length; + uint8_t type_code; + + type_length = areabufptr[current_area_offset]; + + /* ipmi workaround + * + * dell p weredge r610 + * + * my reading of the fru spec is that all non-custom fields are + * required to be listed by the vendor. however, on this + * motherboard, some areas list this, indicating that there is + * no more data to be parsed. so now, for "required" fields, i + * check to see if the type-length field is a sentinel before + * calling this function. + */ + + type_code = (type_length & IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK) >> IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT; + (*number_of_data_bytes) = type_length & IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK; + + /* special case: this shouldn't be a length of 0x01 (see type/length + * byte format in fru information storage definition). + */ + DBG_FRU_DEBUG(DBG_VERBOSE, "areabuflen:%d, current_area_offset:0x%x, type_code:0x%x, number_of_data_bytes:%d\n", + areabuflen, current_area_offset, type_code, *number_of_data_bytes); +#if 0 + if (type_code == IPMI_FRU_TYPE_LENGTH_TYPE_CODE_LANGUAGE_CODE + && (*number_of_data_bytes) == 0x01) { + DBG_FRU_DEBUG(DBG_ERROR, "fru type length error.value:0x%x\n", type_length); + return (-1); + } +#endif + if ((current_area_offset + 1 + (*number_of_data_bytes)) > areabuflen) { + DBG_FRU_DEBUG(DBG_ERROR, "buf length error. current_area_offset:0x%x, need length:%d, total length:0x%x\n", + current_area_offset, *number_of_data_bytes, areabuflen); + return (-1); + } + + if (field) { + mem_clear (field->type_length_field, IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX); + memcpy (field->type_length_field, &areabufptr[current_area_offset + 1], *number_of_data_bytes); + DBG_FRU_DEBUG(DBG_VERBOSE, "fru parse ok. value:%s\n", field->type_length_field); + field->type_length_field_length = *number_of_data_bytes; + } + + return (0); +} + +static int ipmi_fru_product_info_area(const void *areabuf, + unsigned int areabuflen, ipmi_product_info_t *ipmi_product_info) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + unsigned int area_offset = 2; + uint8_t number_of_data_bytes; + int rv; + ipmi_fru_field_t **ipmi_fru_field_point; + int ipmi_fru_field_len, i; + + if (!areabuf || !areabuflen || !ipmi_product_info) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n"); + return -DFD_RV_INVALID_VALUE; + } + + /* Verify the crc and size */ + rv = ipmi_verify_fru_data(areabuf, areabuflen); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n"); + return rv; + } + + ipmi_fru_field_len = (sizeof(ipmi_product_info_t) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *)); + + if (ipmi_product_info->language_code) { + (*ipmi_product_info->language_code) = areabufptr[area_offset]; + } + area_offset++; + ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_product_info + sizeof(uint8_t *)); + for (i = 0; i < ipmi_fru_field_len; i++) { + if (*ipmi_fru_field_point) { + mem_clear(*ipmi_fru_field_point, sizeof(ipmi_fru_field_t)); + } + + if (((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) && (i >= IPMI_FRU_PRODUCT_AREA_MIN_LEN)) + || (area_offset == areabuflen - 1)) { + rv = 0; + break; + } + + rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv); + break; + } + + area_offset += 1; /* type/length byte */ + area_offset += number_of_data_bytes; + ipmi_fru_field_point++; + } + + return (rv); +} + +static int ipmi_fru_board_info_area(const void *areabuf, + unsigned int areabuflen, ipmi_board_info_t *ipmi_board_info) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + unsigned int area_offset = 2; + uint8_t number_of_data_bytes; + int rv; + ipmi_fru_field_t **ipmi_fru_field_point; + int ipmi_fru_field_len, i; + + if (!areabuf || !areabuflen || !ipmi_board_info) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n"); + return -DFD_RV_INVALID_VALUE; + } + + /* Verify the crc and size */ + rv = ipmi_verify_fru_data(areabuf, areabuflen); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n"); + return rv; + } + + ipmi_fru_field_len = (sizeof(ipmi_board_info_t) - sizeof(uint8_t *) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *)); + + if (ipmi_board_info->language_code) { + (*ipmi_board_info->language_code) = areabufptr[area_offset]; + } + area_offset++; + + if (ipmi_board_info->mfg_time) { + memcpy(ipmi_board_info->mfg_time, &areabufptr[area_offset], IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH); + } + area_offset += IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH; + ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_board_info + sizeof(uint8_t *) + sizeof(uint8_t *)); + for (i = 0; i < ipmi_fru_field_len; i++) { + if (*ipmi_fru_field_point) { + mem_clear(*ipmi_fru_field_point, sizeof(ipmi_fru_field_t)); + } + + if (((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) && (i >= IPMI_FRU_BOARD_AREA_MIN_LEN)) + || (area_offset == areabuflen - 1)) { + rv = 0; + break; + } + + rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv); + break; + } + + area_offset += 1; /* type/length byte */ + area_offset += number_of_data_bytes; + ipmi_fru_field_point++; + } + + return (rv); +} + +/** + * Validates the fru data per ipmi common header constructs. + * Returns with updated common_hdr and also file_size + */ +static int ipmi_validate_common_hdr(const uint8_t *fru_data, const size_t data_len) +{ + int rc = -1; + + uint8_t common_hdr[sizeof(fru_common_header_t)] = {0}; + if (data_len >= sizeof(common_hdr)) { + memcpy(common_hdr, fru_data, sizeof(common_hdr)); + } else { + DBG_FRU_DEBUG(DBG_ERROR, "Incomplete fru data file. Size:[%zd]\n", data_len); + return rc; + } + + /* Verify the crc and size */ + rc = ipmi_verify_fru_data(common_hdr, sizeof(common_hdr)); + if (rc < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate common header\n"); + return rc; + } + + return 0; +} + +/* Header information acquisition */ +static int dfd_get_frue2prom_info(int bus, int dev_addr, fru_common_header_t *info, const char *sysfs_name) +{ + int ret; + uint8_t fru_common_header_info[sizeof(fru_common_header_t)]; + + if (info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, 0, (uint8_t *)info, sizeof(fru_common_header_t), sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom head info error(bus: %d, addr: 0x%02x).\n", bus, dev_addr); + return ret; + } + + memcpy(fru_common_header_info, (uint8_t *)info, sizeof(fru_common_header_t)); + + if (ipmi_validate_common_hdr(fru_common_header_info, sizeof(fru_common_header_t)) != 0) { + return -DFD_RV_TYPE_ERR; + } + + return DFD_RV_OK; +} + +static int dfd_set_fru_product_info(ipmi_product_info_t *ipmi_product_info, ipmi_fru_field_t *vpd_info, int type) +{ + int ret; + ret = DFD_RV_OK; + if (ipmi_product_info == NULL || vpd_info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear((uint8_t *)ipmi_product_info, sizeof(ipmi_product_info_t)); + switch (type) { + case DFD_DEV_INFO_TYPE_SN: + ipmi_product_info->product_serial_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_NAME: + ipmi_product_info->product_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_DEV_TYPE: + ipmi_product_info->product_type_fields = vpd_info; + break; + case DFD_DEV_INFO_TYPE_HW_INFO: + ipmi_product_info->product_version = vpd_info; + break; + case DFD_DEV_INFO_TYPE_VENDOR: + ipmi_product_info->product_manufacturer_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_PART_NUMBER: + ipmi_product_info->product_part_model_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_ASSET_TAG: + ipmi_product_info->product_asset_tag = vpd_info; + break; + default: + ret = -1; + break; + } + + return ret; +} + +static int dfd_set_fru_board_info(ipmi_board_info_t *ipmi_board_info, ipmi_fru_field_t *vpd_info, int type) +{ + int ret; + ret = DFD_RV_OK; + if (ipmi_board_info == NULL || vpd_info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear((uint8_t *)ipmi_board_info, sizeof(ipmi_board_info_t)); + switch (type) { + case DFD_DEV_INFO_TYPE_SN: + ipmi_board_info->board_serial_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_NAME: + ipmi_board_info->board_product_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_HW_INFO: + ipmi_board_info->board_custom_fields = vpd_info; + break; + case DFD_DEV_INFO_TYPE_PART_NUMBER: + ipmi_board_info->board_part_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_VENDOR: + ipmi_board_info->board_manufacturer = vpd_info; + break; + default: + ret = -1; + break; + } + + return ret; +} + +/** + * dfd_get_fru_data - Obtain product area FRU information + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type 2: Product name, 3: product serial number 5: hardware version number 6: product ID + * @buf: Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns:0 success, negative value: failed + */ +int dfd_get_fru_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name) +{ + fru_common_header_t info; + uint8_t *fru_data; + int ret; + uint8_t fru_len; + ipmi_product_info_t ipmi_product_info; + ipmi_fru_field_t vpd_info; + int product_offset; + int fru_len_tmp; + + if (buf == NULL || buf_len <= 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n", + bus, dev_addr, type, buf, buf_len); + + ret = dfd_get_frue2prom_info(bus, dev_addr, &info, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n", + bus, dev_addr, buf, buf_len); + return ret; + } + + product_offset = info.product_offset * IPMI_EIGHT_BYTES; + ret = dfd_ko_i2c_read(bus, dev_addr, product_offset + 1, &fru_len, 1, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n", + bus, dev_addr, info.product_offset); + return -DFD_RV_DEV_FAIL; + } + + fru_len_tmp = fru_len * IPMI_EIGHT_BYTES; + fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL); + if (fru_data == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp); + return -DFD_RV_NO_MEMORY; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, product_offset, fru_data, fru_len_tmp, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n"); + kfree(fru_data); + return ret; + } + + mem_clear((uint8_t *)&vpd_info, sizeof(ipmi_fru_field_t)); + ret = dfd_set_fru_product_info(&ipmi_product_info, &vpd_info, type); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type); + kfree(fru_data); + return ret; + } + + ret = ipmi_fru_product_info_area(fru_data, fru_len_tmp, &ipmi_product_info); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n"); + kfree(fru_data); + return ret; + } + + kfree(fru_data); + + buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length; + memcpy(buf, (uint8_t *)&vpd_info, buf_len); + + return DFD_RV_OK; +} + +/** + * dfd_get_fru_board_data - Obtain the FRU information of the board area + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_board_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name) +{ + fru_common_header_t info; + uint8_t *fru_data; + int ret; + uint8_t fru_len; + ipmi_board_info_t ipmi_board_info; + ipmi_fru_field_t vpd_info; + int board_offset; + int fru_len_tmp; + + if (buf == NULL || buf_len <= 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n", + bus, dev_addr, type, buf, buf_len); + + ret = dfd_get_frue2prom_info(bus, dev_addr, &info, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n", + bus, dev_addr, buf, buf_len); + return ret; + } + + board_offset = info.board_offset * IPMI_EIGHT_BYTES; + ret = dfd_ko_i2c_read(bus, dev_addr, board_offset + 1, &fru_len, 1, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n", + bus, dev_addr, info.board_offset); + return -DFD_RV_DEV_FAIL; + } + + fru_len_tmp = fru_len * IPMI_EIGHT_BYTES; + fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL); + if (fru_data == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp); + return -DFD_RV_NO_MEMORY; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, board_offset, fru_data, fru_len_tmp, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n"); + kfree(fru_data); + return ret; + } + + mem_clear((uint8_t *)&vpd_info, sizeof(ipmi_fru_field_t)); + ret = dfd_set_fru_board_info(&ipmi_board_info, &vpd_info, type); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type); + kfree(fru_data); + return ret; + } + + ret = ipmi_fru_board_info_area(fru_data, fru_len_tmp, &ipmi_board_info); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n"); + kfree(fru_data); + return ret; + } + + kfree(fru_data); + + buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length; + memcpy(buf, (uint8_t *)&vpd_info, buf_len); + + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c new file mode 100644 index 000000000000..3011aa2cac04 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c @@ -0,0 +1,469 @@ +/* + * An dfd_tlveeprom driver for tlveeprom devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "dfd_tlveeprom.h" +#include "wb_module.h" + +#define TLV_CODE_PRODUCT_NAME (0x21) +#define TLV_CODE_PART_NUMBER (0x22) +#define TLV_CODE_SERIAL_NUMBER (0x23) +#define TLV_CODE_MAC_BASE (0x24) +#define TLV_CODE_MANUF_DATE (0x25) +#define TLV_CODE_DEVICE_VERSION (0x26) +#define TLV_CODE_LABEL_REVISION (0x27) +#define TLV_CODE_PLATFORM_NAME (0x28) +#define TLV_CODE_ONIE_VERSION (0x29) +#define TLV_CODE_MAC_SIZE (0x2A) +#define TLV_CODE_MANUF_NAME (0x2B) +#define TLV_CODE_MANUF_COUNTRY (0x2C) +#define TLV_CODE_VENDOR_NAME (0x2D) +#define TLV_CODE_DIAG_VERSION (0x2E) +#define TLV_CODE_SERVICE_TAG (0x2F) +#define TLV_CODE_VENDOR_EXT (0xFD) +#define TLV_CODE_CRC_32 (0xFE) + +/* using in is_valid_tlvinfo_header */ +static uint32_t g_eeprom_size; + +/* + * List of TLV codes and names. + */ +static const struct tlv_code_desc tlv_code_list[] = { + { TLV_CODE_PRODUCT_NAME, "Product Name"}, + { TLV_CODE_PART_NUMBER, "Part Number"}, + { TLV_CODE_SERIAL_NUMBER, "Serial Number"}, + { TLV_CODE_MAC_BASE, "Base MAC Address"}, + { TLV_CODE_MANUF_DATE, "Manufacture Date"}, + { TLV_CODE_DEVICE_VERSION, "Device Version"}, + { TLV_CODE_LABEL_REVISION, "Label Revision"}, + { TLV_CODE_PLATFORM_NAME, "Platform Name"}, + { TLV_CODE_ONIE_VERSION, "ONIE Version"}, + { TLV_CODE_MAC_SIZE, "MAC Addresses"}, + { TLV_CODE_MANUF_NAME, "Manufacturer"}, + { TLV_CODE_MANUF_COUNTRY, "Country Code"}, + { TLV_CODE_VENDOR_NAME, "Vendor Name"}, + { TLV_CODE_DIAG_VERSION, "Diag Version"}, + { TLV_CODE_SERVICE_TAG, "Service Tag"}, + { TLV_CODE_VENDOR_EXT, "Vendor Extension"}, + { TLV_CODE_CRC_32, "CRC-32"}, +}; + +#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0])) + +const unsigned long g_crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len) +{ + unsigned i; + if (len < 1) + return 0xffffffff; + + for (i = 0; i != len; ++i) { + crc = g_crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); + } + + crc = crc ^ 0xffffffff; + + return crc; +} + +/* + * is_valid_tlv + * + * Perform basic sanity checks on a TLV field. The TLV is pointed to + * by the parameter provided. + * 1. The type code is not reserved (0x00 or 0xFF) + */ +static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv) +{ + return ((tlv->type != 0x00) && (tlv->type != 0xFF)); +} + +/* + * is_valid_tlvinfo_header + * + * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM + * data pointed to by the parameter: + * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" + * 2. Version byte is 1 + * 3. Total length bytes contain value which is less than or equal + * to the allowed maximum (2048-11) + * + */ +static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr) +{ + int max_size = g_eeprom_size; + return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && + (hdr->version == TLV_INFO_VERSION) && + (be16_to_cpu(hdr->totallen) <= max_size)); +} + +/* + * decode_tlv_value + * + * Decode a single TLV value into a string. + + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value) +{ + int i; + char *value; + uint32_t length; + + value = (char *)decode_value->value; + + switch (tlv->type) { + case TLV_CODE_PRODUCT_NAME: + case TLV_CODE_PART_NUMBER: + case TLV_CODE_SERIAL_NUMBER: + case TLV_CODE_MANUF_DATE: + case TLV_CODE_LABEL_REVISION: + case TLV_CODE_PLATFORM_NAME: + case TLV_CODE_ONIE_VERSION: + case TLV_CODE_MANUF_NAME: + case TLV_CODE_MANUF_COUNTRY: + case TLV_CODE_VENDOR_NAME: + case TLV_CODE_DIAG_VERSION: + case TLV_CODE_SERVICE_TAG: + memcpy(value, tlv->value, tlv->length); + value[tlv->length] = 0; + length = tlv->length; + break; + case TLV_CODE_MAC_BASE: + length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3], tlv->value[4], tlv->value[5]); + break; + case TLV_CODE_DEVICE_VERSION: + length = sprintf(value, "%u", tlv->value[0]); + break; + case TLV_CODE_MAC_SIZE: + length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); + break; + case TLV_CODE_VENDOR_EXT: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s %02X", value, tlv->value[i]); + } + break; + case TLV_CODE_CRC_32: + length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0], + tlv->value[1], tlv->value[2], tlv->value[3]); + break; + default: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + } + + decode_value->length = length; +} + +/* + * is_checksum_valid + * + * Validate the checksum in the provided TlvInfo EEPROM data. First, + * verify that the TlvInfo header is valid, then make sure the last + * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data + * and compare it to the value stored in the EEPROM CRC-32 TLV. + */ +static bool is_checksum_valid(uint8_t *eeprom) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_crc; + unsigned int calc_crc; + unsigned int stored_crc; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + /* Is the eeprom header valid? */ + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + return false; + } + + /* Is the last TLV a CRC? */ + eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)]; + if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) { + return false; + } + + /* Calculate the checksum */ + calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - 4); + stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) | + (eeprom_crc->value[2] << 8) | eeprom_crc->value[3]); + + return (calc_crc == stored_crc); +} + +/* + * tlvinfo_find_tlv + * + * This function finds the TLV with the supplied code in the EERPOM. + * An offset from the beginning of the EEPROM is returned in the + * eeprom_index parameter if the TLV is found. + */ +static bool tlvinfo_find_tlv(uint8_t *eeprom, uint8_t tcode, int *eeprom_index) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + /* Search through the TLVs, looking for the first one which matches the + * supplied type code. */ + *eeprom_index = sizeof(tlvinfo_header_t); + eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen); + while (*eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index]; + if (!is_valid_tlv(eeprom_tlv)) { + return false; + } + + if (eeprom_tlv->type == tcode) { + return true; + } + + *eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + return false; +} + +/* + * tlvinfo_decode_tlv + * + * This function finds the TLV with the supplied code in the EERPOM + * and decodes the value into the buffer provided. + */ +static bool tlvinfo_decode_tlv(uint8_t *eeprom, uint8_t tcode, tlv_decode_value_t *decode_value) +{ + int eeprom_index; + tlvinfo_tlv_t *eeprom_tlv; + + /* Find the TLV and then decode it */ + if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index]; + decode_tlv_value(eeprom_tlv, decode_value); + return true; + } + + return false; +} + +/* + * parse_tlv_eeprom + * + * parse the EEPROM into memory, if it hasn't already been read. + */ +int parse_tlv_eeprom(uint8_t *eeprom, uint32_t size) +{ + unsigned int i; + bool ret; + tlvinfo_header_t *eeprom_hdr; + tlv_decode_value_t decode_value; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + g_eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n"); + return -1; + } + + for (i = 0; i < TLV_CODE_NUM; i++) { + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value); + if (!ret) { + DBG_DEBUG(DBG_ERROR, "No found type: %s\n", tlv_code_list[i].m_name); + continue; + } + + DBG_DEBUG(DBG_VERBOSE, "i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code, + decode_value.value); + for (j = 0; j < decode_value.length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value.value[j]); + } + DBG_DEBUG(DBG_VERBOSE, "\n\n"); + } + return 0; +} +static int dfd_parse_tlv_eeprom(uint8_t *eeprom, uint32_t size, uint8_t main_type, tlv_decode_value_t *decode_value) +{ + bool ret; + tlvinfo_header_t *eeprom_hdr; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + g_eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n"); + return -1; + } + + ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value); + if (!ret) { + DBG_DEBUG(DBG_ERROR, "No found type: %d\n", main_type); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "Found type: %d, value: %s\n", main_type,decode_value->value); + for (j = 0; j < decode_value->length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value->value[j]); + } + DBG_DEBUG(DBG_VERBOSE, "\n\n"); + + return 0; +} +#if 0 +/* Parsing extends the custom TLV format */ +static int tlvinfo_find_wb_ext_tlv(tlv_decode_value_t *ext_tlv_value, uint8_t ext_type, + uint8_t *buf, uint32_t *buf_len) +{ + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end, eeprom_index; + + /* Search through the TLVs, looking for the first one which matches the + * supplied type code.*/ + DBG_DEBUG(DBG_VERBOSE, "ext_tlv_value->length: %d.\n", ext_tlv_value->length); + for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) { + if ((eeprom_index % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", ext_tlv_value->value[eeprom_index]); + } + + DBG_DEBUG(DBG_VERBOSE, "\n"); + + eeprom_index = 0; + eeprom_end = ext_tlv_value->length; + while (eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]); + if (!is_valid_tlv(eeprom_tlv)) { + DBG_DEBUG(DBG_ERROR, "tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length); + if (eeprom_tlv->type == ext_type) { + if (*buf_len >= eeprom_tlv->length) { + memcpy(buf, eeprom_tlv->value, eeprom_tlv->length); + DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length); + *buf_len = eeprom_tlv->length; + return 0; + } + DBG_DEBUG(DBG_VERBOSE, "buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length); + return -1; + } + + eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + DBG_DEBUG(DBG_VERBOSE, "ext_type %d: tlv is not found.\n", ext_type); + return -1; +} +#endif +/* Obtain EEPROM information */ +int dfd_tlvinfo_get_e2prom_info(uint8_t *eeprom, uint32_t size, dfd_tlv_type_t *tlv_type, uint8_t* buf, uint32_t *buf_len) +{ + tlv_decode_value_t decode_value; + int ret; + + if (eeprom == NULL || tlv_type == NULL || buf == NULL) { + DBG_DEBUG(DBG_ERROR, "Input para invalid.\n"); + return -1; + } + + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value); + if (ret) { + DBG_DEBUG(DBG_ERROR, "dfd_parse_tlv_eeprom failed ret %d.\n", ret); + return ret; + } + + if (*buf_len >= decode_value.length) { + memcpy(buf, decode_value.value, decode_value.length); + *buf_len = decode_value.length; + return 0; + } + DBG_DEBUG(DBG_ERROR, "buf_len %d small than info_len %d.\n", *buf_len, decode_value.length); + return -1; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h new file mode 100644 index 000000000000..1cc8143d1f30 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h @@ -0,0 +1,247 @@ +/* + * A header definition for dfd_cfg driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_H__ +#define __DFD_CFG_H__ + +#include + +#define DFD_KO_FILE_NAME_DIR "/etc/s3ip_sysfs_cfg/file_name/" /* Library configuration file name directory */ +#define DFD_KO_CFG_FILE_DIR "/etc/s3ip_sysfs_cfg/cfg_file/" /* Library configuration file directory */ +#define DFD_PUB_CARDTYPE_FILE "/sys/module/platform_common/parameters/dfd_my_type" + +#define DFD_CFG_CMDLINE_MAX_LEN (256) /* The maximum length of the command line is specified */ +#define DFD_CFG_NAME_MAX_LEN (256) /* The maximum length of a name is specified */ +#define DFD_CFG_VALUE_MAX_LEN (256) /* The maximum length of the configuration value */ +#define DFD_CFG_STR_MAX_LEN (64) /* The maximum length of a character string is specified */ +#define DFD_CFG_CPLD_NUM_MAX (16) /* Maximum number of cpld */ +#define DFD_PRODUCT_ID_LENGTH (8) +#define DFD_PID_BUF_LEN (32) +#define DFD_TEMP_NAME_BUF_LEN (32) + +#define DFD_CFG_EMPTY_VALUE (-1) /* Null configuration value */ +#define DFD_CFG_INVALID_VALUE (0) /* Configuring an illegal value */ + +/* Set the key value of the binary tree */ +#define DFD_CFG_KEY(item, index1, index2) \ + (((((uint64_t)item) & 0xffff) << 24) | (((index1) & 0xffff) << 8) | ((index2) & 0xff)) +#define DFD_CFG_ITEM_ID(key) (((key) >> 24) & 0xffff) +#define DFD_CFG_INDEX1(key) (((key) >> 8) & 0xffff) +#define DFD_CFG_INDEX2(key) ((key)& 0xff) + +/* Index range */ +#define INDEX_NOT_EXIST (-1) +#define INDEX1_MAX (0xffff) +#define INDEX2_MAX (0xff) + +#define DFD_CFG_ITEM_ALL \ + DFD_CFG_ITEM(DFD_CFG_ITEM_NONE, "none", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_NUM, "dev_num", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM, "bmc_system_cmd_num", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_THRESHOLD, "fan_threshold", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_LED_STATUS_DECODE, "led_status_decode", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SYSTEM_STATUS_DECODE, "system_status_decode", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_LPC_DEV, "cpld_lpc_dev", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_TYPE_NUM, "fan_type_num", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_SIZE, "eeprom_size", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR, "decode_power_fan_dir", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_ID, "watchdog_id", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_RSUPPLY, "power_rate_supply", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_DIRECTION, "fan_direction", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP_MONITOR_DC, "dc_monitor_flag_hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG_DC, "dc_monitor_flag_hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG_DC, "dc_monitor_flag_hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INT_END, "end_int", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_MODE, "mode_cpld", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_NAME, "cpld_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_TYPE, "cpld_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_NAME, "fpga_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_TYPE, "fpga_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_MODEL_DECODE, "fpga_model_decode", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_E2_MODE, "fan_e2_mode", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_FRU_MODE, "psu_fru_mode", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SYSFS_NAME, "fan_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_NAME, "power_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_NAME, "fan_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_POWER_NAME, "decode_power_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED_CAL, "fan_speed_cal", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_FAN_NAME, "decode_fan_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_PATH, "eeprom_path", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_NAME, "watchdog_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_SYSFS_NAME, "psu_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SLOT_SYSFS_NAME, "slot_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_ALIAS, "eeprom_alias", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_TAG, "eeprom_tag", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_TYPE, "eeprom_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_BLACKBOX_INFO, "psu_blackbox_info", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_PMBUS_INFO, "psu_pmbus_info", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX, "psu_clear_blackbox", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_STRING_END, "end_string", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_I2C_DEV, "cpld_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_OTHER_I2C_DEV, "other_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_I2C_DEV_END, "end_i2c_dev", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_ROLL_STATUS, "fan_roll_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED, "fan_speed", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_RATIO, "fan_ratio", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_LED_STATUS, "led_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_VERSION, "cpld_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_HW_VERSION, "cpld_hw_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_TEST_REG, "cpld_test_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_PRESENT_STATUS, "dev_present_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_STATUS, "psu_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP, "hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP_MONITOR_FLAG, "monitor_flag_hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN, "hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG, "monitor_flag_hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR, "hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG, "monitor_flag_hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_PSU, "hwmon_psu", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_OPTOE_TYPE, "sff_optoe_type", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_POWER, "hwmon_power", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_CPLD_REG, "sff_cpld_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_VERSION, "fpga_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_TEST_REG, "fpga_test_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_MODEL_REG, "fpga_model_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_PMBUS_REG, "psu_pmbus_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_DEV, "watchdog_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_BMC_SYSTEM, "bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM, "pre_check_bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM, "check_val_bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_FRU_PMBUS, "psu_fru_pmbus", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_STATUS, "power_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INFO_CTRL_END, "end_info_ctrl", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + +/* Configuration item id enumeration definition */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _id, +typedef enum dfd_cfg_item_id_s { + DFD_CFG_ITEM_ALL +} dfd_cfg_item_id_t; + +#define DFD_CFG_ITEM_IS_INT(item_id) \ + (((item_id) > DFD_CFG_ITEM_NONE) && ((item_id) < DFD_CFG_ITEM_INT_END)) + +#define DFD_CFG_ITEM_IS_STRING(item_id) \ + (((item_id) > DFD_CFG_ITEM_INT_END) && ((item_id) < DFD_CFG_ITEM_STRING_END)) + +#define DFD_CFG_ITEM_IS_I2C_DEV(item_id) \ + (((item_id) > DFD_CFG_ITEM_STRING_END) && ((item_id) < DFD_CFG_ITEM_I2C_DEV_END)) + +#define DFD_CFG_ITEM_IS_INFO_CTRL(item_id) \ + (((item_id) > DFD_CFG_ITEM_I2C_DEV_END) && ((item_id) < DFD_CFG_ITEM_INFO_CTRL_END)) + +/* Index value range structure */ +typedef struct index_range_s { + int index1_max; /* The primary index indicates the maximum value */ + int index2_max; /* Indicates the maximum value of the secondary index */ +} index_range_t; + +/* Register value conversion node */ +typedef struct val_convert_node_s { + struct list_head lst; + int int_val; /* Integer value */ + char str_val[DFD_CFG_STR_MAX_LEN]; /* String value */ + int index1; /* Index value 1 */ + int index2; /* Index value 2 */ +} val_convert_node_t; + +/** + * dfd_ko_cfg_get_item - Get configuration item + * @key: Node key + * + * @returns: The NULL configuration item does not exist, and other configuration items are successful + */ +void *dfd_ko_cfg_get_item(uint64_t key); + +/** + * dfd_ko_cfg_show_item - Display configuration items + * @key: Node key + */ +void dfd_ko_cfg_show_item(uint64_t key); + +/** + * dfd_dev_cfg_init - Module initialization + * + * @returns: <0 Failed, otherwise succeeded + */ +int32_t dfd_dev_cfg_init(void); + +/** + * dfd_dev_cfg_exit - Module exit + * + * @returns: void + */ +void dfd_dev_cfg_exit(void); + +/* Strip out Spaces and carriage returns */ +void dfd_ko_cfg_del_space_lf_cr(char *str); + +void dfd_ko_cfg_del_lf_cr(char *str); + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the air duct type by fan name + * @fan_name: Fan name + * @fan_direction: Duct type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_direction_by_name(char *fan_name, int *fan_direction); + +/** + * dfd_ko_cfg_get_power_type_by_name - obtain the power supply type by power supply name + * @power_name: Power supply name + * @power_type: Power supply type + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_power_type_by_name(char *power_name, int *power_type); + +/** + * dfd_ko_cfg_get_led_status_decode2_by_regval - Reverse check the register value of the led status + * @regval: Defined led values + * @index1: led type + * @value: Gets the register value of the led status + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_led_status_decode2_by_regval(int regval, int index1, int *value); + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the fan type by fan name + * @fan_name: Fan name + * @fan_type: Fan type + * @sub_type: Fan sub-type + * + * @returns: 0 Succeeded, otherwise failed + */ + int dfd_ko_cfg_get_fan_type_by_name(char *fan_name, int *fan_type, int *sub_type); + + /** + * key_to_name - convert to name by key + * @key: Fan name + * + * @returns: name + */ +char *key_to_name(uint64_t key); + +#endif /* __DFD_CFG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h new file mode 100644 index 000000000000..f70c46328e58 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h @@ -0,0 +1,136 @@ +/* + * A header definition for dfd_cfg_adapter driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_ADAPTER_H__ +#define __DFD_CFG_ADAPTER_H__ + +#define DFD_KO_CPLD_I2C_RETRY_SLEEP (10) /* ms */ +#define DFD_KO_CPLD_I2C_RETRY_TIMES (50 / DFD_KO_CPLD_I2C_RETRY_SLEEP) + +#define DFD_KO_CPLD_GET_SLOT(addr) ((addr >> 24) & 0xff) +#define DFD_KO_CPLD_GET_ID(addr) ((addr >> 16) & 0xff) +#define DFD_KO_CPLD_GET_INDEX(addr) (addr & 0xffff) +#define DFD_KO_CPLD_MODE_I2C_STRING "i2c" +#define DFD_KO_CPLD_MODE_LPC_STRING "lpc" + +#define DFD_KO_OTHER_I2C_GET_MAIN_ID(addr) ((addr >> 24) & 0xff) +#define DFD_KO_OTHER_I2C_GET_INDEX(addr) ((addr >> 16) & 0xff) +#define DFD_KO_OTHER_I2C_GET_OFFSET(addr) (addr & 0xffff) +#define DFD_SYSFS_PATH_MAX_LEN (64) + +typedef struct dfd_i2c_dev_s { + int bus; /* bus number */ + int addr; /* Bus address */ +} dfd_i2c_dev_t; + +/* dfd_i2c_dev_t member macro */ +typedef enum dfd_i2c_dev_mem_s { + DFD_I2C_DEV_MEM_BUS, + DFD_I2C_DEV_MEM_ADDR, + DFD_I2C_DEV_MEM_END +} dfd_i2c_dev_mem_t; + +typedef enum cpld_mode_e { + DFD_CPLD_MODE_I2C, /* I2C bus */ + DFD_CPLD_MODE_LPC, /*LPC bus*/ +} cpld_mode_t; + +/* i2c access mode */ +typedef enum i2c_mode_e { + DFD_I2C_MODE_NORMAL_I2C, /* I2C bus */ + DFD_I2C_MODE_SMBUS, /* SMBUS bus */ +} i2c_mode_t; + +/* Global variable */ +extern char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END]; /* dfd_i2c_dev_t member string */ + +/** + * dfd_ko_cpld_read - cpld read operation + * @addr: Offset address + * @buf: data + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf); + +/** + * dfd_ko_cpld_write - cpld write operation + * @addr: address + * @data: data + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val); + +/** + * dfd_ko_i2c_read - I2C read operation + * @bus: I2C bus + * @addr: I2C device address + * @offset:register offset + * @buf:Read buffer + * @size:Read length + * @sysfs_name:sysfs attribute name + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size, const char *sysfs_name); + +/** + * dfd_ko_i2c_write - I2C write operation + * @bus: I2C bus + * @addr: I2C device address + * @offset:register offset + * @buf:write buffer + * @size: write length + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +/** + * dfd_ko_read_file - File read operation + * @fpath: File path + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes); + +/** + * dfd_ko_write_file - File write operation + * @fpath: File path + * @addr: address + * @val: data + * @write_bytes: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_write_file(char *fpath, int32_t addr, uint8_t *val, int32_t write_bytes); + +/** + * dfd_ko_other_i2c_dev_read - other_i2c read operation + * @addr: address + * @val: data + * @read_len: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_other_i2c_dev_read(int32_t addr, uint8_t *value, int32_t read_len); +#endif /* __DFD_CFG_ADAPTER_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h new file mode 100644 index 000000000000..4eba8aabbd49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h @@ -0,0 +1,101 @@ +/* + * A header definition for dfd_cfg_file driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_FILE_H__ +#define __DFD_CFG_FILE_H__ + +#include + +/* Returned value */ +#define KFILE_RV_OK (0) +#define KFILE_RV_INPUT_ERR (-1) /* Entry error */ +#define KFILE_RV_STAT_FAIL (-2) /* Failed to obtain file properties. Procedure */ +#define KFILE_RV_OPEN_FAIL (-3) /* Failed to open file */ +#define KFILE_RV_MALLOC_FAIL (-4) /* Failed to allocate memory */ +#define KFILE_RV_RD_FAIL (-5) /* Read failure */ +#define KFILE_RV_ADDR_ERR (-6) /* Address error */ +#define KFILE_RV_WR_FAIL (-7) /* Address error */ + +/* Whether it is a newline character */ +#define IS_CR(c) ((c) == '\n') + +/* File operation control structure */ +typedef struct kfile_ctrl_s { + int32_t size; /* File size */ + int32_t pos; /* Current position */ + char *buf; /* File cache */ +} kfile_ctrl_t; + +/* + * Open file + * @fname: filename + * @kfile_ctrl: File control variable + * + * @returns: 0 Succeeded, others failed + */ +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl); + +/* + * Close file + * @kfile_ctrl: File control variable + */ +void kfile_close(kfile_ctrl_t *kfile_ctrl); + +/* + * Close file + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len); + +#if 0 +/* + * Write data + * @fname: filename + * @addr: Offset address of the file written to + * @buf: Write data + * @buf_size: Data size + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size); +#endif +#endif /* __DFD_CFG_FILE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h new file mode 100644 index 000000000000..2e5dd2f3d645 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h @@ -0,0 +1,192 @@ +/* + * A header definition for dfd_cfg_info driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_INFO_H__ +#define __DFD_CFG_INFO_H__ + +#include + +/* num buf format data to convert to a numeric function pointer */ +typedef int (*info_num_buf_to_value_f)(uint8_t *num_buf, int buf_len, int *num_val); + +/* num buf format data to convert to a numeric function pointer */ +typedef int (*info_buf_to_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new); + +/* Information format judgment macro */ +#define IS_INFO_FRMT_BIT(frmt) ((frmt) == INFO_FRMT_BIT) +#define IS_INFO_FRMT_BYTE(frmt) (((frmt) == INFO_FRMT_BYTE) || ((frmt) == INFO_FRMT_NUM_BYTES)) +#define IS_INFO_FRMT_NUM_STR(frmt) ((frmt) == INFO_FRMT_NUM_STR) +#define IS_INFO_FRMT_NUM_BUF(frmt) ((frmt) == INFO_FRMT_NUM_BUF) +#define IS_INFO_FRMT_BUF(frmt) ((frmt) == INFO_FRMT_BUF) + +/* INT Validity judgment of information length */ +#define INFO_INT_MAX_LEN (32) +#define INFO_INT_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_INT_MAX_LEN)) + +/* buf Validity judgment of information length */ +#define INFO_BUF_MAX_LEN (128) +#define INFO_BUF_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_BUF_MAX_LEN)) + +/* Determine the validity of information bit offset */ +#define INFO_BIT_OFFSET_VALID(bit_offset) (((bit_offset) >= 0) && ((bit_offset) < 8)) + +/* Information control mode */ +typedef enum info_ctrl_mode_e { + INFO_CTRL_MODE_NONE, + INFO_CTRL_MODE_CFG, /* Configuration mode */ + INFO_CTRL_MODE_CONS, /* macromode */ + INFO_CTRL_MODE_TLV, /* TLV mode */ + INFO_CTRL_MODE_SRT_CONS, /* String constant*/ + INFO_CTRL_MODE_END +} info_ctrl_mode_t; + +/* Information format */ +typedef enum info_frmt_e { + INFO_FRMT_NONE, + INFO_FRMT_BIT, /* Single or multiple bits, not more than 8 bits */ + INFO_FRMT_BYTE, /* Single byte */ + INFO_FRMT_NUM_BYTES, /* Multiple byte values, up to sizeof(int) */ + INFO_FRMT_NUM_STR, /* String value */ + INFO_FRMT_NUM_BUF, /* String value */ + INFO_FRMT_BUF, /* Multiple bytes */ + INFO_FRMT_END +} info_frmt_t; + +/* Information source */ +typedef enum info_src_e { + INFO_SRC_NONE, + INFO_SRC_CPLD, /* CPLD equipment */ + INFO_SRC_FPGA, /* FPGA equipment */ + INFO_SRC_OTHER_I2C, /* other i2c equipment */ + INFO_SRC_FILE, /* file */ + INFO_SRC_END +} info_src_t; + +/* Polarity of information */ +typedef enum info_pola_e { + INFO_POLA_NONE, + INFO_POLA_POSI, /* Positive polarity bit value 1 Valid value high bytes saved in the source low address space */ + INFO_POLA_NEGA, /* Negative polarity bit value 0 Effective value high bytes saved in the source high address space */ + INFO_POLA_END +} info_pola_t; + +/* Information control structure */ +#define INFO_FPATH_MAX_LEN (128) /* Maximum length of the file source path */ +#define INFO_STR_CONS_MAX_LEN (64) /* Maximum length of a string constant */ +typedef struct info_ctrl_s { + info_ctrl_mode_t mode; /* mode */ + int32_t int_cons; /* Only the int type is supported */ + info_src_t src; /* source */ + info_frmt_t frmt; /* format */ + info_pola_t pola; /* polarity */ + char fpath[INFO_FPATH_MAX_LEN]; /* File path, only the file source information */ + int32_t addr; /* address */ + int32_t len; /* Length, bit length, or byte length */ + int32_t bit_offset; /* Offset number of bits in the address */ + char str_cons[INFO_STR_CONS_MAX_LEN]; /* String constant */ + int32_t int_extra1; /* int type reserved */ + int32_t int_extra2; + int32_t int_extra3; /* cpld voltage mode */ +} info_ctrl_t; + +/* info_ctrl_t member macro */ +typedef enum info_ctrl_mem_s { + INFO_CTRL_MEM_MODE, + INFO_CTRL_MEM_INT_CONS, + INFO_CTRL_MEM_SRC, + INFO_CTRL_MEM_FRMT, + INFO_CTRL_MEM_POLA, + INFO_CTRL_MEM_FPATH, + INFO_CTRL_MEM_ADDR, + INFO_CTRL_MEM_LEN, + INFO_CTRL_MEM_BIT_OFFSET, + INFO_CTRL_MEM_STR_CONS, + INFO_CTRL_MEM_INT_EXTRA1, + INFO_CTRL_MEM_INT_EXTRA2, + INFO_CTRL_MEM_INT_EXTRA3, + INFO_CTRL_MEM_END +} info_ctrl_mem_t; + +/* sensor data format */ +typedef enum sensor_format_mem_s { + LINEAR11 = 1, + LINEAR16 = 2, + TMP464 = 3, + MAC_TH5 = 4, + MAC_TH4 = 5, +} sensor_format_mem_t; + +/* hwmon data format conversion */ +typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, + info_ctrl_t *info_ctrl, int coefficient, int addend); + +/* Global variable */ +extern char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END]; /* info_ctrl_t member string */ +extern char *g_info_src_str[INFO_SRC_END]; /* info_src_t enumeration string */ +extern char *g_info_frmt_str[INFO_FRMT_END]; /* info_frmt_t enumeration string */ +extern char *g_info_pola_str[INFO_POLA_END]; /* info_pola_t enumeration string */ +extern char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END];/* info_ctrl_mode_t enumeration string */ + +/** + * dfd_info_get_int - Get int type information + * @key: Search keyword of the configuration item + * @ret: int type information + * @pfun: num Data conversion function of type buf + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_get_int(uint64_t key, int *ret, info_num_buf_to_value_f pfun); + +/** + * dfd_info_get_buf - Get buf type information + * @key: Search keyword of the configuration item + * @buf: Information buf + * @buf_len: buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_get_buf(uint64_t key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun); + +/** + * dfd_info_set_int - Set the int type information + * @key: Search keyword of the configuration item + * @val: int type information + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_set_int(uint64_t key, int val); + +/** + * dfd_info_get_sensor - Get sensors + * @key: HWMON Configures the key + * @buf: Result storage + * @buf_len: buf length + * + * @returns: <0 Failed, others succeeded + */ +int dfd_info_get_sensor(uint64_t key, char *buf, int buf_len, info_hwmon_buf_f pfun); + +/** + * @buf:Input and result store + * + */ +void dfd_info_del_no_print_string(char *buf); +#endif /* __DFD_CFG_INFO_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h new file mode 100644 index 000000000000..8b2b12ad512a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h @@ -0,0 +1,80 @@ +/* + * A header definition for dfd_cfg_listnode driver + * + * Copyright (C) 2024 Micas 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 + * 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 __DFD_CFG_LISTNODE_H__ +#define __DFD_CFG_LISTNODE_H__ + +#include + +/* Returned value */ +#define LNODE_RV_OK (0) +#define LNODE_RV_INPUT_ERR (-1) /* Entry error */ +#define LNODE_RV_NODE_EXIST (-2) /* Node already exists */ +#define LNODE_RV_NOMEM (-3) /* Node already exists */ + +/* Root node public structure */ +typedef struct lnode_root_s { + struct list_head root; +} lnode_root_t; + +/* Node structure */ +typedef struct lnode_node_s { + struct list_head lst; + + uint64_t key; /* Node search index value */ + void *data; /* The actual data pointer */ +} lnode_node_t; + +/** + * Find node + * @root: Root node pointer + * @key: Node index value + * + * @return : Node data pointer,NULL failed + */ +void *lnode_find_node(lnode_root_t *root, uint64_t key); + +/** + * Insert node + * @root: Root node pointer + * @key: Node index value + * @data: data + * + * @return : 0-- success, other failures + */ +int lnode_insert_node(lnode_root_t *root, uint64_t key, void *data); + +/** + * Example Initialize the root node + * @root: Root node pointer + * + * @return : 0-- success, other failures + */ +int lnode_init_root(lnode_root_t *root); + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void lnode_free_list(lnode_root_t *root); + +#endif /* __DFD_CFG_LISTNODE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h new file mode 100644 index 000000000000..a95943c5a90d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h @@ -0,0 +1,107 @@ +/* + * A header definition for dfd_cfg_frueeprom driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_FRUEEPROM_H_ +#define _DFD_FRUEEPROM_H_ + +/* Per IPMI v2.0 FRU specification */ +typedef struct fru_common_header_s { + uint8_t fixed; + uint8_t internal_offset; + uint8_t chassis_offset; + uint8_t board_offset; + uint8_t product_offset; + uint8_t multi_offset; + uint8_t pad; + uint8_t crc; +} __attribute__((packed)) fru_common_header_t; + +/* first byte in header is 1h per IPMI V2 spec. */ + +#define IPMI_FRU_HDR_BYTE_ZERO 1 +#define IPMI_EIGHT_BYTES 8 +#define IPMI_FRU_PRODUCT_AREA_MIN_LEN (7) +#define IPMI_FRU_BOARD_AREA_MIN_LEN (5) + +#define IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX 512 +#define IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH 3 +#define IPMI_FRU_SENTINEL_VALUE 0xC1 +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK 0xC0 +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT 0x06 +#define IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK 0x3F +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_LANGUAGE_CODE 0x03 + +struct ipmi_fru_field { + uint8_t type_length_field[IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX]; + /* store length of data stored in buffer */ + unsigned int type_length_field_length; +}; + +typedef struct ipmi_fru_field ipmi_fru_field_t; + +typedef struct ipmi_product_info_s { + uint8_t *language_code; + ipmi_fru_field_t *product_manufacturer_name; + ipmi_fru_field_t *product_name; + ipmi_fru_field_t *product_part_model_number; + ipmi_fru_field_t *product_version; + ipmi_fru_field_t *product_serial_number; + ipmi_fru_field_t *product_asset_tag; + ipmi_fru_field_t *product_fru_file_id; + ipmi_fru_field_t *product_custom_fields; + ipmi_fru_field_t *product_type_fields; +} ipmi_product_info_t; + +typedef struct ipmi_board_info_s { + uint8_t *language_code; + uint8_t *mfg_time; + ipmi_fru_field_t *board_manufacturer; + ipmi_fru_field_t *board_product_name; + ipmi_fru_field_t *board_serial_number; + ipmi_fru_field_t *board_part_number; + ipmi_fru_field_t *board_fru_file_id; + ipmi_fru_field_t *board_custom_fields; /*hw version */ +} ipmi_board_info_t; + +/** + * dfd_get_fru_data - Obtain product area FRU information + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number 6: product ID + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name); + +/** + * dfd_get_fru_board_data - Obtain the FRU information of the board area + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_board_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name); + +#endif /* endif _DFD_FRUEEPROM_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h new file mode 100644 index 000000000000..994bb2387ddb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h @@ -0,0 +1,251 @@ +/* + * A header definition for dfd_sysfs_common driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_SYSFS_COMMON_H_ +#define _DFD_SYSFS_COMMON_H_ + +struct switch_drivers_s { + /* temperature sensors */ + int (*get_main_board_temp_number)(void); + ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_high)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_low)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_monitor_flag)(unsigned int temp_index, char *buf, size_t count); + /* voltage sensors */ + int (*get_main_board_vol_number)(void); + ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_monitor_flag)(unsigned int vol_index, char *buf, size_t count); + /* current sensors */ + int (*get_main_board_curr_number)(void); + ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_monitor_flag)(unsigned int curr_index, char *buf, size_t count); + /* syseeprom */ + int (*get_syseeprom_size)(void); + ssize_t (*read_syseeprom_data)(char *buf, loff_t offset, size_t count); + ssize_t (*write_syseeprom_data)(char *buf, loff_t offset, size_t count); + /* fan */ + int (*get_fan_number)(void); + int (*get_fan_motor_number)(unsigned int fan_index); + ssize_t (*get_fan_model_name)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_vendor)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_serial_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_part_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_hardware_version)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_status)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_present)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_led_status)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_led_status)(unsigned int fan_index, int status); + ssize_t (*get_fan_direction)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_motor_status)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_tolerance)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_target)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_max)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_min)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_ratio)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_ratio)(unsigned int fan_index, int ratio); + /* PSU */ + int (*get_psu_number)(void); + int (*get_psu_temp_number)(unsigned int psu_index); + ssize_t (*get_psu_model_name)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_vendor)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_date)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hw_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_alarm)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_serial_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_part_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hardware_version)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_type)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_max_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_present_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status_pmbus)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_ratio)(unsigned int psu_index, char *buf, size_t count); + int (*set_psu_fan_ratio)(unsigned int psu_index, int ratio); + ssize_t (*get_psu_fan_direction)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_led_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed_cal)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_temp_alias)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_type)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_value)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_attr_threshold)(unsigned int psu_index, unsigned int type, char *buf, size_t count); + int (*get_psu_eeprom_size)(unsigned int psu_index); + ssize_t (*read_psu_eeprom_data)(unsigned int psu_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_psu_blackbox_info)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_pmbus_info)(unsigned int psu_index, char *buf, size_t count); + int (*clear_psu_blackbox)(unsigned int psu_index, uint8_t value); + /* transceiver */ + int (*get_eth_number)(void); + ssize_t (*get_transceiver_power_on_status)(char *buf, size_t count); + int (*set_transceiver_power_on_status)(int status); + ssize_t (*get_transceiver_present_status)(char *buf, size_t count); + ssize_t (*get_eth_power_on_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_power_on_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_tx_fault_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_tx_disable_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_tx_disable_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_present_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_rx_los_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_reset_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_reset_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_low_power_mode_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_interrupt_status)(unsigned int eth_index, char *buf, size_t count); + int (*get_eth_eeprom_size)(unsigned int eth_index); + ssize_t (*read_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_eth_optoe_type)(unsigned int sff_index, int *optoe_type, char *buf, size_t count); + int (*set_eth_optoe_type)(unsigned int sff_index, int optoe_type); + /* sysled */ + ssize_t (*get_sys_led_status)(char *buf, size_t count); + int (*set_sys_led_status)(int status); + ssize_t (*get_bmc_led_status)(char *buf, size_t count); + int (*set_bmc_led_status)(int status); + ssize_t (*get_sys_fan_led_status)(char *buf, size_t count); + int (*set_sys_fan_led_status)(int status); + ssize_t (*get_sys_psu_led_status)(char *buf, size_t count); + int (*set_sys_psu_led_status)(int status); + ssize_t (*get_id_led_status)(char *buf, size_t count); + int (*set_id_led_status)(int status); + /* FPGA */ + int (*get_main_board_fpga_number)(void); + ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_type)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_firmware_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_board_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_test_reg)(unsigned int fpga_index, char *buf, size_t count); + int (*set_main_board_fpga_test_reg)(unsigned int fpga_index, unsigned int value); + /* CPLD */ + int (*get_main_board_cpld_number)(void); + ssize_t (*get_main_board_cpld_alias)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_type)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_firmware_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_board_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_test_reg)(unsigned int cpld_index, char *buf, size_t count); + int (*set_main_board_cpld_test_reg)(unsigned int cpld_index, unsigned int value); + /* watchdog */ + ssize_t (*get_watchdog_identify)(char *buf, size_t count); + ssize_t (*get_watchdog_timeleft)(char *buf, size_t count); + ssize_t (*get_watchdog_timeout)(char *buf, size_t count); + int (*set_watchdog_timeout)(int value); + ssize_t (*get_watchdog_enable_status)(char *buf, size_t count); + int (*set_watchdog_enable_status)(int value); + int (*set_watchdog_reset)(int value); + /* slot */ + int (*get_slot_number)(void); + int (*get_slot_temp_number)(unsigned int slot_index); + int (*get_slot_vol_number)(unsigned int slot_index); + int (*get_slot_curr_number)(unsigned int slot_index); + int (*get_slot_cpld_number)(unsigned int slot_index); + int (*get_slot_fpga_number)(unsigned int slot_index); + ssize_t (*get_slot_model_name)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_vendor)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_serial_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_part_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_hardware_version)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_status)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_led_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_led_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_power_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_power_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_temp_alias)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_type)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_value)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_vol_alias)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_type)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_range)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_nominal_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_curr_alias)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_type)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_value)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_alias)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_type)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_firmware_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_board_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + int (*set_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, unsigned int value); + ssize_t (*get_slot_cpld_alias)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_type)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_firmware_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_board_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + int (*set_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, unsigned int value); + /* system */ + ssize_t (*get_system_value)(unsigned int type, int *value, char *buf, size_t count); + ssize_t (*set_system_value)(unsigned int type, int value); + ssize_t (*get_system_port_power_status)(unsigned int type, char *buf, size_t count); + /* eeprom */ + int (*get_eeprom_number)(void); + int (*get_eeprom_size)(unsigned int e2_index); + ssize_t (*get_eeprom_alias)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_tag)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_type)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*read_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); +}; + +extern struct switch_drivers_s * s3ip_switch_driver_get(void); + +#endif /*_DFD_SYSFS_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h new file mode 100644 index 000000000000..75e0f06bd305 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h @@ -0,0 +1,91 @@ +/* + * A header definition for dfd_tlveeprom driver + * + * Copyright (C) 2024 Micas 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 + * 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 _DFD_TLVEEPROM_H_ +#define _DFD_TLVEEPROM_H_ + +#ifndef be16_to_cpu +#define be16_to_cpu(x) ntohs(x) +#endif + +#ifndef cpu_to_be16 +#define cpu_to_be16(x) htons(x) +#endif + +#define TLV_CODE_NAME_LEN 64 + +/* + * Struct for displaying the TLV codes and names. + */ +struct tlv_code_desc { + uint8_t m_code; + char m_name[TLV_CODE_NAME_LEN]; +}; + +/* ONIE TLV Type Type and extended TLV type definition */ +typedef struct dfd_tlv_type_s { + uint8_t main_type; /* ONIE standard TLV TYPE */ + uint8_t ext_type; /* Extended TLV TYPE type */ +} dfd_tlv_type_t; + +/* Header Field Constants */ +#define TLV_INFO_ID_STRING "TlvInfo" +#define TLV_INFO_VERSION 0x01 + +struct __attribute__ ((__packed__)) tlvinfo_header_s { + char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ + uint8_t version; /* 0x08 Structure version */ + uint16_t totallen; /* 0x09 - 0x0A Length of all data which follows */ +}; +typedef struct tlvinfo_header_s tlvinfo_header_t; + +/* + * TlvInfo TLV: Layout of a TLV field + */ +struct __attribute__ ((__packed__)) tlvinfo_tlv_s { + uint8_t type; + uint8_t length; + uint8_t value[0]; +}; +typedef struct tlvinfo_tlv_s tlvinfo_tlv_t; + +#define TLV_VALUE_MAX_LEN 255 +/* + * The max decode value is currently for the 'raw' type or the 'vendor + * extension' type, both of which have the same decode format. The + * max decode string size is computed as follows: + * + * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1 + * + */ +#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1) + +typedef struct tlv_decode_value_s { + uint8_t value[TLV_DECODE_VALUE_MAX_LEN]; + uint32_t length; +} tlv_decode_value_t; + +typedef enum dfd_tlvinfo_ext_tlv_type_e { + DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1, +} dfd_tlvinfo_ext_tlv_type_t; + +int dfd_tlvinfo_get_e2prom_info(uint8_t *eeprom, uint32_t size, dfd_tlv_type_t *tlv_type, uint8_t* buf, uint32_t *buf_len); + +#endif /* endif _DFD_TLVEEPROM_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h new file mode 100644 index 000000000000..7ab38f42d367 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h @@ -0,0 +1,101 @@ +/* + * A header definition for switch_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SWITCH_DRIVER_H_ +#define _SWITCH_DRIVER_H_ + +#define SWITCH_DEV_NO_SUPPORT "NA" +#define SWITCH_DEV_ERROR "ACCESS FAILED" +#define WB_SYSFS_RV_UNSUPPORT (999) + +typedef enum dbg_level_e { + DBG_VERBOSE = 0x01, + DBG_WARN = 0x02, + DBG_ERROR = 0x04, +} dbg_level_t; + +typedef enum fan_status_e { + FAN_STATUS_ABSENT = 0, + FAN_STATUS_OK = 1, + FAN_STATUS_NOT_OK = 2, +} fan_status_t; + +typedef enum led_status_e { + LED_STATUS_DARK = 0, + LED_STATUS_GREEN = 1, + LED_STATUS_YELLOW = 2, + LED_STATUS_RED = 3, + LED_STATUS_BLUE = 4, + LED_STATUS_GREEN_FLASH = 5, + LED_STATUS_YELLOW_FLASH = 6, + LED_STATUS_RED_FLASH = 7, +} led_status_t; + +typedef enum air_flow_direction_e { + F2B = 0, /* air enters from the front of the cabinet, and exhausts from the back */ + B2F = 1, /* air enters from the back of the cabinet, and exhausts from the front */ +} air_flow_direction_t; + +typedef enum psu_input_type_e { + POWER_DC = 0, + POWER_AC = 1, +} psu_input_type_t; + +typedef enum psu_status_e { + PSU_STATUS_ABSENT = 0, /* psu absent */ + PSU_STATUS_PRESENT = 1, /* psu present and status ok */ + PSU_STATUS_WARN = 2, /* psu present and status warn (pmbus 0x79 bit11 value 0)*/ + PSU_STATUS_FAIL = 3, /* psu present and status fail (pmbus 0x79 bit11 value 1)*/ +} psu_status_t; + +typedef enum psu_status_word_e { + PSU_VOUT_FAULT = 0x8000, + PSU_IOUT_FAULT = 0x4000, + PSU_INPUT_FAULT = 0x2000, + PSU_MFR_FAULT = 0x1000, + PSU_PG_FAULT = 0x0800, + PSU_FAN_FAULT = 0x0400, + PSU_OFF_FAULT = 0x0040, + PSU_TEMP_FAULT = 0x0004, +} psu_status_word_t; + +typedef enum psu_io_status_e { + PSU_IO_STATUS_ABNORMAL = 0, + PSU_IO_STATUS_NORMAL = 1, +} psu_io_status_t; + +typedef enum dev_status_e { + DEV_ABSENT = 0, /* dev absent */ + DEV_PRESENT = 1, /* dev present */ +} dev_status_t; + +extern int g_switch_dbg_level; + +#define SWITCH_DEBUG(level, fmt, arg...) do { \ + if (g_switch_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#endif /* _SWITCH_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h new file mode 100644 index 000000000000..7698a3f0ef60 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h @@ -0,0 +1,100 @@ +/* + * A header definition for wb_cpld_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_CPLD_DRIVER_H_ +#define _WB_CPLD_DRIVER_H_ + +/** + * dfd_get_cpld_name - Obtain the CPLD name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_name(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_type - Obtain the CPLD model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_type(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_fw_version - Obtain the CPLD firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_fw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_hw_version - Obtain the hardware version of the CPLD + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_hw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_set_cpld_testreg - Set the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Writes the value of the test register + * return: Success:0 + * :Failed: A negative value is returned + */ +int dfd_set_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int value); + +/** + * dfd_get_cpld_testreg - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Read the test register value + * return: Success:0 + * :Failed: A negative value is returned + */ +int dfd_get_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int *value); + +/** + * dfd_get_cpld_testreg_str - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_testreg_str(uint8_t main_dev_id, unsigned int cpld_index, + char *buf, size_t count); + +#endif /* _WB_CPLD_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h new file mode 100644 index 000000000000..e86ee210be78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h @@ -0,0 +1,59 @@ +/* + * A header definition for wb_eeprom_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_EEPROM_DRIVER_H_ +#define _WB_EEPROM_DRIVER_H_ + +/** + * dfd_get_eeprom_size - Gets the data size of the eeprom + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * return: Succeeded: The data size of the eeprom is returned + * : Failed: A negative value is returned + */ +int dfd_get_eeprom_size(int e2_type, int index); + +/** + * dfd_read_eeprom_data - Read eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data received buf + * @offset: The offset address of the read + * @count: Read length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_read_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count); + +/** + * dfd_write_eeprom_data - Write eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data buf + * @offset: The offset address of the write + * @count: Write length + * return: Success: The length of the written data is returned + * : Failed: A negative value is returned + */ +ssize_t dfd_write_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count); +ssize_t dfd_get_eeprom_alias(int e2_type, unsigned int e2_index, char *buf, size_t count); +ssize_t dfd_get_eeprom_tag(int e2_type, unsigned int e2_index, char *buf, size_t count); +ssize_t dfd_get_eeprom_type(int e2_type, unsigned int e2_index, char *buf, size_t count); +#endif /* _WB_EEPROM_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h new file mode 100644 index 000000000000..b1e66cb0530c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h @@ -0,0 +1,191 @@ +/* + * A header definition for wb_fan_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_FAN_DRIVER_H_ +#define _WB_FAN_DRIVER_H_ + +/** + * dfd_get_fan_status_str - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_status_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_present_str - Obtaining fan present status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_present_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_info - Obtaining Fan Information + * @index: Number of the fan, starting from 1 + * @cmd: Fan information type, fan name :2, fan serial number :3, fan hardware version :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ + +/** + * dfd_get_fan_motor_status_str - Obtain the fan motor status + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_status_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +ssize_t dfd_get_fan_info(unsigned int fan_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_fan_speed - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @speed: Speed value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed); + +/** + * dfd_get_fan_speed_str - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_speed_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_set_fan_pwm - Set the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fan_pwm(unsigned int fan_index, int pwm); + +/** + * dfd_get_fan_pwm - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_pwm(unsigned int fan_index, int *pwm); + +/** + * dfd_get_fan_pwm_str - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_pwm_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_tolerance_str - Obtain the fan speed tolerance + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_tolerance_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_speed_target - Obtain the standard fan speed + * @fan_index + * @motor_index + * @value Standard speed value + * @returns: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed_target(unsigned int fan_index, unsigned int motor_index, int *value); + +/** + * dfd_get_fan_motor_speed_target_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_target_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_direction_str - Obtain the fan air duct type + * @fan_index: Number of the fan, starting from 1 + * @buf :Duct type receives buf + * @count :Duct type receives buf length + * @returns: Succeeded: Air duct type String length + * Failed: A negative value is returned + */ +ssize_t dfd_get_fan_direction_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_max_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buff + * @count: Receive buf length + * return: Success :0 + * :Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_max_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_min_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_min_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_present_status - Obtain the fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:PRESENT + * : Negative value - Read failed + */ +int dfd_get_fan_present_status(unsigned int fan_index); + +#endif /* _WB_FAN_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h new file mode 100644 index 000000000000..05863c4737af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h @@ -0,0 +1,100 @@ +/* + * A header definition for wb_fpga_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_FPGA_DRIVER_H_ +#define _WB_FPGA_DRIVER_H_ + +/** + * dfd_get_fpga_name -Get the FPGA name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_name(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_type - Get FPGA model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_type(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_fw_version - Obtain the FPGA firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_fw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_hw_version - Obtain the hardware version of the FPGA + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_hw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_set_fpga_testreg - Sets the value of the FPGA test register + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index:Number of the FPGA, starting from 1 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int value); + +/** + * dfd_get_fpga_testreg - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: Number of the FPGA, starting from 1 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int *value); + +/** + * dfd_get_fpga_testreg_str - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_testreg_str(uint8_t main_dev_id, unsigned int fpga_index, + char *buf, size_t count); + +#endif /* _WB_FPGA_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h new file mode 100644 index 000000000000..bac7b23d9836 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h @@ -0,0 +1,45 @@ +/* + * A header definition for wb_led_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_LED_DRIVER_H_ +#define _WB_LED_DRIVER_H_ + +/** + * dfd_get_led_status - Get LED and other status + * @led_id: led lamp type + * @led_index: led light offset + * @buf: LED light status receives buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_led_status(uint16_t led_id, uint8_t led_index, char *buf, size_t count); + +/** + * dfd_set_led_status - Set LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @value: LED light status value + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_set_led_status(uint16_t led_id, uint8_t led_index, int value); + +#endif /* _WB_LED_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h new file mode 100644 index 000000000000..6bce2817cb13 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h @@ -0,0 +1,360 @@ +/* + * A header definition for wb_module driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_MODULE_H_ +#define _WB_MODULE_H_ + +#include "switch_driver.h" + +#define mem_clear(data, size) memset((data), 0, (size)) +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, + DFD_RV_INVALID_VALUE = 12, + DFD_RV_NO_MEMORY = 13, + DFD_RV_CHECK_FAIL = 14, +} dfd_rv_t; + +typedef enum status_mem_e { + STATUS_ABSENT = 0, + STATUS_OK = 1, + STATUS_NOT_OK = 2, + STATUS_MEM_END = 3, +} status_mem_t; + +/* psu PMBUS */ +typedef enum psu_sensors_type_e { + PSU_SENSOR_NONE = 0, + PSU_IN_VOL = 1, + PSU_IN_CURR = 2, + PSU_IN_POWER = 3, + PSU_OUT_VOL = 4, + PSU_OUT_CURR = 5, + PSU_OUT_POWER = 6, + PSU_FAN_SPEED = 7, + PSU_OUT_MAX_POWERE = 8, + PSU_OUT_STATUS = 9, + PSU_IN_STATUS = 10, + PSU_IN_TYPE = 11, + PSU_FAN_RATIO = 12, + PSU_IN_VOL_MAX = 13, + PSU_IN_CURR_MAX = 14, + PSU_IN_VOL_MIN = 15, + PSU_IN_CURR_MIN = 16, + PSU_OUT_VOL_MAX = 17, + PSU_OUT_CURR_MAX = 18, + PSU_OUT_VOL_MIN = 19, + PSU_OUT_CURR_MIN = 20, + PSU_FAN_SPEED_MAX = 21, + PSU_FAN_SPEED_MIN = 22, + PSU_IN_POWER_MAX = 23, + PSU_IN_POWER_MIN = 24, + PSU_OUT_POWER_MAX = 25, + PSU_OUT_POWER_MIN = 26, + PSU_HW_STATUS = 27, +} psu_sensors_type_t; + +/* Watchdog type */ +typedef enum wb_wdt_type_e { + WB_WDT_TYPE_NAME = 0, /* watchdog identify */ + WB_WDT_TYPE_STATE = 1, /* watchdog state */ + WB_WDT_TYPE_TIMELEFT = 2, /* watchdog timeleft */ + WB_WDT_TYPE_TIMEOUT = 3, /* watchdog timeout */ + WB_WDT_TYPE_ENABLE = 4, /* watchdog enable */ +} wb_wdt_type_t; + +/* Port Power Status */ +typedef enum wb_port_power_status_e { + WB_PORT_POWER_OFF = 0, /* port power off */ + WB_PORT_POWER_ON = 1, /* port power on */ +} wb_port_power_status_t; + +/* sensor monitor or not */ +typedef enum wb_sensor_monitor_flag_e { + WB_SENSOR_MONITOR_NO = 0, /* sensor not monitor */ + WB_SENSOR_MONITOR_YES = 1, /* sensor monitor */ +} wb_sensor_monitor_flag_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, + DFD_DEV_INFO_TYPE_PART_NAME = 7, + DFD_DEV_INFO_TYPE_PART_NUMBER = 8, /* part number */ + DFD_DEV_INFO_TYPE_FAN_DIRECTION = 9, + DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER = 10, /* max_output_power */ + DFD_DEV_INFO_TYPE_SPEED_CAL = 11, + DFD_DEV_INFO_TYPE_ASSET_TAG = 12, + DFD_DEV_INFO_TYPE_VENDOR = 13, +} dfd_dev_tlv_type_t; + +/* Master device type */ +typedef enum wb_main_dev_type_e { + WB_MAIN_DEV_MAINBOARD = 0, /* Main board */ + WB_MAIN_DEV_FAN = 1, /* FAN */ + WB_MAIN_DEV_PSU = 2, /* PSU */ + WB_MAIN_DEV_SFF = 3, /* Optical module */ + WB_MAIN_DEV_CPLD = 4, /* CPLD */ + WB_MAIN_DEV_SLOT = 5, /* Daughter card */ +} wb_main_dev_type_t; + +/* Subdevice type */ +typedef enum wb_minor_dev_type_e { + WB_MINOR_DEV_NONE = 0, /* None */ + WB_MINOR_DEV_TEMP = 1, /* temperature*/ + WB_MINOR_DEV_IN = 2, /* voltage */ + WB_MINOR_DEV_CURR = 3, /* current */ + WB_MINOR_DEV_POWER = 4, /* power */ + WB_MINOR_DEV_MOTOR = 5, /* motor */ + WB_MINOR_DEV_PSU = 6, /* Power supply type */ + WB_MINOR_DEV_FAN = 7, /* Fan model */ + WB_MINOR_DEV_CPLD = 8, /* CPLD */ + WB_MINOR_DEV_FPGA = 9, /* FPGA */ + WB_MINOR_DEV_EEPROM = 10, /* EEPROM */ +} wb_minor_dev_type_t; + +/* SENSORS attribute type */ +typedef enum wb_sensor_type_e { + WB_SENSOR_INPUT = 0, /* Sensor value */ + WB_SENSOR_ALIAS = 1, /* Sensor nickname */ + WB_SENSOR_TYPE = 2, /* Sensor type*/ + WB_SENSOR_MAX = 3, /* Sensor maximum */ + WB_SENSOR_MAX_HYST = 4, /* Sensor hysteresis value */ + WB_SENSOR_MIN = 5, /* Sensor minimum */ + WB_SENSOR_CRIT = 6, /* Sensor crit value */ + WB_SENSOR_RANGE = 7, /* Sensor error value */ + WB_SENSOR_NOMINAL_VAL = 8, /* Nominal value of the sensor */ + WB_SENSOR_HIGH = 9, /* Sensor height */ + WB_SENSOR_LOW = 10, /* Sensor low */ +} wb_sensor_type_t; + +/* sff cpld attribute type */ +typedef enum wb_sff_cpld_attr_e { + WB_SFF_POWER_ON = 0x01, + WB_SFF_TX_FAULT, + WB_SFF_TX_DIS, + WB_SFF_PRESENT_RESERVED, + WB_SFF_RX_LOS, + WB_SFF_RESET, + WB_SFF_LPMODE, + WB_SFF_MODULE_PRESENT, + WB_SFF_INTERRUPT, +} wb_sff_cpld_attr_t; + +/* LED attribute type */ +typedef enum wb_led_e { + WB_SYS_LED_FRONT = 0, /* Front panel SYS light */ + WB_SYS_LED_REAR = 1, /* SYS light on rear panel */ + WB_BMC_LED_FRONT = 2, /* BMC indicator on the front panel */ + WB_BMC_LED_REAR = 3, /* BMC indicator on the rear panel */ + WB_FAN_LED_FRONT = 4, /* Front panel fan light */ + WB_FAN_LED_REAR = 5, /* Rear panel fan light */ + WB_PSU_LED_FRONT = 6, /* Front panel power light */ + WB_PSU_LED_REAR = 7, /* Rear panel power light */ + WB_ID_LED_FRONT = 8, /* Front panel positioning light */ + WB_ID_LED_REAR = 9, /* Rear panel positioning light */ + WB_FAN_LED_MODULE = 10, /* Fan module indicator */ + WB_PSU_LED_MODULE = 11, /* Power module indicator */ + WB_SLOT_LED_MODULE = 12, /* Sub-card status indicator */ +} wb_led_t; + +extern int g_dfd_dbg_level; +extern int g_dfd_fan_dbg_level; +extern int g_dfd_fru_dbg_level; +extern int g_dfd_eeprom_dbg_level; +extern int g_dfd_cpld_dbg_level; +extern int g_dfd_fpga_dbg_level; +extern int g_dfd_sysled_dbg_level; +extern int g_dfd_slot_dbg_level; +extern int g_dfd_sensor_dbg_level; +extern int g_dfd_psu_dbg_level; +extern int g_dfd_sff_dbg_level; +extern int g_dfd_watchdog_dbg_level; +extern int g_dfd_custom_dbg_level; + +#define WB_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define WB_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define DBG_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_FAN_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fan_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_FRU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fru_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_EEPROM_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_eeprom_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_CPLD_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_cpld_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_FPGA_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fpga_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_SYSLED_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sysled_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SLOT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_slot_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SENSOR_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sensor_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_PSU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_psu_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SFF_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sff_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_WDT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_watchdog_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SYSTEM_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_custom_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +/** + * wb_dev_cfg_init - dfd module initialization + * + * @returns: <0 Failed, otherwise succeeded + */ +int32_t wb_dev_cfg_init(void); + +/** + * wb_dev_cfg_exit - dfd module exit + * + * @returns: void + */ + +void wb_dev_cfg_exit(void); + +/** + * dfd_get_dev_number - Get the number of devices + * @main_dev_id:Master device number + * @minor_dev_id:Secondary device number + * @returns: <0 failed, otherwise number of devices is returned + */ +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id); +#endif /* _WB_MODULE_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h new file mode 100644 index 000000000000..5de93f46bd11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h @@ -0,0 +1,114 @@ +/* + * A header definition for wb_psu_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_PSU_DRIVER_H_ +#define _WB_PSU_DRIVER_H_ + +/** + * dfd_get_psu_info - Get Power Information + * @index: Number of the power supply, starting from 1 + * @cmd: Power supply information Type, power supply name :2, power supply serial number :3, power supply hardware version :5 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_info(unsigned int psu_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_psu_present_status_str - Get Power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_present_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_out_status_str - Get the output power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_out_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_status_pmbus_str - Gets the value on the pmbus register of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_status_pmbus_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_in_status_str - Get the input power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_in_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_input_type - Get the power input type + * @index: Number of the power supply, starting from 1 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_input_type(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_alarm_status - Get power PMBUS WORD STATUS status + * @index: Number of the power supply, starting from 1 + * return: Success:return psu output status + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_alarm_status(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_fan_ratio_str - Gets the target fan rotation rate + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_fan_ratio_str(unsigned int psu_index, char *buf, size_t count); +ssize_t dfd_set_psu_fan_ratio_str(unsigned int psu_index, int pwm); +/** + * dfd_get_psu_pmbus_status - Get power Status Word + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_pmbus_status(unsigned int psu_index, char *buf, size_t count); +/** + * dfd_get_psu_present_status - Obtain the power supply status + * @index: Number of the power supply, starting from 1 + * return: 0:Not in the position + * 1:position + * : Negative value - Read failed + */ +int dfd_get_psu_present_status(unsigned int psu_index); + +ssize_t dfd_get_psu_threshold_str(unsigned int psu_index, unsigned int type, char *buf, size_t count); + +ssize_t dfd_get_psu_hw_status_str(unsigned int psu_index, char *buf, size_t count); + +ssize_t dfd_get_psu_blackbox(unsigned int psu_index, char *buf, size_t count); +ssize_t dfd_get_psu_pmbus(unsigned int psu_index, char *buf, size_t count); +int dfd_clear_psu_blackbox(unsigned int psu_index, uint8_t value); +#endif /* _WB_PSU_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h new file mode 100644 index 000000000000..d33ee3217e37 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h @@ -0,0 +1,82 @@ +/* + * A header definition for wb_sensors_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_SENSORS_DRIVER_H_ +#define _WB_SENSORS_DRIVER_H_ + +/** + * dfd_get_temp_info - Get temperature information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1/psu1 + * @temp_index: Temperature index, starting at 1 + * @temp_type: Read type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t temp_index, + uint8_t temp_attr, char *buf, size_t count); + +/** + * dfd_get_voltage_info - Get voltage information + * @main_dev_id: Motherboard :0 Subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Voltage index, starting at 1 + * @in_type:Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t in_index, + uint8_t in_attr, char *buf, size_t count); + +/** + * dfd_get_current_info - Get current information + * @main_dev_id: Motherboard :0 Subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Current index, starting at 1 + * @in_type: Current type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_current_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t curr_index, + uint8_t curr_attr, char *buf, size_t count); + +/** + * dfd_get_psu_sensor_info - Obtain PMBUS information about the power supply + * @psu_index: Power index, starting at 1 + * @sensor_type: Type of the obtained pmbus information + * @buf: pmbus results are stored in buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_sensor_info(uint8_t psu_index, uint8_t sensor_type, char *buf, size_t count); + + +/** + * dfd_get_main_board_monitor_flag - Get Monitor flag info + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @sensor_type: Type of the obtained pmbus information + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +int dfd_get_main_board_monitor_flag(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, char *buf, size_t count); +#endif /* _WB_SENSORS_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h new file mode 100644 index 000000000000..e26e12805de6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h @@ -0,0 +1,63 @@ +/* + * A header definition for wb_sff_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_SFF_DRIVER_H_ +#define _WB_SFF_DRIVER_H_ + +/** + * dfd_set_sff_cpld_info - Example Set the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @value: Writes the value to the register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, int value); + +/** + * dfd_get_sff_cpld_info - Obtain the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @buf: Optical module E2 receives information from buf + * @count: buf length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, size_t count); + +/** + * dfd_get_single_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_get_single_eth_optoe_type(unsigned int sff_index, int *optoe_type); + +/** + * dfd_set_single_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_set_single_eth_optoe_type(unsigned int sff_index, int optoe_type); + +#endif /* _WB_SFF_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h new file mode 100644 index 000000000000..7978fa5b7698 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h @@ -0,0 +1,64 @@ +/* + * A header definition for wb_slot_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_SLOT_DRIVER_H_ +#define _WB_SLOT_DRIVER_H_ + +/** + * dfd_get_slot_status_str - Gets the subcard status + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_slot_status_str(unsigned int slot_index, char *buf, size_t count); + +/** + * dfd_get_slot_info - Obtain the subcard information + * @slot_index: Number of the sub-card, starting from 1 + * @cmd: Card information type, sub-card name :2, sub-card serial number :3, sub-card hardware version number :5 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_info(unsigned int slot_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_slot_power_status_str - get power status of slot + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_power_status_str(unsigned int slot_index, char *buf, size_t count); + +/** + * dfd_set_slot_power_status_str - set power status of slot + * @slot_index: Number of the sub-card, starting from 1 + * @value: Power status of slot + * return: Success: 0 is returned + * : Failed: A negative value is returned + */ +int dfd_set_slot_power_status_str(unsigned int slot_index, int value); + +#endif /* _WB_SLOT_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h new file mode 100644 index 000000000000..2298c5bb11b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h @@ -0,0 +1,33 @@ +/* + * A header definition for wb_system_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SYSTEM_DRIVER_H_ +#define _SYSTEM_DRIVER_H_ + +typedef enum module_pwr_status_e { + MODULE_POWER_OFF = 0, + MODULE_POWER_ON, +} module_pwr_status_t; + +ssize_t dfd_system_get_system_value(unsigned int type, int *value); +ssize_t dfd_system_set_system_value(unsigned int type, int value); +ssize_t dfd_system_get_port_power_status(unsigned int type, char *buf, size_t count); + +#endif /* _SYSTEM_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h new file mode 100644 index 000000000000..c59bd64e692a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h @@ -0,0 +1,37 @@ +/* + * A header definition for wb_watchdog_driver driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WB_WATCHDOG_DRIVER_H_ +#define _WB_WATCHDOG_DRIVER_H_ + +/** + * dfd_get_watchdog_info - Get watchdog information + * @type: Watchdog information type + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_watchdog_info(uint8_t type, char *buf, size_t count); + +ssize_t dfd_watchdog_get_status_str(char *buf, size_t count); +ssize_t dfd_watchdog_get_status(char *buf, size_t count); +ssize_t dfd_watchdog_set_status(int value); + +#endif /* _WB_WATCHDOG_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c new file mode 100644 index 000000000000..5628aadab430 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c @@ -0,0 +1,4577 @@ +/* + * An switch_driver driver for switch devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "dfd_sysfs_common.h" +#include "switch_driver.h" +#include "wb_module.h" +#include "wb_fan_driver.h" +#include "wb_eeprom_driver.h" +#include "wb_cpld_driver.h" +#include "wb_fpga_driver.h" +#include "wb_led_driver.h" +#include "wb_slot_driver.h" +#include "wb_sensors_driver.h" +#include "wb_psu_driver.h" +#include "wb_sff_driver.h" +#include "wb_watchdog_driver.h" +#include "wb_system_driver.h" +#include "dfd_cfg.h" + +int g_switch_dbg_level = 0; + +/* change the following parameter by your switch. */ +#define MAIN_BOARD_TEMP_SENSOR_NUMBER (10) +#define MAIN_BOARD_VOL_SENSOR_NUMBER (10) +#define MAIN_BOARD_CURR_SENSOR_NUMBER (0) +#define SYSEEPROM_SIZE (256) +#define FAN_NUMBER (6) +#define FAN_MOTOR_NUMBER (2) +#define PSU_NUMBER (2) +#define PSU_TEMP_SENSOR_NUMBER (3) +#define ETH_NUMBER (32) +#define ETH_EEPROM_SIZE (0x8180) +#define MAIN_BOARD_FPGA_NUMBER (1) +#define MAIN_BOARD_CPLD_NUMBER (5) +#define SLOT_NUMBER (0) +#define SLOT_TEMP_NUMBER (0) +#define SLOT_VOL_NUMBER (0) +#define SLOT_CURR_NUMBER (0) +#define SLOT_FPGA_NUMBER (0) +#define SLOT_CPLD_NUMBER (0) + +/***************************************main board temp*****************************************/ +/* + * dfd_get_main_board_temp_number - Used to get main board temperature sensors number, + * + * This function returns main board temperature sensors by your switch, + * If there is no main board temperature sensors, returns 0, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_main_board_temp_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_TEMP); + return ret; +} + +/* + * dfd_get_main_board_temp_alias - Used to identify the location of the temperature sensor, + * such as air_inlet, air_outlet and so on. + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_alias(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_type - Used to get the model of temperature sensor, + * such as lm75, tmp411 and so on + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_type(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_max - Used to get the maximum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_max(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_min - Used to get the minimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_min(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_high - Used to get the high threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_high(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_HIGH, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_low - Used to get the low threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_low(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_LOW, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_value - Used to get the input value of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_value(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_monitor_flag - Used to get monitor flag of temperature sensor + * filled the value to buf, the value is integer + * @index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_monitor_flag(unsigned int index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_TEMP, index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/***********************************end of main board temp*************************************/ + +/*************************************main board voltage***************************************/ +static int dfd_get_main_board_vol_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_IN); + return ret; +} + +/* + * dfd_get_main_board_vol_alias - Used to identify the location of the voltage sensor, + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_alias(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_type - Used to get the model of voltage sensor, + * such as udc90160, tps53622 and so on + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_type(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_max - Used to get the maximum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_max(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_min - Used to get the minimum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_min(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_range - Used to get the output error value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_range(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, + WB_SENSOR_RANGE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_nominal_value - Used to get the nominal value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_nominal_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, + WB_SENSOR_NOMINAL_VAL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_value - Used to get the input value of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_monitor_flag - Used to get monitor flag of voltage sensor + * filled the value to buf, the value is integer + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_monitor_flag(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_IN, temp_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*********************************end of main board voltage************************************/ +/*************************************main board current***************************************/ +static int dfd_get_main_board_curr_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_CURR); + return ret; +} + +/* + * dfd_get_main_board_curr_alias - Used to identify the location of the current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_alias(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_type - Used to get the model of current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_type(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_max - Used to get the maximum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_max(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_min - Used to get the minimum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_min(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_value - Used to get the input value of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_value(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_monitor_flag - Used to get monitor flag of current sensor + * filled the value to buf, the value is integer + * @index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_monitor_flag(unsigned int index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_CURR, index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*********************************end of main board current************************************/ + +/*****************************************syseeprom*******************************************/ +/* + * dfd_get_syseeprom_size - Used to get syseeprom size + * + * This function returns the size of syseeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_syseeprom_size(void) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_MAINBOARD, 0); + return ret; +} + +/* + * dfd_read_syseeprom_data - Used to read syseeprom data, + * @buf: Data read buffer + * @offset: offset address to read syseeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_MAINBOARD, 0, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_syseeprom_data - Used to write syseeprom data + * @buf: Data write buffer + * @offset: offset address to write syseeprom data + * @count: length of buf + * + * This function returns the written length of syseeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_MAINBOARD, 0, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/*************************************end of syseeprom****************************************/ + +/********************************************fan**********************************************/ +static int dfd_get_fan_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_fan_status - Used to get fan status, + * filled the value to buf, fan status define see enum status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_status_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_present - Used to get fan present status, + * filled the value to buf, fan status define see enum status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_present(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_present_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_get_fan_motor_number(unsigned int fan_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + return ret; +} + +/* + * dfd_get_fan_model_name - Used to get fan model name, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_model_name(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_vendor - Used to get fan vendor, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_vendor(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_serial_number - Used to get fan serial number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_serial_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_part_number - Used to get fan part number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_part_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_hardware_version - Used to get fan hardware version, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_hardware_version(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_led_status - Used to get fan led status + * filled the value to buf, led status value define see enum fan_status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_led_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_FAN_LED_MODULE, fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_fan_led_status - Used to set fan led status + * @fan_index: start with 1 + * @status: led status, led status value define see enum led_status_e + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_fan_led_status(unsigned int fan_index, int status) +{ + int ret; + + ret = dfd_set_led_status(WB_FAN_LED_MODULE, fan_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_fan_direction - Used to get fan air flow direction, + * filled the value to buf, air flow direction define see enum air_flow_direction_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_direction(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_direction_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_status - Used to get fan motor status + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_status(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_motor_status_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed - Used to get fan motor speed + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_speed_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_tolerance - Used to get fan motor speed tolerance + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_tolerance_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_target - Used to get fan motor speed target + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_target(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_target_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_max - Used to get the maximum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_max_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_min - Used to get the minimum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_min_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_ratio - Used to get the ratio of fan + * filled the value to buf + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_ratio(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_pwm_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_fan_ratio - Used to set the ratio of fan + * @fan_index: start with 1 + * @ratio: motor speed ratio, from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_fan_ratio(unsigned int fan_index, int ratio) +{ + int ret; + + /* add vendor codes here */ + ret = dfd_set_fan_pwm(fan_index, ratio); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/****************************************end of fan*******************************************/ +/********************************************psu**********************************************/ +static int dfd_get_psu_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_psu_present_status - Used to get psu present status + * filled the value to buf, psu present status define see enum psu_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_present(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_present_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_get_psu_temp_number(unsigned int psu_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_TEMP); + return ret; +} + +/* Similar to dfd_get_psu_model_name */ +static ssize_t dfd_get_psu_model_name(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_PART_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_vendor(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_date(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_ASSET_TAG, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status_word; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + status = status | 0x01; + return (ssize_t)snprintf(buf, count, "0x%x\n", status); + } + + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %ld, psu_index: %u\n", ret, psu_index); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + SWITCH_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + status = 0; + mem_clear(buf, count); + if (status_word < 0) { + return status_word; + } else { + status = (status_word & PSU_OFF_FAULT) ? (status | 0x02) : status; + status = (status_word & PSU_FAN_FAULT) ? (status | 0x04) : status; + status = (status_word & PSU_VOUT_FAULT) ? (status | 0x08) : status; + status = (status_word & PSU_IOUT_FAULT) ? (status | 0x10) : status; + status = (status_word & PSU_INPUT_FAULT) ? (status | 0x20) : status; + status = (status_word & PSU_TEMP_FAULT) ? (status | 0x40) : status; + } + return (ssize_t)snprintf(buf, count, "0x%x\n", status); +} + +static ssize_t dfd_get_psu_alarm(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_alarm_status(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_serial_number */ +static ssize_t dfd_get_psu_serial_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_part_number */ +static ssize_t dfd_get_psu_part_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_hardware_version */ +static ssize_t dfd_get_psu_hardware_version(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_type - Used to get the input type of psu + * filled the value to buf, input type value define see enum psu_input_type_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_type(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_input_type(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_curr - Used to get the input current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_CURR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_vol - Used to get the input voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_VOL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_power - Used to get the input power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_POWER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_curr - Used to get the output current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_CURR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_vol - Used to get the output voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_VOL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_power - Used to get the output power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_POWER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_max_power - Used to get the output max power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_max_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_status - Used to get psu input status + * filled the value to buf, psu input status define see enum psu_io_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_in_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_status - Used to get psu output status + * filled the value to buf, psu output status define see enum psu_io_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_out_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_hw_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_hw_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_attr_threshold(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_threshold_str(psu_index, type, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_status_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_status_pmbus_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_fan_speed - Used to get psu fan speed + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_speed(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_FAN_SPEED, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_fan_ratio - Used to get the ratio of psu fan + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_ratio(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_fan_ratio_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_psu_fan_ratio - Used to set the ratio of psu fan + * @psu_index: start with 1 + * @ratio: from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_psu_fan_ratio(unsigned int psu_index, int ratio) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* + * dfd_get_psu_fan_direction - Used to get psu air flow direction, + * filled the value to buf, air flow direction define enum air_flow_direction_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_direction(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_FAN_DIRECTION, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_led_status */ +static ssize_t dfd_get_psu_led_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status_word; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + status = LED_STATUS_DARK; /* led off */ + return (ssize_t)snprintf(buf, count, "%d\n", status); + } + status = LED_STATUS_GREEN; + + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %ld, psu_index: %u\n", ret, psu_index); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + SWITCH_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + mem_clear(buf, count); + if (status_word > 0) { + status = LED_STATUS_YELLOW; /* led amber */ + return (ssize_t)snprintf(buf, count, "%d\n", status); + } + return (ssize_t)snprintf(buf, count, "%d\n", status); /* led green */ +} + +static ssize_t dfd_get_psu_fan_speed_cal(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_SPEED_CAL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_alias */ +static ssize_t dfd_get_psu_temp_alias(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_type */ +static ssize_t dfd_get_psu_temp_type(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; + +} + +/* Similar to dfd_get_main_board_temp_max */ +static ssize_t dfd_get_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_temp_max */ +static int dfd_set_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* Similar to dfd_get_main_board_temp_min */ +static ssize_t dfd_get_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_temp_min */ +static int dfd_set_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* Similar to dfd_get_main_board_temp_value */ +static ssize_t dfd_get_psu_temp_value(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_eeprom_size - Used to get psu eeprom size + * + * This function returns the size of psu eeprom, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_psu_eeprom_size(unsigned int psu_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_PSU, psu_index); + return ret; +} + +/* + * dfd_read_psu_eeprom_data - Used to read psu eeprom data, + * @buf: Data read buffer + * @offset: offset address to read psu eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_psu_eeprom_data(unsigned int psu_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_PSU, psu_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_psu_blackbox_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_blackbox(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_pmbus_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_pmbus(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_clear_psu_blackbox_info - Used to clear psu blackbox information + * @psu_index: start with 1 + * @value: 1 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_clear_psu_blackbox_info(unsigned int psu_index, uint8_t value) +{ + int ret; + + ret = dfd_clear_psu_blackbox(psu_index, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; + +} +/****************************************end of psu*******************************************/ +/****************************************transceiver******************************************/ +static int dfd_get_eth_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_transceiver_power_on_status - Used to get the whole machine port power on status, + * filled the value to buf, 0: power off, 1: power on + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_transceiver_power_on_status(char *buf, size_t count) +{ + ssize_t ret; + unsigned int eth_index, eth_num; + int len, left_len; + eth_num = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + if (eth_num <= 0) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + + mem_clear(buf, count); + len = 0; + left_len = count - 1; + + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SWITCH_DEBUG(DBG_VERBOSE, "eth index: %u\n", eth_index); + if (left_len > 0) { + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_POWER_ON, buf, left_len); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get eth%u power status failed, ret: %ld\n", eth_index, ret); + break; + } + } else { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_power_on_status are not enough buffers.\n"); + ret = -DFD_RV_NO_MEMORY; + break; + } + dfd_ko_cfg_del_lf_cr(buf); /* del '\n' */ + len = strlen(buf); + left_len = count - len - 2; /* Reserve end to add '\n' and '\0' */ + } + + if (ret < 0) { + mem_clear(buf, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + len = strlen(buf); + if (len >= count) { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_power_on_status buffers too long, need: %ld, act: %d.\n", count, len); + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + buf[len] = '\n'; + ret = strlen(buf); + SWITCH_DEBUG(DBG_VERBOSE, "get_transceiver_power_on_status ok. sff num:%d, len:%ld\n", eth_num, ret); + + return ret; +} + +/* + * dfd_set_transceiver_power_on_status - Used to set the whole machine port power on status, + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_transceiver_power_on_status(int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(0, WB_SFF_POWER_ON, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_transceiver_present_status - Used to get the whole machine port present status, + * filled the value to buf, 0: absent, 1: present + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_transceiver_present_status(char *buf, size_t count) +{ + ssize_t ret; + unsigned int eth_index, eth_num; + int len, left_len; + + eth_num = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + if (eth_num <= 0) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + + mem_clear(buf, count); + len = 0; + left_len = count - 1; + + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SWITCH_DEBUG(DBG_VERBOSE, "eth index: %u\n", eth_index); + if (left_len > 0) { + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_MODULE_PRESENT, buf + len, left_len); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get eth%u present status failed, ret: %ld\n", eth_index, ret); + break; + } + } else { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_present_status are not enough buffers.\n"); + ret = -DFD_RV_NO_MEMORY; + break; + } + dfd_ko_cfg_del_lf_cr(buf); /* del '\n' */ + len = strlen(buf); + left_len = count - len - 2; /* Reserve end to add '\n' and '\0' */ + } + + if (ret < 0) { + mem_clear(buf, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + len = strlen(buf); + if (len >= count) { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_present_status buffers too long, need: %ld, act: %d.\n", count, len); + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + buf[len] = '\n'; + ret = strlen(buf); + SWITCH_DEBUG(DBG_VERBOSE, "get_transceiver_present_status ok. sff num:%d, len:%ld\n", eth_num, ret); + + return ret; +} + + +/* + * dfd_get_eth_power_on_status - Used to get single port power on status, + * filled the value to buf, 0: power off, 1: power on + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_power_on_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_POWER_ON, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_power_on_status - Used to set single port power on status, + * @eth_index: start with 1 + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_power_on_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_POWER_ON, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_eth_tx_fault_status - Used to get port tx_fault status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_tx_fault_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_TX_FAULT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_tx_disable_status - Used to get port tx_disable status, + * filled the value to buf, 0: tx_enable, 1: tx_disable + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_tx_disable_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_TX_DIS, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_tx_disable_status - Used to set port tx_disable status, + * @eth_index: start with 1 + * @status: tx_disable status, 0: tx_enable, 1: tx_disable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_tx_disable_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_TX_DIS, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_eth_present_status - Used to get port present status, + * filled the value to buf, 1: present, 0: absent + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_present_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_MODULE_PRESENT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_rx_los_status - Used to get port rx_los status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_rx_los_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_RX_LOS, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_reset_status - Used to get port reset status, + * filled the value to buf, 0: unreset, 1: reset + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_reset_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_RESET, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_reset_status - Used to set port reset status, + * @eth_index: start with 1 + * @status: reset status, 0: unreset, 1: reset + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_reset_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_RESET, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/** + * dfd_get_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +static ssize_t dfd_get_eth_optoe_type(unsigned int eth_index, int *optoe_type, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_single_eth_optoe_type(eth_index, optoe_type); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return (ssize_t)snprintf(buf, count, "%d\n", *optoe_type); +} + +/** + * dfd_set_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +static int dfd_set_eth_optoe_type(unsigned int eth_index, int optoe_type) +{ + int ret; + + ret = dfd_set_single_eth_optoe_type(eth_index, optoe_type); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + + +/* + * dfd_get_eth_low_power_mode_status - Used to get port low power mode status, + * filled the value to buf, 0: high power mode, 1: low power mode + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_low_power_mode_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_LPMODE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_interrupt_status - Used to get port interruption status, + * filled the value to buf, 0: no interruption, 1: interruption + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_interrupt_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_INTERRUPT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_eeprom_size - Used to get port eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_eth_eeprom_size(unsigned int eth_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_SFF, eth_index); + return ret; +} + +/* + * dfd_read_eth_eeprom_data - Used to read port eeprom data, + * @buf: Data read buffer + * @offset: offset address to read port eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_SFF, eth_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_eth_eeprom_data - Used to write port eeprom data + * @buf: Data write buffer + * @offset: offset address to write port eeprom data + * @count: length of buf + * + * This function returns the written length of port eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_SFF, eth_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/************************************end of transceiver***************************************/ +/*****************************************sysled**********************************************/ +/* + * dfd_get_sys_led_status - Used to get sys led status + * filled the value to buf, led status value define see enum fan_status_e + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_sys_led_status(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_SYS_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_sys_led_status - Used to set sys led status + * @status: led status, led status value define see enum led_status_e + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_sys_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_SYS_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_bmc_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_BMC_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_bmc_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_BMC_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_sys_fan_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_FAN_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_sys_fan_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_FAN_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_sys_psu_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_PSU_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_sys_psu_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_PSU_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_id_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_ID_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_id_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_ID_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/**************************************end of sysled******************************************/ +/******************************************FPGA***********************************************/ +static int dfd_get_main_board_fpga_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_FPGA); + return ret; +} + +/* + * dfd_get_main_board_fpga_alias - Used to identify the location of fpga, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_alias(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_name(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_type - Used to get fpga model name + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_type(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_type(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_firmware_version - Used to get fpga firmware version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_firmware_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_fw_version(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_board_version - Used to get fpga board version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_board_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_hw_version(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_test_reg - Used to test fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_test_reg(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_testreg_str(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_main_board_fpga_test_reg - Used to test fpga register write + * @fpga_index: start with 1 + * @value: value write to fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_main_board_fpga_test_reg(unsigned int fpga_index, unsigned int value) +{ + int ret; + + ret = dfd_set_fpga_testreg(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of FPGA*******************************************/ +/******************************************CPLD***********************************************/ +static int dfd_get_main_board_cpld_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_CPLD); + return ret; +} + +/* + * dfd_get_main_board_cpld_alias - Used to identify the location of cpld, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_alias(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_name(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_type - Used to get cpld model name + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_type(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_type(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_firmware_version - Used to get cpld firmware version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_firmware_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_fw_version(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_board_version - Used to get cpld board version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_board_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_hw_version(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_test_reg - Used to test cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_test_reg(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_testreg_str(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_main_board_cpld_test_reg - Used to test cpld register write + * @cpld_index: start with 1 + * @value: value write to cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_main_board_cpld_test_reg(unsigned int cpld_index, unsigned int value) +{ + int ret; + + ret = dfd_set_cpld_testreg(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of CPLD*******************************************/ +/****************************************watchdog*********************************************/ +/* + * dfd_get_watchdog_identify - Used to get watchdog identify, such as iTCO_wdt + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_identify(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_watchdog_timeleft - Used to get watchdog timeleft, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_timeleft(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_TIMELEFT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_watchdog_timeout - Used to get watchdog timeout, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_timeout(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_TIMEOUT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_watchdog_timeout - Used to set watchdog timeout, + * @value: timeout value + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_timeout(int value) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* + * dfd_get_watchdog_enable_status - Used to get watchdog enable status, + * filled the value to buf, 0: disable, 1: enable + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_enable_status(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_watchdog_get_status(buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_watchdog_enable_status - Used to set watchdog enable status, + * @value: enable status value, 0: disable, 1: enable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_enable_status(int value) +{ + /* add vendor codes here */ + int ret; + ret = dfd_watchdog_set_status(value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_set_watchdog_reset - Used to feed watchdog, + * @value: any value to feed watchdog + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_reset(int value) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} +/*************************************end of watchdog*****************************************/ +/******************************************slot***********************************************/ +static int dfd_get_slot_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_NONE); + return ret; +} + +static int dfd_get_slot_temp_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_TEMP); + return ret; +} + +static int dfd_get_slot_vol_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_IN); + return ret; +} + +static int dfd_get_slot_curr_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_CURR); + return ret; +} + +static int dfd_get_slot_fpga_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_FPGA); + return ret; +} + +static int dfd_get_slot_cpld_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_CPLD); + return ret; +} + +/* Similar to dfd_get_fan_model_name */ +static ssize_t dfd_get_slot_model_name(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_slot_vendor(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_serial_number */ +static ssize_t dfd_get_slot_serial_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_part_number */ +static ssize_t dfd_get_slot_part_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_hardware_version */ +static ssize_t dfd_get_slot_hardware_version(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_status */ +static ssize_t dfd_get_slot_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_status_str(slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_led_status */ +static ssize_t dfd_get_slot_led_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_SLOT_LED_MODULE, slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_fan_led_status */ +static int dfd_set_slot_led_status(unsigned int slot_index, int status) +{ + int ret; + + ret = dfd_set_led_status(WB_SLOT_LED_MODULE, slot_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_slot_power_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_power_status_str(slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_set_slot_power_status(unsigned int slot_index, int status) +{ + int ret; + + ret = dfd_set_slot_power_status_str(slot_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_alias */ +static ssize_t dfd_get_slot_temp_alias(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_type */ +static ssize_t dfd_get_slot_temp_type(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_max */ +static ssize_t dfd_get_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_min */ +static ssize_t dfd_get_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_value */ +static ssize_t dfd_get_slot_temp_value(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_alias */ +static ssize_t dfd_get_slot_vol_alias(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_type */ +static ssize_t dfd_get_slot_vol_type(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_max */ +static ssize_t dfd_get_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_min */ +static ssize_t dfd_get_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_range */ +static ssize_t dfd_get_slot_vol_range(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_RANGE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_nominal_value */ +static ssize_t dfd_get_slot_vol_nominal_value(unsigned int slot_index, + unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_NOMINAL_VAL, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_value */ +static ssize_t dfd_get_slot_vol_value(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_alias */ +static ssize_t dfd_get_slot_curr_alias(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_type */ +static ssize_t dfd_get_slot_curr_type(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_max */ +static ssize_t dfd_get_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_min */ +static ssize_t dfd_get_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_value */ +static ssize_t dfd_get_slot_curr_value(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_alias */ +static ssize_t dfd_get_slot_fpga_alias(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_name(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_type */ +static ssize_t dfd_get_slot_fpga_type(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_type(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_firmware_version */ +static ssize_t dfd_get_slot_fpga_firmware_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_fw_version(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_board_version */ +static ssize_t dfd_get_slot_fpga_board_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_hw_version(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_test_reg */ +static ssize_t dfd_get_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_testreg_str(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_fpga_test_reg */ +static int dfd_set_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + unsigned int value) +{ + int ret; + + ret = dfd_set_fpga_testreg(slot_index, fpga_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_alias */ +static ssize_t dfd_get_slot_cpld_alias(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_name(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_type */ +static ssize_t dfd_get_slot_cpld_type(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_type(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_firmware_version */ +static ssize_t dfd_get_slot_cpld_firmware_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_fw_version(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_board_version */ +static ssize_t dfd_get_slot_cpld_board_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_hw_version(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_test_reg */ +static ssize_t dfd_get_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_testreg_str(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_cpld_test_reg */ +static int dfd_set_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + unsigned int value) +{ + int ret; + + ret = dfd_set_cpld_testreg(slot_index, cpld_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of slot*******************************************/ +/*****************************************system*********************************************/ +static ssize_t dfd_get_system_value(unsigned int type, int *value, char *buf, size_t count) +{ + int ret; + + ret = dfd_system_get_system_value(type, value); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return (ssize_t)snprintf(buf, count, "%d\n", *value); +} + +static ssize_t dfd_set_system_value(unsigned int type, int value) +{ + int ret; + + ret = dfd_system_set_system_value(type, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_system_port_power_status(unsigned int type, char *buf, size_t count) +{ + int ret; + + ret = dfd_system_get_port_power_status(type, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*************************************end of system*****************************************/ +/*****************************************eeprom*********************************************/ +static int dfd_get_eeprom_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_EEPROM); + return ret; +} + +/* + * dfd_get_board_eeprom_size - Used to get board eeprom size, including slots eeprom + * + * This function returns the size of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static int dfd_get_board_eeprom_size(unsigned int e2_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_MAINBOARD, e2_index); + return ret; +} + +/* + * dfd_get_board_eeprom_alias - Used to get board eeprom alias, including slots eeprom + * + * This function returns the alias of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_alias(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_alias(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_board_eeprom_tag - Used to get board eeprom tag, including slots eeprom + * + * This function returns the alias of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_tag(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_tag(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_board_eeprom_type - Used to get board eeprom type, including slots eeprom + * + * This function returns the type of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_type(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_type(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_read_board_eeprom_data - Used to read board eeprom data, including slots eeprom + * @buf: Data read buffer + * @offset: offset address to read board eeprom data, including slots eeprom + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_board_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_MAINBOARD, e2_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_board_eeprom_data - Used to write board eeprom data, including slots eeprom + * @buf: Data write buffer + * @offset: offset address to write board eeprom data, including slots eeprom + * @count: length of buf + * + * This function returns the written length of eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_board_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_MAINBOARD, e2_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/*************************************end of eeprom*****************************************/ + + +static struct switch_drivers_s switch_drivers = { + /* + * set odm switch drivers, + * if not support the function, set corresponding hook to NULL. + */ + /* temperature sensors */ + .get_main_board_temp_number = dfd_get_main_board_temp_number, + .get_main_board_temp_alias = dfd_get_main_board_temp_alias, + .get_main_board_temp_type = dfd_get_main_board_temp_type, + .get_main_board_temp_max = dfd_get_main_board_temp_max, + .get_main_board_temp_min = dfd_get_main_board_temp_min, + .get_main_board_temp_value = dfd_get_main_board_temp_value, + .get_main_board_temp_high = dfd_get_main_board_temp_high, + .get_main_board_temp_low = dfd_get_main_board_temp_low, + .get_main_board_temp_monitor_flag = dfd_get_main_board_temp_monitor_flag, + /* voltage sensors */ + .get_main_board_vol_number = dfd_get_main_board_vol_number, + .get_main_board_vol_alias = dfd_get_main_board_vol_alias, + .get_main_board_vol_type = dfd_get_main_board_vol_type, + .get_main_board_vol_max = dfd_get_main_board_vol_max, + .get_main_board_vol_min = dfd_get_main_board_vol_min, + .get_main_board_vol_range = dfd_get_main_board_vol_range, + .get_main_board_vol_nominal_value = dfd_get_main_board_vol_nominal_value, + .get_main_board_vol_value = dfd_get_main_board_vol_value, + .get_main_board_vol_monitor_flag = dfd_get_main_board_vol_monitor_flag, + /* current sensors */ + .get_main_board_curr_number = dfd_get_main_board_curr_number, + .get_main_board_curr_alias = dfd_get_main_board_curr_alias, + .get_main_board_curr_type = dfd_get_main_board_curr_type, + .get_main_board_curr_max = dfd_get_main_board_curr_max, + .get_main_board_curr_min = dfd_get_main_board_curr_min, + .get_main_board_curr_value = dfd_get_main_board_curr_value, + .get_main_board_curr_monitor_flag = dfd_get_main_board_curr_monitor_flag, + /* syseeprom */ + .get_syseeprom_size = dfd_get_syseeprom_size, + .read_syseeprom_data = dfd_read_syseeprom_data, + .write_syseeprom_data = dfd_write_syseeprom_data, + /* fan */ + .get_fan_number = dfd_get_fan_number, + .get_fan_motor_number = dfd_get_fan_motor_number, + .get_fan_model_name = dfd_get_fan_model_name, + .get_fan_vendor = dfd_get_fan_vendor, + .get_fan_serial_number = dfd_get_fan_serial_number, + .get_fan_part_number = dfd_get_fan_part_number, + .get_fan_hardware_version = dfd_get_fan_hardware_version, + .get_fan_status = dfd_get_fan_status, + .get_fan_present = dfd_get_fan_present, + .get_fan_led_status = dfd_get_fan_led_status, + .set_fan_led_status = dfd_set_fan_led_status, + .get_fan_direction = dfd_get_fan_direction, + .get_fan_motor_status = dfd_get_fan_motor_status, + .get_fan_motor_speed = dfd_get_fan_motor_speed, + .get_fan_motor_speed_tolerance = dfd_get_fan_motor_speed_tolerance, + .get_fan_motor_speed_target = dfd_get_fan_motor_speed_target, + .get_fan_motor_speed_max = dfd_get_fan_motor_speed_max, + .get_fan_motor_speed_min = dfd_get_fan_motor_speed_min, + .get_fan_ratio = dfd_get_fan_ratio, + .set_fan_ratio = dfd_set_fan_ratio, + /* psu */ + .get_psu_number = dfd_get_psu_number, + .get_psu_temp_number = dfd_get_psu_temp_number, + .get_psu_model_name = dfd_get_psu_model_name, + .get_psu_vendor = dfd_get_psu_vendor, + .get_psu_date = dfd_get_psu_date, + .get_psu_status = dfd_get_psu_status, + .get_psu_hw_status = dfd_get_psu_hw_status, + .get_psu_alarm = dfd_get_psu_alarm, + .get_psu_serial_number = dfd_get_psu_serial_number, + .get_psu_part_number = dfd_get_psu_part_number, + .get_psu_hardware_version = dfd_get_psu_hardware_version, + .get_psu_type = dfd_get_psu_type, + .get_psu_in_curr = dfd_get_psu_in_curr, + .get_psu_in_vol = dfd_get_psu_in_vol, + .get_psu_in_power = dfd_get_psu_in_power, + .get_psu_out_curr = dfd_get_psu_out_curr, + .get_psu_out_vol = dfd_get_psu_out_vol, + .get_psu_out_power = dfd_get_psu_out_power, + .get_psu_out_max_power = dfd_get_psu_out_max_power, + .get_psu_present_status = dfd_get_psu_present, + .get_psu_in_status = dfd_get_psu_in_status, + .get_psu_out_status = dfd_get_psu_out_status, + .get_psu_status_pmbus = dfd_get_psu_status_pmbus, + .get_psu_fan_speed = dfd_get_psu_fan_speed, + .get_psu_fan_ratio = dfd_get_psu_fan_ratio, + .set_psu_fan_ratio = dfd_set_psu_fan_ratio, + .get_psu_fan_direction = dfd_get_psu_fan_direction, + .get_psu_led_status = dfd_get_psu_led_status, + .get_psu_temp_alias = dfd_get_psu_temp_alias, + .get_psu_temp_type = dfd_get_psu_temp_type, + .get_psu_temp_max = dfd_get_psu_temp_max, + .set_psu_temp_max = dfd_set_psu_temp_max, + .get_psu_temp_min = dfd_get_psu_temp_min, + .set_psu_temp_min = dfd_set_psu_temp_min, + .get_psu_temp_value = dfd_get_psu_temp_value, + .get_psu_fan_speed_cal = dfd_get_psu_fan_speed_cal, + .get_psu_attr_threshold = dfd_get_psu_attr_threshold, + .get_psu_eeprom_size = dfd_get_psu_eeprom_size, + .read_psu_eeprom_data = dfd_read_psu_eeprom_data, + .get_psu_blackbox_info = dfd_get_psu_blackbox_info, + .get_psu_pmbus_info = dfd_get_psu_pmbus_info, + .clear_psu_blackbox = dfd_clear_psu_blackbox_info, + /* transceiver */ + .get_eth_number = dfd_get_eth_number, + .get_transceiver_power_on_status = dfd_get_transceiver_power_on_status, + .set_transceiver_power_on_status = dfd_set_transceiver_power_on_status, + .get_eth_power_on_status = dfd_get_eth_power_on_status, + .set_eth_power_on_status = dfd_set_eth_power_on_status, + .get_eth_tx_fault_status = dfd_get_eth_tx_fault_status, + .get_eth_tx_disable_status = dfd_get_eth_tx_disable_status, + .set_eth_tx_disable_status = dfd_set_eth_tx_disable_status, + .get_transceiver_present_status = dfd_get_transceiver_present_status, + .get_eth_present_status = dfd_get_eth_present_status, + .get_eth_rx_los_status = dfd_get_eth_rx_los_status, + .get_eth_reset_status = dfd_get_eth_reset_status, + .set_eth_reset_status = dfd_set_eth_reset_status, + .get_eth_low_power_mode_status = dfd_get_eth_low_power_mode_status, + .get_eth_interrupt_status = dfd_get_eth_interrupt_status, + .get_eth_eeprom_size = dfd_get_eth_eeprom_size, + .read_eth_eeprom_data = dfd_read_eth_eeprom_data, + .write_eth_eeprom_data = dfd_write_eth_eeprom_data, + .get_eth_optoe_type = dfd_get_eth_optoe_type, + .set_eth_optoe_type = dfd_set_eth_optoe_type, + /* sysled */ + .get_sys_led_status = dfd_get_sys_led_status, + .set_sys_led_status = dfd_set_sys_led_status, + .get_bmc_led_status = dfd_get_bmc_led_status, + .set_bmc_led_status = dfd_set_bmc_led_status, + .get_sys_fan_led_status = dfd_get_sys_fan_led_status, + .set_sys_fan_led_status = dfd_set_sys_fan_led_status, + .get_sys_psu_led_status = dfd_get_sys_psu_led_status, + .set_sys_psu_led_status = dfd_set_sys_psu_led_status, + .get_id_led_status = dfd_get_id_led_status, + .set_id_led_status = dfd_set_id_led_status, + /* FPGA */ + .get_main_board_fpga_number = dfd_get_main_board_fpga_number, + .get_main_board_fpga_alias = dfd_get_main_board_fpga_alias, + .get_main_board_fpga_type = dfd_get_main_board_fpga_type, + .get_main_board_fpga_firmware_version = dfd_get_main_board_fpga_firmware_version, + .get_main_board_fpga_board_version = dfd_get_main_board_fpga_board_version, + .get_main_board_fpga_test_reg = dfd_get_main_board_fpga_test_reg, + .set_main_board_fpga_test_reg = dfd_set_main_board_fpga_test_reg, + /* CPLD */ + .get_main_board_cpld_number = dfd_get_main_board_cpld_number, + .get_main_board_cpld_alias = dfd_get_main_board_cpld_alias, + .get_main_board_cpld_type = dfd_get_main_board_cpld_type, + .get_main_board_cpld_firmware_version = dfd_get_main_board_cpld_firmware_version, + .get_main_board_cpld_board_version = dfd_get_main_board_cpld_board_version, + .get_main_board_cpld_test_reg = dfd_get_main_board_cpld_test_reg, + .set_main_board_cpld_test_reg = dfd_set_main_board_cpld_test_reg, + /* watchdog */ + .get_watchdog_identify = dfd_get_watchdog_identify, + .get_watchdog_timeleft = dfd_get_watchdog_timeleft, + .get_watchdog_timeout = dfd_get_watchdog_timeout, + .set_watchdog_timeout = dfd_set_watchdog_timeout, + .get_watchdog_enable_status = dfd_get_watchdog_enable_status, + .set_watchdog_enable_status = dfd_set_watchdog_enable_status, + .set_watchdog_reset = dfd_set_watchdog_reset, + /* slot */ + .get_slot_number = dfd_get_slot_number, + .get_slot_temp_number = dfd_get_slot_temp_number, + .get_slot_vol_number = dfd_get_slot_vol_number, + .get_slot_curr_number = dfd_get_slot_curr_number, + .get_slot_cpld_number = dfd_get_slot_cpld_number, + .get_slot_fpga_number = dfd_get_slot_fpga_number, + .get_slot_model_name = dfd_get_slot_model_name, + .get_slot_vendor = dfd_get_slot_vendor, + .get_slot_serial_number = dfd_get_slot_serial_number, + .get_slot_part_number = dfd_get_slot_part_number, + .get_slot_hardware_version = dfd_get_slot_hardware_version, + .get_slot_status = dfd_get_slot_status, + .get_slot_led_status = dfd_get_slot_led_status, + .set_slot_led_status = dfd_set_slot_led_status, + .get_slot_power_status = dfd_get_slot_power_status, + .set_slot_power_status = dfd_set_slot_power_status, + .get_slot_temp_alias = dfd_get_slot_temp_alias, + .get_slot_temp_type = dfd_get_slot_temp_type, + .get_slot_temp_max = dfd_get_slot_temp_max, + .get_slot_temp_min = dfd_get_slot_temp_min, + .get_slot_temp_value = dfd_get_slot_temp_value, + .get_slot_vol_alias = dfd_get_slot_vol_alias, + .get_slot_vol_type = dfd_get_slot_vol_type, + .get_slot_vol_max = dfd_get_slot_vol_max, + .get_slot_vol_min = dfd_get_slot_vol_min, + .get_slot_vol_range = dfd_get_slot_vol_range, + .get_slot_vol_nominal_value = dfd_get_slot_vol_nominal_value, + .get_slot_vol_value = dfd_get_slot_vol_value, + .get_slot_curr_alias = dfd_get_slot_curr_alias, + .get_slot_curr_type = dfd_get_slot_curr_type, + .get_slot_curr_max = dfd_get_slot_curr_max, + .get_slot_curr_min = dfd_get_slot_curr_min, + .get_slot_curr_value = dfd_get_slot_curr_value, + .get_slot_fpga_alias = dfd_get_slot_fpga_alias, + .get_slot_fpga_type = dfd_get_slot_fpga_type, + .get_slot_fpga_firmware_version = dfd_get_slot_fpga_firmware_version, + .get_slot_fpga_board_version = dfd_get_slot_fpga_board_version, + .get_slot_fpga_test_reg = dfd_get_slot_fpga_test_reg, + .set_slot_fpga_test_reg = dfd_set_slot_fpga_test_reg, + .get_slot_cpld_alias = dfd_get_slot_cpld_alias, + .get_slot_cpld_type = dfd_get_slot_cpld_type, + .get_slot_cpld_firmware_version = dfd_get_slot_cpld_firmware_version, + .get_slot_cpld_board_version = dfd_get_slot_cpld_board_version, + .get_slot_cpld_test_reg = dfd_get_slot_cpld_test_reg, + .set_slot_cpld_test_reg = dfd_set_slot_cpld_test_reg, + .get_system_value = dfd_get_system_value, + .get_system_port_power_status = dfd_get_system_port_power_status, + .set_system_value = dfd_set_system_value, + /* eeprom */ + .get_eeprom_number = dfd_get_eeprom_number, + .get_eeprom_size = dfd_get_board_eeprom_size, + .get_eeprom_alias = dfd_get_board_eeprom_alias, + .get_eeprom_tag = dfd_get_board_eeprom_tag, + .get_eeprom_type = dfd_get_board_eeprom_type, + .read_eeprom_data = dfd_read_board_eeprom_data, + .write_eeprom_data = dfd_write_board_eeprom_data, +}; + +struct switch_drivers_s * s3ip_switch_driver_get(void) +{ + return &switch_drivers; +} + +static int32_t __init switch_driver_init(void) +{ + int ret; + + SWITCH_DEBUG(DBG_VERBOSE, "Enter.\n"); + ret = wb_dev_cfg_init(); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "wb_dev_cfg_init failed ret %d.\n", ret); + return ret; + } + SWITCH_DEBUG(DBG_VERBOSE, "success.\n"); + return 0; +} + +static void __exit switch_driver_exit(void) +{ + SWITCH_DEBUG(DBG_VERBOSE, "switch_driver_exit.\n"); + wb_dev_cfg_exit(); + return; +} + +module_init(switch_driver_init); +module_exit(switch_driver_exit); +EXPORT_SYMBOL(s3ip_switch_driver_get); +module_param(g_switch_dbg_level, int, S_IRUGO | S_IWUSR); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c new file mode 100644 index 000000000000..d5bf876041ea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c @@ -0,0 +1,274 @@ +/* + * An wb_cpld_driver driver for cpld devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" + +int g_dfd_cpld_dbg_level = 0; +module_param(g_dfd_cpld_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_cpld_name - Obtain the CPLD name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_name(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + char *cpld_name; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL. main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_NAME, main_dev_id, cpld_index); + cpld_name = dfd_ko_cfg_get_item(key); + if (cpld_name == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u name config error, key_name:%s\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_name); + snprintf(buf, count, "%s\n", cpld_name); + return strlen(buf); +} + +/** + * dfd_get_cpld_type - Obtain the CPLD model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_type(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + char *cpld_type; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TYPE, main_dev_id, cpld_index); + cpld_type = dfd_ko_cfg_get_item(key); + if (cpld_type == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u type config error, key_name: %s\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TYPE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_type); + snprintf(buf, count, "%s\n", cpld_type); + return strlen(buf); +} + +/** + * dfd_get_cpld_fw_version - Obtain the CPLD firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_fw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + uint32_t value; + int rv; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_VERSION, main_dev_id, cpld_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_VERSION), rv); + return rv; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "main_dev_id: %u, cpld%u firmware version: %x\n", + main_dev_id, cpld_index, value); + snprintf(buf, count, "%08x\n", value); + return strlen(buf); +} + +/** + * dfd_get_cpld_hw_version - Obtain the hardware version of the CPLD + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_hw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + uint32_t value; + int rv; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_HW_VERSION, main_dev_id, cpld_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_HW_VERSION), rv); + return rv; + } + DBG_CPLD_DEBUG(DBG_VERBOSE, "main_dev_id: %u, cpld%u hardware version 0x%x\n", main_dev_id, cpld_index, value); + snprintf(buf, count, "%02x\n", value); + return strlen(buf); +} + +/** + * dfd_set_cpld_testreg - Set the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int value) +{ + uint64_t key; + int ret; + + if (value < 0 || value > 0xff) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, can't set cpld%u test reg value = 0x%02x\n", + main_dev_id, cpld_index, value); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, main_dev_id, cpld_index); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, set cpld%u test reg error, key_name: %s, ret:%d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_cpld_testreg - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int *value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, main_dev_id, cpld_index); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, get cpld%u test reg error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_cpld_testreg_str - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_testreg_str(uint8_t main_dev_id, unsigned int cpld_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_cpld_testreg(main_dev_id, cpld_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "0x%02x\n", value); +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c new file mode 100644 index 000000000000..7a3b760c2266 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c @@ -0,0 +1,230 @@ +/* + * An wb_eeprom_driver driver for eeprom devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_tlveeprom.h" + +int g_dfd_eeprom_dbg_level = 0; +module_param(g_dfd_eeprom_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_eeprom_size - Gets the data size of the eeprom + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * return: Succeeded: The data size of the eeprom is returned + * : Failed: A negative value is returned + */ +int dfd_get_eeprom_size(int e2_type, int index) +{ + uint64_t key; + int *p_eeprom_size; + + /* Obtain the eeprom size */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_SIZE, e2_type, index); + + p_eeprom_size = dfd_ko_cfg_get_item(key); + if (p_eeprom_size == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom size error. key_name:%s\n", + key_to_name(DFD_CFG_ITEM_EEPROM_SIZE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + return *p_eeprom_size; +} + +/** + * dfd_read_eeprom_data - Read eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data receives buf + * @offset: The offset address of the read + * @count: Read length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_read_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *eeprom_path; + + if (buf == NULL || offset < 0 || count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "params error, offset: 0x%llx, rd_count: %lu.\n", + offset, count); + return -DFD_RV_INVALID_VALUE; + } + + /* Obtain the eeprom read path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_PATH, e2_type, index); + eeprom_path = dfd_ko_cfg_get_item(key); + if (eeprom_path == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom path error, e2_type: %d, index: %d, key_name: %s\n", + e2_type, index, key_to_name(DFD_CFG_ITEM_EEPROM_PATH)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_EEPROM_DEBUG(DBG_VERBOSE, "e2_type: %d, index: %d, path: %s, offset: 0x%llx, \ + rd_count: %lu\n", e2_type, index, eeprom_path, offset, count); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(eeprom_path, offset, buf, count); + if (rd_len < 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "read eeprom data failed, loc: %s, offset: 0x%llx, \ + rd_count: %lu, ret: %ld,\n", eeprom_path, offset, count, rd_len); + } else { + DBG_EEPROM_DEBUG(DBG_VERBOSE, "read eeprom data success, loc: %s, offset: 0x%llx, \ + rd_count: %lu, rd_len: %ld,\n", eeprom_path, offset, count, rd_len); + } + + return rd_len; +} + +/** + * dfd_write_eeprom_data - Write eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data buf + * @offset: The offset address of the write + * @count: Write length + * return: Success: The length of the written data is returned + * : Failed: A negative value is returned + */ +ssize_t dfd_write_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count) +{ + uint64_t key; + ssize_t wr_len; + char *eeprom_path; + + if (buf == NULL || offset < 0 || count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "params error, offset: 0x%llx, count: %lu.\n", offset, count); + return -DFD_RV_INVALID_VALUE; + } + + /* Obtain the eeprom read path */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_PATH, e2_type, index); + eeprom_path = dfd_ko_cfg_get_item(key); + if (eeprom_path == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom path error, e2_type: %d, index: %d, key_name: %s\n", + e2_type, index, key_to_name(DFD_CFG_ITEM_EEPROM_PATH)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_EEPROM_DEBUG(DBG_VERBOSE, "e2_type: %d, index: %d, path: %s, offset: 0x%llx, \ + wr_count: %lu.\n", e2_type, index, eeprom_path, offset, count); + + wr_len = dfd_ko_write_file(eeprom_path, offset, buf, count); + if (wr_len < 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "write eeprom data failed, loc:%s, offset: 0x%llx, \ + wr_count: %lu, ret: %ld.\n", eeprom_path, offset, count, wr_len); + } else { + DBG_EEPROM_DEBUG(DBG_VERBOSE, "write eeprom data success, loc:%s, offset: 0x%llx, \ + wr_count: %lu, wr_len: %ld.\n", eeprom_path, offset, count, wr_len); + } + + return wr_len; +} + +ssize_t dfd_get_eeprom_alias(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *e2_alias; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_ALIAS, e2_type, e2_index); + e2_alias = dfd_ko_cfg_get_item(key); + if (e2_alias == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom alias config error, e2_type: %d, e2_index: %u, key_name: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_ALIAS)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", e2_alias); + snprintf(buf, count, "%s\n", e2_alias); + return strlen(buf); +} + +ssize_t dfd_get_eeprom_tag(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *e2_tag; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_TAG, e2_type, e2_index); + e2_tag = dfd_ko_cfg_get_item(key); + if (e2_tag == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom tag config error, e2_type: %d, e2_index: %u, key: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_TAG)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", e2_tag); + snprintf(buf, count, "%s\n", e2_tag); + return strlen(buf); +} + +ssize_t dfd_get_eeprom_type(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *eeprom_type; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_TYPE, e2_type, e2_index); + eeprom_type = dfd_ko_cfg_get_item(key); + if (eeprom_type == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom type config error, e2_type: %d, e2_index: %u, key_name: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_TYPE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", eeprom_type); + snprintf(buf, count, "%s\n", eeprom_type); + return strlen(buf); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c new file mode 100644 index 000000000000..77f88429edfb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c @@ -0,0 +1,1093 @@ +/* + * An wb_fan_driver driver for fan devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define DFD_FAN_EEPROM_MODE_TLV_STRING "tlv" +#define DFD_FAN_EEPROM_MODE_FRU_STRING "fru" +#define FAN_SIZE (256) + +typedef enum fan_present_status_e { + ABSENT = 0, + PRESENT = 1, +} fan_present_status_t; + +typedef enum fan_motor_status_e { + MOTOR_STALL = 0, + MOTOR_ROLL = 1, +} fan_motor_status_t; + +typedef enum fan_eeprom_mode_e { + FAN_EEPROM_MODE_TLV, /* TLV */ + FAN_EEPROM_MODE_FRU, /*FRU*/ +} fan_eeprom_mode_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; /* The version number defined in the E2PROM file, initially 0x01 */ + uint8_t flag; /* The new version E2PROM is identified as 0x7E */ + uint8_t hw_ver; /* It consists of two parts: the main version number and the revised version */ + uint8_t type; /* Hardware type definition information */ + int16_t tlv_len; /* Valid data length (16 bits) */ +} dfd_dev_head_info_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; /* Data type */ + uint8_t len; /* Data length */ + uint8_t data[0]; /* Data */ +} dfd_dev_tlv_info_t; + +/* Specifies the fixed value of the fan speed */ +typedef enum wb_fan_threshold_e { + FAN_SPEED_MIN = 1, /* Minimum value */ + FAN_SPEED_MAX = 2, /* Maximum value */ + FAN_SPEED_TOLERANCE = 3, /* tolerance */ + FAN_SPEED_TARGET_0 = 0x10, /* index of the rated speed when PWM=0x */ + FAN_SPEED_TARGET_10 = 0x11, + FAN_SPEED_TARGET_20 = 0x12, + FAN_SPEED_TARGET_30 = 0x13, + FAN_SPEED_TARGET_40 = 0x14, + FAN_SPEED_TARGET_50 = 0x15, + FAN_SPEED_TARGET_60 = 0x16, + FAN_SPEED_TARGET_70 = 0x17, + FAN_SPEED_TARGET_80 = 0x18, + FAN_SPEED_TARGET_90 = 0x19, + FAN_SPEED_TARGET_100 = 0x1a, /* index of the rated speed when PWM=100 */ + +} wb_fan_threshold_t; + +/* fan_threshold_[Threshold type(high 8bit)+Master device type(low 8bit)]_[subdevice ID(high 4bit)+Front and rear motor id(low 4bit)] */ +#define DFD_GET_FAN_THRESHOLD_KEY1(threshold_type, main_dev_id) \ + (((threshold_type & 0xff) << 8) | (main_dev_id & 0xff)) +#define DFD_GET_FAN_THRESHOLD_KEY2(sub_type_id, motor_id) \ + (((sub_type_id & 0x0f) << 4) | (motor_id & 0x0f)) + +int g_dfd_fan_dbg_level = 0; +module_param(g_dfd_fan_dbg_level, int, S_IRUGO | S_IWUSR); + +static char *dfd_get_fan_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_FAN_SYSFS_NAME)); + } else { + DFD_FAN_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +/** + * dfd_get_fan_eeprom_mode - The fan type E2 is obtained + * return: 0:TLV + * 1:FRU + * : Negative value - Read failed + */ +static int dfd_get_fan_eeprom_mode(void) +{ + uint64_t key; + int mode; + char *name; + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_E2_MODE, 0, 0); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + /* By default, the TLV format is returned */ + DFD_FAN_DEBUG(DBG_WARN, "get fan eeprom mode fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_FAN_E2_MODE)); + return FAN_EEPROM_MODE_TLV; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode_name %s.\n", name); + if (!strncmp(name, DFD_FAN_EEPROM_MODE_TLV_STRING, strlen(DFD_FAN_EEPROM_MODE_TLV_STRING))) { + mode = FAN_EEPROM_MODE_TLV; + } else if (!strncmp(name, DFD_FAN_EEPROM_MODE_FRU_STRING, strlen(DFD_FAN_EEPROM_MODE_FRU_STRING))) { + mode = FAN_EEPROM_MODE_FRU; + } else { + /* The default TLV mode is returned */ + mode = FAN_EEPROM_MODE_TLV; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode %d.\n", mode); + return mode; +} + +static int dfd_fan_tlv_eeprom_read(int bus, int addr, uint8_t cmd, char *buf, int len, + const char *sysfs_name) +{ + dfd_dev_head_info_t info; + char tmp_tlv_len[sizeof(uint16_t)]; + char *tlv_data; + dfd_dev_tlv_info_t *tlv; + int buf_len; + int rv, match_flag; + + rv = dfd_ko_i2c_read(bus, addr, 0, (uint8_t *)&info, sizeof(dfd_dev_head_info_t), sysfs_name); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "read fan i2c failed, bus: %d, addr: 0x%x, rv: %d\n", + bus, addr, rv); + return -DFD_RV_DEV_FAIL; + } + + /* convert TLV_LEN */ + memcpy(tmp_tlv_len, (uint8_t *)&info.tlv_len, sizeof(uint16_t)); + info.tlv_len = (tmp_tlv_len[0] << 8) + tmp_tlv_len[1]; + + if ((info.tlv_len <= 0) || (info.tlv_len > 0xFF)) { + DFD_FAN_DEBUG(DBG_ERROR, "fan maybe not set mac.\n"); + return -DFD_RV_TYPE_ERR; + } + DFD_FAN_DEBUG(DBG_VERBOSE, "info.tlv_len: %d\n", info.tlv_len); + + tlv_data = (uint8_t *)kmalloc(info.tlv_len, GFP_KERNEL); + if (tlv_data == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "tlv_data kmalloc failed \n"); + return -DFD_RV_NO_MEMORY; + } + mem_clear(tlv_data, info.tlv_len); + + rv = dfd_ko_i2c_read(bus, addr, sizeof(dfd_dev_head_info_t), tlv_data, info.tlv_len, sysfs_name); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR,"fan eeprom read failed\n"); + kfree(tlv_data); + return -DFD_RV_DEV_FAIL; + } + + buf_len = len - 1; + match_flag = 0; + for (tlv = (dfd_dev_tlv_info_t *)tlv_data; (ulong)tlv < (ulong)tlv_data + info.tlv_len;) { + DFD_FAN_DEBUG(DBG_VERBOSE, "tlv: %p, tlv->type: 0x%x, tlv->len: 0x%x info->tlv_len: 0x%x\n", + tlv, tlv->type, tlv->len, info.tlv_len); + if (tlv->type == cmd && tlv->len <= buf_len) { + DFD_FAN_DEBUG(DBG_VERBOSE, "find tlv data, copy...\n"); + memcpy(buf, (uint8_t *)tlv->data, tlv->len); + buf_len = (uint32_t)tlv->len; + match_flag = 1; + break; + } + tlv = (dfd_dev_tlv_info_t *)((uint8_t*)tlv + sizeof(dfd_dev_tlv_info_t) + tlv->len); + } + kfree(tlv_data); + if (match_flag == 0) { + DFD_FAN_DEBUG(DBG_ERROR,"can't find fan tlv date. bus: %d, addr: 0x%02x, tlv type: %d.\n", + bus, addr, cmd); + return -DFD_RV_TYPE_ERR; + } + return buf_len; +} + +/** + * dfd_get_fan_present_status - Obtain the fan running status + * @index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * return: 0:STALL + * 1:ROLL + * : Negative value - Read failed + */ +static int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_ROLL_STATUS, fan_index, motor_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan: %u, motor: %u, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_ROLL_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_fan_present_status - Obtain the fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:PRESENT + * : Negative value - Read failed + */ +int dfd_get_fan_present_status(unsigned int fan_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_FAN, fan_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan present status error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DEV_PRESENT_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_fan_status - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:OK + * 2:NOT OK + * : Negative value - Read failed + */ +static int dfd_get_fan_status(unsigned int fan_index) +{ + int motor_num, motor_index, status, errcnt; + + /* Obtaining fan status */ + status = dfd_get_fan_present_status(fan_index); + if (status != PRESENT) { + DFD_FAN_DEBUG(DBG_ERROR, "fan index: %u, status: %d\n", fan_index, status); + return status; + } + + /* Get the motor running state */ + motor_num = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + if (motor_num <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get motor number error: %d\n", motor_num); + return -DFD_RV_DEV_FAIL; + } + errcnt = 0; + for (motor_index = 1; motor_index <= motor_num; motor_index++) { + status = dfd_get_fan_roll_status(fan_index, motor_index); + if (status < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan index: %u, motor index: %d, status: %d\n", + fan_index, motor_index, status); + return status; + } + if (status != MOTOR_ROLL) { + DFD_FAN_DEBUG(DBG_ERROR, + "stall:fan index: %u, motor index: %d, status: %d\n",fan_index, motor_index, status); + errcnt++; + } + } + if (errcnt > 0) { + return FAN_STATUS_NOT_OK; + } + return FAN_STATUS_OK; +} + +/** + * dfd_get_fan_status_str - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_status_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "params error, fan_index: %u count: %lu", + fan_index, count); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", + count, fan_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_status(fan_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan status error, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + + +/** + * dfd_get_fan_present_str - Obtaining fan present status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_present_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "params error, fan_index: %u count: %lu", + fan_index, count); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", + count, fan_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_present_status(fan_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan present status error, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_get_fan_motor_status_str - Obtain the fan motor status + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_status_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_roll_status(fan_index, motor_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan motor status error, ret: %d, fan_index: %u, motor index: %u\n", + ret, fan_index, motor_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_fan_product_name_decode - Fan name conversion + * @psu_buf: Original fan name + * @buf_len: fan_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_fan_product_name_decode(char *fan_buf, int buf_len) +{ + uint64_t key; + int i, j; + char *p_fan_name, *p_decode_name; + int *fan_type_num; + int *fan_display_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, WB_MAIN_DEV_FAN, WB_MINOR_DEV_FAN); + fan_display_num = dfd_ko_cfg_get_item(key); + if (fan_display_num == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan display name number error, key_name:%s, \ + skip fan name decode\n", key_to_name(DFD_CFG_ITEM_DEV_NUM)); + return DFD_RV_OK; + } + + for (i = 1; i <= *fan_display_num; i++) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_TYPE_NUM, i, 0); + fan_type_num = dfd_ko_cfg_get_item(key); + if (fan_type_num == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan type number error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_TYPE_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + for (j = 1; j <= *fan_type_num; j++) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_NAME, i, j); + p_fan_name = dfd_ko_cfg_get_item(key); + if (p_fan_name == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan origin name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + if (!strncmp(fan_buf, p_fan_name, strlen(p_fan_name))) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_FAN_NAME, i, 0); + p_decode_name = dfd_ko_cfg_get_item(key); + if (p_decode_name == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan decode name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_FAN_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(fan_buf, buf_len); + strlcpy(fan_buf, p_decode_name, buf_len); + DFD_FAN_DEBUG(DBG_VERBOSE, "fan name match ok, display fan name: %s.\n", fan_buf); + return DFD_RV_OK; + } + } + } + + DFD_FAN_DEBUG(DBG_ERROR, "fan name: %s error, can't match.\n", fan_buf); + return -DFD_RV_DEV_NOTSUPPORT; +} + +/** + * dfd_get_fan_info - Obtaining Fan Information + * @index: Number of the fan, starting from 1 + * @cmd: Fan information type, fan name :2, fan serial number :3, fan hardware version :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_info(unsigned int fan_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv, eeprom_mode; + char fan_buf[FAN_SIZE]; + dfd_i2c_dev_t *i2c_dev; + const char *sysfs_name; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, cmd: 0x%x.\n", fan_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, cmd: 0x%x.\n", + count, fan_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_FAN, fan_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "can't find fan%u I2C dfd config, key_name: %s\n", + fan_index, key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + sysfs_name = dfd_get_fan_sysfs_name(); + eeprom_mode = dfd_get_fan_eeprom_mode(); + mem_clear(fan_buf, FAN_SIZE); + if (eeprom_mode == FAN_EEPROM_MODE_TLV) { + if (cmd == DFD_DEV_INFO_TYPE_PART_NUMBER) { + DFD_FAN_DEBUG(DBG_VERBOSE, "fan tlv not have part_number attributes\n"); + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_fan_tlv_eeprom_read(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } else { + if (cmd == DFD_DEV_INFO_TYPE_VENDOR) { + rv = dfd_get_fru_board_data(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } + } + + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan eeprom read failed"); + return -DFD_RV_DEV_FAIL; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "%s\n", fan_buf); + /* Fan product name conversion */ + if (cmd == DFD_DEV_INFO_TYPE_NAME) { + rv = dfd_fan_product_name_decode(fan_buf, FAN_SIZE); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan name decode error. rv: %d\n", rv); + } + } + + snprintf(buf, count, "%s\n", fan_buf); + return strlen(buf); +} + +/** + * dfd_get_fan_speed - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @speed: Speed value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index, unsigned int *speed) +{ + uint64_t key; + int ret, speed_tmp; + + if (speed == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_tmp, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed error, key: %s, ret: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_SPEED), ret); + return ret; + } + + if (speed_tmp == 0 || speed_tmp == 0xffff) { + *speed = 0; + } else { + *speed = 15000000 / speed_tmp; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_speed_str - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_speed_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret; + unsigned int speed; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_speed(fan_index, motor_index, &speed); + if (ret < 0) { + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", speed); +} + +/** + * dfd_set_fan_pwm - set the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fan_pwm(unsigned int fan_index, int pwm) +{ + uint64_t key; + int ret, data; + + if (pwm < 0 || pwm > 100) { + DFD_FAN_DEBUG(DBG_ERROR, "can not set pwm = %d.\n", pwm); + return -DFD_RV_INVALID_VALUE; + } + + data = pwm * 255 / 100; + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, 0); + ret = dfd_info_set_int(key, data); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "set fan%u ratio error, key_name: %s,ret: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_RATIO), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_pwm - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_pwm(unsigned int fan_index, int *pwm) +{ + uint64_t key; + int ret, ratio; + + if (pwm == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, 0); + ret = dfd_info_get_int(key, &ratio, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u ratio error, key_name: %s,ret: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_RATIO), ret); + return ret; + } + if ((ratio * 100) % 255 > 0) { + *pwm = ratio * 100 / 255 + 1; + } else { + *pwm = ratio * 100 / 255; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_pwm_str - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_pwm_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", count, + fan_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_pwm(fan_index, &value); + if (ret < 0) { + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +static int dfd_get_fan_type(unsigned int fan_index, int *fan_type, int *fan_sub_type) +{ + int rv; + char fan_buf[FAN_SIZE]; + + /* Get the fan name */ + rv = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_NAME, fan_buf, FAN_SIZE); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u name error, ret: %d\n", fan_index, rv); + return rv; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "%s\n", fan_buf); + dfd_info_del_no_print_string(fan_buf); + + DFD_FAN_DEBUG(DBG_VERBOSE, "dfd_fan_product_name_decode get fan name %s\n", fan_buf); + rv = dfd_ko_cfg_get_fan_type_by_name((char *)fan_buf, fan_type, fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u type by name error, ret: %d\n", fan_index, rv); + return -DFD_RV_NO_NODE; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u type %d subtype %d by name ok\n", fan_index, *fan_type, *fan_sub_type); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_speed_target - Obtain the standard fan speed + * @fan_index + * @motor_index + * @value Standard speed value + * @returns: 0 success, negative value: failed + */ +int dfd_get_fan_speed_target(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_target; + int key1, key2, fan_type, fan_sub_type, pwm; + int ret; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + ret = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", ret); + return -EIO; + } + + /* Get current PWM */ + ret = dfd_get_fan_pwm(fan_index, &pwm); + if (ret < 0) { + return ret; + } + + /* Gets the rated speed corresponding to the current PWM */ + key1 = DFD_GET_FAN_THRESHOLD_KEY1((pwm / 10 + FAN_SPEED_TARGET_0), WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_target = dfd_ko_cfg_get_item(key); + if (p_fan_speed_target == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed target failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_target; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed target ok, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_target_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_target_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_speed_target(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_tolerance - Obtain the fan speed tolerance + * @fan_index + * @motor_index + * @value Speed tolerance + */ +static int dfd_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_tolerance; + int target, ret; + int key1, key2, fan_type, fan_sub_type; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + ret = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, ret: %d\n", ret); + return -EIO; + } + + /* Obtain the error rate of the fan */ + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_TOLERANCE, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_tolerance = dfd_ko_cfg_get_item(key); + if (p_fan_speed_tolerance == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed tolerance failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Obtain the fan speed target */ + ret = dfd_get_fan_speed_target(fan_index, motor_index, &target); + if (ret < 0) { + return ret; + } + + /* error rpm = Rated speed corresponding to the current pwm * Fan error ratio / 100 */ + *value = target * *p_fan_speed_tolerance / 100; + + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed tolerance ok, key: %s, tolerance rate: %d, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *p_fan_speed_tolerance, *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_tolerance_str - Obtain the fan speed tolerance + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Duct type receives buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_tolerance_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_tolerance(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_direction - Obtain the fan air duct type + * @fan_index: The fan offset starts from 1 + * @value 0:F2B, 1:B2F + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_direction(unsigned int fan_index, int *value) +{ + uint64_t key; + int *p_fan_dirction; + int fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + /* Obtain the fan direction based on the fan type and subtype */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_DIRECTION, fan_type, fan_sub_type); + p_fan_dirction = dfd_ko_cfg_get_item(key); + if (p_fan_dirction == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u direction failed, key_name: %s\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_DIRECTION)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_dirction; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u direction success, key_name: %s, value: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_DIRECTION), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_direction_str - Obtain the fan air duct type + * @fan_index:The fan offset starts from 1 + * @buf :Duct type receives buf + * @count :Duct type receives buf length + * @returns: Succeeded: Air duct type String length + * Failure: negative value + */ +ssize_t dfd_get_fan_direction_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, buf is NULL, fan index: %u.\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, buf is NULL, fan index: %u.\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_direction(fan_index, &value); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan direction string failed, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_max - Obtain the maximum fan speed + * @fan_index + * @motor_index + * @value Maximum fan speed + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_max; + int key1, key2, fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_MAX, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_max = dfd_ko_cfg_get_item(key); + if (p_fan_speed_max == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed max failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_max; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed max success, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_max_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_max_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_max(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_min - Obtain the minimum fan speed + * @fan_index + * @motor_index + * @value Minimum fan speed + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_min; + int key1, key2, fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_MIN, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_min = dfd_ko_cfg_get_item(key); + if (p_fan_speed_min == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed min failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_min; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed min success, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_min_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_min_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_min(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c new file mode 100644 index 000000000000..e5c326df0eb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c @@ -0,0 +1,341 @@ +/* + * An wb_fpga_driver driver for fpga devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" + +#define FPGA_REG_WIDTH_MAX (4) + +int g_dfd_fpga_dbg_level = 0; +module_param(g_dfd_fpga_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_fpga_name - Get the FPGA name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_name(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + char *fpga_name; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL. main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_NAME, main_dev_id, fpga_index); + fpga_name = dfd_ko_cfg_get_item(key); + if (fpga_name == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u name config error, key_name: %s\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", fpga_name); + snprintf(buf, count, "%s\n", fpga_name); + return strlen(buf); +} + +static ssize_t dfd_get_fpga_model(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + int ret, fpga_model_val; + char *fpga_type; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_MODEL_REG, main_dev_id, fpga_index); + ret = dfd_info_get_int(key, &fpga_model_val, NULL); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "get main_dev_id: %u, fpga%u model failed, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_MODEL_REG), ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_MODEL_DECODE, fpga_model_val, 0); + fpga_type = dfd_ko_cfg_get_item(key); + if (fpga_type == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u decode fpga model val 0x%08x failed\n", + main_dev_id, fpga_index, fpga_model_val); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, + "main_dev_id: %u, fpga%u decode fpga model success, origin value: 0x%08x decode value: %s\n", + main_dev_id, fpga_index, fpga_model_val, fpga_type); + snprintf(buf, count, "%s\n", fpga_type); + return strlen(buf); +} + +/** + * dfd_get_fpga_type - Get FPGA model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_type(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + char *fpga_type; + ssize_t ret; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TYPE, main_dev_id, fpga_index); + fpga_type = dfd_ko_cfg_get_item(key); + if (fpga_type == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, + "main_dev_id: %u, fpga%u type config is NULL, try to get fpga type from fpga model\n", + main_dev_id, fpga_index); + /* Unconfigured fpga_type Obtain the device model from fpga_model */ + ret = dfd_get_fpga_model(main_dev_id, fpga_index, buf, count); + return ret; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", fpga_type); + snprintf(buf, count, "%s\n", fpga_type); + return strlen(buf); +} + +/** + * dfd_get_fpga_fw_version - Obtain the FPGA firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_fw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + int rv; + uint32_t value; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_VERSION, main_dev_id, fpga_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_VERSION), rv); + return rv; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u firmware version: %x\n", + main_dev_id, fpga_index, value); + snprintf(buf, count, "0x%08x\n", value); + return strlen(buf); +} + +/** + * dfd_get_fpga_hw_version - Obtain the hardware version of the FPGA + * @main_dev_id: Motherboard :0 Subcard :5 + * @index: FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_hw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u hardware version not support\n", + main_dev_id, fpga_index); + return -DFD_RV_DEV_NOTSUPPORT; +} + +static int value_convert_to_buf(unsigned int value, uint8_t *buf, int len, int pola) +{ + int i; + + if ((pola != INFO_POLA_POSI) && (pola != INFO_POLA_NEGA)) { + DBG_FPGA_DEBUG(DBG_ERROR, "unsupport pola mode: %d\n", pola); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, len); + if (pola == INFO_POLA_POSI) { /* Big-end mode */ + for (i = 0; i < len; i++) { + buf[i] = (value >> ((len - i - 1) * 8)) & 0xff; + } + } else { /* Small terminal mode */ + for (i = 0; i < len; i++) { + buf[i] = (value >> (i * 8)) & 0xff; + } + } + return DFD_RV_OK; +} + +/** + * dfd_set_fpga_testreg - Sets the value of the FPGA test register + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, unsigned int value) +{ + uint64_t key; + int ret; + uint8_t wr_buf[FPGA_REG_WIDTH_MAX]; + info_ctrl_t *info_ctrl; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TEST_REG, main_dev_id, fpga_index); + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u get info ctrl failed, key_name: %s\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_TEST_REG)); + return -DFD_RV_DEV_NOTSUPPORT; + } + if (info_ctrl->fpath == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u get fpath failed\n", main_dev_id, + fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (info_ctrl->len > FPGA_REG_WIDTH_MAX) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u info_ctrl len: %d, unsupport\n", + main_dev_id, fpga_index, info_ctrl->len); + return -DFD_RV_INVALID_VALUE; + } + + ret = value_convert_to_buf(value, wr_buf, FPGA_REG_WIDTH_MAX, info_ctrl->pola); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "value: 0x%x convert to buf failed, pola:%d, ret: %d\n", + value, info_ctrl->pola, ret); + return ret; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u fpath: %s, addr: 0x%x, len: %d value: 0x%x\n", + main_dev_id, fpga_index, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, value); + ret = dfd_ko_write_file(info_ctrl->fpath, info_ctrl->addr, wr_buf, info_ctrl->len); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "set fpga test reg failed, ret: %d", ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fpga_testreg - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int *value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TEST_REG, main_dev_id, fpga_index); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, get fpga%u test reg error, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fpga_testreg_str - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_testreg_str(uint8_t main_dev_id, unsigned int fpga_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fpga_testreg(main_dev_id, fpga_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "0x%08x\n", value); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c new file mode 100644 index 000000000000..c66c3150dd79 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c @@ -0,0 +1,133 @@ +/* + * An wb_led_driver driver for led devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +int g_dfd_sysled_dbg_level = 0; +module_param(g_dfd_sysled_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_led_status_value - Get LED light status value + * @led_id See the wb_led_t definition + * @value 0: Off, 1: green, 2: yellow, 3: red, 4: blue, 5: green, 6: yellow, 7: red + * @returns: 0 success, negative value: failed + */ +static int dfd_get_led_status_value(uint16_t led_id, uint8_t led_index, int *value) +{ + uint64_t key; + int ori_value, ret; + int *p_decode_value; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS, led_id, led_index); + ret = dfd_info_get_int(key, &ori_value, NULL); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error, key: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_LED_STATUS), ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS_DECODE, led_id, ori_value); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value != NULL) { + DBG_SYSLED_DEBUG(DBG_VERBOSE, "led id: %u index: %u, ori_value: 0x%x, decode value :0x%x\n", + led_id, led_index, ori_value, *p_decode_value); + *value = *p_decode_value; + return DFD_RV_OK; + } + return -DFD_RV_INVALID_VALUE; +} + +/** + * dfd_get_led_status - Get LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @buf: LED light status receives buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_led_status(uint16_t led_id, uint8_t led_index, char *buf, size_t count) +{ + int ret, led_value; + + if (buf == NULL) { + DBG_SYSLED_DEBUG(DBG_ERROR, "param error, buf is NULL. led_id: %u, led_index: %u\n", + led_id, led_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "buf size error, count: %lu, led_id: %u, led_index: %u\n", + count, led_id, led_index); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + ret = dfd_get_led_status_value(led_id, led_index, &led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error, ret: %d, led_id: %u, led_index: %u\n", + ret, led_id, led_index); + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", led_value); +} + +/** + * dfd_set_led_status - Set LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @value: LED light status value + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_set_led_status(uint16_t led_id, uint8_t led_index, int value) +{ + uint64_t key; + int ret, led_value; + + if (value < 0 || value > 0xff) { + DBG_SYSLED_DEBUG(DBG_ERROR, "can not set led status value = %d.\n", value); + return -DFD_RV_INVALID_VALUE; + } + + DBG_SYSLED_DEBUG(DBG_VERBOSE, "set led id: %u index: %u, status[%d].\n", + led_id, led_index, value); + ret = dfd_ko_cfg_get_led_status_decode2_by_regval(value, led_id, &led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status register error, ret: %d, led_id: %u, value: %d\n", + ret, led_id, value); + return ret; + } + + DBG_SYSLED_DEBUG(DBG_VERBOSE, "get led[%u] index[%u] status[%d] decode value[%d]\n", + led_id, led_index, value, led_value); + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS, led_id, led_index); + ret = dfd_info_set_int(key, led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "set led status error, key_name: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_LED_STATUS), ret); + return ret; + } + + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c new file mode 100644 index 000000000000..69610668a971 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c @@ -0,0 +1,73 @@ +/* + * An wb_module driver for module devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" + +int g_dfd_dbg_level = 0; /* Debug level */ +module_param(g_dfd_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * wb_dev_cfg_init - dfd module initialization + * + * @returns:<0 Failed, otherwise succeeded + */ +int32_t wb_dev_cfg_init(void) +{ + return dfd_dev_cfg_init(); +} + +/** + * wb_dev_cfg_exit - dfd module exit + * + * @returns: void + */ + +void wb_dev_cfg_exit(void) +{ + dfd_dev_cfg_exit(); + return; +} + +/** + * dfd_get_dev_number - Get the number of devices + * @main_dev_id:Master device number + * @minor_dev_id:Secondary device number + * @returns: <0 failed, otherwise number of devices is returned + */ +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id) +{ + uint64_t key; + int dev_num; + int *p_dev_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, main_dev_id, minor_dev_id); + p_dev_num = dfd_ko_cfg_get_item(key); + if (p_dev_num == NULL) { + DBG_DEBUG(DBG_ERROR, "get device number failed, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_DEV_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + dev_num = *p_dev_num; + DBG_DEBUG(DBG_VERBOSE, "get device number ok, number:%d\n",dev_num); + return dev_num; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c new file mode 100644 index 000000000000..aad65d282921 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c @@ -0,0 +1,950 @@ +/* + * An wb_psu_driver driver for psu devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define PSU_SIZE (256) +#define WB_GET_PSU_PMBUS_BUS(addr) (((addr) >> 24) & 0xff) +#define WB_GET_PSU_PMBUS_ADDR(addr) (((addr) >> 8) & 0xffff) +#define WB_GET_PSU_PMBUS_OFFSET(addr) ((addr) & 0xff) +#define DFD_PSU_FRU_MODE_E2_STRING "eeprom" +#define DFD_PSU_FRU_MODE_PMBUS_STRING "pmbus" + +#define PSU_PMBUS_POWER_GOOD BIT(11) + +typedef enum dfd_psu_pmbus_type_e { + DFD_PSU_PMBUS_TYPE_AC = 1, + DFD_PSU_PMBUS_TYPE_DC = 2, +} dfd_psu_pmbus_type_t; + +typedef enum dfd_psu_sysfs_type_e { + DFD_PSU_SYSFS_TYPE_DC = 0, + DFD_PSU_SYSFS_TYPE_AC = 1, +} dfd_psu_sysfs_type_t; + +typedef enum dfd_psu_status_e { + DFD_PSU_PRESENT_STATUS = 0, + DFD_PSU_OUTPUT_STATUS = 1, + DFD_PSU_ALERT_STATUS = 2, + DFD_PSU_INPUT_STATUS = 3, +} dfd_psu_status_t; + +typedef enum dfd_psu_alarm_e { + DFD_PSU_NOT_OK = 0, + DFD_PSU_OK = 1, +} dfd_psu_alarm_t; + +enum knos_alarm { + PSU_TERMAL_ERROR = 0x1, + PSU_FAN_ERROR = 0x2, + PSU_VOL_ERROR = 0x4, +}; + +typedef enum psu_fru_mode_e { + PSU_FRU_MODE_E2, /* eeprom */ + PSU_FRU_MODE_PMBUS, /*pmbus*/ +} fan_eeprom_mode_t; + + +/* PMBUS STATUS WORD decode */ +#define PSU_STATUS_WORD_CML (1 << 1) +#define PSU_STATUS_WORD_TEMPERATURE (1 << 2) +#define PSU_STATUS_WORD_VIN_UV (1 << 3) +#define PSU_STATUS_WORD_IOUT_OC (1 << 4) +#define PSU_STATUS_WORD_VOUT_OV (1 << 5) +#define PSU_STATUS_WORD_OFF (1 << 6) +#define PSU_STATUS_WORD_BUSY (1 << 7) +#define PSU_STATUS_WORD_FANS (1 << 10) +#define PSU_STATUS_WORD_POWER_GOOD (1 << 11) +#define PSU_STATUS_WORD_INPUT (1 << 13) +#define PSU_STATUS_WORD_IOUT (1 << 14) +#define PSU_STATUS_WORD_VOUT (1 << 15) + +#define PSU_VOLTAGE_ERR_OFFSET (PSU_STATUS_WORD_VOUT | PSU_STATUS_WORD_IOUT | \ + PSU_STATUS_WORD_INPUT | PSU_STATUS_WORD_POWER_GOOD| \ + PSU_STATUS_WORD_OFF | PSU_STATUS_WORD_VOUT_OV| \ + PSU_STATUS_WORD_IOUT_OC | PSU_STATUS_WORD_VIN_UV) + +int g_dfd_psu_dbg_level = 0; +module_param(g_dfd_psu_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_get_psu_fru_mode(void) +{ + uint64_t key; + int mode; + char *name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_FRU_MODE, 0, 0); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + /* The default EEPROM format is returned */ + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu fru mode config fail, key=%s, use default eeprom mode\n", + key_to_name(DFD_CFG_ITEM_PSU_FRU_MODE)); + return PSU_FRU_MODE_E2; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu fru mode %s.\n", name); + if (!strncmp(name, DFD_PSU_FRU_MODE_E2_STRING, strlen(DFD_PSU_FRU_MODE_E2_STRING))) { + mode = PSU_FRU_MODE_E2; + } else if (!strncmp(name, DFD_PSU_FRU_MODE_PMBUS_STRING, strlen(DFD_PSU_FRU_MODE_PMBUS_STRING))) { + mode = PSU_FRU_MODE_PMBUS; + } else { + /* The default EEPROM format is returned */ + mode = PSU_FRU_MODE_E2; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "psu fru mode %d.\n", mode); + return mode; +} + +static char *dfd_get_psu_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_PSU_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_PSU_SYSFS_NAME)); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +static void dfd_psu_del_no_print_string(char *buf) +{ + int i, len; + + len = strlen(buf); + /* Culling noncharacter */ + for (i = 0; i < len; i++) { + if ((buf[i] < 0x21) || (buf[i] > 0x7E)) { + buf[i] = '\0'; + break; + } + } + return; +} + +/** + * dfd_get_psu_present_status - Obtain the power supply status + * @index: Number of the power supply, starting from 1 + * return: 0:Not in the position + * 1:position + * : Negative value - Read failed + */ +int dfd_get_psu_present_status(unsigned int psu_index) +{ + int present_key, present_status; + int ret; + + /* Get presence status */ + present_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_PRESENT_STATUS); + ret = dfd_info_get_int(present_key, &present_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_status error. psu_index: %u, ret: %d\n", + psu_index, ret); + return ret; + } + + return present_status; +} + +/** + * dfd_get_psu_present_status_str - Obtain power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Gets the value on the pmbus register of the power supply + */ +ssize_t dfd_get_psu_present_status_str(unsigned int psu_index, char *buf, size_t count) +{ + int ret; + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + ret = dfd_get_psu_present_status(psu_index); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +ssize_t dfd_get_psu_pmbus_status(unsigned int psu_index, char *buf, size_t count) +{ + int key; + int ret; + + /* PMBUS STATUS WORD (0x79) */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, PSU_HW_STATUS); + ret = dfd_info_get_sensor(key, buf, count, NULL); + + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key: 0x%08x, ret: %d\n", + psu_index, DFD_CFG_ITEM_HWMON_PSU, ret); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = %s \n", psu_index, buf); + } + return ret; +} + +/** + * dfd_get_psu_hw_status_str - get psu status str + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Gets the value on the pmbus register of the power supply + */ +ssize_t dfd_get_psu_hw_status_str(unsigned int psu_index, char *buf, size_t count) +{ + int ret; + int status_word; + int status; + int output_key, output_status; + int alert_key, alert_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error, psu_index: %u", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* get psu present status first */ + ret = dfd_get_psu_present_status(psu_index); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu present status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } + if (ret == PSU_STATUS_ABSENT) { + return (ssize_t)snprintf(buf, count, "%d\n", PSU_STATUS_ABSENT); + } + + /* get psu alert and power status from cpld */ + output_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_OUTPUT_STATUS); + alert_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_ALERT_STATUS); + ret = dfd_info_get_int(output_key, &output_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu output_key error, ret: %d, psu_index: %u\n", + ret, psu_index); + return ret; + } + ret = dfd_info_get_int(alert_key, &alert_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu alert_key error, ret: %d, psu_index: %u\n", + ret, psu_index); + return ret; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu %u alert: %u, output: %u.\n", psu_index, alert_status, output_status); + /* if cpld status not ok */ + if (!alert_status || !output_status) { + /* jduge psu status from psu pmbus 0x79 */ + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + DFD_PSU_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return -EINVAL; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu %u statu reg value: %u.\n", psu_index, status_word); + status = (status_word & PSU_PMBUS_POWER_GOOD) ? PSU_STATUS_FAIL : PSU_STATUS_WARN; + } + } else { + status = PSU_STATUS_PRESENT; + } + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", status); +} + +/** + * dfd_get_psu_status_pmbus_str - Gets the value on the pmbus register of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_status_pmbus_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_SENSOR_NONE); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", pmbus_data); +} + +/** + * dfd_get_psu_fan_speed_cal_str - Obtain the formula for calculating the speed of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +static int dfd_get_psu_fan_speed_cal_str(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *speed_cal; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED_CAL, power_type, 0); + speed_cal = dfd_ko_cfg_get_item(key); + if (speed_cal == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu speed cal error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_SPEED_CAL)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + strlcpy(psu_buf, speed_cal, buf_len); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu speed cal match ok, speed_cal: %s\n", psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_get_psu_out_status_str - Obtain the output power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_out_status_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int output_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_OUT_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + output_status = DFD_PSU_OK; + if (pmbus_data & (PSU_STATUS_WORD_INPUT | PSU_STATUS_WORD_OFF | PSU_STATUS_WORD_POWER_GOOD)) { + /* The judgment logic of no power is consistent with that of Baidu sysfs */ + output_status = DFD_PSU_NOT_OK; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", output_status); +} + +/** + * dfd_psu_product_name_decode - Power name conversion + * @power_type: Power supply type + * @psu_buf: Power name buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_product_name_decode(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *p_decode_name; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_POWER_NAME, power_type, 0); + p_decode_name = dfd_ko_cfg_get_item(key); + if (p_decode_name == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu decode name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_POWER_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + strlcpy(psu_buf, p_decode_name, buf_len); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu name match ok, display psu name: %s\n", psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_psu_fan_direction_decode - Power duct type conversion + * @power_type: Power supply type + * @psu_buf: Power name buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_fan_direction_decode(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *p_decode_direction; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR, power_type, 0); + p_decode_direction = dfd_ko_cfg_get_item(key); + if (p_decode_direction == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu decode direction error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + snprintf(psu_buf, buf_len, "%d", *p_decode_direction); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%u fan direction match ok, display psu direction: %s\n", + power_type, psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_psu_max_output_power - Rated power of supply + * @power_type: Power supply type + * @psu_buf: Data buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_max_output_power(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + int value; + int *p_power_max_output_power; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_RSUPPLY, power_type, 0); + p_power_max_output_power = dfd_ko_cfg_get_item(key); + if (p_power_max_output_power == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu input type error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_POWER_RSUPPLY)); + return -DFD_RV_DEV_NOTSUPPORT; + } + value = *p_power_max_output_power; + mem_clear(psu_buf, buf_len); + snprintf(psu_buf, buf_len, "%d", value); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu name %s match max output power %d\n", psu_buf, value); + return DFD_RV_OK; +} + +static int dfd_get_psu_fru_pmbus(unsigned int psu_index, uint8_t cmd, char *buf, size_t buf_len) +{ + uint64_t key; + int rv, len; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_FRU_PMBUS, psu_index, cmd); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu index: %d, cmd: %d, key_name: %s\n", + psu_index, cmd, key_to_name(DFD_CFG_ITEM_PSU_FRU_PMBUS)); + + rv = dfd_info_get_sensor(key, buf, buf_len, NULL); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu fru info by pmbus failed, key_name: %s, rv: %d\n", + key_to_name(DFD_CFG_ITEM_PSU_FRU_PMBUS), rv); + } else { + len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu fru info by pmbus success, value: %s\n", buf); + } + return rv; +} + +static int dfd_get_psu_type(unsigned int psu_index, dfd_i2c_dev_t *i2c_dev, int *power_type, + const char *sysfs_name, int fru_mode) +{ + int rv; + char psu_buf[PSU_SIZE]; + + mem_clear(psu_buf, sizeof(psu_buf)); + if (fru_mode == PSU_FRU_MODE_PMBUS) { + rv = dfd_get_psu_fru_pmbus(psu_index, DFD_DEV_INFO_TYPE_PART_NUMBER, psu_buf, PSU_SIZE); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, DFD_DEV_INFO_TYPE_PART_NUMBER, psu_buf, + PSU_SIZE, sysfs_name); + } + + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu type from eeprom read failed, rv: %d\n", rv); + return -DFD_RV_DEV_FAIL; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "%s\n", psu_buf); + dfd_psu_del_no_print_string(psu_buf); + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_psu_product_name_decode get psu name %s\n", psu_buf); + rv = dfd_ko_cfg_get_power_type_by_name((char *)psu_buf, power_type); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get power type by name[%s] fail, rv: %d\n", psu_buf, rv); + return -DFD_RV_NO_NODE; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu%u return power_type[0x%x]\n", psu_index, *power_type); + return DFD_RV_OK; +} + +/** + * dfd_get_psu_info - Get Power Information + * @index: Number of the power supply, starting from 1 + * @cmd: Power supply information Type, power supply name :2, power supply serial number :3, power supply hardware version :5 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_info(unsigned int psu_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv; + char psu_buf[PSU_SIZE]; + dfd_i2c_dev_t *i2c_dev; + int power_type; + int fru_mode; + const char *sysfs_name; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u, cmd: 0x%x\n", psu_index, cmd); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u, cmd: 0x%x\n", + count, psu_index, cmd); + return -EINVAL; + } + + fru_mode = dfd_get_psu_fru_mode(); + mem_clear(buf, count); + mem_clear(psu_buf, PSU_SIZE); + if (fru_mode == PSU_FRU_MODE_E2) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_PSU, psu_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "psu i2c dev config error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + sysfs_name = dfd_get_psu_sysfs_name(); + } + + /* Power E2 product name conversion */ + if (cmd == DFD_DEV_INFO_TYPE_PART_NAME) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv: %d\n", rv); + return -EIO; + } + rv = dfd_psu_product_name_decode(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu name decode error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_FAN_DIRECTION) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv: %d\n", rv); + return -EIO; + } + rv = dfd_psu_fan_direction_decode(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu input type decode error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv:%d\n", rv); + return -EIO; + } + rv = dfd_psu_max_output_power(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu max ouput power error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_SPEED_CAL) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv:%d\n", rv); + return -EIO; + } + rv = dfd_get_psu_fan_speed_cal_str(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu fan speed cal error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else { + if (fru_mode == PSU_FRU_MODE_PMBUS) { + rv = dfd_get_psu_fru_pmbus(psu_index, cmd, psu_buf, PSU_SIZE); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, cmd, psu_buf, PSU_SIZE, sysfs_name); + } + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu eeprom read failed, rv: %d\n", rv); + return -EIO; + } + } + + snprintf(buf, count, "%s\n", psu_buf); + return strlen(buf); +} + +/** + * dfd_get_psu_input_type - Obtain the power input type + * @index: Number of the power supply, starting from 1 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_input_type(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_IN_TYPE); + ret = dfd_info_get_int(key, &data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, data); + + if (data == DFD_PSU_PMBUS_TYPE_AC) { + return snprintf(buf, count, "%d\n", DFD_PSU_SYSFS_TYPE_AC); + } else if (data == DFD_PSU_PMBUS_TYPE_DC) { + return snprintf(buf, count, "%d\n", DFD_PSU_SYSFS_TYPE_DC); + } else { + DFD_PSU_DEBUG(DBG_WARN, "get psu%u input type data[%u] unknow, ret: %d\n", + psu_index, data, ret); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus type data[%u] unknow, ret: %d\n", + psu_index, data, ret); + return -EIO; +} + +/** + * dfd_get_psu_in_status_str - Obtain the input power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_in_status_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int input_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_IN_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + input_status = DFD_PSU_OK; + if (pmbus_data & PSU_STATUS_WORD_INPUT) { + /* no power judgment logic, according to the opinion only bit13 judgment */ + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, no power, pmbus_data = 0x%x \n", psu_index, pmbus_data); + input_status = DFD_PSU_NOT_OK; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", input_status); +} + +ssize_t dfd_get_psu_alarm_status(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int alarm; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* PMBUS STATUS WORD (0x79) */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_OUT_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + alarm = 0; + if (pmbus_data & PSU_STATUS_WORD_TEMPERATURE) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_TERMAL_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_TERMAL_ERROR; + } + + if (pmbus_data & PSU_STATUS_WORD_FANS) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_FAN_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_FAN_ERROR; + } + + if (pmbus_data & PSU_VOLTAGE_ERR_OFFSET) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_VOL_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_VOL_ERROR; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", alarm); +} + +/** + * dfd_get_psu_fan_ratio_str - Gets the target fan rotation rate + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_fan_ratio_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_FAN_RATIO); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus fan ratio info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", pmbus_data); +} + +ssize_t dfd_get_psu_threshold_str(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + uint64_t key; + int ret; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, type); + ret = dfd_info_get_sensor(key, buf, count, NULL); + if (ret < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get psu sensor info error, key_name: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_HWMON_PSU), ret); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get psu sensor info success, value: %s\n", buf); + } + return ret; +} + +ssize_t dfd_get_psu_blackbox(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *blackbox_path; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* Obtain the blackbox_info path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_BLACKBOX_INFO, psu_index, 0); + blackbox_path = dfd_ko_cfg_get_item(key); + if (blackbox_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u blackbox_info path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_BLACKBOX_INFO)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, blackbox_info path: %s\n", psu_index, blackbox_path); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(blackbox_path, 0, buf, count); + if (rd_len < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "read psu%u blackbox info failed, blackbox_info path: %s, ret: %ld\n", + psu_index, blackbox_path, rd_len); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "read psu%u blackbox info success, blackbox_info path: %s, rd_len: %ld\n", + psu_index, blackbox_path, rd_len); + } + + return rd_len; +} + +ssize_t dfd_get_psu_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *pmbus_info_path; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* Obtain the pmbus_info path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_INFO, psu_index, 0); + pmbus_info_path = dfd_ko_cfg_get_item(key); + if (pmbus_info_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus_info path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_INFO)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_info path: %s\n", psu_index, pmbus_info_path); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(pmbus_info_path, 0, buf, count); + if (rd_len < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "read psu%u pmbus info failed, pmbus_info path: %s, ret: %ld\n", + psu_index, pmbus_info_path, rd_len); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "read psu%u pmbus info success, pmbus_info path: %s, rd_len: %ld\n", + psu_index, pmbus_info_path, rd_len); + } + + return rd_len; +} + +int dfd_clear_psu_blackbox(unsigned int psu_index, uint8_t value) +{ + uint64_t key; + int ret; + char *clear_blackbox_info_path; + uint8_t wr_buf[INFO_INT_MAX_LEN]; + + /* Obtain the clear_blackbox path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX, psu_index, 0); + clear_blackbox_info_path = dfd_ko_cfg_get_item(key); + if (clear_blackbox_info_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u clear blackbox path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, clear blackbox path: %s, write value: %u\n", + psu_index, clear_blackbox_info_path, value); + + mem_clear(wr_buf, sizeof(wr_buf)); + snprintf(wr_buf, sizeof(wr_buf), "%u", value); + ret = dfd_ko_write_file(clear_blackbox_info_path, 0, wr_buf, strlen(wr_buf)); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "clear psu%u blackbox info failed, ret: %d\n", psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, clear blackbox info success\n", psu_index); + return DFD_RV_OK; +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c new file mode 100644 index 000000000000..c7342de6e3e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c @@ -0,0 +1,345 @@ +/* + * An wb_sensors_driver driver for snesors devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" +#include "dfd_cfg_file.h" + +#define DFD_GET_TEMP_SENSOR_KEY1(dev_index, temp_index) \ + (((dev_index & 0xff) << 8) | (temp_index & 0xff)) +#define DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, temp_type) \ + (((main_dev_id & 0x0f) << 4) | (temp_type & 0x0f)) +#define DFD_FORMAT_STR_MAX_LEN (32) + +int g_dfd_sensor_dbg_level = 0; +module_param(g_dfd_sensor_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_deal_hwmon_buf(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, + info_ctrl_t *info_ctrl, int coefficient, int addend) +{ + int i, tmp_len; + int exp, decimal, divisor; + int org_value, tmp_value; + int div_result, div_mod; + char fmt_str[DFD_FORMAT_STR_MAX_LEN]; + + exp = info_ctrl->int_cons; /* Numerical conversion index */ + decimal = info_ctrl->bit_offset; /* Decimal point retention number */ + + /* No conversion is required, just copy the value */ + if ((exp <= 0) && (coefficient == 1) && (addend == 0)) { + DBG_DEBUG(DBG_VERBOSE, "exponent %d, coefficient: %d, addend: %d, don't need transform, buf_len: %d, buf_len_new: %d\n", + exp, coefficient, addend, buf_len, *buf_len_new); + snprintf(buf_new, *buf_len_new, "%s", buf); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + + divisor = 1; + for (i = 0; i < exp; i++) { + divisor *= 10; + } + org_value = simple_strtol(buf, NULL, 10); + DBG_DEBUG(DBG_VERBOSE, "original value: %d, exp: %d, divisor: %d, decimal: %d, coefficient: %d, addend: %d\n", + org_value, exp, divisor, decimal, coefficient, addend); + + org_value = (org_value + addend) * coefficient; + if (org_value < 0) { + tmp_value = 0 - org_value; + } else { + tmp_value = org_value; + } + div_result = tmp_value / divisor; + div_mod = tmp_value % divisor; + DBG_DEBUG(DBG_VERBOSE, "tmp_value: %d, divisor: %d, div_result: %d, div_mod: %d\n", + tmp_value, divisor, div_result, div_mod); + /* don't need to keep the decimal, just round it */ + if (decimal == 0) { + snprintf(buf_new, *buf_len_new, "%d\n", div_result); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + mem_clear(fmt_str, sizeof(fmt_str)); + if (org_value < 0) { + snprintf(fmt_str, sizeof(fmt_str), "-%%d.%%0%dd\n",exp); + } else { + snprintf(fmt_str, sizeof(fmt_str), "%%d.%%0%dd\n",exp); + } + DBG_DEBUG(DBG_VERBOSE, "format string: %s",fmt_str); + snprintf(buf_new, *buf_len_new, fmt_str, div_result, div_mod); + *buf_len_new = strlen(buf_new); + tmp_len = *buf_len_new; + /* Keep decimal places only when the number of decimal places is reduced */ + if (decimal > 0) { + for (i = 0; i < *buf_len_new; i++) { + if (buf_new[i] == '.') { + if (i + decimal + 2 <= *buf_len_new) { + buf_new[i + decimal + 1 ] = '\n'; + buf_new[i + decimal + 2 ] = '\0'; + *buf_len_new = strlen(buf_new); + DBG_DEBUG(DBG_VERBOSE, "deal decimal[%d] ok, str len:%d, value:%s\n", + decimal, *buf_len_new, buf_new); + } + break; + } + } + if (tmp_len == *buf_len_new) { + DBG_DEBUG(DBG_WARN, "deal decimal[%d] failed, use original value:%s\n", decimal, + buf_new); + } + } + return DFD_RV_OK; +} + +static int dfd_get_sensor_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, uint8_t sensor_attr, char *buf, size_t count) +{ + uint64_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv; + info_hwmon_buf_f pfunc; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, sensor_attr); + if (sensor_type == WB_MINOR_DEV_TEMP) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_TEMP, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_IN) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_IN, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_CURR) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_CURR, key_index1, key_index2); + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "Unknow sensor type: %u\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "main_dev_id: %u, dev_index: 0x%x, sensor_index: 0x%x, \ + sensor_attr: 0x%x, key: 0x%08llx\n", main_dev_id, dev_index, sensor_index, sensor_attr, key); + + pfunc = dfd_deal_hwmon_buf; + rv = dfd_info_get_sensor(key, buf, count, pfunc); + return rv; +} + +/** + * dfd_get_temp_info - Get temperature information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1/psu1 + * @temp_index: Temperature index, starting at 1 + * @temp_type: Read type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t temp_index, + uint8_t temp_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error, buf is NULL\n"); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_TEMP, temp_index, temp_attr, + buf, count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get temp info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get temp info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_voltage_info - Get voltage information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Voltage index, starting at 1 + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t in_index, + uint8_t in_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_IN, in_index, in_attr, buf, + count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get voltage info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get voltage info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_current_info - Get current information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Current index, starting at 1 + * @in_type: Current type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_current_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t curr_index, + uint8_t curr_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_CURR, curr_index, curr_attr, + buf, count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get current info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get current info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_psu_sensor_info - Obtain PMBUS information about the power supply + * @psu_index: Power index, starting at 1 + * @sensor_type: Type of the obtained pmbus information + * @buf: pmbus results are stored in buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_sensor_info(uint8_t psu_index, uint8_t sensor_type, char *buf, size_t count) +{ + uint64_t key; + int rv; + info_hwmon_buf_f pfunc; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, sensor_type); + DFD_SENSOR_DEBUG(DBG_VERBOSE, "psu index: %d, sensor type: %d, key_name: %s,\n", psu_index, + sensor_type, key_to_name(DFD_CFG_ITEM_HWMON_PSU)); + pfunc = dfd_deal_hwmon_buf; + rv = dfd_info_get_sensor(key, buf, count, pfunc); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get psu sensor info error, key_name: %s, rv: %d\n", + key_to_name(DFD_CFG_ITEM_HWMON_PSU), rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get psu sensor info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_main_board_monitor_flag - Get Monitor flag info + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @sensor_type: Type of the obtained pmbus information + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +int dfd_get_main_board_monitor_flag(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, char *buf, size_t count) +{ + uint64_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv, sensor_type_key, decode_key; + int data; + info_ctrl_t *info_ctrl; + int *p_decode_value; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, 0); /* 4bytes. currently low bytes is 0. */ + if (sensor_type == WB_MINOR_DEV_TEMP) { + sensor_type_key = DFD_CFG_ITEM_HWMON_TEMP_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_TEMP_MONITOR_DC; + } else if (sensor_type == WB_MINOR_DEV_IN) { + sensor_type_key = DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG_DC; + } else if (sensor_type == WB_MINOR_DEV_CURR) { + sensor_type_key = DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG_DC; + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "Unknow sensor type: %u\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(sensor_type_key, key_index1, key_index2); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_VERBOSE, "get info ctrl failed, key=0x%08llx\n", key); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", WB_SENSOR_MONITOR_YES); + } + + rv = dfd_info_get_int(key, &data, NULL); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get monitor flag error, key_name: %s, rv: %d\n", + key_to_name(sensor_type_key), rv); + return rv; + } + + key = DFD_CFG_KEY(decode_key, key_index1, data); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value == NULL) { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "status needn't decode. value:0x%x\n", data); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "ori_value:0x%x, decoded value:0x%x\n", data, *p_decode_value); + data = *p_decode_value; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "main_dev_id: %u, dev_index: 0x%x, sensor_index: 0x%x, \ + key_name: %s, data = %d\n", main_dev_id, dev_index, sensor_index, key_to_name(sensor_type_key), data); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", data); +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c new file mode 100644 index 000000000000..1b55989ebde0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c @@ -0,0 +1,143 @@ +/* + * An wb_sff_driver driver for sff devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +int g_dfd_sff_dbg_level = 0; +module_param(g_dfd_sff_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_set_sff_cpld_info - Example Set the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @value: Writes the value to the register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, int value) +{ + uint64_t key; + int ret; + + if ((value != 0) && (value != 1)) { + DFD_SFF_DEBUG(DBG_ERROR, "sff%u cpld reg type %d, can't set invalid value: %d\n", + sff_index, cpld_reg_type, value); + return -DFD_RV_INVALID_VALUE; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "set sff%u cpld reg type %d error, key_name: %s, ret: %d.\n", + sff_index, cpld_reg_type, key_to_name(DFD_CFG_ITEM_SFF_CPLD_REG), ret); + return ret; + } + + return DFD_RV_OK; +} + +/** + * dfd_get_sff_cpld_info - Obtain the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @buf: Optical module E2 receives information from buf + * @count: buf length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, size_t count) +{ + uint64_t key; + int ret, value; + + if (buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error, buf is NULL. sff_index: %u, cpld_reg_type: %d\n", + sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SFF_DEBUG(DBG_ERROR, "buf size error, count: %lu, sff index: %u, cpld_reg_type: %d\n", + count, sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff%u cpld reg type %d error, key_name: %s, ret: %d\n", + sff_index, cpld_reg_type, key_to_name(DFD_CFG_ITEM_SFF_CPLD_REG), ret); + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_single_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_get_single_eth_optoe_type(unsigned int sff_index, int *optoe_type) +{ + uint64_t key; + int ret, value; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_OPTOE_TYPE, sff_index, 0); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff optoe type error, key_name: %s, ret:%d.\n", + key_to_name(DFD_CFG_ITEM_SFF_OPTOE_TYPE), ret); + return ret; + } + + /* assic int to int */ + *optoe_type = value - '0'; + return ret; +} + +/** + * dfd_set_single_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_set_single_eth_optoe_type(unsigned int sff_index, int optoe_type) +{ + uint64_t key; + int ret, value; + + /* int to assic int */ + value = optoe_type + '0'; + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_OPTOE_TYPE, sff_index, 0); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "set sff optoe type error, key_name: %s, ret:%d.\n", + key_to_name(DFD_CFG_ITEM_SFF_OPTOE_TYPE), ret); + return ret; + } + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c new file mode 100644 index 000000000000..5ba743f3c4d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c @@ -0,0 +1,174 @@ +/* + * An wb_slot_driver driver for slot devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define SLOT_SIZE (256) + +int g_dfd_slot_dbg_level = 0; +module_param(g_dfd_slot_dbg_level, int, S_IRUGO | S_IWUSR); + +static char *dfd_get_slot_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_SLOT_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_SLOT_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_SLOT_SYSFS_NAME)); + } else { + DFD_SLOT_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +/** + * dfd_get_slot_status - Gets the subcard status + * @index: Number of the sub-card, starting from 1 + * return: 0:ABSENT + * 1:OK + * : Negative value - Read failed + */ +static int dfd_get_slot_status(unsigned int slot_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_DEV_PRESENT_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_slot_status_str - Gets the subcard status + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_slot_status_str(unsigned int slot_index, char *buf, size_t count) +{ + int ret; + if (buf == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "params error.slot_index:%d.",slot_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_slot_status(slot_index); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error,ret:%d, slot_index:%d\n", ret, slot_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_get_slot_info - Obtain the subcard information + * @slot_index: Number of the sub-card, starting from 1 + * @cmd: Subcard information type, subcard name :2, subcard serial number :3, subcard hardware version number :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_info(unsigned int slot_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv; + char slot_buf[SLOT_SIZE]; + dfd_i2c_dev_t *i2c_dev; + const char *sysfs_name; + + if (buf == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "buf is NULL, slot index:%d, cmd:%d\n", slot_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + mem_clear(slot_buf, SLOT_SIZE); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_SLOT, slot_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "slot i2c dev config error, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + sysfs_name = dfd_get_slot_sysfs_name(); + rv = dfd_get_fru_board_data(i2c_dev->bus, i2c_dev->addr, cmd, slot_buf, SLOT_SIZE, sysfs_name); + + if (rv < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "slot eeprom read failed"); + return -DFD_RV_DEV_FAIL; + } + + DFD_SLOT_DEBUG(DBG_VERBOSE, "%s\n", slot_buf); + snprintf(buf, count, "%s\n", slot_buf); + return strlen(buf); +} + +ssize_t dfd_get_slot_power_status_str(unsigned int slot_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key_name: %s\r\n", + key_to_name(DFD_CFG_ITEM_POWER_STATUS)); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", status); +} + +int dfd_set_slot_power_status_str(unsigned int slot_index, int value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "set led status error, key_name: %s,ret:%d\r\n", + key_to_name(DFD_CFG_ITEM_POWER_STATUS), ret); + return ret; + } + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c new file mode 100644 index 000000000000..d938c118b086 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c @@ -0,0 +1,253 @@ +/* + * An wb_system_driver driver for system devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" +#include "wb_system_driver.h" +#include "switch_driver.h" + +#define NODE_MAX_LEN (64) + +int g_dfd_custom_dbg_level = 0; +module_param(g_dfd_custom_dbg_level, int, S_IRUGO | S_IWUSR); + +/* Get current function step number */ +int dfd_get_cmd_count(unsigned int type) +{ + uint64_t key; + int cmd_num; + int *p_cmd_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM, type, 0); + p_cmd_num = dfd_ko_cfg_get_item(key); + if (p_cmd_num == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number failed, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + cmd_num = *p_cmd_num; + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "get cmd number ok, type:0x%x, number:%d\n", type, cmd_num); + return cmd_num; +} + +void dfd_cmd_delay(unsigned int usdelay) +{ + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "usdelay:%d\n", usdelay); + usleep_range(usdelay, usdelay + 1); + return; +} + +ssize_t dfd_system_get_system_value(unsigned int type, int *value) +{ + uint64_t key; + int ret; + info_ctrl_t *info_ctrl; + int *p_decode_value; + + + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM, type, 0); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get info ctrl fail, key_name: %s, type=0x%x\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type); + return -DFD_RV_DEV_NOTSUPPORT; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "get, key_name: %s, type=0x%x\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get system value error, key_name: %s, type=0x%x, ret:%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type, ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SYSTEM_STATUS_DECODE, type, *value); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value == NULL) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "type:%d, status needn't decode. value:0x%x\n", type, *value); + } else { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "type:%d, ori_value:0x%x, decoded value:0x%x\n", type, *value, *p_decode_value); + *value = *p_decode_value; + } + return DFD_RV_OK; +} + +static int dfd_system_check_value_i(unsigned int type_detail, int cmd_i) +{ + uint64_t key; + int ret, i; + info_ctrl_t *info_ctrl; + int tmp_value, retry_times; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key=%s, type_detail=0x%x, cmd_i=%d, don't need to check value\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i); + return DFD_RV_OK; + } + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, start to check value,\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i); + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "check value, except value: %d, retry_times: %d, sleep_time: %dus\n", + info_ctrl->int_extra1, info_ctrl->int_extra2, info_ctrl->int_extra3); + + if (info_ctrl->int_extra2 <= 0) { + retry_times = 1; + } else { + retry_times = info_ctrl->int_extra2; + } + + for (i = 0; i < retry_times; i++) { + ret = dfd_info_get_int(key, &tmp_value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, get check value error, ret: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, ret); + return ret; + } + if (tmp_value == info_ctrl->int_extra1) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value ok, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + return DFD_RV_OK; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value failed, get value: %d, except value: %d, retry: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1, i + 1); + + if (info_ctrl->int_extra3 > 0) { + dfd_cmd_delay(info_ctrl->int_extra3); + } + } + + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value failed, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + return -DFD_RV_CHECK_FAIL; +} + +ssize_t dfd_system_set_system_value(unsigned int type, int value) +{ + uint64_t key; + int ret, cmd_i, cmd_count; + info_ctrl_t *info_ctrl; + unsigned int type_detail; + int tmp_value; + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "set system value, type=0x%x, value=%d\n", type, value); + /* get step number */ + type_detail = type | (value & 0xff); + ret = dfd_get_cmd_count(type_detail); + if(ret <= 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number, type_detail=0x%x\n", type_detail); + return -DFD_RV_DEV_NOTSUPPORT; + } + + cmd_count = ret; + /* exec each step */ + for(cmd_i = 0; cmd_i < cmd_count; cmd_i++) { + /* first do pre check */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, start to pre check\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i); + ret = dfd_info_get_int(key, &tmp_value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, get pre check value error, ret: %d\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, ret); + return ret; + } + if (tmp_value != info_ctrl->int_extra1) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, pre check error, get value: %d, except value: %d, skip this step\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + continue; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, pre check ok, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + } + /* get current step cfg */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get info ctrl fail, key_name=%s, type_detail=0x%x, cmd_i=%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "set, key_name=%s, type_detail=0x%x, cmd_i=%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i); + /* set int type info */ + ret = dfd_info_set_int(key, info_ctrl->int_cons); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value error, key_name=%s, type_detail=0x%x, cmd_i=%d, value=%d, ret:%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i, value, ret); + return ret; + } + + /* delay if it has */ + if(info_ctrl->int_extra1 > 0) { + dfd_cmd_delay(info_ctrl->int_extra1); + } + + /* check value */ + ret = dfd_system_check_value_i(type_detail, cmd_i); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value check value error, ret: %d\n", ret); + return ret; + } + } + + return DFD_RV_OK; +} + +ssize_t dfd_system_get_port_power_status(unsigned int type, char *buf, size_t count) +{ + int ret, cmd_i, cmd_count; + unsigned int type_detail; + + /* get step number */ + type_detail = type; + ret = dfd_get_cmd_count(type_detail); + if(ret <= 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number, type_detail=0x%x\n", type_detail); + return -DFD_RV_DEV_NOTSUPPORT; + } + + cmd_count = ret; + /* exec each step */ + for(cmd_i = 0; cmd_i < cmd_count; cmd_i++) { + /* check value */ + ret = dfd_system_check_value_i(type_detail, cmd_i); + if (ret < 0) { + if(ret == -DFD_RV_CHECK_FAIL) { + return (ssize_t)snprintf(buf, count, "%d\n", WB_PORT_POWER_ON); + } + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value check value error, ret: %d\n", ret); + return ret; + } + } + + return (ssize_t)snprintf(buf, count, "%d\n", WB_PORT_POWER_OFF); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c new file mode 100644 index 000000000000..a146b2e9a337 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c @@ -0,0 +1,217 @@ +/* + * An wb_watchdog_driver driver for watchdog devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +#define WDT_FILE_NAME_LEN (64) +#define WDT_ABSOLUTE_PATH_NAME_LEN (256) +#define WDT_SYSFS_FILE_DIR ("/sys/class/watchdog/watchdog%d/") + +typedef enum wb_wdt_enable_status_e { + WB_WDT_DISENABLE = 0, /* close watchdog */ + WB_WDT_ENABLE = 1, /* open watchdog */ +} wb_wdt_enable_status_t; + +struct wdt_file_enable_status_s { + wb_wdt_enable_status_t value; + char state[WDT_FILE_NAME_LEN]; +}; + +struct wdt_file_enable_status_s wdt_file_enable_status_match[] = { + {WB_WDT_DISENABLE, "inactive"}, + {WB_WDT_ENABLE, "active"}, +}; + +int g_dfd_watchdog_dbg_level = 0; +module_param(g_dfd_watchdog_dbg_level, int, S_IRUGO | S_IWUSR); + +static int watchdog_file_read(char *fpath, char *buf, int size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog can't open %s.\n", fpath); + filp = NULL; + ret = -ENOENT; + return ret; + } + + mem_clear(buf, size); + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + fpath, size -1, ret); + } + + filp_close(filp, NULL); + filp = NULL; + return ret; +} + +/** + * dfd_get_watchdog_id - Obtain watchdog Number + * @wdt_index: watchdwatchdog index number + + * return: Succeeded: The watchdog number is returned + * : Failed: A negative value is returned + */ +static int dfd_get_watchdog_id(unsigned int wdt_index) +{ + uint64_t key; + int *p_watchdog_id; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_ID, wdt_index, 0); + p_watchdog_id = dfd_ko_cfg_get_item(key); + if (p_watchdog_id == NULL) { + DFD_WDT_DEBUG(DBG_ERROR, "get watchdog id error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_ID)); + return -DFD_RV_DEV_NOTSUPPORT; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog id ok, watchdog index:%u, id:0x%x.\n", + wdt_index, *p_watchdog_id); + return *p_watchdog_id; +} + +static int watchdog_get_file_name(unsigned int wdt_index, wb_wdt_type_t type, char *buf, int len) +{ + uint64_t key; + char *watchdog_name; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_NAME, wdt_index, type); + watchdog_name = dfd_ko_cfg_get_item(key); + if (watchdog_name == NULL) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog name config error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog%u %s\n", wdt_index, watchdog_name); + snprintf(buf, len, "%s", watchdog_name); + return DFD_RV_OK; +} + +/** + * dfd_get_watchdog_info - Get watchdog information + * @type: Watchdog information type + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_watchdog_info(uint8_t type, char *buf, size_t count) +{ + char fpath[WDT_ABSOLUTE_PATH_NAME_LEN]; + int watchdog_id, len, ret; + + /* get watchdog sysfs name */ + watchdog_id = dfd_get_watchdog_id(0); + mem_clear(fpath, WDT_ABSOLUTE_PATH_NAME_LEN); + snprintf(fpath, WDT_ABSOLUTE_PATH_NAME_LEN - 1, WDT_SYSFS_FILE_DIR, watchdog_id); + len = strlen(fpath); + ret = watchdog_get_file_name(watchdog_id, type, &fpath[len], WDT_ABSOLUTE_PATH_NAME_LEN - len); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_WARN, "watchdog type[%u] don't support to get sysfs name.\n", type); + return -DFD_RV_DEV_NOTSUPPORT; + } + + ret = watchdog_file_read(fpath, buf, count - 1); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog read file %s error, ret: %d\n", fpath, ret); + } + + return ret; +} + +ssize_t dfd_watchdog_get_status(char *buf, size_t count) +{ + uint64_t key; + int watchdog_id, ret, value; + + watchdog_id = dfd_get_watchdog_id(0); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_DEV, watchdog_id, WB_WDT_TYPE_ENABLE); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "get watchdog enable status, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_DEV)); + return ret; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog enable status ok, watchdog index:%u, enable:0x%x.\n", + watchdog_id, value); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +ssize_t dfd_watchdog_set_status(int value) +{ + uint64_t key; + int watchdog_id, ret; + + watchdog_id = dfd_get_watchdog_id(0); + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_DEV, watchdog_id, WB_WDT_TYPE_ENABLE); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "set watchdog enable status, key: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_DEV)); + return ret; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "set watchdog enable status ok, watchdog index:%u, enable:0x%x.\n", + watchdog_id, value); + return 0; +} + +ssize_t dfd_watchdog_get_status_str(char *buf, size_t count) +{ + int ret, i; + int enable_status; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_STATE, buf, count); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog type[%d] get sysfs name failed.\n", WB_WDT_TYPE_STATE); + return -DFD_RV_DEV_FAIL; + } + + enable_status = -1; + for (i = 0; i < ARRAY_SIZE(wdt_file_enable_status_match); i++) { + if (strncmp(wdt_file_enable_status_match[i].state, buf, \ + strlen(wdt_file_enable_status_match[i].state)) == 0) { + enable_status = wdt_file_enable_status_match[i].value; + DFD_WDT_DEBUG(DBG_VERBOSE, "watchdog read state file %s match enable status[%d].\n", + buf, enable_status); + break; + } + } + + if (enable_status < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog read state file %s don't match enable status\n", buf); + return -DFD_RV_DEV_FAIL; + } + + return (ssize_t)snprintf(buf, count, "%d\n", enable_status); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile new file mode 100644 index 000000000000..197a0e6ff98f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile @@ -0,0 +1,34 @@ +PWD = $(shell pwd) + +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +DEV_SYSFS_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../sysfs_driver/include) +SWITCH_DVR_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../switch_driver/include) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -I$(DEV_SYSFS_HEADER_DIR) +EXTRA_CFLAGS+= -I$(SWITCH_DVR_HEADER_DIR) +EXTRA_CFLAGS+= -Wall + +s3ip_sysfs-objs := switch.o cpld_sysfs.o \ +curr_sensor_sysfs.o \ +fan_sysfs.o \ +fpga_sysfs.o \ +psu_sysfs.o \ +slot_sysfs.o \ +sysled_sysfs.o \ +temp_sensor_sysfs.o \ +transceiver_sysfs.o \ +vol_sensor_sysfs.o \ +watchdog_sysfs.o \ +system_sysfs.o \ +eeprom_sysfs.o \ + +obj-m := s3ip_sysfs.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c new file mode 100644 index 000000000000..d5b13e3a83f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c @@ -0,0 +1,444 @@ +/* + * An cpld_sysfs driver for cpld sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "cpld_sysfs.h" + +static int g_cpld_loglevel = 0; + +#define CPLD_REBOOT_CAUSE_FILE "/etc/.reboot/.previous-reboot-cause.txt" +#define REBOOT_CAUSE_NAME_LEN (64) + +/* Reboot cause type */ +typedef enum wb_reboot_cause_type_e { + REBOOT_CAUSE_NON_HARDWARE = 0, + REBOOT_CAUSE_POWER_LOSS, + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER, + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED, + REBOOT_CAUSE_WATCHDOG, + REBOOT_CAUSE_HARDWARE_OTHER, + REBOOT_CAUSE_CPU_COLD_RESET, + REBOOT_CAUSE_CPU_WARM_RESET, + REBOOT_CAUSE_BIOS_RESET, + REBOOT_CAUSE_PSU_SHUTDOWN, + REBOOT_CAUSE_BMC_SHUTDOWN, + REBOOT_CAUSE_RESET_BUTTON_SHUTDOWN, + REBOOT_CAUSE_RESET_BUTTON_COLD_SHUTDOWN, +} wb_reboot_cause_type_t; + +struct reboot_cause_file_info_s { + wb_reboot_cause_type_t reboot_cause_type; + char reboot_cause_name[REBOOT_CAUSE_NAME_LEN]; +}; + +struct reboot_cause_file_info_s reboot_cause_file_info_match[] = { + {REBOOT_CAUSE_POWER_LOSS, "Power Loss"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, "Watchdog reboot"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER, "BMC reboot"}, + {REBOOT_CAUSE_BMC_SHUTDOWN, "BMC powerdown"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, "Thermal Overload: ASIC"}, + {REBOOT_CAUSE_CPU_WARM_RESET, "Warm reboot"}, +}; + +#define CPLD_INFO(fmt, args...) do { \ + if (g_cpld_loglevel & INFO) { \ + printk(KERN_INFO "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_ERR(fmt, args...) do { \ + if (g_cpld_loglevel & ERR) { \ + printk(KERN_ERR "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_DBG(fmt, args...) do { \ + if (g_cpld_loglevel & DBG) { \ + printk(KERN_DEBUG "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct cpld_obj_s { + struct switch_obj *obj; +}; + +struct cpld_s { + unsigned int cpld_number; + struct cpld_obj_s *cpld; +}; + +static struct cpld_s g_cpld; +static struct switch_obj *g_cpld_obj = NULL; +static struct s3ip_sysfs_cpld_drivers_s *g_cpld_drv = NULL; + +static int cpld_file_read(char *fpath, char *buf, int size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + CPLD_ERR("can't open %s", fpath); + filp = NULL; + ret = -ENOENT; + goto fail; + } + mem_clear(buf, size); + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + CPLD_ERR("read file %s error, ret:%d\n", fpath, ret); + } +fail: + if (filp != NULL) { + filp_close(filp, NULL); + filp = NULL; + } + + return ret; +} + +static ssize_t cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_cpld.cpld_number); +} + +static ssize_t cpld_reboot_cause_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + char reboot_cause_buf[REBOOT_CAUSE_NAME_LEN]; + int ret, i; + char *point; + int reboot_cause_type; + + mem_clear(reboot_cause_buf, sizeof(reboot_cause_buf)); + ret = cpld_file_read(CPLD_REBOOT_CAUSE_FILE, reboot_cause_buf, REBOOT_CAUSE_NAME_LEN - 1); + if (ret < 0) { + CPLD_ERR("read file %s error, ret:%d\n", CPLD_REBOOT_CAUSE_FILE, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + + point = strchr(reboot_cause_buf, ','); + if (point != NULL) { + *point = 0; + } + CPLD_DBG("read reboot cause:%s\n", reboot_cause_buf); + + reboot_cause_type = 0; + for (i = 0; i < ARRAY_SIZE(reboot_cause_file_info_match); i++) { + if (strncmp(reboot_cause_file_info_match[i].reboot_cause_name, reboot_cause_buf, \ + strlen(reboot_cause_file_info_match[i].reboot_cause_name)) == 0) { + reboot_cause_type = reboot_cause_file_info_match[i].reboot_cause_type; + CPLD_DBG("reboot cause %s match type[%d].\n", reboot_cause_file_info_match[i].reboot_cause_name, reboot_cause_type); + break; + } + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", reboot_cause_type); +} + +static ssize_t cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_alias); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_alias(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_type); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_type(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_firmware_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_firmware_version(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_board_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_board_version(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_test_reg); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_test_reg(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int cpld_index, value; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->set_main_board_cpld_test_reg); + + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_cpld_drv->set_main_board_cpld_test_reg(cpld_index, value); + if (ret < 0) { + CPLD_ERR("set cpld%u test reg failed, value:0x%x, ret: %d.\n", cpld_index, value, ret); + return ret; + } + CPLD_DBG("set cpld%u test reg success, value: 0x%x.\n", cpld_index, value); + return count; +} + +/************************************cpld dir and attrs*******************************************/ +static struct switch_attribute cpld_number_att = __ATTR(number, S_IRUGO, cpld_number_show, NULL); +static struct switch_attribute cpld_reboot_cause_att = __ATTR(reboot_cause, S_IRUGO, cpld_reboot_cause_show, NULL); + +static struct attribute *cpld_dir_attrs[] = { + &cpld_number_att.attr, + &cpld_reboot_cause_att.attr, + NULL, +}; + +static struct attribute_group cpld_root_attr_group = { + .attrs = cpld_dir_attrs, +}; + +/*******************************cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute cpld_alias_attr = __ATTR(alias, S_IRUGO, cpld_alias_show, NULL); +static struct switch_attribute cpld_type_attr = __ATTR(type, S_IRUGO, cpld_type_show, NULL); +static struct switch_attribute cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, cpld_fw_version_show, NULL); +static struct switch_attribute cpld_board_version_attr = __ATTR(board_version, S_IRUGO, cpld_board_version_show, NULL); +static struct switch_attribute cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, cpld_test_reg_show, cpld_test_reg_store); + +static struct attribute *cpld_attrs[] = { + &cpld_alias_attr.attr, + &cpld_type_attr.attr, + &cpld_fw_version_attr.attr, + &cpld_board_version_attr.attr, + &cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group cpld_attr_group = { + .attrs = cpld_attrs, +}; + +static int cpld_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + CPLD_DBG("delete cpld%u dir and attrs success.\n", index); + } + + return 0; +} + +static int cpld_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", index); + curr_cpld->obj = switch_kobject_create(name, parent); + if (!curr_cpld->obj) { + CPLD_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_cpld->obj->index = index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &cpld_attr_group) != 0) { + CPLD_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + CPLD_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int cpld_sub_create_kobj_and_attrs(struct kobject *parent, int cpld_num) +{ + unsigned int cpld_index, i; + + g_cpld.cpld = kzalloc(sizeof(struct cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!g_cpld.cpld) { + CPLD_ERR("kzalloc g_cpld.cpld error, cpld number = %d.\n", cpld_num); + return -ENOMEM; + } + + for (cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if (cpld_sub_single_create_kobj_and_attrs(parent, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = cpld_index; i > 0; i--) { + cpld_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + return -EBADRQC; +} + +/* create cpld[1-n] directory and attributes*/ +static int cpld_sub_create(void) +{ + int ret; + + ret = cpld_sub_create_kobj_and_attrs(&g_cpld_obj->kobj, g_cpld.cpld_number); + return ret; +} + +/* delete cpld[1-n] directory and attributes*/ +static void cpld_sub_remove(void) +{ + unsigned int cpld_index; + + if (g_cpld.cpld) { + for (cpld_index = g_cpld.cpld_number; cpld_index > 0; cpld_index--) { + cpld_sub_single_remove_kobj_and_attrs(cpld_index); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + } + g_cpld.cpld_number = 0; + return; +} + +/* create cpld directory and number attributes */ +static int cpld_root_create(void) +{ + g_cpld_obj = switch_kobject_create("cpld", NULL); + if (!g_cpld_obj) { + CPLD_ERR("switch_kobject_create cpld error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_cpld_obj->kobj, &cpld_root_attr_group) != 0) { + switch_kobject_delete(&g_cpld_obj); + CPLD_ERR("create cpld dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete cpld directory and number attributes */ +static void cpld_root_remove(void) +{ + if (g_cpld_obj) { + sysfs_remove_group(&g_cpld_obj->kobj, &cpld_root_attr_group); + switch_kobject_delete(&g_cpld_obj); + } + + return; +} + +int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv) +{ + int ret, cpld_num; + + CPLD_INFO("s3ip_sysfs_cpld_drivers_register...\n"); + if (g_cpld_drv) { + CPLD_ERR("g_cpld_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_cpld_number); + g_cpld_drv = drv; + + cpld_num = g_cpld_drv->get_main_board_cpld_number(); + if (cpld_num <= 0) { + CPLD_ERR("cpld number: %d, don't need to create cpld dirs and attrs.\n", cpld_num); + g_cpld_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_cpld, sizeof(struct cpld_s)); + g_cpld.cpld_number = cpld_num; + ret = cpld_root_create(); + if (ret < 0) { + CPLD_ERR("create cpld root dir and attrs failed, ret: %d\n", ret); + g_cpld_drv = NULL; + return ret; + } + ret = cpld_sub_create(); + if (ret < 0) { + CPLD_ERR("create cpld sub dir and attrs failed, ret: %d\n", ret); + cpld_root_remove(); + g_cpld_drv = NULL; + return ret; + } + CPLD_INFO("s3ip_sysfs_cpld_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_cpld_drivers_unregister(void) +{ + if (g_cpld_drv) { + cpld_sub_remove(); + cpld_root_remove(); + g_cpld_drv = NULL; + CPLD_DBG("s3ip_sysfs_cpld_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_unregister); +module_param(g_cpld_loglevel, int, 0644); +MODULE_PARM_DESC(g_cpld_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c new file mode 100644 index 000000000000..3d2e86382ef1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c @@ -0,0 +1,385 @@ +/* + * An curr_sensor_sysfs driver for current sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "curr_sensor_sysfs.h" + +static int g_curr_sensor_loglevel = 0; + +#define CURR_SENSOR_INFO(fmt, args...) do { \ + if (g_curr_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_ERR(fmt, args...) do { \ + if (g_curr_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_DBG(fmt, args...) do { \ + if (g_curr_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct curr_sensor_obj_s { + struct switch_obj *obj; +}; + +struct curr_sensor_s { + unsigned int curr_number; + struct curr_sensor_obj_s *curr; +}; + +static struct s3ip_sysfs_curr_sensor_drivers_s *g_curr_sensor_drv = NULL; +static struct curr_sensor_s g_curr_sensor; +static struct switch_obj *g_curr_sensor_obj = NULL; + +static ssize_t curr_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_curr_sensor.curr_number); +} + +static ssize_t curr_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_value); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_value(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_alias); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_alias(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_type); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_type(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_max(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_max(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return ret; + } + CURR_SENSOR_DBG("set curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +static ssize_t curr_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_min(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_min(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return ret; + } + CURR_SENSOR_DBG("set curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +static ssize_t curr_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_monitor_flag); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_monitor_flag(curr_index, buf, PAGE_SIZE); +} +/************************************curr_sensor dir and attrs*******************************************/ +static struct switch_attribute num_curr_att = __ATTR(number, S_IRUGO, curr_sensor_number_show, NULL); + +static struct attribute *curr_sensor_dir_attrs[] = { + &num_curr_att.attr, + NULL, +}; + +static struct attribute_group curr_sensor_root_attr_group = { + .attrs = curr_sensor_dir_attrs, +}; + +/*******************************curr1 curr2 dir and attrs*******************************************/ +static struct switch_attribute curr_value_attr = __ATTR(value, S_IRUGO, curr_sensor_value_show, NULL); +static struct switch_attribute curr_alias_attr = __ATTR(alias, S_IRUGO, curr_sensor_alias_show, NULL); +static struct switch_attribute curr_type_attr = __ATTR(type, S_IRUGO, curr_sensor_type_show, NULL); +static struct switch_attribute curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, curr_sensor_max_show, curr_sensor_max_store); +static struct switch_attribute curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, curr_sensor_min_show, curr_sensor_min_store); +static struct switch_attribute curr_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, curr_sensor_monitor_flag_show, NULL); + +static struct attribute *curr_sensor_attrs[] = { + &curr_value_attr.attr, + &curr_alias_attr.attr, + &curr_type_attr.attr, + &curr_max_attr.attr, + &curr_min_attr.attr, + &curr_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group curr_sensor_attr_group = { + .attrs = curr_sensor_attrs, +}; + +static int curr_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "curr%u", index); + curr_sensor->obj = switch_kobject_create(name, parent); + if (!curr_sensor->obj) { + CURR_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group) != 0) { + CURR_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + CURR_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void curr_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + if (curr_sensor->obj) { + sysfs_remove_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group); + switch_kobject_delete(&curr_sensor->obj); + CURR_SENSOR_DBG("delete curr%u dir and attrs success.\n", index); + } + + return; +} + +static int curr_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int curr_num) +{ + unsigned int curr_index, i; + + g_curr_sensor.curr = kzalloc(sizeof(struct curr_sensor_obj_s) * curr_num, GFP_KERNEL); + if (!g_curr_sensor.curr) { + CURR_SENSOR_ERR("kzalloc g_curr_sensor.curr error, curr number: %d.\n", curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (curr_sensor_sub_single_create_kobj_and_attrs(parent, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + curr_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + return -EBADRQC; +} + +/* create curr[1-n] directory and attributes*/ +static int curr_sensor_sub_create(void) +{ + int ret; + + ret = curr_sensor_sub_create_kobj_and_attrs(&g_curr_sensor_obj->kobj, + g_curr_sensor.curr_number); + return ret; +} + +/* delete curr[1-n] directory and attributes*/ +static void curr_sensor_sub_remove(void) +{ + unsigned int curr_index; + + if (g_curr_sensor.curr) { + for (curr_index = g_curr_sensor.curr_number; curr_index > 0; curr_index--) { + curr_sensor_sub_single_remove_kobj_and_attrs(curr_index); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + } + g_curr_sensor.curr_number = 0; + return; +} + +/* create curr_sensor directory and number attributes */ +static int curr_sensor_root_create(void) +{ + g_curr_sensor_obj = switch_kobject_create("curr_sensor", NULL); + if (!g_curr_sensor_obj) { + CURR_SENSOR_ERR("switch_kobject_create curr_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_curr_sensor_obj); + CURR_SENSOR_ERR("create curr_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete curr_sensor directory and number attributes */ +static void curr_sensor_root_remove(void) +{ + if (g_curr_sensor_obj) { + sysfs_remove_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group); + switch_kobject_delete(&g_curr_sensor_obj); + } + + return; +} + +int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv) +{ + int ret, curr_num; + + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register...\n"); + if (g_curr_sensor_drv) { + CURR_SENSOR_ERR("g_curr_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_curr_number); + g_curr_sensor_drv = drv; + + curr_num = g_curr_sensor_drv->get_main_board_curr_number(); + if (curr_num <= 0) { + CURR_SENSOR_ERR("curr sensor number: %d, don't need to create curr_sensor dirs and attrs.\n", + curr_num); + g_curr_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_curr_sensor, sizeof(struct curr_sensor_s)); + g_curr_sensor.curr_number = curr_num; + ret = curr_sensor_root_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor root dir and attrs failed, ret: %d\n", ret); + g_curr_sensor_drv = NULL; + return ret; + } + + ret = curr_sensor_sub_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor sub dir and attrs failed, ret: %d\n", ret); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + return ret; + } + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_curr_sensor_drivers_unregister(void) +{ + if (g_curr_sensor_drv) { + curr_sensor_sub_remove(); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + CURR_SENSOR_DBG("s3ip_sysfs_curr_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_unregister); +module_param(g_curr_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_curr_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c new file mode 100644 index 000000000000..920cbf0bb824 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c @@ -0,0 +1,417 @@ +/* + * An eeprom_sysfs driver for eeprom sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "eeprom_sysfs.h" + +static int g_eeprom_loglevel = 0; + +#define EEPROM_INFO(fmt, args...) do { \ + if (g_eeprom_loglevel & INFO) { \ + printk(KERN_INFO "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define EEPROM_ERR(fmt, args...) do { \ + if (g_eeprom_loglevel & ERR) { \ + printk(KERN_ERR "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define EEPROM_DBG(fmt, args...) do { \ + if (g_eeprom_loglevel & DBG) { \ + printk(KERN_DEBUG "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_obj_s { + struct switch_obj *eeprom_obj; + struct bin_attribute bin; + int eeprom_creat_bin_flag; +}; + +struct eeprom_s { + unsigned int eeprom_number; + struct eeprom_obj_s *eeprom; +}; + +static struct eeprom_s g_eeprom; +static struct switch_obj *g_eeprom_obj = NULL; +static struct s3ip_sysfs_eeprom_drivers_s *g_eeprom_drv = NULL; + +static ssize_t eeprom_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_eeprom.eeprom_number); +} + +static ssize_t eeprom_size_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + struct eeprom_obj_s *curr_eeprom; + + EEPROM_DBG("get eeprom size, eeprom index: %u\n", obj->index); + curr_eeprom = &g_eeprom.eeprom[obj->index - 1]; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%ld\n", curr_eeprom->bin.size); +} + +static ssize_t eeprom_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_alias); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom alias, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_alias(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_tag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_tag); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom tag, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_tag(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_type); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom type, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_type(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eeprom_obj; + ssize_t rd_len; + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->read_eeprom_data); + + eeprom_obj = to_switch_obj(kobj); + eeprom_index = eeprom_obj->index; + mem_clear(buf, count); + rd_len = g_eeprom_drv->read_eeprom_data(eeprom_index, buf, offset, count); + if (rd_len < 0) { + EEPROM_ERR("read eeprom%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eeprom_index, offset, count, rd_len); + return rd_len; + } + + EEPROM_DBG("read eeprom%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + eeprom_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t eeprom_eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eeprom_obj; + ssize_t wr_len; + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->write_eeprom_data); + + eeprom_obj = to_switch_obj(kobj); + eeprom_index = eeprom_obj->index; + wr_len = g_eeprom_drv->write_eeprom_data(eeprom_index, buf, offset, count); + if (wr_len < 0) { + EEPROM_ERR("write eeprom%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eeprom_index, offset, count, wr_len); + return wr_len; + } + + EEPROM_DBG("write eeprom%u eeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + eeprom_index, offset, count, wr_len); + + return wr_len; +} + +/************************************eeprom* signal attrs*******************************************/ +static struct switch_attribute eeprom_alias_attr = __ATTR(alias, S_IRUGO | S_IWUSR, eeprom_alias_show, NULL); +static struct switch_attribute eeprom_tag_attr = __ATTR(tag, S_IRUGO | S_IWUSR, eeprom_tag_show, NULL); +static struct switch_attribute eeprom_size_attr = __ATTR(size, S_IRUGO, eeprom_size_show, NULL); +static struct switch_attribute eeprom_type_attr = __ATTR(type, S_IRUGO | S_IWUSR, eeprom_type_show, NULL); + +static struct attribute *eeprom_signal_attrs[] = { + &eeprom_alias_attr.attr, + &eeprom_tag_attr.attr, + &eeprom_size_attr.attr, + &eeprom_type_attr.attr, + NULL, +}; + +static struct attribute_group eeprom_signal_attr_group = { + .attrs = eeprom_signal_attrs, +}; + +/*******************************eeprom dir and attrs*******************************************/ +static struct switch_attribute eeprom_number_attr = __ATTR(number, S_IRUGO, eeprom_number_show, NULL); + +static struct attribute *eeprom_dir_attrs[] = { + &eeprom_number_attr.attr, + NULL, +}; + +static struct attribute_group eeprom_eeprom_attr_group = { + .attrs = eeprom_dir_attrs, +}; + +/* create eeprom* eeprom attributes */ +static int eeprom_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct eeprom_obj_s *curr_eeprom; + + check_p(g_eeprom_drv->get_eeprom_size); + eeprom_size = g_eeprom_drv->get_eeprom_size(index); + if (eeprom_size <= 0) { + EEPROM_ERR("Invalid eeprom size, eeprom index: %u, eeprom_size: %d\n", + index, eeprom_size); + return -EINVAL; + } + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + sysfs_bin_attr_init(&curr_eeprom->bin); + curr_eeprom->bin.attr.name = "data"; + curr_eeprom->bin.attr.mode = 0644; + curr_eeprom->bin.read = eeprom_eeprom_read; + curr_eeprom->bin.write = eeprom_eeprom_write; + curr_eeprom->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_eeprom->eeprom_obj->kobj, &curr_eeprom->bin); + if (ret) { + EEPROM_ERR("eeprom%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + EEPROM_DBG("eeprom%u, create bin file success, eeprom size: %d.\n", index, eeprom_size); + curr_eeprom->eeprom_creat_bin_flag = 1; + return 0; +} + +static int eeprom_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct eeprom_obj_s *curr_eeprom; + char eeprom_dir_name[DIR_NAME_MAX_LEN]; + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + mem_clear(eeprom_dir_name, sizeof(eeprom_dir_name)); + snprintf(eeprom_dir_name, sizeof(eeprom_dir_name), "eeprom%d", index); + curr_eeprom->eeprom_obj = switch_kobject_create(eeprom_dir_name, parent); + if (!curr_eeprom->eeprom_obj) { + EEPROM_ERR("create eeprom%d object error! \n", index); + return -EBADRQC; + } + curr_eeprom->eeprom_obj->index = index; + if (sysfs_create_group(&curr_eeprom->eeprom_obj->kobj, &eeprom_signal_attr_group) != 0) { + switch_kobject_delete(&curr_eeprom->eeprom_obj); + return -EBADRQC; + } + + EEPROM_DBG("create eeprom%d dir and attrs success\n", index); + return 0; +} + +/* remove eeprom directory and attributes */ +static void eeprom_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct eeprom_obj_s *curr_eeprom; + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + if (curr_eeprom->eeprom_obj) { + if (curr_eeprom->eeprom_creat_bin_flag) { + sysfs_remove_bin_file(&curr_eeprom->eeprom_obj->kobj, &curr_eeprom->bin); + curr_eeprom->eeprom_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_eeprom->eeprom_obj->kobj, &eeprom_signal_attr_group); + switch_kobject_delete(&curr_eeprom->eeprom_obj); + } + + return; +} + +static int eeprom_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = eeprom_sub_single_create_kobj(parent, index); + if (ret < 0) { + EEPROM_ERR("create eeprom%d dir error.\n", index); + return ret; + } + + ret = eeprom_sub_single_create_eeprom_attrs(index); + if (ret < 0) { + eeprom_sub_single_remove_kobj_and_attrs(index); + EEPROM_ERR("create eeprom%d data error.\n", index); + return ret; + } + return 0; +} + +static int eeprom_sub_create_kobj_and_attrs(struct kobject *parent, int eeprom_num) +{ + unsigned int eeprom_index, i; + + g_eeprom.eeprom = kzalloc(sizeof(struct eeprom_obj_s) * eeprom_num, GFP_KERNEL); + if (!g_eeprom.eeprom) { + EEPROM_ERR("kzalloc g_eeprom.eeprom error, eeprom number = %d.\n", eeprom_num); + return -ENOMEM; + } + + for (eeprom_index = 1; eeprom_index <= eeprom_num; eeprom_index++) { + if (eeprom_sub_single_create_kobj_and_attrs(parent, eeprom_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = eeprom_index; i > 0; i--) { + eeprom_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_eeprom.eeprom); + g_eeprom.eeprom = NULL; + return -EBADRQC; +} + +/* create eeprom directory and attributes */ +static int eeprom_sub_create(void) +{ + int ret; + + ret = eeprom_sub_create_kobj_and_attrs(&g_eeprom_obj->kobj, g_eeprom.eeprom_number); + return ret; +} + +/* delete eeprom directory and attributes */ +static void eeprom_sub_remove(void) +{ + unsigned int eeprom_index; + + if (g_eeprom.eeprom) { + for (eeprom_index = g_eeprom.eeprom_number; eeprom_index > 0; eeprom_index--) { + eeprom_sub_single_remove_kobj_and_attrs(eeprom_index); + } + kfree(g_eeprom.eeprom); + g_eeprom.eeprom = NULL; + } + g_eeprom.eeprom_number = 0; + return; +} + +/* create eeprom directory and attributes */ +static int eeprom_eeprom_create(void) +{ + g_eeprom_obj = switch_kobject_create("eeprom", NULL); + if (!g_eeprom_obj) { + EEPROM_ERR("switch_kobject_create eeprom error!\n"); + return -ENOMEM; + } + g_eeprom_obj->index = 0; + if (sysfs_create_group(&g_eeprom_obj->kobj, &eeprom_eeprom_attr_group) != 0) { + switch_kobject_delete(&g_eeprom_obj); + EEPROM_ERR("create eeprom dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete eeprom directory and attributes */ +static void eeprom_eeprom_remove(void) +{ + if (g_eeprom_obj) { + sysfs_remove_group(&g_eeprom_obj->kobj, &eeprom_eeprom_attr_group); + switch_kobject_delete(&g_eeprom_obj); + } + + return; +} + +int s3ip_sysfs_eeprom_drivers_register(struct s3ip_sysfs_eeprom_drivers_s *drv) +{ + int ret, eeprom_num; + + EEPROM_INFO("s3ip_sysfs_eeprom_drivers_register...\n"); + if (g_eeprom_drv) { + EEPROM_ERR("g_eeprom_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_eeprom_number); + g_eeprom_drv = drv; + + eeprom_num = g_eeprom_drv->get_eeprom_number(); + if (eeprom_num <= 0) { + EEPROM_ERR("eeprom number: %d, don't need to create eeprom dirs and attrs.\n", eeprom_num); + g_eeprom_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_eeprom, sizeof(struct eeprom_s)); + g_eeprom.eeprom_number = eeprom_num; + ret = eeprom_eeprom_create(); + if (ret < 0) { + EEPROM_ERR("create eeprom root dir and attrs failed, ret: %d\n", ret); + g_eeprom_drv = NULL; + return ret; + } + ret = eeprom_sub_create(); + if (ret < 0) { + EEPROM_ERR("create eeprom sub dir and attrs failed, ret: %d\n", ret); + eeprom_eeprom_remove(); + g_eeprom_drv = NULL; + return ret; + } + EEPROM_INFO("s3ip_sysfs_eeprom_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_eeprom_drivers_unregister(void) +{ + if (g_eeprom_drv) { + eeprom_sub_remove(); + eeprom_eeprom_remove(); + g_eeprom_drv = NULL; + EEPROM_DBG("s3ip_sysfs_eeprom_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_eeprom_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_eeprom_drivers_unregister); +module_param(g_eeprom_loglevel, int, 0644); +MODULE_PARM_DESC(g_eeprom_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c new file mode 100644 index 000000000000..e1b9b56d3ab5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c @@ -0,0 +1,777 @@ +/* + * An fan_sysfs driver for fan sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "fan_sysfs.h" + +static int g_fan_loglevel = 0; +static bool g_fan_status_debug = 0; + +#define FAN_INFO(fmt, args...) do { \ + if (g_fan_loglevel & INFO) { \ + printk(KERN_INFO "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_ERR(fmt, args...) do { \ + if (g_fan_loglevel & ERR) { \ + printk(KERN_ERR "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_DBG(fmt, args...) do { \ + if (g_fan_loglevel & DBG) { \ + printk(KERN_DEBUG "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct motor_obj_s { + struct switch_obj *obj; +}; + +struct fan_obj_s { + unsigned int motor_number; + struct motor_obj_s *motor; + struct switch_obj *obj; +}; + +struct fan_s { + unsigned int fan_number; + struct fan_obj_s *fan; +}; + +static struct fan_s g_fan; +static struct switch_obj *g_fan_obj = NULL; +static struct s3ip_sysfs_fan_drivers_s *g_fan_drv = NULL; + +static ssize_t fan_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan_number); +} + +static ssize_t fan_motor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + FAN_DBG("fan_motor_number_show, fan index: %u\n", index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fan.fan[index - 1].motor_number); +} + +static ssize_t fan_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_model_name); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_model_name(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_vendor); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_vendor(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_serial_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_serial_number(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_part_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_part_number(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_hardware_version); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_hardware_version(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_status(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u status failed, ret: %d\n", fan_index, ret); + return ret; + } + + if (g_fan_status_debug) { + FAN_INFO("s3ip sysfs fan status debug is enable\n"); + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + FAN_DBG("fan%d status sysfs unsupport or error\n", fan_index); + return ret; + } + + if (strcmp(buf, FAN_ABSENT_STR) == 0) { + FAN_DBG("fan%d absent, return act value\n", fan_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_FAN_STATUS_DEBUG_FILE, fan_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + FAN_ERR("fan%u status debug file read failed, ret: %d\n", fan_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, FAN_ABSENT_STR) == 0) || (strcmp(debug_file_buf, FAN_OK_STR) == 0) || (strcmp(debug_file_buf, FAN_NOTOK_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + FAN_ERR("fan%d status debug file value err, value: %s, not 0 1 or 2\n", fan_index, debug_file_buf); + return ret; + } + } + return ret; +} + +static ssize_t fan_present_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_present); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_present(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_led_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_led_status(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int fan_index; + int ret, led_status; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_led_status); + + fan_index = obj->index; + ret = kstrtoint(buf, 0, &led_status); + if (ret != 0) { + FAN_ERR("invaild fan led status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + FAN_DBG("fan index: %u, led_status: %d\n", fan_index, led_status); + ret = g_fan_drv->set_fan_led_status(fan_index, led_status); + if (ret < 0) { + FAN_ERR("set fan%u led_status: %d failed, ret: %d\n", fan_index, led_status, ret); + return ret; + } + FAN_DBG("set fan%u led_status: %d success\n", fan_index, led_status); + return count; +} + +static ssize_t fan_motor_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_status); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_status(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_tolerance_show(struct switch_obj *obj, + struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_tolerance); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_tolerance(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_target_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_target); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_target(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_max_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_max); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_max(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_min_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_min); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_min(fan_index, motor_index, buf, PAGE_SIZE); +} + +ssize_t fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_ratio); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_ratio(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fan_index; + int ret, ratio; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_ratio); + + fan_index = obj->index; + + ret = kstrtoint(buf, 0, &ratio); + if (ret != 0) { + FAN_ERR("invaild fan ratio ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + + if (ratio < 0 || ratio > 100) { + FAN_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + FAN_DBG("fan index: %u, ratio: %d\n", fan_index, ratio); + ret = g_fan_drv->set_fan_ratio(fan_index, ratio); + if (ret < 0) { + FAN_ERR("set fan%u ratio: %d failed, ret: %d\n", fan_index, ratio, ret); + return ret; + } + FAN_DBG("set fan%u, ratio: %d success\n", fan_index, ratio); + return count; +} + +ssize_t fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_direction); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_direction(fan_index, buf, PAGE_SIZE); +} + +/************************************fan dir and attrs*******************************************/ +static struct switch_attribute fan_number_att = __ATTR(number, S_IRUGO, fan_number_show, NULL); + +static struct attribute *fan_dir_attrs[] = { + &fan_number_att.attr, + NULL, +}; + +static struct attribute_group fan_root_attr_group = { + .attrs = fan_dir_attrs, +}; + +/*******************************fan1 fan2 dir and attrs*******************************************/ +static struct switch_attribute fan_model_name_attr = __ATTR(model_name, S_IRUGO, fan_model_name_show, NULL); +static struct switch_attribute fan_vendor_attr = __ATTR(vendor, S_IRUGO, fan_vendor_show, NULL); +static struct switch_attribute fan_sn_attr = __ATTR(serial_number, S_IRUGO, fan_sn_show, NULL); +static struct switch_attribute fan_pn_attr = __ATTR(part_number, S_IRUGO, fan_pn_show, NULL); +static struct switch_attribute fan_hw_attr = __ATTR(hardware_version, S_IRUGO, fan_hw_show, NULL); +static struct switch_attribute fan_num_motors_attr = __ATTR(motor_number, S_IRUGO, fan_motor_number_show, NULL); +static struct switch_attribute fan_status_attr = __ATTR(status, S_IRUGO, fan_status_show, NULL); +static struct switch_attribute fan_present_attr = __ATTR(present, S_IRUGO, fan_present_show, NULL); +static struct switch_attribute fan_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, fan_led_status_show, fan_led_status_store); +static struct switch_attribute fan_direction_attr = __ATTR(direction, S_IRUGO, fan_direction_show, NULL); +static struct switch_attribute fan_ratio_attr = __ATTR(ratio, S_IRUGO | S_IWUSR, fan_ratio_show, fan_ratio_store); + +static struct attribute *fan_attrs[] = { + &fan_model_name_attr.attr, + &fan_vendor_attr.attr, + &fan_sn_attr.attr, + &fan_pn_attr.attr, + &fan_hw_attr.attr, + &fan_num_motors_attr.attr, + &fan_status_attr.attr, + &fan_present_attr.attr, + &fan_led_status_attr.attr, + &fan_direction_attr.attr, + &fan_ratio_attr.attr, + NULL, +}; + +static struct attribute_group fan_attr_group = { + .attrs = fan_attrs, +}; + +/*******************************motor1 motor2 dir and attrs*******************************************/ +static struct switch_attribute motor_status_attr = __ATTR(status, S_IRUGO, fan_motor_status_show, NULL); +static struct switch_attribute motor_speed_attr = __ATTR(speed, S_IRUGO, fan_motor_speed_show, NULL); +static struct switch_attribute motor_speed_tolerance_attr = __ATTR(speed_tolerance, S_IRUGO, fan_motor_speed_tolerance_show, NULL); +static struct switch_attribute motor_speed_target_attr = __ATTR(speed_target, S_IRUGO, fan_motor_speed_target_show, NULL); +static struct switch_attribute motor_speed_max_attr = __ATTR(speed_max, S_IRUGO, fan_motor_speed_max_show, NULL); +static struct switch_attribute motor_speed_min_attr = __ATTR(speed_min, S_IRUGO, fan_motor_speed_min_show, NULL); + +static struct attribute *motor_attrs[] = { + &motor_status_attr.attr, + &motor_speed_attr.attr, + &motor_speed_tolerance_attr.attr, + &motor_speed_target_attr.attr, + &motor_speed_max_attr.attr, + &motor_speed_min_attr.attr, + NULL, +}; + +static struct attribute_group motor_attr_group = { + .attrs = motor_attrs, +}; + +static void fanindex_single_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + if (curr_motor->obj) { + sysfs_remove_group(&curr_motor->obj->kobj, &motor_attr_group); + switch_kobject_delete(&curr_motor->obj); + FAN_DBG("delete fan%u motor%u dir and attrs success.\n", curr_fan->obj->index, + motor_index); + } + return; +} + +static int fanindex_single_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + char name[8]; + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "motor%u", motor_index); + curr_motor->obj = switch_kobject_create(name, &curr_fan->obj->kobj); + if (!curr_motor->obj) { + FAN_ERR("create fan%u, motor%u object error!\n", curr_fan->obj->index, motor_index); + return -ENOMEM; + } + + curr_motor->obj->index = motor_index; + if (sysfs_create_group(&curr_motor->obj->kobj, &motor_attr_group) != 0) { + FAN_ERR("create fan%u, motor%u attrs error.\n", curr_fan->obj->index, motor_index); + switch_kobject_delete(&curr_motor->obj); + return -EBADRQC; + } + FAN_DBG("create fan%u, motor%u dir and attrs success.\n", curr_fan->obj->index, motor_index); + return 0; +} + +/* create motor[1-n] directory and attributes in fan directory */ +static int fanindex_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, i, motor_num; + + motor_num = curr_fan->motor_number; + curr_fan->motor = kzalloc(sizeof(struct motor_obj_s) * motor_num, GFP_KERNEL); + if (!curr_fan->motor) { + FAN_ERR("kzalloc motor error, fan index: %u, motor number: %d.\n", + curr_fan->obj->index, motor_num); + return -ENOMEM; + } + for (motor_index = 1; motor_index <= motor_num; motor_index++) { + if (fanindex_single_motor_create_kobj_and_attrs(curr_fan, motor_index) != 0) { + goto motor_error; + } + } + return 0; +motor_error: + for (i = motor_index; i > 0; i--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, i); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes in fan directory */ +static void fanindex_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, motor_num; + + if (curr_fan->motor) { + motor_num = curr_fan->motor_number; + for (motor_index = motor_num; motor_index > 0; motor_index--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, motor_index); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + } + + return; +} + +/* create motor[1-n] directory and attributes */ +static int fan_motor_create(void) +{ + int fan_num, motor_num; + unsigned int fan_index, i; + struct fan_obj_s *curr_fan; /* point to fan1 fan2...*/ + + fan_num = g_fan.fan_number; + if (fan_num <= 0) { + FAN_DBG("fan number: %d, skip to create motor* dirs and attrs.\n", fan_num); + return 0; + } + + check_p(g_fan_drv->get_fan_motor_number); + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + motor_num = g_fan_drv->get_fan_motor_number(fan_index); + if (motor_num <= 0) { + FAN_DBG("fan%u motor number: %d, don't need to create motor* dirs and attrs.\n", + fan_index, motor_num); + continue; + } + curr_fan = &g_fan.fan[fan_index - 1]; + curr_fan->motor_number = motor_num; + if (fanindex_motor_create_kobj_and_attrs(curr_fan) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index; i > 0; i--) { + curr_fan = &g_fan.fan[i - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + } + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes */ +static void fan_motor_remove(void) +{ + unsigned int fan_index; + struct fan_obj_s *curr_fan; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + curr_fan = &g_fan.fan[fan_index - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + curr_fan->motor_number = 0; + } + } + return; +} + +static int fan_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + if (curr_fan->obj) { + sysfs_remove_group(&curr_fan->obj->kobj, &fan_attr_group); + switch_kobject_delete(&curr_fan->obj); + FAN_DBG("delete fan%u dir and attrs success.\n", index); + } + return 0; +} + +static int fan_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fan%u", index); + curr_fan->obj = switch_kobject_create(name, parent); + if (!curr_fan->obj) { + FAN_ERR("create %s object error!\n", name); + return -ENOMEM; + } + + curr_fan->obj->index = index; + if (sysfs_create_group(&curr_fan->obj->kobj, &fan_attr_group) != 0) { + FAN_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fan->obj); + return -EBADRQC; + } + FAN_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +/* create fan[1-n] directory and attributes */ +static int fan_sub_create_kobj_and_attrs(struct kobject *parent, int fan_num) +{ + unsigned int fan_index, i; + + g_fan.fan = kzalloc(sizeof(struct fan_obj_s) * fan_num, GFP_KERNEL); + if (!g_fan.fan) { + FAN_ERR("kzalloc fan.fan error, fan number: %d.\n", fan_num); + return -ENOMEM; + } + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + if (fan_sub_single_create_kobj_and_attrs(parent, fan_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index; i > 0; i--) { + fan_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + return -EBADRQC; +} + +static int fan_sub_create(void) +{ + int ret; + + ret = fan_sub_create_kobj_and_attrs(&g_fan_obj->kobj, g_fan.fan_number); + return ret; +} + +/* delete fan[1-n] directory and attributes */ +static void fan_sub_remove(void) +{ + unsigned int fan_index; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + fan_sub_single_remove_kobj_and_attrs(fan_index); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + } + g_fan.fan_number = 0; + + return; +} + +/* create fan directory and number attributes */ +static int fan_root_create(void) +{ + g_fan_obj = switch_kobject_create("fan", NULL); + if (!g_fan_obj) { + FAN_ERR("switch_kobject_create fan error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fan_obj->kobj, &fan_root_attr_group) != 0) { + switch_kobject_delete(&g_fan_obj); + FAN_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fan directory and number attributes */ +static void fan_root_remove(void) +{ + if (g_fan_obj) { + sysfs_remove_group(&g_fan_obj->kobj, &fan_root_attr_group); + switch_kobject_delete(&g_fan_obj); + FAN_DBG("delete fan dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv) +{ + int ret, fan_num; + + FAN_INFO("s3ip_sysfs_fan_drivers_register...\n"); + if (g_fan_drv) { + FAN_ERR("g_fan_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_fan_number); + g_fan_drv = drv; + + fan_num = g_fan_drv->get_fan_number(); + if (fan_num <= 0) { + FAN_ERR("fan number: %d, don't need to create fan dirs and attrs.\n", fan_num); + g_fan_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_fan, sizeof(struct fan_s)); + g_fan.fan_number = fan_num; + ret = fan_root_create(); + if (ret < 0) { + FAN_ERR("create fan root dir and attrs failed, ret: %d\n", ret); + g_fan_drv = NULL; + return ret; + } + + ret = fan_sub_create(); + if (ret < 0) { + FAN_ERR("create fan sub dir and attrs failed, ret: %d\n", ret); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + + ret = fan_motor_create(); + if (ret < 0) { + FAN_ERR("create fan motor dir and attrs failed, ret: %d\n", ret); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + FAN_INFO("s3ip_sysfs_fan_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_fan_drivers_unregister(void) +{ + if (g_fan_drv) { + fan_motor_remove(); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + FAN_DBG("s3ip_sysfs_fan_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_unregister); +module_param(g_fan_loglevel, int, 0644); +MODULE_PARM_DESC(g_fan_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_fan_status_debug, bool, 0644); +MODULE_PARM_DESC(g_fan_status_debug, "the fan present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c new file mode 100644 index 000000000000..d0ec8dfc62f7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c @@ -0,0 +1,345 @@ +/* + * An fpga_sysfs driver for fpga sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "fpga_sysfs.h" + +static int g_fpga_loglevel = 0; + +#define FPGA_INFO(fmt, args...) do { \ + if (g_fpga_loglevel & INFO) { \ + printk(KERN_INFO "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_ERR(fmt, args...) do { \ + if (g_fpga_loglevel & ERR) { \ + printk(KERN_ERR "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_DBG(fmt, args...) do { \ + if (g_fpga_loglevel & DBG) { \ + printk(KERN_DEBUG "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct fpga_obj_s { + struct switch_obj *obj; +}; + +struct fpga_s { + unsigned int fpga_number; + struct fpga_obj_s *fpga; +}; + +static struct fpga_s g_fpga; +static struct switch_obj *g_fpga_obj = NULL; +static struct s3ip_sysfs_fpga_drivers_s *g_fpga_drv = NULL; + +static ssize_t fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fpga.fpga_number); +} + +static ssize_t fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_alias); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_alias(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_type); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_type(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_firmware_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_firmware_version(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_board_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_board_version(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_test_reg); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_test_reg(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fpga_index, value; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->set_main_board_fpga_test_reg); + + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_fpga_drv->set_main_board_fpga_test_reg(fpga_index, value); + if (ret < 0) { + FPGA_ERR("set fpga%u test reg failed, value:0x%x, ret: %d.\n", fpga_index, value, ret); + return ret; + } + FPGA_DBG("set fpga%u test reg success, value: 0x%x.\n", fpga_index, value); + return count; +} + +/************************************fpga dir and attrs*******************************************/ +static struct switch_attribute fpga_number_att = __ATTR(number, S_IRUGO, fpga_number_show, NULL); + +static struct attribute *fpga_dir_attrs[] = { + &fpga_number_att.attr, + NULL, +}; + +static struct attribute_group fpga_root_attr_group = { + .attrs = fpga_dir_attrs, +}; + +/*******************************fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute fpga_alias_attr = __ATTR(alias, S_IRUGO, fpga_alias_show, NULL); +static struct switch_attribute fpga_type_attr = __ATTR(type, S_IRUGO, fpga_type_show, NULL); +static struct switch_attribute fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, fpga_fw_version_show, NULL); +static struct switch_attribute fpga_board_version_attr = __ATTR(board_version, S_IRUGO, fpga_board_version_show, NULL); +static struct switch_attribute fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, fpga_test_reg_show, fpga_test_reg_store); + +static struct attribute *fpga_attrs[] = { + &fpga_alias_attr.attr, + &fpga_type_attr.attr, + &fpga_fw_version_attr.attr, + &fpga_board_version_attr.attr, + &fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group fpga_attr_group = { + .attrs = fpga_attrs, +}; + +static int fpga_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + FPGA_DBG("delete fpga%u dir and attrs success.\n", index); + } + return 0; +} + +static int fpga_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", index); + curr_fpga->obj = switch_kobject_create(name, parent); + if (!curr_fpga->obj) { + FPGA_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_fpga->obj->index = index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &fpga_attr_group) != 0) { + FPGA_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + FPGA_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int fpga_sub_create_kobj_and_attrs(struct kobject *parent, int fpga_num) +{ + unsigned int fpga_index, i; + + g_fpga.fpga = kzalloc(sizeof(struct fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!g_fpga.fpga) { + FPGA_ERR("kzalloc g_fpga.fpga error, fpga number = %d.\n", fpga_num); + return -ENOMEM; + } + + for (fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if (fpga_sub_single_create_kobj_and_attrs(parent, fpga_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fpga_index; i > 0; i--) { + fpga_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + return -EBADRQC; +} + +/* create fpga[1-n] directory and attributes*/ +static int fpga_sub_create(void) +{ + int ret; + + ret = fpga_sub_create_kobj_and_attrs(&g_fpga_obj->kobj, g_fpga.fpga_number); + return ret; +} + +/* delete fpga[1-n] directory and attributes*/ +static void fpga_sub_remove(void) +{ + unsigned int fpga_index; + + if (g_fpga.fpga) { + for (fpga_index = g_fpga.fpga_number; fpga_index > 0; fpga_index--) { + fpga_sub_single_remove_kobj_and_attrs(fpga_index); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + } + g_fpga.fpga_number = 0; + return; +} + +/* create fpga directory and number attributes */ +static int fpga_root_create(void) +{ + g_fpga_obj = switch_kobject_create("fpga", NULL); + if (!g_fpga_obj) { + FPGA_ERR("switch_kobject_create fpga error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fpga_obj->kobj, &fpga_root_attr_group) != 0) { + switch_kobject_delete(&g_fpga_obj); + FPGA_ERR("create fpga dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fpga directory and number attributes */ +static void fpga_root_remove(void) +{ + if (g_fpga_obj) { + sysfs_remove_group(&g_fpga_obj->kobj, &fpga_root_attr_group); + switch_kobject_delete(&g_fpga_obj); + } + + return; +} + +int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv) +{ + int ret, fpga_num; + + FPGA_INFO("s3ip_sysfs_fpga_drivers_register...\n"); + if (g_fpga_drv) { + FPGA_ERR("g_fpga_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_fpga_number); + g_fpga_drv = drv; + + fpga_num = g_fpga_drv->get_main_board_fpga_number(); + if (fpga_num <= 0) { + FPGA_ERR("fpga number: %d, don't need to create fpga dirs and attrs.\n", fpga_num); + g_fpga_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_fpga, sizeof(struct fpga_s)); + g_fpga.fpga_number = fpga_num; + ret = fpga_root_create(); + if (ret < 0) { + FPGA_ERR("create fpga root dir and attrs failed, ret: %d\n", ret); + g_fpga_drv = NULL; + return ret; + } + ret = fpga_sub_create(); + if (ret < 0) { + FPGA_ERR("create fpga sub dir and attrs failed, ret: %d\n", ret); + fpga_root_remove(); + g_fpga_drv = NULL; + return ret; + } + FPGA_INFO("s3ip_sysfs_fpga_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_fpga_drivers_unregister(void) +{ + if (g_fpga_drv) { + fpga_sub_remove(); + fpga_root_remove(); + g_fpga_drv = NULL; + FPGA_DBG("s3ip_sysfs_fpga_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_unregister); +module_param(g_fpga_loglevel, int, 0644); +MODULE_PARM_DESC(g_fpga_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h new file mode 100644 index 000000000000..2638b18c6f4c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for cpld_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _CPLD_SYSFS_H_ +#define _CPLD_SYSFS_H_ + +struct s3ip_sysfs_cpld_drivers_s { + int (*get_main_board_cpld_number)(void); + ssize_t (*get_main_board_cpld_alias)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_type)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_firmware_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_board_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_test_reg)(unsigned int cpld_index, char *buf, size_t count); + int (*set_main_board_cpld_test_reg)(unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv); +extern void s3ip_sysfs_cpld_drivers_unregister(void); +#endif /*_CPLD_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h new file mode 100644 index 000000000000..fc9bb4948a14 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h @@ -0,0 +1,38 @@ +/* + * A header definition for curr_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _CURR_SENSOR_SYSFS_H_ +#define _CURR_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_curr_sensor_drivers_s { + int (*get_main_board_curr_number)(void); + ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_monitor_flag)(unsigned int curr_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv); +extern void s3ip_sysfs_curr_sensor_drivers_unregister(void); +#endif /*_CURR_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h new file mode 100644 index 000000000000..5ebb79afdc9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for eeprom_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _EEPROM_SYSFS_H_ +#define _EEPROM_SYSFS_H_ + +struct s3ip_sysfs_eeprom_drivers_s { + int (*get_eeprom_number)(void); + ssize_t (*get_eeprom_alias)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_tag)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_type)(unsigned int e2_index, char *buf, size_t count); + int (*get_eeprom_size)(unsigned int e2_index); + ssize_t (*read_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_eeprom_drivers_register(struct s3ip_sysfs_eeprom_drivers_s *drv); +extern void s3ip_sysfs_eeprom_drivers_unregister(void); +#endif /*_EEPROM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h new file mode 100644 index 000000000000..f89afabd86bd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h @@ -0,0 +1,53 @@ +/* + * A header definition for fan_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _FAN_SYSFS_H_ +#define _FAN_SYSFS_H_ + +struct s3ip_sysfs_fan_drivers_s { + int (*get_fan_number)(void); + int (*get_fan_motor_number)(unsigned int fan_index); + ssize_t (*get_fan_model_name)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_vendor)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_serial_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_part_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_hardware_version)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_status)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_present)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_led_status)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_led_status)(unsigned int fan_index, int status); + ssize_t (*get_fan_direction)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_motor_status)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_tolerance)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_target)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_max)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_min)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_ratio)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_ratio)(unsigned int fan_index, int ratio); +}; + +extern int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv); +extern void s3ip_sysfs_fan_drivers_unregister(void); +#define SINGLE_FAN_STATUS_DEBUG_FILE "/etc/sonic/.status_fan_%d" +#define FAN_ABSENT_STR "0\n" +#define FAN_OK_STR "1\n" +#define FAN_NOTOK_STR "2\n" +#endif /*_FAN_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h new file mode 100644 index 000000000000..5335a5b0fa4c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for fpga_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _FPGA_SYSFS_H_ +#define _FPGA_SYSFS_H_ + +struct s3ip_sysfs_fpga_drivers_s { + int (*get_main_board_fpga_number)(void); + ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_type)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_firmware_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_board_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_test_reg)(unsigned int fpga_index, char *buf, size_t count); + int (*set_main_board_fpga_test_reg)(unsigned int fpga_index, unsigned int value); +}; + +extern int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv); +extern void s3ip_sysfs_fpga_drivers_unregister(void); +#endif /*_FPGA_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h new file mode 100644 index 000000000000..c89de1cea6a2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h @@ -0,0 +1,73 @@ +/* + * A header definition for psu_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _PSU_SYSFS_H_ +#define _PSU_SYSFS_H_ + +struct s3ip_sysfs_psu_drivers_s { + int (*get_psu_number)(void); + int (*get_psu_temp_number)(unsigned int psu_index); + ssize_t (*get_psu_model_name)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_vendor)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_date)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hw_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_alarm)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_serial_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_part_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hardware_version)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_type)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_max_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_present_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status_pmbus)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_ratio)(unsigned int psu_index, char *buf, size_t count); + int (*set_psu_fan_ratio)(unsigned int psu_index, int ratio); + ssize_t (*get_psu_fan_direction)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_led_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed_cal)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_temp_alias)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_type)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_value)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_attr_threshold)(unsigned int psu_index, unsigned int type, char *buf, size_t count); + int (*get_psu_eeprom_size)(unsigned int psu_index); + ssize_t (*read_psu_eeprom_data)(unsigned int psu_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_psu_blackbox_info)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_pmbus_info)(unsigned int psu_index, char *buf, size_t count); + int (*clear_psu_blackbox)(unsigned int psu_index, uint8_t value); +}; + +extern int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv); +extern void s3ip_sysfs_psu_drivers_unregister(void); +#define SINGLE_PSU_PRESENT_DEBUG_FILE "/etc/sonic/.present_psu_%d" + +#endif /*_PSU_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h new file mode 100644 index 000000000000..e5cba548f224 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h @@ -0,0 +1,80 @@ +/* + * A header definition for slot_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SLOT_SYSFS_H_ +#define _SLOT_SYSFS_H_ + +struct s3ip_sysfs_slot_drivers_s { + int (*get_slot_number)(void); + int (*get_slot_temp_number)(unsigned int slot_index); + int (*get_slot_vol_number)(unsigned int slot_index); + int (*get_slot_curr_number)(unsigned int slot_index); + int (*get_slot_cpld_number)(unsigned int slot_index); + int (*get_slot_fpga_number)(unsigned int slot_index); + ssize_t (*get_slot_model_name)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_vendor)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_serial_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_part_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_hardware_version)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_status)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_led_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_led_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_power_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_power_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_temp_alias)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_type)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_value)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_vol_alias)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_type)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_range)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_nominal_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_curr_alias)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_type)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_value)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_alias)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_type)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_firmware_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_board_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + int (*set_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, unsigned int value); + ssize_t (*get_slot_cpld_alias)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_type)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_firmware_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_board_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + int (*set_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv); +extern void s3ip_sysfs_slot_drivers_unregister(void); +#endif /*_SLOT_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h new file mode 100644 index 000000000000..2f7e1ef2f8a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h @@ -0,0 +1,96 @@ +/* + * A header definition for switch driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SWITCH_H_ +#define _SWITCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "switch_driver.h" +#include "wb_module.h" + +#define DIR_NAME_MAX_LEN (64) +#define DEBUG_FILE_SIZE (64) +#define DEV_PRESEN_STR "1\n" +#define DEV_ABSENT_STR "0\n" +#define mem_clear(data, size) memset((data), 0, (size)) + +enum LOG_LEVEL { + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +extern int g_switch_loglevel; + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_switch_loglevel & ERR) { \ + printk(KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -WB_SYSFS_RV_UNSUPPORT; \ + } \ +} while (0) + +#define check_p(p) check_pfun(p) + +#define to_switch_obj(x) container_of(x, struct switch_obj, kobj) +#define to_switch_attr(x) container_of(x, struct switch_attribute, attr) +#define to_switch_device_attr(x) container_of(x, struct switch_device_attribute, switch_attr) + +#define SWITCH_ATTR(_name, _mode, _show, _store, _type) \ + { .switch_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type } + +#define SWITCH_DEVICE_ATTR(_name, _mode, _show, _store, _type) \ +struct switch_device_attribute switch_dev_attr_##_name \ + = SWITCH_ATTR(_name, _mode, _show, _store, _type) + +struct switch_obj { + struct kobject kobj; + unsigned int index; +}; + +/* a custom attribute that works just for a struct switch_obj. */ +struct switch_attribute { + struct attribute attr; + ssize_t (*show)(struct switch_obj *foo, struct switch_attribute *attr, char *buf); + ssize_t (*store)(struct switch_obj *foo, struct switch_attribute *attr, const char *buf, size_t count); +}; + +struct switch_device_attribute { + struct switch_attribute switch_attr; + int type; +}; + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent); +void switch_kobject_delete(struct switch_obj **obj); +int dev_debug_file_read(char *file_name, unsigned int dev_index, char *buf, int size); + +#endif /* _SWITCH_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h new file mode 100644 index 000000000000..7ce272ad6112 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h @@ -0,0 +1,32 @@ +/* + * A header definition for syseeprom_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SYSEEPROM_SYSFS_H_ +#define _SYSEEPROM_SYSFS_H_ + +struct s3ip_sysfs_syseeprom_drivers_s { + int (*get_syseeprom_size)(void); + ssize_t (*read_syseeprom_data)(char *buf, loff_t offset, size_t count); + ssize_t (*write_syseeprom_data)(char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv); +extern void s3ip_sysfs_syseeprom_drivers_unregister(void); +#endif /*_SYSEEPROM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h new file mode 100644 index 000000000000..5eaf3af7057e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h @@ -0,0 +1,39 @@ +/* + * A header definition for sysled_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SYSLED_SYSFS_H_ +#define _SYSLED_SYSFS_H_ + +struct s3ip_sysfs_sysled_drivers_s { + ssize_t (*get_sys_led_status)(char *buf, size_t count); + int (*set_sys_led_status)(int status); + ssize_t (*get_bmc_led_status)(char *buf, size_t count); + int (*set_bmc_led_status)(int status); + ssize_t (*get_sys_fan_led_status)(char *buf, size_t count); + int (*set_sys_fan_led_status)(int status); + ssize_t (*get_sys_psu_led_status)(char *buf, size_t count); + int (*set_sys_psu_led_status)(int status); + ssize_t (*get_id_led_status)(char *buf, size_t count); + int (*set_id_led_status)(int status); +}; + +extern int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv); +extern void s3ip_sysfs_sysled_drivers_unregister(void); +#endif /*_SYSLED_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h new file mode 100644 index 000000000000..a5edf5e107b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h @@ -0,0 +1,54 @@ +/* + * A header definition for system_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _SYSTEM_SYSFS_H_ +#define _SYSTEM_SYSFS_H_ + +struct s3ip_sysfs_system_drivers_s { + ssize_t (*get_system_value)(unsigned int type, int *value, char *buf, size_t count); + ssize_t (*set_system_value)(unsigned int type, int value); + ssize_t (*get_system_port_power_status)(unsigned int type, char *buf, size_t count); +}; + +extern int s3ip_sysfs_system_drivers_register(struct s3ip_sysfs_system_drivers_s *drv); +extern void s3ip_sysfs_system_drivers_unregister(void); + +/* system api type */ +typedef enum wb_plat_system_type_e { + WB_SYSTEM_BMC_READY = 0x0000, /* bmc ready */ + WB_SYSTEM_SOL_ACTIVE = 0x0100, /* sol active */ + WB_SYSTEM_PSU_RESET = 0x0200, /* psu reset */ + WB_SYSTEM_CPU_BOARD_CTRL = 0x0300, /* cpu board control */ + WB_SYSTEM_CPU_BOARD_STATUS = 0x0400, /* cpu board status */ + WB_SYSTEM_BIOS_UPGRADE = 0x0500, /* bios upgrade */ + WB_SYSTEM_BIOS_SWITCH = 0x0600, /* bios switch */ + WB_SYSTEM_BIOS_VIEW = 0x0700, /* bios flash view */ + WB_SYSTEM_BIOS_BOOT_OK = 0x0800, /* bios boot status */ + WB_SYSTEM_BIOS_FAIL_RECORD = 0x0900, /* bios startup failure record */ + WB_SYSTEM_BMC_RESET = 0x0a00, /* bmc reset */ + WB_SYSTEM_MAC_BOARD_RESET = 0x0b00, /* mac board reset */ + WB_SYSTEM_MAC_PWR_CTRL = 0x0c00, /* mac power on/off */ + WB_SYSTEM_EMMC_PWR_CTRL = 0x0d00, /* emmc power on/off */ + WB_SYSTEM_PORT_PWR_CTL = 0x0e00, /* power power on/off*/ + WB_SYSTEM_BMC_VIEW = 0x0f00, /* bmc view */ + WB_SYSTEM_BMC_SWITCH = 0x1000, /* bmc switch */ +} wb_plat_system_type_t; + +#endif /*_SYSTEM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h new file mode 100644 index 000000000000..dc6138388b34 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h @@ -0,0 +1,42 @@ +/* + * A header definition for temp_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _TEMP_SENSOR_SYSFS_H_ +#define _TEMP_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_temp_sensor_drivers_s { + int (*get_main_board_temp_number)(void); + ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_high)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_high)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_low)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_low)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_monitor_flag)(unsigned int temp_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv); +extern void s3ip_sysfs_temp_sensor_drivers_unregister(void); +#endif /*_TEMP_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h new file mode 100644 index 000000000000..a4fcb485d37a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h @@ -0,0 +1,50 @@ +/* + * A header definition for transceiver_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _TRANSCEIVER_SYSFS_H_ +#define _TRANSCEIVER_SYSFS_H_ + +struct s3ip_sysfs_transceiver_drivers_s { + int (*get_eth_number)(void); + ssize_t (*get_transceiver_power_on_status)(char *buf, size_t count); + int (*set_transceiver_power_on_status)(int status); + ssize_t (*get_transceiver_present_status)(char *buf, size_t count); + ssize_t (*get_eth_power_on_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_power_on_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_tx_fault_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_tx_disable_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_tx_disable_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_present_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_rx_los_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_reset_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_reset_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_low_power_mode_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_interrupt_status)(unsigned int eth_index, char *buf, size_t count); + int (*get_eth_eeprom_size)(unsigned int eth_index); + ssize_t (*read_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_eth_optoe_type)(unsigned int sff_index, int *optoe_type, char *buf, size_t count); + ssize_t (*set_eth_optoe_type)(unsigned int sff_index, int optoe_type); +}; + +extern int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv); +extern void s3ip_sysfs_sff_drivers_unregister(void); +#define SINGLE_TRANSCEIVER_PRESENT_DEBUG_FILE "/etc/sonic/.present_eth_%d" +#endif /*_TRANSCEIVER_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h new file mode 100644 index 000000000000..f13d4a2057e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h @@ -0,0 +1,40 @@ +/* + * A header definition for vol_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _VOL_SENSOR_SYSFS_H_ +#define _VOL_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_vol_sensor_drivers_s { + int (*get_main_board_vol_number)(void); + ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_monitor_flag)(unsigned int vol_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv); +extern void s3ip_sysfs_vol_sensor_drivers_unregister(void); +#endif /*_VOL_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h new file mode 100644 index 000000000000..ac9e7666aee8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for watchdog_sysfs driver + * + * Copyright (C) 2024 Micas 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 + * 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 _WATCHDOG_SYSFS_H_ +#define _WATCHDOG_SYSFS_H_ + +struct s3ip_sysfs_watchdog_drivers_s { + ssize_t (*get_watchdog_identify)(char *buf, size_t count); + ssize_t (*get_watchdog_timeleft)(char *buf, size_t count); + ssize_t (*get_watchdog_timeout)(char *buf, size_t count); + int (*set_watchdog_timeout)(int value); + ssize_t (*get_watchdog_enable_status)(char *buf, size_t count); + int (*set_watchdog_enable_status)(int value); + int (*set_watchdog_reset)(int value); +}; + +extern int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv); +extern void s3ip_sysfs_watchdog_drivers_unregister(void); +#endif /*_WATCHDOG_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c new file mode 100644 index 000000000000..ecb6ca30e6d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c @@ -0,0 +1,1180 @@ +/* + * An psu_sysfs driver for psu sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "psu_sysfs.h" + +static int g_psu_loglevel = 0; +static bool g_psu_present_debug = 0; + +#define PSU_INFO(fmt, args...) do { \ + if (g_psu_loglevel & INFO) { \ + printk(KERN_INFO "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_ERR(fmt, args...) do { \ + if (g_psu_loglevel & ERR) { \ + printk(KERN_ERR "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_DBG(fmt, args...) do { \ + if (g_psu_loglevel & DBG) { \ + printk(KERN_DEBUG "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_obj_s { + struct switch_obj *obj; +}; + +struct psu_obj_s { + unsigned int temp_number; + struct temp_obj_s *temp; + struct switch_obj *obj; + struct bin_attribute bin; + int psu_creat_bin_flag; +}; + +struct psu_s { + unsigned int psu_number; + struct psu_obj_s *psu; +}; + +static struct psu_s g_psu; +static struct switch_obj *g_psu_obj = NULL; +static struct s3ip_sysfs_psu_drivers_s *g_psu_drv = NULL; + +static ssize_t psu_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_psu.psu_number); +} + +static ssize_t psu_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + PSU_DBG("psu index: %u\n",index); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_psu.psu[index - 1].temp_number); +} + +static ssize_t psu_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_model_name); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_model_name(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_vendor); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_vendor(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_date_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_date); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_date(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_hardware_version); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_hardware_version(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_serial_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_serial_number(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_part_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_part_number(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_type); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_type(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_curr(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_vol(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_curr(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_vol(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_max_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_max_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_max_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_present_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_present_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u present status failed, ret: %d\n", psu_index, ret); + return ret; + } + + if (g_psu_present_debug) { + PSU_INFO("s3ip sysfs psu present debug is enable\n"); + if (strcmp(buf, DEV_ABSENT_STR) == 0) { + PSU_DBG("psu%d absent, return act value\n", psu_index); + return ret; + } + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + PSU_DBG("psu%d status sysfs unsupport or error\n", psu_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_PSU_PRESENT_DEBUG_FILE, psu_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + PSU_ERR("psu%u present debug file read failed, ret: %d\n", psu_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, DEV_PRESEN_STR) == 0) || (strcmp(debug_file_buf, DEV_ABSENT_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + PSU_ERR("psu%d present debug file value err, value: %s, not 0 or 1\n", psu_index, debug_file_buf); + return ret; + } + } + + return ret; +} + +static ssize_t get_psu_status_pmbus_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_status_pmbus); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_status_pmbus(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_hw_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_hw_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_hw_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_alarm_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_alarm); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_alarm(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_speed_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_speed); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_speed(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_speed_cal_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_speed_cal); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_speed_cal(psu_index, buf, PAGE_SIZE); +} + +ssize_t psu_fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_ratio); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_ratio(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index; + int ret, ratio; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_fan_ratio); + + psu_index = obj->index; + ret = kstrtoint(buf, 0, &ratio); + if (ret != 0) { + PSU_ERR("invaild psu fan ratio ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + if (ratio < 0 || ratio > 100) { + PSU_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + PSU_DBG("psu index: %u, ratio: %d\n", psu_index, ratio); + ret = g_psu_drv->set_psu_fan_ratio(psu_index, ratio); + if (ret < 0) { + PSU_ERR("set psu%u ratio: %d failed, ret: %d\n", + psu_index, ratio, ret); + return ret; + } + PSU_DBG("set psu%u, ratio: %d success\n", psu_index, ratio); + return count; +} + +static ssize_t psu_fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_direction); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_direction(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_led_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_led_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_value(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_alias(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_type(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_max(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_max(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return ret; + } + PSU_DBG("set psu%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t psu_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_min(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_min(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return ret; + } + PSU_DBG("set psu%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t psu_attr_threshold_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + struct switch_device_attribute *tmp_attr; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_attr_threshold); + + psu_index = obj->index; + tmp_attr = to_switch_device_attr(attr); + check_p(tmp_attr); + return g_psu_drv->get_psu_attr_threshold(psu_index, tmp_attr->type, buf, PAGE_SIZE); +} + +static ssize_t psu_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *psu_obj; + ssize_t rd_len; + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->read_psu_eeprom_data); + + psu_obj = to_switch_obj(kobj); + psu_index = psu_obj->index; + mem_clear(buf, count); + rd_len = g_psu_drv->read_psu_eeprom_data(psu_index, buf, offset, count); + if (rd_len < 0) { + PSU_ERR("read psu%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + psu_index, offset, count, rd_len); + return rd_len; + } + + PSU_DBG("read psu%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + psu_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t psu_blackbox_info_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_blackbox_info); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_blackbox_info(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_pmbus_info_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_pmbus_info); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_pmbus_info(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_clear_blackbox_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index; + int ret; + uint8_t vaule; + + check_p(g_psu_drv); + check_p(g_psu_drv->clear_psu_blackbox); + + psu_index = obj->index; + ret = kstrtou8(buf, 0, &vaule); + if (ret != 0) { + PSU_ERR("Invaild value ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + if (vaule != 1) { + PSU_ERR("Invaild value: %u, only support write 1 to clear psu blackbox information\n", vaule); + return -EINVAL; + } + PSU_DBG("psu index: %u, clear psu blackbox information\n", psu_index); + ret = g_psu_drv->clear_psu_blackbox(psu_index, vaule); + if (ret < 0) { + PSU_ERR("clear psu%u blackbox information failed, ret: %d\n", + psu_index, ret); + return ret; + } + PSU_DBG("clear psu%u blackbox information success\n", psu_index); + return count; +} + +/************************************psu dir and attrs*******************************************/ +static struct switch_attribute psu_number_att = __ATTR(number, S_IRUGO, psu_number_show, NULL); + +static struct attribute *psu_dir_attrs[] = { + &psu_number_att.attr, + NULL, +}; + +static struct attribute_group psu_root_attr_group = { + .attrs = psu_dir_attrs, +}; + +/*******************************psu[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_model_name_attr = __ATTR(model_name, S_IRUGO, psu_model_name_show, NULL); +static struct switch_attribute psu_vendor_attr = __ATTR(vendor, S_IRUGO, psu_vendor_show, NULL); +static struct switch_attribute psu_date_attr = __ATTR(date, S_IRUGO, psu_date_show, NULL); +static struct switch_attribute psu_hw_attr = __ATTR(hardware_version, S_IRUGO, psu_hw_show, NULL); +static struct switch_attribute psu_sn_attr = __ATTR(serial_number, S_IRUGO, psu_sn_show, NULL); +static struct switch_attribute psu_pn_attr = __ATTR(part_number, S_IRUGO, psu_pn_show, NULL); +static struct switch_attribute psu_type_attr = __ATTR(type, S_IRUGO, psu_type_show, NULL); +static struct switch_attribute psu_in_curr_attr = __ATTR(in_curr, S_IRUGO, psu_in_curr_show, NULL); +static struct switch_attribute psu_in_vol_attr = __ATTR(in_vol, S_IRUGO, psu_in_vol_show, NULL); +static struct switch_attribute psu_in_power_attr = __ATTR(in_power, S_IRUGO, psu_in_power_show, NULL); +static struct switch_attribute psu_out_curr_attr = __ATTR(out_curr, S_IRUGO, psu_out_curr_show, NULL); +static struct switch_attribute psu_out_vol_attr = __ATTR(out_vol, S_IRUGO, psu_out_vol_show, NULL); +static struct switch_attribute psu_out_power_attr = __ATTR(out_power, S_IRUGO, psu_out_power_show, NULL); +static struct switch_attribute psu_out_max_power_attr = __ATTR(out_max_power, S_IRUGO, psu_out_max_power_show, NULL); +static struct switch_attribute psu_num_temps_attr = __ATTR(num_temp_sensors, S_IRUGO, psu_temp_number_show, NULL); +static struct switch_attribute psu_present_attr = __ATTR(present, S_IRUGO, psu_present_status_show, NULL); +static struct switch_attribute status_fr_pmbus_attr = __ATTR(status_fr_pmbus, S_IRUGO, get_psu_status_pmbus_show, NULL); +static struct switch_attribute psu_status_attr = __ATTR(status, S_IRUGO, get_psu_status_show, NULL); +static struct switch_attribute psu_hw_status_attr = __ATTR(hw_status, S_IRUGO, get_psu_hw_status_show, NULL); +static struct switch_attribute psu_alarm_attr = __ATTR(alarm, S_IRUGO, get_psu_alarm_show, NULL); +static struct switch_attribute psu_out_status_attr = __ATTR(out_status, S_IRUGO, psu_out_status_show, NULL); +static struct switch_attribute psu_in_status_attr = __ATTR(in_status, S_IRUGO, psu_in_status_show, NULL); +static struct switch_attribute psu_fan_speed_attr = __ATTR(fan_speed, S_IRUGO, psu_fan_speed_show, NULL); +static struct switch_attribute psu_fan_ratio_attr = __ATTR(fan_ratio, S_IRUGO | S_IWUSR, psu_fan_ratio_show, psu_fan_ratio_store); +static struct switch_attribute psu_fan_direction_attr = __ATTR(fan_direction, S_IRUGO, psu_fan_direction_show, NULL); +static struct switch_attribute psu_led_status_attr = __ATTR(led_status, S_IRUGO, psu_led_status_show, NULL); +static struct switch_attribute psu_fan_speed_cal_attr = __ATTR(fan_speed_cal, S_IRUGO, psu_fan_speed_cal_show, NULL); +static struct switch_attribute psu_blackbox_info_attr = __ATTR(blackbox_info, S_IRUGO, psu_blackbox_info_show, NULL); +static struct switch_attribute psu_pmbus_info_attr = __ATTR(pmbus_info, S_IRUGO, psu_pmbus_info_show, NULL); +static struct switch_attribute psu_clear_blackbox_attr = __ATTR(clear_blackbox, S_IWUSR, NULL, psu_clear_blackbox_store); +static SWITCH_DEVICE_ATTR(in_vol_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_VOL_MAX); +static SWITCH_DEVICE_ATTR(in_vol_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_VOL_MIN); +static SWITCH_DEVICE_ATTR(in_curr_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_CURR_MAX); +static SWITCH_DEVICE_ATTR(in_curr_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_CURR_MIN); +static SWITCH_DEVICE_ATTR(in_power_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_POWER_MAX); +static SWITCH_DEVICE_ATTR(in_power_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_POWER_MIN); +static SWITCH_DEVICE_ATTR(out_vol_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_VOL_MAX); +static SWITCH_DEVICE_ATTR(out_vol_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_VOL_MIN); +static SWITCH_DEVICE_ATTR(out_curr_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_CURR_MAX); +static SWITCH_DEVICE_ATTR(out_curr_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_CURR_MIN); +static SWITCH_DEVICE_ATTR(out_power_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_POWER_MAX); +static SWITCH_DEVICE_ATTR(out_power_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_POWER_MIN); +static SWITCH_DEVICE_ATTR(fan_speed_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_FAN_SPEED_MAX); +static SWITCH_DEVICE_ATTR(fan_speed_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_FAN_SPEED_MIN); + +static struct attribute *psu_attrs[] = { + &psu_model_name_attr.attr, + &psu_vendor_attr.attr, + &psu_date_attr.attr, + &psu_hw_attr.attr, + &psu_sn_attr.attr, + &psu_pn_attr.attr, + &psu_type_attr.attr, + &psu_in_curr_attr.attr, + &psu_in_vol_attr.attr, + &psu_in_power_attr.attr, + &psu_out_curr_attr.attr, + &psu_out_vol_attr.attr, + &psu_out_power_attr.attr, + &psu_out_max_power_attr.attr, + &psu_num_temps_attr.attr, + &psu_present_attr.attr, + &status_fr_pmbus_attr.attr, + &psu_status_attr.attr, + &psu_hw_status_attr.attr, + &psu_alarm_attr.attr, + &psu_out_status_attr.attr, + &psu_in_status_attr.attr, + &psu_fan_speed_attr.attr, + &psu_fan_ratio_attr.attr, + &psu_fan_direction_attr.attr, + &psu_led_status_attr.attr, + &psu_fan_speed_cal_attr.attr, + &psu_blackbox_info_attr.attr, + &psu_pmbus_info_attr.attr, + &psu_clear_blackbox_attr.attr, + &switch_dev_attr_in_vol_max.switch_attr.attr, + &switch_dev_attr_in_vol_min.switch_attr.attr, + &switch_dev_attr_in_curr_max.switch_attr.attr, + &switch_dev_attr_in_curr_min.switch_attr.attr, + &switch_dev_attr_in_power_max.switch_attr.attr, + &switch_dev_attr_in_power_min.switch_attr.attr, + &switch_dev_attr_out_vol_max.switch_attr.attr, + &switch_dev_attr_out_vol_min.switch_attr.attr, + &switch_dev_attr_out_curr_max.switch_attr.attr, + &switch_dev_attr_out_curr_min.switch_attr.attr, + &switch_dev_attr_out_power_max.switch_attr.attr, + &switch_dev_attr_out_power_min.switch_attr.attr, + &switch_dev_attr_fan_speed_max.switch_attr.attr, + &switch_dev_attr_fan_speed_min.switch_attr.attr, + NULL, +}; + +static struct attribute_group psu_attr_group = { + .attrs = psu_attrs, +}; + +/*******************************psu temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_temp_alias_attr = __ATTR(alias, S_IRUGO, psu_temp_alias_show, NULL); +static struct switch_attribute psu_temp_type_attr = __ATTR(type, S_IRUGO, psu_temp_type_show, NULL); +static struct switch_attribute psu_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, psu_temp_max_show, psu_temp_max_store); +static struct switch_attribute psu_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, psu_temp_min_show, psu_temp_min_store); +static struct switch_attribute psu_temp_value_attr = __ATTR(value, S_IRUGO, psu_temp_value_show, NULL); + +static struct attribute *psu_temp_attrs[] = { + &psu_temp_alias_attr.attr, + &psu_temp_type_attr.attr, + &psu_temp_max_attr.attr, + &psu_temp_min_attr.attr, + &psu_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group psu_temp_attr_group = { + .attrs = psu_temp_attrs, +}; + +static void psuindex_single_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &psu_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + PSU_DBG("delete psu%u temp%u dir and attrs success.\n", curr_psu->obj->index, temp_index); + } + return; +} + +static int psuindex_single_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_psu->obj->kobj); + if (!curr_temp->obj) { + PSU_ERR("create psu%u, %s object error!\n", curr_psu->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &psu_temp_attr_group) != 0) { + PSU_ERR("create psu%u, %s attrs error.\n", curr_psu->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + PSU_DBG("create psu%u, %s success.\n", curr_psu->obj->index, name); + return 0; +} + +static int psuindex_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_psu->temp_number; + curr_psu->temp = kzalloc(sizeof(struct temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_psu->temp) { + PSU_ERR("kzalloc temp error, psu index: %u, temp number: %u.\n", + curr_psu->obj->index, temp_num); + return -ENOMEM; + } + for(temp_index = 1; temp_index <= temp_num; temp_index++) { + if(psuindex_single_temp_create_kobj_and_attrs(curr_psu, temp_index) != 0 ) { + goto temp_error; + } + } + return 0; +temp_error: + for(i = temp_index; i > 0; i--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, i); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + return -EBADRQC; +} + +static void psuindex_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, temp_num; + + if (curr_psu->temp) { + temp_num = curr_psu->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, temp_index); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + } + return; +} + +/* create psu temp[1-n] directory and attributes*/ +static int psu_temp_create(void) +{ + int psu_num, temp_num; + unsigned int psu_index, i; + struct psu_obj_s *curr_psu; /* point to psu1 psu2...*/ + + psu_num = g_psu.psu_number; + if (psu_num <= 0) { + PSU_DBG("psu number: %d, skip to create temp* dirs and attrs.\n", psu_num); + return 0; + } + + check_p(g_psu_drv->get_psu_temp_number); + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + temp_num = g_psu_drv->get_psu_temp_number(psu_index); + if (temp_num <= 0) { + PSU_DBG("psu%u temp number: %d, don't need to create temp* dirs and attrs.\n", + psu_index, temp_num); + continue; + } + curr_psu = &g_psu.psu[psu_index - 1]; + curr_psu->temp_number = temp_num; + if(psuindex_temp_create_kobj_and_attrs(curr_psu) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index; i > 0; i--) { + curr_psu = &g_psu.psu[i - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + } + return -EBADRQC; +} + +/* delete psu temp[1-n] directory and attributes*/ +static void psu_temp_remove(void) +{ + unsigned int psu_index; + struct psu_obj_s *curr_psu; + + if (g_psu.psu) { + for(psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + curr_psu = &g_psu.psu[psu_index - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + curr_psu->temp_number = 0; + } + } + return; +} + +/* create psu* eeprom attributes */ +static int psu_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct psu_obj_s *curr_psu; + + check_p(g_psu_drv->get_psu_eeprom_size); + eeprom_size = g_psu_drv->get_psu_eeprom_size(index); + if (eeprom_size <= 0) { + PSU_INFO("psu%u, eeprom_size: %d, don't need to creat eeprom attr.\n", + index, eeprom_size); + return 0; + } + + curr_psu = &g_psu.psu[index - 1]; + sysfs_bin_attr_init(&curr_psu->bin); + curr_psu->bin.attr.name = "eeprom"; + curr_psu->bin.attr.mode = 0444; + curr_psu->bin.read = psu_eeprom_read; + curr_psu->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_psu->obj->kobj, &curr_psu->bin); + if (ret) { + PSU_ERR("psu%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + PSU_DBG("psu%u, create bin file success, eeprom size:%d.\n", index, eeprom_size); + curr_psu->psu_creat_bin_flag = 1; + return 0; +} + +static int psu_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + if (curr_psu->obj) { + if (curr_psu->psu_creat_bin_flag) { + sysfs_remove_bin_file(&curr_psu->obj->kobj, &curr_psu->bin); + curr_psu->psu_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_psu->obj->kobj, &psu_attr_group); + switch_kobject_delete(&curr_psu->obj); + PSU_DBG("delete psu%u dir and attrs success.\n", index); + } + return 0; +} + +static int psu_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "psu%u", index); + curr_psu->obj = switch_kobject_create(name, parent); + if (!curr_psu->obj) { + PSU_ERR("create %s object error!\n", name); + return -ENOMEM; + } + curr_psu->obj->index = index; + if (sysfs_create_group(&curr_psu->obj->kobj, &psu_attr_group) != 0) { + PSU_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_psu->obj); + return -EBADRQC; + } + PSU_DBG("create %s dir and attrs success.\n", name); + return 0; +} + + +static int psu_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = psu_sub_single_create_kobj(parent, index); + if (ret < 0) { + PSU_ERR("create psu%d dir error.\n", index); + return ret; + } + + psu_sub_single_create_eeprom_attrs(index); + return 0; +} + +static int psu_sub_create_kobj_and_attrs(struct kobject *parent, int psu_num) +{ + unsigned int psu_index, i; + + g_psu.psu = kzalloc(sizeof(struct psu_obj_s) * psu_num, GFP_KERNEL); + if (!g_psu.psu) { + PSU_ERR("kzalloc psu.psu error, psu number = %d.\n", psu_num); + return -ENOMEM; + } + + for (psu_index = 1; psu_index <= psu_num; psu_index++) { + if (psu_sub_single_create_kobj_and_attrs(parent, psu_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = psu_index; i > 0; i--) { + psu_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + return -EBADRQC; +} + +/* create psu[1-n] directory and attributes*/ +static int psu_sub_create(void) +{ + int ret; + + ret = psu_sub_create_kobj_and_attrs(&g_psu_obj->kobj, g_psu.psu_number); + return ret; +} + +/* delete psu[1-n] directory and attributes*/ +static void psu_sub_remove(void) +{ + unsigned int psu_index; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + psu_sub_single_remove_kobj_and_attrs(psu_index); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + } + g_psu.psu_number = 0; + return; +} + +/* create psu directory and number attributes*/ +static int psu_root_create(void) +{ + g_psu_obj = switch_kobject_create("psu", NULL); + if (!g_psu_obj) { + PSU_ERR("switch_kobject_create psu error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_psu_obj->kobj, &psu_root_attr_group) != 0) { + switch_kobject_delete(&g_psu_obj); + PSU_ERR("create psu dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete psu directory and number attributes*/ +static void psu_root_remove(void) +{ + if (g_psu_obj) { + sysfs_remove_group(&g_psu_obj->kobj, &psu_root_attr_group); + switch_kobject_delete(&g_psu_obj); + PSU_DBG("delete psu dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv) +{ + int ret, psu_num; + + PSU_INFO("s3ip_sysfs_psu_drivers_register...\n"); + if (g_psu_drv) { + PSU_ERR("g_psu_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_psu_number); + g_psu_drv = drv; + + psu_num = g_psu_drv->get_psu_number(); + if (psu_num <= 0) { + PSU_ERR("psu number: %d, don't need to create psu dirs and attrs.\n", psu_num); + g_psu_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_psu, sizeof(struct psu_s)); + g_psu.psu_number = psu_num; + ret = psu_root_create(); + if (ret < 0) { + PSU_ERR("create psu root dir and attrs failed, ret: %d\n", ret); + g_psu_drv = NULL; + return ret; + } + + ret = psu_sub_create(); + if (ret < 0) { + PSU_ERR("create psu sub dir and attrs failed, ret: %d\n", ret); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + + ret = psu_temp_create(); + if (ret < 0) { + PSU_ERR("create psu temp dir and attrs failed, ret: %d\n", ret); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + PSU_INFO("s3ip_sysfs_psu_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_psu_drivers_unregister(void) +{ + if (g_psu_drv) { + psu_temp_remove(); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + PSU_DBG("s3ip_sysfs_psu_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_unregister); +module_param(g_psu_loglevel, int, 0644); +MODULE_PARM_DESC(g_psu_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_psu_present_debug, bool, 0644); +MODULE_PARM_DESC(g_psu_present_debug, "the psu present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c new file mode 100644 index 000000000000..eb3bde77b7dd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c @@ -0,0 +1,1955 @@ +/* + * An slot_sysfs driver for slot sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "slot_sysfs.h" + +static int g_slot_loglevel = 0; + +#define SLOT_INFO(fmt, args...) do { \ + if (g_slot_loglevel & INFO) { \ + printk(KERN_INFO "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_ERR(fmt, args...) do { \ + if (g_slot_loglevel & ERR) { \ + printk(KERN_ERR "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_DBG(fmt, args...) do { \ + if (g_slot_loglevel & DBG) { \ + printk(KERN_DEBUG "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct slot_temp_obj_s { + struct switch_obj *obj; +}; + +struct slot_vol_obj_s { + struct switch_obj *obj; +}; + +struct slot_curr_obj_s { + struct switch_obj *obj; +}; + +struct slot_fpga_obj_s { + struct switch_obj *obj; +}; + +struct slot_cpld_obj_s { + struct switch_obj *obj; +}; + +struct slot_obj_s { + unsigned int temp_number; + unsigned int vol_number; + unsigned int curr_number; + unsigned int fpga_number; + unsigned int cpld_number; + struct slot_temp_obj_s *temp; + struct slot_vol_obj_s *vol; + struct slot_curr_obj_s *curr; + struct slot_fpga_obj_s *fpga; + struct slot_cpld_obj_s *cpld; + struct switch_obj *obj; +}; + +struct slot_s { + unsigned int slot_number; + struct slot_obj_s *slot; +}; + +static struct slot_s g_slot; +static struct switch_obj *g_slot_obj = NULL; +static struct s3ip_sysfs_slot_drivers_s *g_slot_drv = NULL; + +static ssize_t slot_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot_number); +} + +static ssize_t slot_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].temp_number); +} + +static ssize_t slot_vol_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].vol_number); +} + +static ssize_t slot_curr_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].curr_number); +} + +static ssize_t slot_fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].fpga_number); +} + +static ssize_t slot_cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].cpld_number); +} + +static ssize_t slot_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_model_name); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_model_name(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vendor); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_vendor(slot_index, buf, PAGE_SIZE); +} +static ssize_t slot_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_serial_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_serial_number(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_part_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_part_number(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_hardware_version); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_hardware_version(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_led_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_led_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int slot_index; + int ret, led_status; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_led_status); + + slot_index = obj->index; + ret = kstrtoint(buf, 0, &led_status); + if (ret != 0) { + SLOT_ERR("invaild slot led status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + SLOT_DBG("slot index: %u, led_status: %d\n", slot_index, led_status); + ret = g_slot_drv->set_slot_led_status(slot_index, led_status); + if (ret < 0) { + SLOT_ERR("set slot%u led_status: %d failed, ret: %d\n", slot_index, led_status, ret); + return -EIO; + } + SLOT_DBG("set slot%u led_status: %d success\n", slot_index, led_status); + return count; +} + +/*************************************slot temp*************************************************/ +static ssize_t slot_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_value(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_alias(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_type(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_max(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_max(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t slot_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_min(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_min(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} +/**********************************end of slot temp**********************************************/ + +/*************************************slot vol*************************************************/ +static ssize_t slot_vol_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_value(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_alias(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_type(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_max(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_max(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_min(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_min(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_range); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_range(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_nominal_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_nominal_value(slot_index, vol_index, buf, PAGE_SIZE); +} +/**********************************end of slot vol**********************************************/ +/*************************************slot curr*************************************************/ +static ssize_t slot_curr_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_value(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_alias(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_type(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_max(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + return g_slot_drv->set_slot_curr_max(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} + +static ssize_t slot_curr_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_min(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + ret = g_slot_drv->set_slot_curr_min(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} +/**********************************end of slot curr**********************************************/ +/*************************************slot fpga*************************************************/ +static ssize_t slot_fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_alias(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_type(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_firmware_version(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_board_version(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_test_reg(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, fpga_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_fpga_test_reg(slot_index, fpga_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u fpga%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, fpga_index, value, ret); + return ret; + } + SLOT_DBG("set slot%u fpga%u test reg success, value: 0x%x.\n", slot_index, fpga_index, value); + return count; +} +/**********************************end of slot fpga**********************************************/ +/*************************************slot cpld*************************************************/ +static ssize_t slot_cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_alias(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_type(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_firmware_version(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_board_version(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_test_reg(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, cpld_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_cpld_test_reg(slot_index, cpld_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u cpld%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, cpld_index, value, ret); + return ret; + } + SLOT_DBG("set slot%u cpld%u test reg success, value: 0x%x.\n", slot_index, cpld_index, value); + return count; +} + +static ssize_t slot_power_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_power_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_power_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_power_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int slot_index; + int ret, power; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_power_status); + + slot_index = obj->index; + ret = kstrtoint(buf, 0, &power); + if (ret != 0) { + SLOT_ERR("invaild slot power status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + SLOT_DBG("slot index: %u, power: %d\n", slot_index, power); + ret = g_slot_drv->set_slot_power_status(slot_index, power); + if (ret < 0) { + SLOT_ERR("set slot%u power: %d failed, ret: %d\n", slot_index, power, ret); + return ret; + } + SLOT_DBG("set slot%u power: %d success\n", slot_index, power); + return count; +} +/**********************************end of slot cpld**********************************************/ +/**********************************slot dir and attrs********************************************/ +static struct switch_attribute slot_number_attr = __ATTR(number, S_IRUGO, slot_number_show, NULL); + +static struct attribute *slot_dir_attrs[] = { + &slot_number_attr.attr, + NULL, +}; + +static struct attribute_group slot_root_attr_group = { + .attrs = slot_dir_attrs, +}; + +/*******************************slot[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_model_name_attr = __ATTR(model_name, S_IRUGO, slot_model_name_show, NULL); +static struct switch_attribute slot_vendor_attr = __ATTR(vendor, S_IRUGO, slot_vendor_show, NULL); +static struct switch_attribute slot_hw_attr = __ATTR(hardware_version, S_IRUGO, slot_hw_show, NULL); +static struct switch_attribute slot_sn_attr = __ATTR(serial_number, S_IRUGO, slot_sn_show, NULL); +static struct switch_attribute slot_pn_attr = __ATTR(part_number, S_IRUGO, slot_pn_show, NULL); +static struct switch_attribute slot_status_attr = __ATTR(status, S_IRUGO, slot_status_show, NULL); +static struct switch_attribute slot_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, slot_led_status_show, slot_led_status_store); +static struct switch_attribute slot_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, slot_power_show, slot_power_store); +static struct switch_attribute num_temp_sensors_attr = __ATTR(num_temp_sensors, S_IRUGO, slot_temp_number_show, NULL); +static struct switch_attribute num_vol_sensors_attr = __ATTR(num_vol_sensors, S_IRUGO, slot_vol_number_show, NULL); +static struct switch_attribute num_curr_sensors_attr = __ATTR(num_curr_sensors, S_IRUGO, slot_curr_number_show, NULL); +static struct switch_attribute num_fpga_attr = __ATTR(num_fpgas, S_IRUGO, slot_fpga_number_show, NULL); +static struct switch_attribute num_cpld_attr = __ATTR(num_cplds, S_IRUGO, slot_cpld_number_show, NULL); + +static struct attribute *slot_attrs[] = { + &slot_model_name_attr.attr, + &slot_vendor_attr.attr, + &slot_power_on_attr.attr, + &slot_hw_attr.attr, + &slot_sn_attr.attr, + &slot_pn_attr.attr, + &slot_status_attr.attr, + &slot_led_status_attr.attr, + &num_temp_sensors_attr.attr, + &num_vol_sensors_attr.attr, + &num_curr_sensors_attr.attr, + &num_fpga_attr.attr, + &num_cpld_attr.attr, + NULL, +}; + +static struct attribute_group slot_attr_group = { + .attrs = slot_attrs, +}; + +/*******************************slot temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_temp_alias_attr = __ATTR(alias, S_IRUGO, slot_temp_alias_show, NULL); +static struct switch_attribute slot_temp_type_attr = __ATTR(type, S_IRUGO, slot_temp_type_show, NULL); +static struct switch_attribute slot_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_temp_max_show, slot_temp_max_store); +static struct switch_attribute slot_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_temp_min_show, slot_temp_min_store); +static struct switch_attribute slot_temp_value_attr = __ATTR(value, S_IRUGO, slot_temp_value_show, NULL); + +static struct attribute *slot_temp_attrs[] = { + &slot_temp_alias_attr.attr, + &slot_temp_type_attr.attr, + &slot_temp_max_attr.attr, + &slot_temp_min_attr.attr, + &slot_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_temp_attr_group = { + .attrs = slot_temp_attrs, +}; + +/*******************************slot vol[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_vol_alias_attr = __ATTR(alias, S_IRUGO, slot_vol_alias_show, NULL); +static struct switch_attribute slot_vol_type_attr = __ATTR(type, S_IRUGO, slot_vol_type_show, NULL); +static struct switch_attribute slot_vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_vol_max_show, slot_vol_max_store); +static struct switch_attribute slot_vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_vol_min_show, slot_vol_min_store); +static struct switch_attribute slot_vol_value_attr = __ATTR(value, S_IRUGO, slot_vol_value_show, NULL); +static struct switch_attribute slot_vol_range_attr = __ATTR(range, S_IRUGO, slot_vol_range_show, NULL); +static struct switch_attribute slot_vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, slot_vol_nominal_value_show, NULL); + +static struct attribute *slot_vol_attrs[] = { + &slot_vol_alias_attr.attr, + &slot_vol_type_attr.attr, + &slot_vol_max_attr.attr, + &slot_vol_min_attr.attr, + &slot_vol_value_attr.attr, + &slot_vol_range_attr.attr, + &slot_vol_nominal_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_vol_attr_group = { + .attrs = slot_vol_attrs, +}; + +/*******************************slot curr[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_curr_alias_attr = __ATTR(alias, S_IRUGO, slot_curr_alias_show, NULL); +static struct switch_attribute slot_curr_type_attr = __ATTR(type, S_IRUGO, slot_curr_type_show, NULL); +static struct switch_attribute slot_curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_curr_max_show, slot_curr_max_store); +static struct switch_attribute slot_curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_curr_min_show, slot_curr_min_store); +static struct switch_attribute slot_curr_value_attr = __ATTR(value, S_IRUGO, slot_curr_value_show, NULL); + +static struct attribute *slot_curr_attrs[] = { + &slot_curr_alias_attr.attr, + &slot_curr_type_attr.attr, + &slot_curr_max_attr.attr, + &slot_curr_min_attr.attr, + &slot_curr_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_curr_attr_group = { + .attrs = slot_curr_attrs, +}; + +/*******************************slot fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_fpga_alias_attr = __ATTR(alias, S_IRUGO, slot_fpga_alias_show, NULL); +static struct switch_attribute slot_fpga_type_attr = __ATTR(type, S_IRUGO, slot_fpga_type_show, NULL); +static struct switch_attribute slot_fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_fpga_fw_version_show, NULL); +static struct switch_attribute slot_fpga_board_version_attr = __ATTR(board_version, S_IRUGO, slot_fpga_board_version_show, NULL); +static struct switch_attribute slot_fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_fpga_test_reg_show, slot_fpga_test_reg_store); + +static struct attribute *slot_fpga_attrs[] = { + &slot_fpga_alias_attr.attr, + &slot_fpga_type_attr.attr, + &slot_fpga_fw_version_attr.attr, + &slot_fpga_board_version_attr.attr, + &slot_fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_fpga_attr_group = { + .attrs = slot_fpga_attrs, +}; + +/*******************************slot cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_cpld_alias_attr = __ATTR(alias, S_IRUGO, slot_cpld_alias_show, NULL); +static struct switch_attribute slot_cpld_type_attr = __ATTR(type, S_IRUGO, slot_cpld_type_show, NULL); +static struct switch_attribute slot_cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_cpld_fw_version_show, NULL); +static struct switch_attribute slot_cpld_board_version_attr = __ATTR(board_version, S_IRUGO, slot_cpld_board_version_show, NULL); +static struct switch_attribute slot_cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_cpld_test_reg_show, slot_cpld_test_reg_store); + +static struct attribute *slot_cpld_attrs[] = { + &slot_cpld_alias_attr.attr, + &slot_cpld_type_attr.attr, + &slot_cpld_fw_version_attr.attr, + &slot_cpld_board_version_attr.attr, + &slot_cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_cpld_attr_group = { + .attrs = slot_cpld_attrs, +}; + +/***************************************slot cpld*****************************************/ +static void slotindex_single_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + SLOT_DBG("delete slot%u cpld%u dir and attrs success.\n", curr_slot->obj->index, + cpld_index); + } + return; +} + +static int slotindex_single_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", cpld_index); + curr_cpld->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_cpld->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_cpld->obj->index = cpld_index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, cpld_num; + + if (curr_slot->cpld) { + cpld_num = curr_slot->cpld_number; + for (cpld_index = cpld_num; cpld_index > 0; cpld_index--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, cpld_index); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + } + return; +} + +static int slotindex_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, i, cpld_num; + + cpld_num = curr_slot->cpld_number; + curr_slot->cpld = kzalloc(sizeof(struct slot_cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!curr_slot->cpld) { + SLOT_ERR("kzalloc slot cpld error, slot index: %u, cpld number: %u.\n", + curr_slot->obj->index, cpld_num); + return -ENOMEM; + } + + for (cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if (slotindex_single_cpld_create_kobj_and_attrs(curr_slot, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = cpld_index; i > 0; i--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + return -EBADRQC; +} + +/* create slot cpld[1-n] directory and attributes*/ +static int slot_cpld_create(void) +{ + int cpld_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_cpld_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + cpld_num = g_slot_drv->get_slot_cpld_number(slot_index); + if (cpld_num <= 0) { + SLOT_DBG("slot%u cpld number: %d, don't need to create cpld* dirs and attrs.\n", + slot_index, cpld_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->cpld_number = cpld_num; + if (slotindex_cpld_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot cpld[1-n] directory and attributes*/ +static void slot_cpld_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + curr_slot->cpld_number = 0; + } + } + return; +} +/************************************end of slot cpld**************************************/ +/***************************************slot fpga*****************************************/ +static void slotindex_single_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + SLOT_DBG("delete slot%u fpga%u dir and attrs success.\n", curr_slot->obj->index, + fpga_index); + } + return; +} + +static int slotindex_single_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", fpga_index); + curr_fpga->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_fpga->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_fpga->obj->index = fpga_index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, fpga_num; + + if (curr_slot->fpga) { + fpga_num = curr_slot->fpga_number; + for (fpga_index = fpga_num; fpga_index > 0; fpga_index--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, fpga_index); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + } + return; +} + +static int slotindex_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, i, fpga_num; + + fpga_num = curr_slot->fpga_number; + curr_slot->fpga = kzalloc(sizeof(struct slot_fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!curr_slot->fpga) { + SLOT_ERR("kzalloc slot fpga error, slot index: %u, fpga number: %u.\n", + curr_slot->obj->index, fpga_num); + return -ENOMEM; + } + + for (fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if (slotindex_single_fpga_create_kobj_and_attrs(curr_slot, fpga_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fpga_index; i > 0; i--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + return -EBADRQC; +} + +/* create slot fpga[1-n] directory and attributes*/ +static int slot_fpga_create(void) +{ + int fpga_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_fpga_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + fpga_num = g_slot_drv->get_slot_fpga_number(slot_index); + if (fpga_num <= 0) { + SLOT_DBG("slot%u fpga number: %d, don't need to create fpga* dirs and attrs.\n", + slot_index, fpga_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->fpga_number = fpga_num; + if (slotindex_fpga_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot fpga[1-n] directory and attributes*/ +static void slot_fpga_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + curr_slot->fpga_number = 0; + } + } + return; +} +/************************************end of slot fpga**************************************/ +/*************************************slot current*****************************************/ +static void slotindex_single_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + if (curr->obj) { + sysfs_remove_group(&curr->obj->kobj, &slot_curr_attr_group); + switch_kobject_delete(&curr->obj); + SLOT_DBG("delete slot%u curr_sensor%u dir and attrs success.\n", curr_slot->obj->index, + curr_index); + } + return; +} + +static int slotindex_single_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "curr_sensor%u", curr_index); + curr->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr->obj->index = curr_index; + if (sysfs_create_group(&curr->obj->kobj, &slot_curr_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, curr_num; + + if (curr_slot->curr) { + curr_num = curr_slot->curr_number; + for (curr_index = curr_num; curr_index > 0; curr_index--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, curr_index); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + } + return; +} + +static int slotindex_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, i, curr_num; + + curr_num = curr_slot->curr_number; + curr_slot->curr = kzalloc(sizeof(struct slot_curr_obj_s) * curr_num, GFP_KERNEL); + if (!curr_slot->curr) { + SLOT_ERR("kzalloc slot curr error, slot index: %u, curr number: %u.\n", + curr_slot->obj->index, curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (slotindex_single_curr_create_kobj_and_attrs(curr_slot, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + return -EBADRQC; +} + +/* create slot curr_snesor[1-n] directory and attributes*/ +static int slot_curr_create(void) +{ + int curr_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_curr_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + curr_num = g_slot_drv->get_slot_curr_number(slot_index); + if (curr_num <= 0) { + SLOT_DBG("slot%u curr number: %d, don't need to create curr_sensor* dirs and attrs.\n", + slot_index, curr_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->curr_number = curr_num; + if (slotindex_curr_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot curr_sensor[1-n] directory and attributes*/ +static void slot_curr_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + curr_slot->curr_number = 0; + } + } + return; +} +/**********************************end of slot current************************************/ +/*************************************slot voltage****************************************/ +static void slotindex_single_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + if (curr_vol->obj) { + sysfs_remove_group(&curr_vol->obj->kobj, &slot_vol_attr_group); + switch_kobject_delete(&curr_vol->obj); + SLOT_DBG("delete slot%u vol_sensor%u dir and attrs success.\n", curr_slot->obj->index, + vol_index); + } + return; +} + +static int slotindex_single_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "vol_sensor%u", vol_index); + curr_vol->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_vol->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_vol->obj->index = vol_index; + if (sysfs_create_group(&curr_vol->obj->kobj, &slot_vol_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_vol->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, vol_num; + + if (curr_slot->vol) { + vol_num = curr_slot->vol_number; + for (vol_index = vol_num; vol_index > 0; vol_index--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, vol_index); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + } + return; +} + +static int slotindex_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, i, vol_num; + + vol_num = curr_slot->vol_number; + curr_slot->vol = kzalloc(sizeof(struct slot_vol_obj_s) * vol_num, GFP_KERNEL); + if (!curr_slot->vol) { + SLOT_ERR("kzalloc slot vol error, slot index: %u, vol number: %u.\n", + curr_slot->obj->index, vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (slotindex_single_vol_create_kobj_and_attrs(curr_slot, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + return -EBADRQC; +} + +/* create slot vol_snesor[1-n] directory and attributes*/ +static int slot_vol_create(void) +{ + int vol_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_vol_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + vol_num = g_slot_drv->get_slot_vol_number(slot_index); + if (vol_num <= 0) { + SLOT_DBG("slot%u vol number: %d, don't need to create vol_sensor* dirs and attrs.\n", + slot_index, vol_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->vol_number = vol_num; + if (slotindex_vol_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot vol_sensor[1-n] directory and attributes*/ +static void slot_vol_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + curr_slot->vol_number = 0; + } + } + return; +} +/**********************************end of slot voltage************************************/ +/***************************************slot temp*****************************************/ +static void slotindex_single_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &slot_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + SLOT_DBG("delete slot%u temp_sensor%u dir and attrs success.\n", curr_slot->obj->index, + temp_index); + } + return; +} + +static int slotindex_single_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp_sensor%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_temp->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &slot_temp_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, temp_num; + + if (curr_slot->temp) { + temp_num = curr_slot->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, temp_index); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + } + return; +} + +static int slotindex_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_slot->temp_number; + curr_slot->temp = kzalloc(sizeof(struct slot_temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_slot->temp) { + SLOT_ERR("kzalloc slot temp error, slot index: %u, temp number: %u.\n", + curr_slot->obj->index, temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (slotindex_single_temp_create_kobj_and_attrs(curr_slot, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + return -EBADRQC; +} + +/* create slot temp_sensor[1-n] directory and attributes*/ +static int slot_temp_create(void) +{ + int temp_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_temp_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + temp_num = g_slot_drv->get_slot_temp_number(slot_index); + if (temp_num <= 0) { + SLOT_DBG("slot%u temp number: %d, don't need to create temp_sensor* dirs and attrs.\n", + slot_index, temp_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->temp_number = temp_num; + if (slotindex_temp_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot temp_sensor[1-n] directory and attributes*/ +static void slot_temp_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + curr_slot->temp_number = 0; + } + } + return; +} +/************************************end of slot temp**************************************/ + +static int slot_child_obj_create(void) +{ + int ret; + + if (g_slot.slot_number <= 0) { + SLOT_DBG("slot number: %u, skip to create slot child dirs and attrs.\n", + g_slot.slot_number); + return 0; + } + /* temp create */ + ret = slot_temp_create(); + if (ret < 0) { + goto temp_err; + } + /* Voltage create */ + ret = slot_vol_create(); + if(ret < 0) { + goto vol_err; + } + /* current create */ + ret = slot_curr_create(); + if(ret < 0) { + goto curr_err; + } + /* fpga create */ + ret = slot_fpga_create(); + if(ret < 0) { + goto fpga_err; + } + /* cplf create */ + ret = slot_cpld_create(); + if(ret < 0) { + goto cpld_err; + } + return 0; +cpld_err: + slot_fpga_remove(); +fpga_err: + slot_curr_remove(); +curr_err: + slot_vol_remove(); +vol_err: + slot_temp_remove(); +temp_err: + return ret; +} + +static void slot_child_obj_remove(void) +{ + slot_cpld_remove(); + slot_fpga_remove(); + slot_curr_remove(); + slot_vol_remove(); + slot_temp_remove(); + return; +} + +static void slot_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct slot_obj_s *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + if (curr_slot->obj) { + sysfs_remove_group(&curr_slot->obj->kobj, &slot_attr_group); + switch_kobject_delete(&curr_slot->obj); + SLOT_DBG("delete slot%u dir and attrs success.\n", index); + } + + return; +} + +static int slot_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_obj_s * curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "slot%u", index); + curr_slot->obj = switch_kobject_create(name, parent); + if (!curr_slot->obj) { + SLOT_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_slot->obj->index = index; + if (sysfs_create_group(&curr_slot->obj->kobj, &slot_attr_group) != 0) { + SLOT_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_slot->obj); + return -EBADRQC; + } + SLOT_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int slot_sub_create_kobj_and_attrs(struct kobject *parent, int slot_num) +{ + unsigned int slot_index, i; + + g_slot.slot = kzalloc(sizeof(struct slot_obj_s) * slot_num, GFP_KERNEL); + if (!g_slot.slot) { + SLOT_ERR("kzalloc slot.slot error, slot number = %d.\n", slot_num); + return -ENOMEM; + } + + for(slot_index = 1; slot_index <= slot_num; slot_index++) { + if(slot_sub_single_create_kobj_and_attrs(parent, slot_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = slot_index; i > 0; i--) { + slot_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + return -EBADRQC; +} + +/* create slot[1-n] directory and attributes*/ +static int slot_sub_create(void) +{ + int ret; + + ret = slot_sub_create_kobj_and_attrs(&g_slot_obj->kobj, g_slot.slot_number); + return ret; +} + +/* delete slot[1-n] directory and attributes*/ +static void slot_sub_remove(void) +{ + unsigned int slot_index; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + slot_sub_single_remove_kobj_and_attrs(slot_index); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + } + g_slot.slot_number = 0; + return; +} + +/* create slot directory and number attributes*/ +static int slot_root_create(void) +{ + g_slot_obj = switch_kobject_create("slot", NULL); + if (!g_slot_obj) { + SLOT_ERR("switch_kobject_create slot error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_slot_obj->kobj, &slot_root_attr_group) != 0) { + switch_kobject_delete(&g_slot_obj); + SLOT_ERR("create slot dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete slot directory and number attributes*/ +static void slot_root_remove(void) +{ + if (g_slot_obj) { + sysfs_remove_group(&g_slot_obj->kobj, &slot_root_attr_group); + switch_kobject_delete(&g_slot_obj); + } + + return; +} + +int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv) +{ + int ret, slot_num; + + SLOT_INFO("s3ip_sysfs_slot_drivers_register...\n"); + if (g_slot_drv) { + SLOT_ERR("g_slot_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_slot_number); + g_slot_drv = drv; + + slot_num = g_slot_drv->get_slot_number(); + if (slot_num <= 0) { + SLOT_ERR("slot number: %d, don't need to create slot dirs and attrs.\n", slot_num); + g_slot_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_slot, sizeof(struct slot_s)); + g_slot.slot_number = slot_num; + ret = slot_root_create(); + if (ret < 0) { + SLOT_ERR("create slot root dir and attrs failed, ret: %d\n", ret); + g_slot_drv = NULL; + return ret; + } + + ret = slot_sub_create(); + if (ret < 0) { + SLOT_ERR("create slot sub dir and attrs failed, ret: %d\n", ret); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + + ret = slot_child_obj_create(); + if (ret < 0) { + SLOT_ERR("create slot child dir and attrs failed, ret: %d\n", ret); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + SLOT_INFO("s3ip_sysfs_slot_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_slot_drivers_unregister(void) +{ + if (g_slot_drv) { + slot_child_obj_remove(); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + SLOT_DBG("s3ip_sysfs_slot_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_unregister); +module_param(g_slot_loglevel, int, 0644); +MODULE_PARM_DESC(g_slot_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c new file mode 100644 index 000000000000..c34d48e4caf5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c @@ -0,0 +1,309 @@ +/* + * An switch driver for switch devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "syseeprom_sysfs.h" + +int g_switch_loglevel = 0; + +#define SWITCH_INFO(fmt, args...) do { \ + if (g_switch_loglevel & INFO) { \ + printk(KERN_INFO "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_ERR(fmt, args...) do { \ + if (g_switch_loglevel & ERR) { \ + printk(KERN_ERR "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_DBG(fmt, args...) do { \ + if (g_switch_loglevel & DBG) { \ + printk(KERN_DEBUG "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct syseeprom_s { + struct bin_attribute bin; + int creat_eeprom_bin_flag; +}; + +static struct s3ip_sysfs_syseeprom_drivers_s *g_syseeprom_drv = NULL; +static struct kset *switch_kset; +static struct syseeprom_s g_syseeprom; + +static ssize_t switch_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct switch_attribute *attribute; + struct switch_obj *device; + + attribute = to_switch_attr(attr); + device = to_switch_obj(kobj); + + if (!attribute->show) { + return -ENOSYS; + } + + return attribute->show(device, attribute, buf); +} + +static ssize_t switch_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t len) +{ + struct switch_attribute *attribute; + struct switch_obj *obj; + + attribute = to_switch_attr(attr); + obj = to_switch_obj(kobj); + + if (!attribute->store) { + return -ENOSYS; + } + + return attribute->store(obj, attribute, buf, len); +} + +static const struct sysfs_ops switch_sysfs_ops = { + .show = switch_attr_show, + .store = switch_attr_store, +}; + +static void switch_obj_release(struct kobject *kobj) +{ + struct switch_obj *obj; + + obj = to_switch_obj(kobj); + kfree(obj); + return; +} + +static struct kobj_type switch_ktype = { + .sysfs_ops = &switch_sysfs_ops, + .release = switch_obj_release, +}; + +static ssize_t syseeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t rd_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->read_syseeprom_data); + + mem_clear(buf, count); + rd_len = g_syseeprom_drv->read_syseeprom_data(buf, offset, count); + if (rd_len < 0) { + SWITCH_ERR("read syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, rd_len); + return rd_len; + } + SWITCH_DBG("read syseeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + offset, count, rd_len); + return rd_len; +} + +static ssize_t syseeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t wr_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->write_syseeprom_data); + + wr_len = g_syseeprom_drv->write_syseeprom_data(buf, offset, count); + if (wr_len < 0) { + SWITCH_ERR("write syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, wr_len); + return wr_len; + } + SWITCH_DBG("write syseeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + offset, count, wr_len); + return wr_len; +} + +static int syseeprom_create_eeprom_attrs(void) +{ + int ret, eeprom_size; + + eeprom_size = g_syseeprom_drv->get_syseeprom_size(); + if (eeprom_size <= 0) { + SWITCH_ERR("syseeprom size: %d, invalid.\n", eeprom_size); + return -EINVAL; + } + + sysfs_bin_attr_init(&g_syseeprom.bin); + g_syseeprom.bin.attr.name = "syseeprom"; + g_syseeprom.bin.attr.mode = 0644; + g_syseeprom.bin.read = syseeprom_read; + g_syseeprom.bin.write = syseeprom_write; + g_syseeprom.bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + if (ret) { + SWITCH_ERR("create syseeprom bin error, ret: %d. \n", ret); + return -EBADRQC; + } + SWITCH_DBG("create syseeprom bin file success, eeprom size:%d.\n", eeprom_size); + g_syseeprom.creat_eeprom_bin_flag = 1; + return 0; +} + +static void syseeprom_remove_eeprom_attrs(void) +{ + if (g_syseeprom.creat_eeprom_bin_flag) { + sysfs_remove_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + g_syseeprom.creat_eeprom_bin_flag = 0; + } + + return; +} + +int dev_debug_file_read(char *file_name, unsigned int dev_index, char *buf, int size) +{ + char file_path[DIR_NAME_MAX_LEN]; + loff_t pos; + struct file *filp; + int ret; + + mem_clear(file_path, sizeof(file_path)); + mem_clear(buf, size); + + sprintf(file_path, file_name, dev_index); + filp = filp_open(file_path, O_RDONLY, 0); + if (IS_ERR(filp)) { + SWITCH_ERR("dev_debug_file open failed, path=%s, ret=%d\n", file_path, ret); + filp = NULL; + ret = -ENOENT; + return ret; + } + + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + SWITCH_ERR("dev_debug_file kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", file_name, size - 1, ret); + filp_close(filp, NULL); + return ret; + } + + filp_close(filp, NULL); + filp = NULL; + return 0; +} + +int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv) +{ + int ret; + + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register...\n"); + if (g_syseeprom_drv) { + SWITCH_ERR("g_syseeprom_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_syseeprom_size); + g_syseeprom_drv = drv; + + ret = syseeprom_create_eeprom_attrs(); + if (ret < 0) { + SWITCH_ERR("create syseeprom attributes failed, ret: %d\n", ret); + g_syseeprom_drv = NULL; + return ret; + } + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_syseeprom_drivers_unregister(void) +{ + if (g_syseeprom_drv) { + syseeprom_remove_eeprom_attrs(); + g_syseeprom_drv = NULL; + SWITCH_DBG("s3ip_sysfs_syseeprom_drivers_unregister success.\n"); + } + + return; +} + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent) +{ + struct switch_obj *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) { + SWITCH_DBG("switch_kobject_create %s kzalloc error", name); + return NULL; + } + + obj->kobj.kset = switch_kset; + + ret = kobject_init_and_add(&obj->kobj, &switch_ktype, parent, "%s", name); + if (ret) { + kobject_put(&obj->kobj); + SWITCH_DBG("kobject_init_and_add %s error", name); + return NULL; + } + + return obj; +} + +void switch_kobject_delete(struct switch_obj **obj) +{ + if (*obj) { + SWITCH_DBG("%s delete %s.\n", (*obj)->kobj.parent->name, (*obj)->kobj.name); + kobject_put(&((*obj)->kobj)); + *obj = NULL; + } +} + +static int __init switch_init(void) +{ + SWITCH_INFO("switch_init...\n"); + + switch_kset = kset_create_and_add("s3ip", NULL, NULL); + if (!switch_kset) { + SWITCH_ERR("create switch_kset error.\n"); + return -ENOMEM; + } + + SWITCH_INFO("switch_init success.\n"); + return 0; +} + +static void __exit switch_exit(void) +{ + if (switch_kset) { + kset_unregister(switch_kset); + } + + SWITCH_INFO("switch_exit success.\n"); +} + +module_init(switch_init); +module_exit(switch_exit); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_unregister); +module_param(g_switch_loglevel, int, 0644); +MODULE_PARM_DESC(g_switch_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("switch driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c new file mode 100644 index 000000000000..242fb20a8755 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c @@ -0,0 +1,289 @@ +/* + * An sysled_sysfs driver for sysled sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "sysled_sysfs.h" + +static int g_sysled_loglevel = 0; + +#define SYSLED_INFO(fmt, args...) do { \ + if (g_sysled_loglevel & INFO) { \ + printk(KERN_INFO "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_ERR(fmt, args...) do { \ + if (g_sysled_loglevel & ERR) { \ + printk(KERN_ERR "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_DBG(fmt, args...) do { \ + if (g_sysled_loglevel & DBG) { \ + printk(KERN_DEBUG "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct switch_obj *g_sysled_obj = NULL; +static struct s3ip_sysfs_sysled_drivers_s *g_sysled_drv = NULL; + +static ssize_t sys_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_led_status); + + return g_sysled_drv->get_sys_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys led status %d success\n", value); + return count; +} + +static ssize_t bmc_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_bmc_led_status); + + return g_sysled_drv->get_bmc_led_status(buf, PAGE_SIZE); +} + +static ssize_t bmc_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_bmc_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set bmc led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_bmc_led_status(value); + if (ret < 0) { + SYSLED_ERR("set bmc led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set bmc led status %d success\n", value); + return count; +} + +static ssize_t sys_fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_fan_led_status); + + return g_sysled_drv->get_sys_fan_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_fan_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys fan led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_fan_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys fan led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys fan led status %d success\n", value); + return count; +} + +static ssize_t sys_psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_psu_led_status); + + return g_sysled_drv->get_sys_psu_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_psu_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_psu_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys psu led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_psu_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys psu led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys psu led status %d success\n", value); + return count; +} + +static ssize_t id_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_id_led_status); + + return g_sysled_drv->get_id_led_status(buf, PAGE_SIZE); +} + +static ssize_t id_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_id_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set id led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_id_led_status(value); + if (ret < 0) { + SYSLED_ERR("set id led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set id led status %d success\n", value); + return count; +} + +/************************************syseeprom dir and attrs*******************************************/ +static struct switch_attribute sys_led_attr = __ATTR(sys_led_status, S_IRUGO | S_IWUSR, sys_led_status_show, sys_led_status_store); +static struct switch_attribute bmc_led_attr = __ATTR(bmc_led_status, S_IRUGO | S_IWUSR, bmc_led_status_show, bmc_led_status_store); +static struct switch_attribute fan_led_attr = __ATTR(fan_led_status, S_IRUGO | S_IWUSR, sys_fan_led_status_show, sys_fan_led_status_store); +static struct switch_attribute psu_led_attr = __ATTR(psu_led_status, S_IRUGO | S_IWUSR, sys_psu_led_status_show, sys_psu_led_status_store); +static struct switch_attribute id_led_attr = __ATTR(id_led_status, S_IRUGO | S_IWUSR, id_led_status_show, id_led_status_store); + +static struct attribute *sysled_dir_attrs[] = { + &sys_led_attr.attr, + &bmc_led_attr.attr, + &fan_led_attr.attr, + &psu_led_attr.attr, + &id_led_attr.attr, + NULL, +}; + +static struct attribute_group sysled_attr_group = { + .attrs = sysled_dir_attrs, +}; + +/* create syseled directory and attributes*/ +static int sysled_root_create(void) +{ + g_sysled_obj = switch_kobject_create("sysled", NULL); + if (!g_sysled_obj) { + SYSLED_ERR("switch_kobject_create sysled error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_sysled_obj->kobj, &sysled_attr_group) != 0) { + switch_kobject_delete(&g_sysled_obj); + SYSLED_ERR("create sysled dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete syseled directory and attributes*/ +static void sysled_root_remove(void) +{ + if (g_sysled_obj) { + sysfs_remove_group(&g_sysled_obj->kobj, &sysled_attr_group); + switch_kobject_delete(&g_sysled_obj); + } + + return; +} + +int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv) +{ + int ret; + + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register...\n"); + if (g_sysled_drv) { + SYSLED_ERR("g_sysled_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_sysled_drv = drv; + + ret = sysled_root_create(); + if (ret < 0) { + SYSLED_ERR("sysled create error.\n"); + g_sysled_drv = NULL; + return ret; + } + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_sysled_drivers_unregister(void) +{ + if (g_sysled_drv) { + sysled_root_remove(); + g_sysled_drv = NULL; + SYSLED_DBG("s3ip_sysfs_sysled_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_unregister); +module_param(g_sysled_loglevel, int, 0644); +MODULE_PARM_DESC(g_sysled_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c new file mode 100644 index 000000000000..dd1c3e859a1a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c @@ -0,0 +1,218 @@ +/* + * An system_sysfs driver for system sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "system_sysfs.h" +#include "switch_driver.h" + +static int g_system_loglevel = 0; + +#define SYSTEM_INFO(fmt, args...) do { \ + if (g_system_loglevel & INFO) { \ + printk(KERN_INFO "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSTEM_ERR(fmt, args...) do { \ + if (g_system_loglevel & ERR) { \ + printk(KERN_ERR "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSTEM_DBG(fmt, args...) do { \ + if (g_system_loglevel & DBG) { \ + printk(KERN_DEBUG "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct system_obj_s { + struct switch_obj *obj; +}; + +struct system_s { + unsigned int api_number; + struct system_obj_s *temp; +}; + +static struct s3ip_sysfs_system_drivers_s *g_system_drv = NULL; +static struct switch_obj *g_system_obj = NULL; + +static ssize_t system_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int value; + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->get_system_value); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + SYSTEM_DBG("system_value_show type 0x%x \n", system_attr->type); + return g_system_drv->get_system_value(system_attr->type, &value, buf, PAGE_SIZE); +} + +static ssize_t system_value_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->set_system_value); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + + ret = kstrtoint(buf, 0, &value); + if (ret) { + SYSTEM_ERR("system_value_store, input parameter: %s error. ret:%d\n", buf, ret); + return ret; + } + + if(value > 0xff) { + SYSTEM_ERR("system_value_store, input parameter bigger than 0xff: %d\n", value); + return -EINVAL; + } + SYSTEM_DBG("system_value_store, type: 0x%x. value=%d\n", system_attr->type, value); + ret = g_system_drv->set_system_value(system_attr->type, value); + if (ret < 0) { + /* ret=-999 if not support */ + SYSTEM_ERR("set system reg value: %d failed. ret:%d\n", value, ret); + return ret; + } + return count; +} + +static ssize_t system_port_port_status_value(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->get_system_port_power_status); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + SYSTEM_DBG("type 0x%x \n", system_attr->type); + return g_system_drv->get_system_port_power_status(system_attr->type, buf, PAGE_SIZE); +} + +/************************************system dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(bmc_ready, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_BMC_READY); +static SWITCH_DEVICE_ATTR(sol_active, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_SOL_ACTIVE); +static SWITCH_DEVICE_ATTR(psu_reset, S_IWUSR, NULL, system_value_store, WB_SYSTEM_PSU_RESET); +static SWITCH_DEVICE_ATTR(cpu_board_ctrl, S_IWUSR, NULL, system_value_store, WB_SYSTEM_CPU_BOARD_CTRL); +static SWITCH_DEVICE_ATTR(cpu_board_status, S_IRUGO , system_value_show, NULL, WB_SYSTEM_CPU_BOARD_STATUS); +static SWITCH_DEVICE_ATTR(bios_switch, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BIOS_SWITCH); +static SWITCH_DEVICE_ATTR(bios_view, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_VIEW); +static SWITCH_DEVICE_ATTR(bios_boot_ok, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_BOOT_OK); +static SWITCH_DEVICE_ATTR(bios_fail_record, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_FAIL_RECORD); +static SWITCH_DEVICE_ATTR(bmc_reset, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BMC_RESET); +static SWITCH_DEVICE_ATTR(mac_board_reset, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_MAC_BOARD_RESET); +static SWITCH_DEVICE_ATTR(mac_pwr_ctrl, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_MAC_PWR_CTRL); +static SWITCH_DEVICE_ATTR(emmc_pwr_ctrl, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_EMMC_PWR_CTRL); +static SWITCH_DEVICE_ATTR(port_pwr_ctl, S_IRUGO | S_IWUSR, system_port_port_status_value, system_value_store, WB_SYSTEM_PORT_PWR_CTL); +static SWITCH_DEVICE_ATTR(bmc_view, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BMC_VIEW); +static SWITCH_DEVICE_ATTR(bmc_switch, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BMC_SWITCH); + +static struct attribute *system_dir_attrs[] = { + &switch_dev_attr_bmc_ready.switch_attr.attr, + &switch_dev_attr_sol_active.switch_attr.attr, + &switch_dev_attr_psu_reset.switch_attr.attr, + &switch_dev_attr_cpu_board_ctrl.switch_attr.attr, + &switch_dev_attr_cpu_board_status.switch_attr.attr, + &switch_dev_attr_bios_switch.switch_attr.attr, + &switch_dev_attr_bios_view.switch_attr.attr, + &switch_dev_attr_bios_boot_ok.switch_attr.attr, + &switch_dev_attr_bios_fail_record.switch_attr.attr, + &switch_dev_attr_bmc_reset.switch_attr.attr, + &switch_dev_attr_mac_board_reset.switch_attr.attr, + &switch_dev_attr_mac_pwr_ctrl.switch_attr.attr, + &switch_dev_attr_emmc_pwr_ctrl.switch_attr.attr, + &switch_dev_attr_port_pwr_ctl.switch_attr.attr, + &switch_dev_attr_bmc_view.switch_attr.attr, + &switch_dev_attr_bmc_switch.switch_attr.attr, + NULL, +}; + +static struct attribute_group system_root_attr_group = { + .attrs = system_dir_attrs, +}; + +/* create system directory and number attributes */ +static int system_root_create(void) +{ + g_system_obj = switch_kobject_create("system", NULL); + if (!g_system_obj) { + SYSTEM_ERR("switch_kobject_create system error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_system_obj->kobj, &system_root_attr_group) != 0) { + switch_kobject_delete(&g_system_obj); + SYSTEM_ERR("create system dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete system directory and number attributes */ +static void system_root_remove(void) +{ + if (g_system_obj) { + sysfs_remove_group(&g_system_obj->kobj, &system_root_attr_group); + switch_kobject_delete(&g_system_obj); + } + + return; +} + +int s3ip_sysfs_system_drivers_register(struct s3ip_sysfs_system_drivers_s *drv) +{ + int ret; + + SYSTEM_INFO("s3ip_sysfs_system_drivers_register...\n"); + check_p(drv); + g_system_drv = drv; + ret = system_root_create(); + if (ret < 0) { + SYSTEM_ERR("create system root dir and attrs failed, ret: %d\n", ret); + return ret; + } + + SYSTEM_INFO("s3ip_sysfs_system_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_system_drivers_unregister(void) +{ + if (g_system_drv) { + system_root_remove(); + g_system_drv = NULL; + SYSTEM_DBG("s3ip_sysfs_system_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_system_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_system_drivers_unregister); +module_param(g_system_loglevel, int, 0644); +MODULE_PARM_DESC(g_system_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c new file mode 100644 index 000000000000..bfda43b47973 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c @@ -0,0 +1,458 @@ +/* + * An temp_sensor_sysfs driver for temperature sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "temp_sensor_sysfs.h" + +static int g_temp_sensor_loglevel = 0; + +#define TEMP_SENSOR_INFO(fmt, args...) do { \ + if (g_temp_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_ERR(fmt, args...) do { \ + if (g_temp_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_DBG(fmt, args...) do { \ + if (g_temp_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_sensor_obj_s { + struct switch_obj *obj; +}; + +struct temp_sensor_s { + unsigned int temp_number; + struct temp_sensor_obj_s *temp; +}; + +static struct s3ip_sysfs_temp_sensor_drivers_s *g_temp_sensor_drv = NULL; +static struct temp_sensor_s g_temp_sensor; +static struct switch_obj *g_temp_sensor_obj = NULL; + +static ssize_t temp_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_temp_sensor.temp_number); +} + +static ssize_t temp_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_value); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_value(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_alias); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_alias(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_type); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_type(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_max(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_max(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_min(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_min(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_high_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_high); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_high(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_high_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_high); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_high(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u high threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u high threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_low_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_low); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_low(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_low_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_low); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_low(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u low threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u low threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_monitor_flag); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_monitor_flag(temp_index, buf, PAGE_SIZE); +} + +/************************************temp_sensor dir and attrs*******************************************/ +static struct switch_attribute num_temp_att = __ATTR(number, S_IRUGO, temp_sensor_number_show, NULL); + +static struct attribute *temp_sensor_dir_attrs[] = { + &num_temp_att.attr, + NULL, +}; + +static struct attribute_group temp_sensor_root_attr_group = { + .attrs = temp_sensor_dir_attrs, +}; + +/*******************************temp1 temp2 dir and attrs*******************************************/ +static struct switch_attribute temp_value_attr = __ATTR(value, S_IRUGO, temp_sensor_value_show, NULL); +static struct switch_attribute temp_alias_attr = __ATTR(alias, S_IRUGO, temp_sensor_alias_show, NULL); +static struct switch_attribute temp_type_attr = __ATTR(type, S_IRUGO, temp_sensor_type_show, NULL); +static struct switch_attribute temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, temp_sensor_max_show, temp_sensor_max_store); +static struct switch_attribute temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, temp_sensor_min_show, temp_sensor_min_store); +static struct switch_attribute temp_high_attr = __ATTR(high, S_IRUGO | S_IWUSR, temp_sensor_high_show, temp_sensor_high_store); +static struct switch_attribute temp_low_attr = __ATTR(low, S_IRUGO | S_IWUSR, temp_sensor_low_show, temp_sensor_low_store); +static struct switch_attribute temp_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, temp_sensor_monitor_flag_show, NULL); + +static struct attribute *temp_sensor_attrs[] = { + &temp_value_attr.attr, + &temp_alias_attr.attr, + &temp_type_attr.attr, + &temp_max_attr.attr, + &temp_min_attr.attr, + &temp_high_attr.attr, + &temp_low_attr.attr, + &temp_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group temp_sensor_attr_group = { + .attrs = temp_sensor_attrs, +}; + +static int temp_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", index); + temp_sensor->obj = switch_kobject_create(name, parent); + if (!temp_sensor->obj) { + TEMP_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + temp_sensor->obj->index = index; + if (sysfs_create_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group) != 0) { + TEMP_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&temp_sensor->obj); + return -EBADRQC; + } + TEMP_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void temp_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + if (temp_sensor->obj) { + sysfs_remove_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group); + switch_kobject_delete(&temp_sensor->obj); + TEMP_SENSOR_DBG("delete temp%u dir and attrs success.\n", index); + } + + return; +} + +static int temp_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num) +{ + unsigned int temp_index, i; + + g_temp_sensor.temp = kzalloc(sizeof(struct temp_sensor_obj_s) * temp_num, GFP_KERNEL); + if (!g_temp_sensor.temp) { + TEMP_SENSOR_ERR("kzalloc g_temp_sensor.temp error, temp number: %d.\n", temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (temp_sensor_sub_single_create_kobj_and_attrs(parent, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + temp_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + return -EBADRQC; +} + +/* create temp[1-n] directory and attributes*/ +static int temp_sensor_sub_create(void) +{ + int ret; + + ret = temp_sensor_sub_create_kobj_and_attrs(&g_temp_sensor_obj->kobj, + g_temp_sensor.temp_number); + return ret; +} + +/* delete temp[1-n] directory and attributes*/ +static void temp_sensor_sub_remove(void) +{ + unsigned int temp_index; + + if (g_temp_sensor.temp) { + for (temp_index = g_temp_sensor.temp_number; temp_index > 0; temp_index--) { + temp_sensor_sub_single_remove_kobj_and_attrs(temp_index); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + } + + return; +} + +/* create temp_sensor directory and number attributes */ +static int temp_sensor_root_create(void) +{ + g_temp_sensor_obj = switch_kobject_create("temp_sensor", NULL); + if (!g_temp_sensor_obj) { + TEMP_SENSOR_ERR("switch_kobject_create temp_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_temp_sensor_obj); + TEMP_SENSOR_ERR("create temp_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete temp_sensor directory and number attributes */ +static void temp_sensor_root_remove(void) +{ + if (g_temp_sensor_obj) { + sysfs_remove_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group); + switch_kobject_delete(&g_temp_sensor_obj); + } + + return; +} + +int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv) +{ + int ret, temp_num; + + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register...\n"); + if (g_temp_sensor_drv) { + TEMP_SENSOR_ERR("g_temp_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_temp_number); + g_temp_sensor_drv = drv; + + temp_num = g_temp_sensor_drv->get_main_board_temp_number(); + if (temp_num <= 0) { + TEMP_SENSOR_ERR("temp sensor number: %d, don't need to create temp_sensor dirs and attrs.\n", + temp_num); + g_temp_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_temp_sensor, sizeof(struct temp_sensor_s)); + g_temp_sensor.temp_number = temp_num; + ret = temp_sensor_root_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor root dir and attrs failed, ret: %d\n", ret); + g_temp_sensor_drv = NULL; + return ret; + } + + ret = temp_sensor_sub_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor sub dir and attrs failed, ret: %d\n", ret); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + return ret; + } + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_temp_sensor_drivers_unregister(void) +{ + if (g_temp_sensor_drv) { + temp_sensor_sub_remove(); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + TEMP_SENSOR_DBG("s3ip_sysfs_temp_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_unregister); +module_param(g_temp_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_temp_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c new file mode 100644 index 000000000000..6384b452186c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c @@ -0,0 +1,996 @@ +/* + * An transceiver_sysfs driver for transceiver sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "transceiver_sysfs.h" + +static int g_sff_loglevel = 0; +static bool g_sff_present_debug = 0; + +#define WB_QSFP_TX_FAULT_OFFSET (4) +#define WB_QSFPDD_TX_FAULT_OFFSET (17*128 + 135) +#define WB_QSFP_TX_DISABLE_OFFSET (86) +#define WB_QSFPDD_TX_DISABLE_OFFSET (16*128 + 130) +#define WB_QSFP_RX_LOS_OFFSET (3) +#define WB_QSFPDD_RX_LOS_OFFSET (17*128 + 147) +#define WB_QSFP_LP_MODE_OFFSET (93) +#define WB_QSFPDD_LP_MODE_OFFSET (26) + +#define SFF_INFO(fmt, args...) do { \ + if (g_sff_loglevel & INFO) { \ + printk(KERN_INFO "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_ERR(fmt, args...) do { \ + if (g_sff_loglevel & ERR) { \ + printk(KERN_ERR "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_DBG(fmt, args...) do { \ + if (g_sff_loglevel & DBG) { \ + printk(KERN_DEBUG "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct sff_obj_s { + struct switch_obj *sff_obj; + struct bin_attribute bin; + int sff_creat_bin_flag; +}; + +struct sff_s { + unsigned int sff_number; + struct sff_obj_s *sff; +}; + +static struct sff_s g_sff; +static struct switch_obj *g_sff_obj = NULL; +static struct s3ip_sysfs_transceiver_drivers_s *g_sff_drv = NULL; + +static ssize_t transceiver_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + check_p(g_sff_drv); + check_p(g_sff_drv->get_transceiver_power_on_status); + + return g_sff_drv->get_transceiver_power_on_status(buf, PAGE_SIZE); +} + +static ssize_t transceiver_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index, eth_num; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_power_on_status); + + sscanf(buf, "%d", &value); + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set power on status.\n", value); + return -EINVAL; + } + + eth_num = g_sff.sff_number; + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->set_eth_power_on_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u power status failed, ret: %d\n", eth_index, ret); + break; + } + } + SFF_DBG("transceiver_power_on_store ok. sff num:%d, len:%d\n", eth_num, ret); + return count; +} + +static ssize_t transceiver_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sff.sff_number); +} + +static ssize_t eth_optoe_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int sff_index; + int optoe_type; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_optoe_type); + + sff_index = obj->index; + SFF_DBG("eth_optoe_type_show, sff index:%u\n", sff_index); + return g_sff_drv->get_eth_optoe_type(sff_index, &optoe_type, buf, PAGE_SIZE); +} + +static ssize_t eth_optoe_type_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int sff_index; + int ret; + int optoe_type; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_optoe_type); + + ret = kstrtoint(buf, 0, &optoe_type); + if (ret != 0) { + SFF_ERR("invaild optoe_type ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + + sff_index = obj->index; + SFF_DBG("eth_optoe_type_store, sff index:%u, optoe_type:%d\n", sff_index, optoe_type); + ret = g_sff_drv->set_eth_optoe_type(sff_index, optoe_type); + if(ret < 0) { + SFF_ERR("set_eth_optoe_type error. sff index:%u, ret:%d\n", sff_index, ret); + return ret; + } + + SFF_DBG("eth_optoe_type_store ok. sff index:%u, optoe_type:%d\n", sff_index, optoe_type); + return count; +} + + +static ssize_t transceiver_present_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + check_p(g_sff_drv); + check_p(g_sff_drv->get_transceiver_present_status); + + return g_sff_drv->get_transceiver_present_status(buf, PAGE_SIZE); +} + +static ssize_t eth_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_power_on_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_power_on_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_power_on_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u power on status.\n", value, eth_index); + return -EINVAL; + } + + ret = g_sff_drv->set_eth_power_on_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u power on status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + SFF_DBG("set eth%u power on status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_tx_fault_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_tx_fault_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_tx_fault_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_FAULT_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_FAULT_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module tx fault value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_tx_disable_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_tx_disable_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_tx_disable_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_DISABLE_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_DISABLE_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module tx disable value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_tx_disable_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + char module_type[1], write_buf[1]; + loff_t offset; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->write_eth_eeprom_data); + check_p(g_sff_drv->set_eth_tx_disable_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + SFF_DBG("eth index: %u, tx_disable:0x%x\n", eth_index, value); + + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u tx disable status.\n", value, eth_index); + } + + write_buf[0] = 0; + mem_clear(module_type, sizeof(module_type)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + + ret = g_sff_drv->set_eth_tx_disable_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u tx disable status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_DISABLE_OFFSET; + if (value != 0) { + write_buf[0] = 0xf; + } + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_DISABLE_OFFSET; + if (value != 0) { + write_buf[0] = 0xff; + } + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return -EINVAL; + } + + ret = g_sff_drv->write_eth_eeprom_data(eth_index, write_buf, offset, 1); + if (ret < 0) { + SFF_ERR("set eth%u tx disable status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + } + + SFF_DBG("set eth%u tx disable status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_present_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_present_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_present_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u present status failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (g_sff_present_debug) { + SFF_INFO("s3ip sysfs sff present debug is enable\n"); + if (strcmp(buf, DEV_ABSENT_STR) == 0) { + SFF_DBG("eth%d absent, return act value\n", eth_index); + return ret; + } + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + SFF_DBG("eth%d status sysfs unsupport or error\n", eth_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_TRANSCEIVER_PRESENT_DEBUG_FILE, eth_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + SFF_ERR("eth%u present debug file read failed, ret: %d\n", eth_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, DEV_PRESEN_STR) == 0) || (strcmp(debug_file_buf, DEV_ABSENT_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + SFF_ERR("eth%d present debug file value err, value: %s, not 0 or 1\n", eth_index, debug_file_buf); + return ret; + } + } + return ret; +} + +static ssize_t eth_rx_los_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_rx_los_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_rx_los_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_RX_LOS_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_RX_LOS_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module rx los value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_reset_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_reset_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_reset_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_reset_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + ret = g_sff_drv->set_eth_reset_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u reset status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + SFF_DBG("set eth%u reset status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_low_power_mode_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_ERR("eth%u SFP module low power mode no support\n", eth_index); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_LP_MODE_OFFSET; + mask = 0x3; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_LP_MODE_OFFSET; + mask = 0x10; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) == mask) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_low_power_mode_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + char module_type[1], tmp_v[1]; + loff_t offset; + unsigned char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->write_eth_eeprom_data); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u lp mode status.\n", value, eth_index); + return -EINVAL; + } + + mask = 0; + mem_clear(module_type, sizeof(module_type)); + mem_clear(tmp_v, sizeof(tmp_v)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + return ret; + } + SFF_DBG("module type:0x%x\n", module_type[0]); + + if (module_type[0] == 0x03) { + SFF_ERR("eth%u SFP module low power mode no support\n", eth_index); + return -WB_SYSFS_RV_UNSUPPORT; + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_LP_MODE_OFFSET; + mask = 0x3; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_LP_MODE_OFFSET; + mask = 0x10; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return -EINVAL; + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, tmp_v, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (value == 1) { + tmp_v[0] = tmp_v[0] | mask; + } else { + tmp_v[0] = tmp_v[0] & (~mask); + } + + ret = g_sff_drv->write_eth_eeprom_data(eth_index, tmp_v, offset, 1); + if (ret < 0) { + SFF_ERR("set eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + return -EIO; + } + } + + return count; +} + +static ssize_t eth_interrupt_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_interrupt_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_interrupt_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t rd_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + mem_clear(buf, count); + rd_len = g_sff_drv->read_eth_eeprom_data(eth_index, buf, offset, count); + if (rd_len < 0) { + SFF_ERR("read eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, rd_len); + return rd_len; + } + + SFF_DBG("read eth%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + eth_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t eth_eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t wr_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->write_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + wr_len = g_sff_drv->write_eth_eeprom_data(eth_index, buf, offset, count); + if (wr_len < 0) { + SFF_ERR("write eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, wr_len); + return wr_len; + } + + SFF_DBG("write eth%u eeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + eth_index, offset, count, wr_len); + + return wr_len; +} + +/************************************eth* signal attrs*******************************************/ +static struct switch_attribute eth_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, eth_power_on_show, eth_power_on_store); +static struct switch_attribute eth_tx_fault_attr = __ATTR(tx_fault, S_IRUGO, eth_tx_fault_show, NULL); +static struct switch_attribute eth_tx_disable_attr = __ATTR(tx_disable, S_IRUGO | S_IWUSR, eth_tx_disable_show, eth_tx_disable_store); +static struct switch_attribute eth_present_attr = __ATTR(present, S_IRUGO, eth_present_show, NULL); +static struct switch_attribute eth_rx_los_attr = __ATTR(rx_los, S_IRUGO, eth_rx_los_show, NULL); +static struct switch_attribute eth_reset_attr = __ATTR(reset, S_IRUGO | S_IWUSR, eth_reset_show, eth_reset_store); +static struct switch_attribute eth_low_power_mode_attr = __ATTR(low_power_mode, S_IRUGO | S_IWUSR, eth_low_power_mode_show, eth_low_power_mode_store); +static struct switch_attribute eth_interrupt_attr = __ATTR(interrupt, S_IRUGO, eth_interrupt_show, NULL); +static struct switch_attribute eth_optoe_type_attr = __ATTR(optoe_type, S_IRUGO | S_IWUSR, eth_optoe_type_show, eth_optoe_type_store); + +static struct attribute *sff_signal_attrs[] = { + ð_power_on_attr.attr, + ð_tx_fault_attr.attr, + ð_tx_disable_attr.attr, + ð_present_attr.attr, + ð_rx_los_attr.attr, + ð_reset_attr.attr, + ð_low_power_mode_attr.attr, + ð_interrupt_attr.attr, + ð_optoe_type_attr.attr, + NULL, +}; + +static struct attribute_group sff_signal_attr_group = { + .attrs = sff_signal_attrs, +}; + +/*******************************transceiver dir and attrs*******************************************/ +static struct switch_attribute transceiver_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, transceiver_power_on_show, transceiver_power_on_store); +static struct switch_attribute transceiver_number_attr = __ATTR(number, S_IRUGO, transceiver_number_show, NULL); +static struct switch_attribute transceiver_present_attr = __ATTR(present, S_IRUGO, transceiver_present_show, NULL); + +static struct attribute *transceiver_dir_attrs[] = { + &transceiver_power_on_attr.attr, + &transceiver_number_attr.attr, + &transceiver_present_attr.attr, + NULL, +}; + +static struct attribute_group sff_transceiver_attr_group = { + .attrs = transceiver_dir_attrs, +}; + +/* create eth* eeprom attributes */ +static int sff_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct sff_obj_s *curr_sff; + + check_p(g_sff_drv->get_eth_eeprom_size); + eeprom_size = g_sff_drv->get_eth_eeprom_size(index); + if (eeprom_size <= 0) { + SFF_INFO("eth%u, eeprom_size: %d, don't need to creat eeprom attr.\n", + index, eeprom_size); + return 0; + } + + curr_sff = &g_sff.sff[index - 1]; + sysfs_bin_attr_init(&curr_sff->bin); + curr_sff->bin.attr.name = "eeprom"; + curr_sff->bin.attr.mode = 0644; + curr_sff->bin.read = eth_eeprom_read; + curr_sff->bin.write = eth_eeprom_write; + curr_sff->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + if (ret) { + SFF_ERR("eth%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + SFF_DBG("eth%u, create bin file success, eeprom size:%d.\n", index, eeprom_size); + curr_sff->sff_creat_bin_flag = 1; + return 0; +} + +static int sff_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct sff_obj_s *curr_sff; + char sff_dir_name[DIR_NAME_MAX_LEN]; + + curr_sff = &g_sff.sff[index - 1]; + mem_clear(sff_dir_name, sizeof(sff_dir_name)); + snprintf(sff_dir_name, sizeof(sff_dir_name), "eth%d", index); + curr_sff->sff_obj = switch_kobject_create(sff_dir_name, parent); + if (!curr_sff->sff_obj) { + SFF_ERR("create eth%d object error! \n", index); + return -EBADRQC; + } + curr_sff->sff_obj->index = index; + if (sysfs_create_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group) != 0) { + switch_kobject_delete(&curr_sff->sff_obj); + return -EBADRQC; + } + + SFF_DBG("create eth%d dir and attrs success\n", index); + return 0; +} + +/* remove eth directory and attributes */ +static void sff_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sff_obj_s *curr_sff; + + curr_sff = &g_sff.sff[index - 1]; + if (curr_sff->sff_obj) { + if (curr_sff->sff_creat_bin_flag) { + sysfs_remove_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + curr_sff->sff_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group); + switch_kobject_delete(&curr_sff->sff_obj); + } + + return; +} + +static int sff_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = sff_sub_single_create_kobj(parent, index); + if (ret < 0) { + SFF_ERR("create eth%d dir error.\n", index); + return ret; + } + + sff_sub_single_create_eeprom_attrs(index); + return 0; +} + +static int sff_sub_create_kobj_and_attrs(struct kobject *parent, int sff_num) +{ + unsigned int sff_index, i; + + g_sff.sff = kzalloc(sizeof(struct sff_obj_s) * sff_num, GFP_KERNEL); + if (!g_sff.sff) { + SFF_ERR("kzalloc g_sff.sff error, sff number = %d.\n", sff_num); + return -ENOMEM; + } + + for (sff_index = 1; sff_index <= sff_num; sff_index++) { + if (sff_sub_single_create_kobj_and_attrs(parent, sff_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = sff_index; i > 0; i--) { + sff_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + return -EBADRQC; +} + +/* create eth directory and attributes */ +static int sff_sub_create(void) +{ + int ret; + + ret = sff_sub_create_kobj_and_attrs(&g_sff_obj->kobj, g_sff.sff_number); + return ret; +} + +/* delete eth directory and attributes */ +static void sff_sub_remove(void) +{ + unsigned int sff_index; + + if (g_sff.sff) { + for (sff_index = g_sff.sff_number; sff_index > 0; sff_index--) { + sff_sub_single_remove_kobj_and_attrs(sff_index); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + } + g_sff.sff_number = 0; + return; +} + +/* create transceiver directory and attributes */ +static int sff_transceiver_create(void) +{ + g_sff_obj = switch_kobject_create("transceiver", NULL); + if (!g_sff_obj) { + SFF_ERR("switch_kobject_create transceiver error!\n"); + return -ENOMEM; + } + g_sff_obj->index = 0; + if (sysfs_create_group(&g_sff_obj->kobj, &sff_transceiver_attr_group) != 0) { + switch_kobject_delete(&g_sff_obj); + SFF_ERR("create transceiver dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete transceiver directory and attributes */ +static void sff_transceiver_remove(void) +{ + if (g_sff_obj) { + sysfs_remove_group(&g_sff_obj->kobj, &sff_transceiver_attr_group); + switch_kobject_delete(&g_sff_obj); + } + + return; +} + +int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv) +{ + int ret, sff_num; + + SFF_INFO("s3ip_sysfs_sff_drivers_register...\n"); + if (g_sff_drv) { + SFF_ERR("g_sff_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_eth_number); + g_sff_drv = drv; + + sff_num = g_sff_drv->get_eth_number(); + if (sff_num <= 0) { + SFF_ERR("eth number: %d, don't need to create transceiver dirs and attrs.\n", sff_num); + g_sff_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_sff, sizeof(struct sff_s)); + g_sff.sff_number = sff_num; + ret = sff_transceiver_create(); + if (ret < 0) { + SFF_ERR("create transceiver root dir and attrs failed, ret: %d\n", ret); + g_sff_drv = NULL; + return ret; + } + ret = sff_sub_create(); + if (ret < 0) { + SFF_ERR("create transceiver sub dir and attrs failed, ret: %d\n", ret); + sff_transceiver_remove(); + g_sff_drv = NULL; + return ret; + } + SFF_INFO("s3ip_sysfs_sff_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_sff_drivers_unregister(void) +{ + if (g_sff_drv) { + sff_sub_remove(); + sff_transceiver_remove(); + g_sff_drv = NULL; + SFF_DBG("s3ip_sysfs_sff_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_unregister); +module_param(g_sff_loglevel, int, 0644); +MODULE_PARM_DESC(g_sff_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_sff_present_debug, bool, 0644); +MODULE_PARM_DESC(g_sff_present_debug, "the sff present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c new file mode 100644 index 000000000000..737aa3d94393 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c @@ -0,0 +1,416 @@ +/* + * An vol_sensor_sysfs driver for voltage sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "vol_sensor_sysfs.h" + +static int g_vol_sensor_loglevel = 0; + +#define VOL_SENSOR_INFO(fmt, args...) do { \ + if (g_vol_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_ERR(fmt, args...) do { \ + if (g_vol_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_DBG(fmt, args...) do { \ + if (g_vol_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct vol_sensor_obj_s { + struct switch_obj *obj; +}; + +struct vol_sensor_s { + unsigned int vol_number; + struct vol_sensor_obj_s *vol; +}; + +static struct s3ip_sysfs_vol_sensor_drivers_s *g_vol_sensor_drv = NULL; +static struct vol_sensor_s g_vol_sensor; +static struct switch_obj *g_vol_sensor_obj = NULL; + +static ssize_t vol_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_vol_sensor.vol_number); +} + +static ssize_t vol_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_value(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_alias); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_alias(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_type); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_type(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_max(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_max(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return ret; + } + VOL_SENSOR_DBG("set vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_min(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_min(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return ret; + } + VOL_SENSOR_DBG("set vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_range); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_range(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_nominal_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_nominal_value(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_monitor_flag); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_monitor_flag(vol_index, buf, PAGE_SIZE); +} + +/************************************vol_sensor dir and attrs*******************************************/ +static struct switch_attribute num_vol_att = __ATTR(number, S_IRUGO, vol_sensor_number_show, NULL); + +static struct attribute *vol_sensor_dir_attrs[] = { + &num_vol_att.attr, + NULL, +}; + +static struct attribute_group vol_sensor_root_attr_group = { + .attrs = vol_sensor_dir_attrs, +}; + +/*******************************vol1 vol2 dir and attrs*******************************************/ +static struct switch_attribute vol_value_attr = __ATTR(value, S_IRUGO, vol_sensor_value_show, NULL); +static struct switch_attribute vol_alias_attr = __ATTR(alias, S_IRUGO, vol_sensor_alias_show, NULL); +static struct switch_attribute vol_type_attr = __ATTR(type, S_IRUGO, vol_sensor_type_show, NULL); +static struct switch_attribute vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, vol_sensor_max_show, vol_sensor_max_store); +static struct switch_attribute vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, vol_sensor_min_show, vol_sensor_min_store); +static struct switch_attribute vol_range_attr = __ATTR(range, S_IRUGO, vol_sensor_range_show, NULL); +static struct switch_attribute vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, vol_sensor_nominal_value_show, NULL); +static struct switch_attribute vol_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, vol_sensor_monitor_flag_show, NULL); + +static struct attribute *vol_sensor_attrs[] = { + &vol_value_attr.attr, + &vol_alias_attr.attr, + &vol_type_attr.attr, + &vol_max_attr.attr, + &vol_min_attr.attr, + &vol_range_attr.attr, + &vol_nominal_value_attr.attr, + &vol_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group vol_sensor_attr_group = { + .attrs = vol_sensor_attrs, +}; + +static int vol_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "vol%u", index); + vol_sensor->obj = switch_kobject_create(name, parent); + if (!vol_sensor->obj) { + VOL_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + + vol_sensor->obj->index = index; + if (sysfs_create_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group) != 0) { + VOL_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&vol_sensor->obj); + return -EBADRQC; + } + VOL_SENSOR_DBG("create %s dir and attrs success.\n", name); + + return 0; +} + +static void vol_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + if (vol_sensor->obj) { + sysfs_remove_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group); + switch_kobject_delete(&vol_sensor->obj); + VOL_SENSOR_DBG("delete vol%u dir and attrs success.\n", index); + } + + return; +} + +static int vol_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int vol_num) +{ + unsigned int vol_index, i; + + g_vol_sensor.vol = kzalloc(sizeof(struct vol_sensor_obj_s) * vol_num, GFP_KERNEL); + if (!g_vol_sensor.vol) { + VOL_SENSOR_ERR("kzalloc g_vol_sensor.vol error, vol number: %d.\n", vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (vol_sensor_sub_single_create_kobj_and_attrs(parent, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + vol_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + return -EBADRQC; +} + +/* create vol[1-n] directory and attributes*/ +static int vol_sensor_sub_create(void) +{ + int ret; + + ret = vol_sensor_sub_create_kobj_and_attrs(&g_vol_sensor_obj->kobj, g_vol_sensor.vol_number); + return ret; +} + +/* delete vol[1-n] directory and attributes*/ +static void vol_sensor_sub_remove(void) +{ + unsigned int vol_index; + + if (g_vol_sensor.vol) { + for (vol_index = g_vol_sensor.vol_number; vol_index > 0; vol_index--) { + vol_sensor_sub_single_remove_kobj_and_attrs(vol_index); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + } + + return; +} + +/* create vol_sensor directory and number attributes */ +static int vol_sensor_root_create(void) +{ + g_vol_sensor_obj = switch_kobject_create("vol_sensor", NULL); + if (!g_vol_sensor_obj) { + VOL_SENSOR_ERR("switch_kobject_create vol_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_vol_sensor_obj); + VOL_SENSOR_ERR("create vol_sensor dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete vol_sensor directory and number attributes */ +static void vol_sensor_root_remove(void) +{ + if (g_vol_sensor_obj) { + sysfs_remove_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group); + switch_kobject_delete(&g_vol_sensor_obj); + } + + return; +} + +int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv) +{ + int ret, vol_num; + + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register...\n"); + if (g_vol_sensor_drv) { + VOL_SENSOR_ERR("g_vol_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_vol_number); + g_vol_sensor_drv = drv; + + vol_num = g_vol_sensor_drv->get_main_board_vol_number(); + if (vol_num <= 0) { + VOL_SENSOR_ERR("vol sensor number: %d, don't need to create vol_sensor dirs and attrs.\n", + vol_num); + g_vol_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_vol_sensor, sizeof(struct vol_sensor_s)); + g_vol_sensor.vol_number = vol_num; + ret = vol_sensor_root_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor root dir and attrs failed, ret: %d\n", ret); + g_vol_sensor_drv = NULL; + return ret; + } + + ret = vol_sensor_sub_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor sub dir and attrs failed, ret: %d\n", ret); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + return ret; + } + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_vol_sensor_drivers_unregister(void) +{ + if (g_vol_sensor_drv) { + vol_sensor_sub_remove(); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + VOL_SENSOR_DBG("s3ip_sysfs_vol_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_unregister); +module_param(g_vol_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_vol_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c new file mode 100644 index 000000000000..3188f18958f4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c @@ -0,0 +1,241 @@ +/* + * An watchdog_sysfs driver for watchdog sysfs devcie function + * + * Copyright (C) 2024 Micas 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 + * 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 "switch.h" +#include "watchdog_sysfs.h" + +static int g_wdt_loglevel = 0; + +#define WDT_INFO(fmt, args...) do { \ + if (g_wdt_loglevel & INFO) { \ + printk(KERN_INFO "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_ERR(fmt, args...) do { \ + if (g_wdt_loglevel & ERR) { \ + printk(KERN_ERR "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_DBG(fmt, args...) do { \ + if (g_wdt_loglevel & DBG) { \ + printk(KERN_DEBUG "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef enum wdt_enable_status_e { + WDT_DISENABLE = 0, /* close watchdog */ + WDT_ENABLE = 1, /* open watchdog */ +} wdt_enable_status_t; + +static struct switch_obj *g_watchdog_obj = NULL; +static struct s3ip_sysfs_watchdog_drivers_s *g_wdt_drv = NULL; + +static ssize_t watchdog_identify_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_identify); + + return g_wdt_drv->get_watchdog_identify(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeleft_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeleft); + + return g_wdt_drv->get_watchdog_timeleft(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeout_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeout); + + return g_wdt_drv->get_watchdog_timeout(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeout_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_timeout); + + sscanf(buf, "%d", &value); + if (value < 0) { + WDT_ERR("invaild timeout value: %d, can't set watchdog timeout\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_timeout(value); + if (ret < 0) { + WDT_ERR("set watchdog timeout value: %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog timeout value: %d success\n", ret); + return count; +} + +static ssize_t watchdog_enable_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_enable_status); + + return g_wdt_drv->get_watchdog_enable_status(buf, PAGE_SIZE); +} + +static ssize_t watchdog_enable_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_enable_status); + + sscanf(buf, "%d", &value); + if ((value != WDT_DISENABLE) && (value != WDT_ENABLE)) { + WDT_ERR("invaild enable value: %d, can't set watchdog enable status\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_enable_status(value); + if (ret < 0) { + WDT_ERR("set watchdog enable status %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog enable status %d success\n", ret); + return count; +} + +static ssize_t watchdog_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_reset); + + ret = kstrtoint(buf, 0, &value); + if (ret) { + WDT_ERR("invalid value: %s \n", buf); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_reset(value); + if (ret < 0) { + WDT_ERR("set watchdog reset %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog reset %d success\n", ret); + return count; +} + +/************************************watchdog*******************************************/ +static struct switch_attribute watchdog_identify_attr = __ATTR(identify, S_IRUGO, watchdog_identify_show, NULL); +static struct switch_attribute watchdog_timeleft_attr = __ATTR(timeleft, S_IRUGO, watchdog_timeleft_show, NULL); +static struct switch_attribute watchdog_timeout_attr = __ATTR(timeout, S_IRUGO | S_IWUSR, watchdog_timeout_show, watchdog_timeout_store); +static struct switch_attribute watchdog_enable_attr = __ATTR(enable, S_IRUGO | S_IWUSR, watchdog_enable_status_show, watchdog_enable_status_store); +static struct switch_attribute watchdog_reset_attr = __ATTR(reset, S_IWUSR, NULL, watchdog_reset_store); + +static struct attribute *watchdog_dir_attrs[] = { + &watchdog_identify_attr.attr, + &watchdog_timeleft_attr.attr, + &watchdog_timeout_attr.attr, + &watchdog_enable_attr.attr, + &watchdog_reset_attr.attr, + NULL, +}; + +static struct attribute_group watchdog_attr_group = { + .attrs = watchdog_dir_attrs, +}; + +/* create watchdog directory and attributes */ +static int watchdog_root_create(void) +{ + g_watchdog_obj = switch_kobject_create("watchdog", NULL); + if (!g_watchdog_obj) { + WDT_ERR("switch_kobject_create watchdog error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_watchdog_obj->kobj, &watchdog_attr_group) != 0) { + switch_kobject_delete(&g_watchdog_obj); + WDT_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete watchdog directory and attributes */ +static void watchdog_root_remove(void) +{ + if (g_watchdog_obj) { + sysfs_remove_group(&g_watchdog_obj->kobj, &watchdog_attr_group); + switch_kobject_delete(&g_watchdog_obj); + } + + return; +} + +int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv) +{ + int ret; + + WDT_INFO("s3ip_sysfs_watchdog_drivers_register...\n"); + if (g_wdt_drv) { + WDT_ERR("g_wdt_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_wdt_drv = drv; + + ret = watchdog_root_create(); + if (ret < 0) { + WDT_ERR("watchdog create error.\n"); + g_wdt_drv = NULL; + return ret; + } + WDT_INFO("s3ip_sysfs_watchdog_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_watchdog_drivers_unregister(void) +{ + if (g_wdt_drv) { + watchdog_root_remove(); + g_wdt_drv = NULL; + WDT_DBG("s3ip_sysfs_watchdog_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_unregister); +module_param(g_wdt_loglevel, int, 0644); +MODULE_PARM_DESC(g_wdt_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c index 0b95663b9bad..55f6a529c7be 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c @@ -1,8 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0-or-later /* - * Hardware monitoring driver for PMBus devices + * An wb_csu550 driver for psu csu550 function * - * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c index 22cd9e16de08..b237df4e36a9 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c @@ -1,7 +1,23 @@ /* - * fpga_i2c_bus_drv.c - * ko to create fpga i2c adapter + * An wb_fpga_i2c_bus_drv driver for create fpga i2c adapter function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -34,6 +50,8 @@ extern int io_device_func_write(const char *path, uint32_t pos, uint8_t *val, si extern int io_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); extern int spi_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int indirect_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int indirect_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); #define FPGA_I2C_STRETCH_TIMEOUT (0x01) #define FPGA_I2C_DEADLOCK_FAILED (0x02) @@ -53,6 +71,7 @@ extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf #define SYMBOL_PCIE_DEV_MODE (3) #define SYMBOL_IO_DEV_MODE (4) #define SYMBOL_SPI_DEV_MODE (5) +#define SYMBOL_INDIRECT_DEV_MODE (6) int g_wb_fpga_i2c_debug = 0; int g_wb_fpga_i2c_error = 0; @@ -170,6 +189,9 @@ static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *va case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_write(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_I2C_ERROR("err func_mode %d, write failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; @@ -198,6 +220,9 @@ static int fpga_device_read(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_read(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_I2C_ERROR("err func_mode %d, read failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c index 25f2d60b9334..d55d0cef122f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c @@ -1,3 +1,23 @@ +/* + * An wb_fpga_pca954x_drv driver for create fpga pca954x adapter function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -17,6 +37,7 @@ extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, s extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); extern int io_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int indirect_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); #define PCA954X_MAX_NCHANS (8) #define FPGA_INTERNAL_PCA9548 (1) @@ -29,6 +50,7 @@ extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf #define SYMBOL_PCIE_DEV_MODE (3) #define SYMBOL_IO_DEV_MODE (4) #define SYMBOL_SPI_DEV_MODE (5) +#define SYMBOL_INDIRECT_DEV_MODE (6) int g_fpga_pca954x_debug = 0; int g_fpga_pca954x_error = 0; @@ -189,6 +211,9 @@ static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, int pos, unsigned char *v case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_write(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_PCA954X_ERROR("err func_mode %d, write failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; @@ -416,7 +441,6 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de data->type = id->driver_data; /* BUS ID */ ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag); - ret += of_property_read_u32(dev->of_node, "fpga_9548_reset_flag", &data->fpga_9548_reset_flag); if (ret != 0) { dev_err(&client->dev, "Failed to get 954x dts config, ret:%d.\n", ret); ret = -EINVAL; @@ -431,7 +455,8 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); } } - + data->fpga_9548_reset_flag = 1; + dev_info(&client->dev, "pca9548_reset_mode is forcibly set to the hardware automatic reset mode.\n"); if (data->fpga_9548_flag != FPGA_EXTERNAL_PCA9548 && data->fpga_9548_flag != FPGA_INTERNAL_PCA9548) { dev_err(&client->dev, "Error: fpga 954x flag config error, value:0x%x.\n", data->fpga_9548_flag); ret = -EINVAL; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c index baabfb5cd4d0..43fc67419f0a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c @@ -1,7 +1,23 @@ /* - * wb_fpga_pcie.c - * ko to enable fpga pcie + * An wb_fpga_pcie driver for create fpga pcie adapter function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c index 7d5d5da87ea7..25fa7acc1f1f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c @@ -1,10 +1,24 @@ /* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * An wb_gpio_d1500 driver for gpio d1500 function * - * Copyright (C) 2011, 2012 Cavium Inc. + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c index 75f883b5909d..cd1fc43da118 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_gpio_device driver for gpio device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c index 59cee0b1e1c0..69b2aad0e7c8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c @@ -1,7 +1,23 @@ /* - * wb_io_dev.c - * ko to read/write i2c client through /dev/XXX device + * An wb_i2c_dev driver for i2c dev function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -27,8 +43,8 @@ #define WIDTH_2Byte (2) #define WIDTH_4Byte (4) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_i2c_dev_debug = 0; static int g_i2c_dev_error = 0; @@ -467,7 +483,7 @@ static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, l } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { I2C_DEV_DEBUG_DMESG("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, val, read_len)) { @@ -491,7 +507,7 @@ static ssize_t i2c_dev_read_user(struct file *file, char __user *buf, size_t cou I2C_DEV_DEBUG_DMESG("i2c_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = i2c_dev_read(file, buf, count, offset, USER_SPASE); + ret = i2c_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -501,7 +517,7 @@ static ssize_t i2c_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) I2C_DEV_DEBUG_DMESG("i2c_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -530,7 +546,7 @@ static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t c mem_clear(val, sizeof(val)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { I2C_DEV_DEBUG_DMESG("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(val, buf, count)) { @@ -560,7 +576,7 @@ static ssize_t i2c_dev_write_user(struct file *file, const char __user *buf, siz I2C_DEV_DEBUG_DMESG("i2c_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = i2c_dev_write(file, buf, count, offset, USER_SPASE); + ret = i2c_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -570,7 +586,7 @@ static ssize_t i2c_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) I2C_DEV_DEBUG_DMESG("i2c_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h index 9cc95d88e804..5d294a7ed410 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_I2C_DEV_H__ #define __WB_I2C_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c index 80f18b2eab55..f884dd202e6a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_i2c_gpio_device driver for i2c gpio device adapter function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c index 854675d9fa99..5c7c566ed4fe 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c @@ -1,21 +1,7 @@ /* - * I2C multiplexer + * An wb_i2c_mux_pca954x driver for i2c pca954x multiplexer/switch function * - * Copyright (c) 2008-2009 Rodolfo Giometti - * Copyright (c) 2008-2009 Eurotech S.p.A. - * - * This module supports the PCA954x series of I2C multiplexer/switch chips - * made by Philips Semiconductors. - * This includes the: - * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 - * and PCA9548. - * - * These chips are all controlled via the I2C bus itself, and all have a - * single 8-bit register. The upstream "parent" bus fans out to two, - * four, or eight downstream busses or channels; which of these - * are selected is determined by the chip type and register contents. A - * mux can select only one sub-bus at a time; a switch can select any - * combination simultaneously. + * Copyright (C) 2024 Micas Networks Inc. * * Based on: * pca954x.c from Kumar Gala @@ -30,11 +16,22 @@ * and * pca9540.c from Jean Delvare . * - * 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. + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h index beed9b2f94ac..700b36e0236f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_mux_pca954x driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_I2C_MUX_PCA954X_H__ #define __WB_I2C_MUX_PCA954X_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c index a3ae9f4b2431..83b0774ec901 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c @@ -1,19 +1,21 @@ /* - * I2C multiplexer driver for PCA9541 bus master selector + * An wb_i2c_mux_pca9641 driver for pca9641 multiplexer/switch function * - * Copyright (c) 2010 Ericsson AB. + * Copyright (C) 2024 Micas Networks Inc. * - * Author: 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. * - * Derived from: - * pca954x.c + * 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) 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. + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h index b87f7585567b..8c8ffa3da03d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_mux_pca9641 driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_I2C_MUX_PCA9641_H__ #define __WB_I2C_MUX_PCA9641_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c index 20f8954cce83..643fc3b605d7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c @@ -1,12 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * i2c-ocores.c: I2C bus driver for OpenCores I2C controller - * (https://opencores.org/project/i2c/overview) + * An wb_i2c_ocores driver for i2c ocores function * - * Peter Korsgaard + * Copyright (C) 2024 Micas Networks Inc. * - * Support for the GRLIB port of the controller by - * Andreas Larsson + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h index d413ebb3ad44..8b2cd206c084 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_ocores driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_I2C_OCORES_H__ #define __WB_I2C_OCORES_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c new file mode 100644 index 000000000000..c0a730e77462 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c @@ -0,0 +1,869 @@ +/* + * An wb_indirect_dev driver for indirect adapter device function + * + * Copyright (C) 2024 Micas 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 + * 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 "wb_indirect_dev.h" +#define MODULE_NAME "wb-indirect-dev" + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) +#define SYMBOL_SPI_DEV_MODE (5) + +#define KERNEL_SPACE (0) +#define USER_SPACE (1) + +#define MAX_INDIRECT_DEV_NUM (256) +#define INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) +#define INDIRECT_ADDR_L(addr) ((addr) & 0xff) +#define INDIRECT_OP_WRITE (0x2) +#define INDIRECT_OP_READ (0x3) + +static int g_indirect_dev_debug = 0; +static int g_indirect_dev_error = 0; + +module_param(g_indirect_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_indirect_dev_error, int, S_IRUGO | S_IWUSR); + +#define INDIRECT_DEV_INFO(fmt, args...) do { \ + printk(KERN_INFO "[INDIRECT_DEV][INFO][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ +} while (0) + +#define INDIRECT_DEV_DEBUG(fmt, args...) do { \ + if (g_indirect_dev_debug) { \ + printk(KERN_DEBUG "[INDIRECT_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define INDIRECT_DEV_ERROR(fmt, args...) do { \ + if (g_indirect_dev_error) { \ + printk(KERN_ERR "[INDIRECT_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct indirect_dev_info* indirect_dev_arry[MAX_INDIRECT_DEV_NUM]; + +static int noop_pre(struct kprobe *p, struct pt_regs *regs) { return 0; } +static struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name", +}; +unsigned long (*kallsyms_lookup_name_fun)(const char *name) = NULL; + +/* Call kprobe to find the address location of kallsyms_lookup_name */ +static int find_kallsyms_lookup_name(void) +{ + int ret = -1; + + kp.pre_handler = noop_pre; + ret = register_kprobe(&kp); + if (ret < 0) { + INDIRECT_DEV_ERROR("register_kprobe failed, error:%d\n", ret); + return ret; + } + INDIRECT_DEV_DEBUG("kallsyms_lookup_name addr: %p\n", kp.addr); + kallsyms_lookup_name_fun = (void*)kp.addr; + unregister_kprobe(&kp); + + return ret; +} + +struct indirect_dev_info { + const char *name; /* generate dev name */ + const char *logic_dev_name; /* dependent dev name */ + uint32_t indirect_len; /* dev data len */ + uint32_t data_bus_width; /* dev data_bus_width */ + uint32_t addr_bus_width; /* dev addr_bus_width */ + uint32_t wr_data; /* dependent dev wr date reg */ + uint32_t wr_data_width; /* dependent dev wr_data_width */ + uint32_t addr_low; /* dependent dev w/r addr reg low */ + uint32_t addr_high; /* dependent dev w/r addr reg high */ + uint32_t rd_data; /* dependent dev rd date reg */ + uint32_t rd_data_width; /* dependent dev rd_data_width */ + uint32_t opt_ctl; /* dependent dev opt code reg */ + uint32_t logic_func_mode; /* 1: i2c, 2: file, 3:pcie, 4:io, 5:spi */ + unsigned long write_intf_addr; + unsigned long read_intf_addr; + spinlock_t indirect_dev_lock; + struct miscdevice misc; + struct device *dev; +}; + +static int wb_dev_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, size, MAX_RW_COUNT), + }; + struct iov_iter iter; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + INDIRECT_DEV_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + tmp_pos = (loff_t)pos; + iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); + ret = vfs_iter_read(filp, &iter, &tmp_pos, 0); + if (ret < 0) { + INDIRECT_DEV_ERROR("vfs_iter_read failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_dev_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, size, MAX_RW_COUNT), + }; + struct iov_iter iter; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + INDIRECT_DEV_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); + ret = vfs_iter_write(filp, &iter, &tmp_pos, 0); + if (ret < 0) { + INDIRECT_DEV_ERROR("vfs_iter_write failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_logic_reg_write(struct indirect_dev_info *indirect_dev, uint32_t pos, uint8_t *val, size_t size) +{ + device_func_write pfunc; + + pfunc = (device_func_write)indirect_dev->write_intf_addr; + return pfunc(indirect_dev->logic_dev_name, pos, val, size); +} + +static int wb_logic_reg_read(struct indirect_dev_info *indirect_dev, uint32_t pos, uint8_t *val, size_t size) +{ + device_func_read pfunc; + + pfunc = (device_func_read)indirect_dev->read_intf_addr; + return pfunc(indirect_dev->logic_dev_name, pos, val, size); +} + + +static int indirect_addressing_read(struct indirect_dev_info *indirect_dev, uint8_t *buf, uint32_t address, uint32_t rd_data_width) +{ + uint8_t addr_l, addr_h, op_code; + unsigned long flags; + int ret = 0; + + addr_h = INDIRECT_ADDR_H(address); + addr_l = INDIRECT_ADDR_L(address); + op_code = INDIRECT_OP_READ; + + spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + goto fail; + } + + ret = wb_logic_reg_read(indirect_dev, indirect_dev->rd_data, buf, rd_data_width); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->rd_data, ret); + goto fail; + } + + INDIRECT_DEV_DEBUG("indirect_read success, addr = 0x%x\n", address); + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +fail: + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +} + +static int device_read(struct indirect_dev_info *indirect_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, ret; + u32 data_width; + u32 tmp; + + data_width = indirect_dev->data_bus_width; + + if (offset % data_width) { + INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + if (count > indirect_dev->indirect_len - offset) { + INDIRECT_DEV_DEBUG("read count out of range. input len:%zu, read len:%u.\n", + count, indirect_dev->indirect_len - offset); + count = indirect_dev->indirect_len - offset; + } + tmp = count; + + for (i = 0; i < count; i += data_width) { + ret = indirect_addressing_read(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); + if (ret < 0) { + INDIRECT_DEV_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + tmp -= data_width; + } + + return count; +} + +static int indirect_addressing_write(struct indirect_dev_info *indirect_dev, uint8_t *buf, uint32_t address, uint32_t wr_data_width) +{ + uint8_t addr_l, addr_h, op_code; + unsigned long flags; + int ret = 0; + + addr_h = INDIRECT_ADDR_H(address); + addr_l = INDIRECT_ADDR_L(address); + op_code = INDIRECT_OP_WRITE; + + spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->wr_data, buf, wr_data_width); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->wr_data, ret); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + goto fail; + } + + INDIRECT_DEV_DEBUG("indirect_write success, addr = 0x%x\n", address); + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +fail: + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +} + +static int device_write(struct indirect_dev_info *indirect_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, ret; + u32 data_width; + u32 tmp; + + if (offset > indirect_dev->indirect_len) { + INDIRECT_DEV_DEBUG("offset: 0x%x, spi len: 0x%x, count: %zu, EOF.\n", + offset, indirect_dev->indirect_len, count); + return 0; + } + + data_width = indirect_dev->data_bus_width; + if (offset % data_width) { + INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + if (count > (indirect_dev->indirect_len - offset)) { + INDIRECT_DEV_DEBUG("write count out of range. input len:%zu, read len:%u.\n", + count, indirect_dev->indirect_len - offset); + count = indirect_dev->indirect_len - offset; + } + + if (count == 0) { + INDIRECT_DEV_DEBUG("offset: 0x%x, i2c len: 0x%x, read len: %zu, EOF.\n", + offset, indirect_dev->indirect_len, count); + return 0; + } + + tmp = count; + for (i = 0; i < count; i += data_width) { + ret = indirect_addressing_write(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); + if (ret < 0) { + INDIRECT_DEV_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + tmp -= data_width; + } + return count; +} + +static ssize_t indirect_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset, int flag) +{ + u8 val[MAX_RW_LEN]; + int ret, read_len; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("can't get read private_data.\n"); + return -EINVAL; + } + + if (count == 0) { + INDIRECT_DEV_ERROR("Invalid params, read count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + INDIRECT_DEV_DEBUG("read count %zu exceed max %zu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + read_len = device_read(indirect_dev, (uint32_t)*offset, val, count); + if (read_len < 0) { + INDIRECT_DEV_ERROR("indirect dev read failed, dev name:%s, offset:0x%x, len:%zu.\n", + indirect_dev->name, (uint32_t)*offset, count); + return read_len; + } + + /* check flag is user spase or kernel spase */ + if (flag == USER_SPACE) { + INDIRECT_DEV_DEBUG("user space read, buf: %p, offset: %lld, read count %zu.\n", + buf, *offset, count); + if (copy_to_user(buf, val, read_len)) { + INDIRECT_DEV_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + INDIRECT_DEV_DEBUG("kernel space read, buf: %p, offset: %lld, read count %zu.\n", + buf, *offset, count); + memcpy(buf, val, read_len); + } + + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t indirect_dev_read_user(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_read_user, file: %p, count: %lu, offset: %lld\n", + file, count, *offset); + ret = indirect_dev_read(file, buf, count, offset, USER_SPACE); + return ret; +} + + +static ssize_t indirect_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_read_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = indirect_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); + return ret; +} + +static ssize_t indirect_dev_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset, int flag) +{ + u8 val[MAX_RW_LEN]; + int write_len; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + if (count == 0) { + INDIRECT_DEV_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + INDIRECT_DEV_DEBUG("write count %zu exceed max %zu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + /* check flag is user spase or kernel spase */ + if (flag == USER_SPACE) { + INDIRECT_DEV_DEBUG("user space write, buf: %p, offset: %lld, write count %zu.\n", + buf, *offset, count); + if (copy_from_user(val, buf, count)) { + INDIRECT_DEV_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + INDIRECT_DEV_DEBUG("kernel space write, buf: %p, offset: %lld, write count %zu.\n", + buf, *offset, count); + memcpy(val, buf, count); + } + + write_len = device_write(indirect_dev, (uint32_t)*offset, val, count); + if (write_len < 0) { + INDIRECT_DEV_ERROR("indirect dev write failed, dev name:%s, offset:0x%llx, len:%zu.\n", + indirect_dev->name, *offset, count); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t indirect_dev_write_user(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_write_user, file: %p, count: %lu, offset: %lld\n", + file, count, *offset); + ret = indirect_dev_write(file, buf, count, offset, USER_SPACE); + return ret; +} + +static ssize_t indirect_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_write_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = indirect_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); + return ret; +} + +static loff_t indirect_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + INDIRECT_DEV_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > indirect_dev->indirect_len) { + INDIRECT_DEV_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", + offset, indirect_dev->indirect_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > indirect_dev->indirect_len) || ((file->f_pos + offset) < 0)) { + INDIRECT_DEV_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + INDIRECT_DEV_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long indirect_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int indirect_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct indirect_dev_info *indirect_dev; + + if (minor >= MAX_INDIRECT_DEV_NUM) { + INDIRECT_DEV_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + indirect_dev = indirect_dev_arry[minor]; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = indirect_dev; + + return 0; +} + +static int indirect_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static const struct file_operations indirect_dev_fops = { + .owner = THIS_MODULE, + .llseek = indirect_dev_llseek, + .read = indirect_dev_read_user, + .write = indirect_dev_write_user, + .read_iter = indirect_dev_read_iter, + .write_iter = indirect_dev_write_iter, + .unlocked_ioctl = indirect_dev_ioctl, + .open = indirect_dev_open, + .release = indirect_dev_release, +}; + +static struct indirect_dev_info *dev_match(const char *path) +{ + struct indirect_dev_info *indirect_dev; + char dev_name[DEV_NAME_LEN]; + int i; + + for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { + if (indirect_dev_arry[i] == NULL) { + continue; + } + indirect_dev = indirect_dev_arry[i]; + snprintf(dev_name, DEV_NAME_LEN,"/dev/%s", indirect_dev->name); + if (!strcmp(path, dev_name)) { + INDIRECT_DEV_DEBUG("get dev_name = %s, minor = %d\n", dev_name, i); + return indirect_dev; + } + } + + return NULL; +} + +int indirect_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct indirect_dev_info *indirect_dev; + int read_len; + + if (path == NULL) { + INDIRECT_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + INDIRECT_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + indirect_dev = dev_match(path); + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = device_read(indirect_dev, offset, buf, count); + if (read_len < 0) { + INDIRECT_DEV_ERROR("indirect_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(indirect_device_func_read); + +int indirect_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct indirect_dev_info *indirect_dev; + int write_len; + + if (path == NULL) { + INDIRECT_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + INDIRECT_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + indirect_dev = dev_match(path); + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = device_write(indirect_dev, offset, buf, count); + if (write_len < 0) { + INDIRECT_DEV_ERROR("indirect_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(indirect_device_func_write); + + +static int wb_indirect_dev_probe(struct platform_device *pdev) +{ + int ret; + struct indirect_dev_info *indirect_dev; + struct miscdevice *misc; + indirect_dev_device_t *indirect_dev_device; + + INDIRECT_DEV_DEBUG("wb_indirect_dev_probe\n"); + + indirect_dev = devm_kzalloc(&pdev->dev, sizeof(struct indirect_dev_info), GFP_KERNEL); + if (!indirect_dev) { + dev_err(&pdev->dev, "devm_kzalloc error.\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, indirect_dev); + indirect_dev->dev = &pdev->dev; + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "dev_name", &indirect_dev->name); + ret += of_property_read_string(pdev->dev.of_node, "logic_dev_name", &indirect_dev->logic_dev_name); + ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &indirect_dev->addr_low); + ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &indirect_dev->data_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_bus_width", &indirect_dev->addr_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &indirect_dev->addr_high); + ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &indirect_dev->wr_data); + ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &indirect_dev->rd_data); + ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &indirect_dev->opt_ctl); + ret += of_property_read_u32(pdev->dev.of_node, "indirect_len", &indirect_dev->indirect_len); + ret += of_property_read_u32(pdev->dev.of_node, "logic_func_mode", &indirect_dev->logic_func_mode); + + if (of_property_read_u32(pdev->dev.of_node, "wr_data_width", &indirect_dev->wr_data_width)) { + /* dts have no wr_data_width,set default 1 */ + indirect_dev->wr_data_width = WIDTH_1Byte; + } + if (of_property_read_u32(pdev->dev.of_node, "rd_data_width", &indirect_dev->rd_data_width)) { + /* dts have no rd_data_width,set default 1 */ + indirect_dev->rd_data_width = WIDTH_1Byte; + } + if (ret != 0) { + dev_err(&pdev->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + indirect_dev_device = pdev->dev.platform_data; + indirect_dev->name = indirect_dev_device->dev_name; + indirect_dev->logic_dev_name = indirect_dev_device->logic_dev_name; + indirect_dev->data_bus_width = indirect_dev_device->data_bus_width; + indirect_dev->addr_bus_width = indirect_dev_device->addr_bus_width; + indirect_dev->wr_data = indirect_dev_device->wr_data; + indirect_dev->wr_data_width = indirect_dev_device->wr_data_width; + indirect_dev->addr_low = indirect_dev_device->addr_low; + indirect_dev->addr_high = indirect_dev_device->addr_high; + indirect_dev->rd_data = indirect_dev_device->rd_data; + indirect_dev->rd_data_width = indirect_dev_device->rd_data_width; + indirect_dev->opt_ctl = indirect_dev_device->opt_ctl; + indirect_dev->indirect_len = indirect_dev_device->indirect_len; + indirect_dev->logic_func_mode = indirect_dev_device->logic_func_mode; + } + + switch (indirect_dev->logic_func_mode) { + case SYMBOL_I2C_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_read"); + break; + case SYMBOL_SPI_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_read"); + break; + case SYMBOL_IO_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_read"); + break; + case SYMBOL_PCIE_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_read"); + break; + case FILE_MODE: + indirect_dev->write_intf_addr = (unsigned long)wb_dev_file_write; + indirect_dev->read_intf_addr = (unsigned long)wb_dev_file_read; + break; + default: + dev_err(&pdev->dev, "func mode %d don't support.\n", indirect_dev->logic_func_mode); + return -EINVAL; + } + + if (!indirect_dev->write_intf_addr || !indirect_dev->read_intf_addr) { + dev_err(&pdev->dev, "Fail: func mode %u rw symbol undefined.\n", indirect_dev->logic_func_mode); + return -ENOSYS; + } + + /* TODO: data_bus_width unuse now, need judge in rd or wr */ + dev_info(&pdev->dev, "register indirect device %s success. logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: 0x%x, dependent dev: 0x%x, wr_data: 0x%x, wr_data_width: %d, \ + rd_data: 0x%x, rd_data_width: %d, addr_low: 0x%x, addr_high: 0x%x, opt_ctl: 0x%x, logic_func_mode: %d\n", indirect_dev->name, indirect_dev->logic_dev_name, indirect_dev->indirect_len, indirect_dev->data_bus_width, \ + indirect_dev->addr_bus_width, indirect_dev->wr_data, indirect_dev->wr_data_width, indirect_dev->rd_data, indirect_dev->rd_data_width, indirect_dev->addr_low, indirect_dev->addr_high,\ + indirect_dev->opt_ctl, indirect_dev->logic_func_mode); + + misc = &indirect_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = indirect_dev->name; + misc->fops = &indirect_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_INDIRECT_DEV_NUM) { + dev_err(&pdev->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + spin_lock_init(&indirect_dev->indirect_dev_lock); + indirect_dev_arry[misc->minor] = indirect_dev; + + dev_info(&pdev->dev, "register indirect device %s success.\n", indirect_dev->name); + return 0; +} + +static int wb_indirect_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { + if (indirect_dev_arry[i] != NULL) { + if (indirect_dev_arry[i]->dev == &pdev->dev) { + misc_deregister(&indirect_dev_arry[i]->misc); + indirect_dev_arry[i] = NULL; + return 0; + } + } + } + return 0; +} + +static const struct of_device_id wb_indirect_dev_driver_of_match[] = { + { .compatible = "wb-indirect-dev" }, + { }, +}; + +static struct platform_driver wb_indirect_dev_driver = { + .probe = wb_indirect_dev_probe, + .remove = wb_indirect_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = MODULE_NAME, + .of_match_table = wb_indirect_dev_driver_of_match, + }, +}; + +static int __init wb_indirect_dev_init(void) +{ + int ret; + + ret = find_kallsyms_lookup_name(); + if (ret < 0) { + INDIRECT_DEV_ERROR("find kallsyms_lookup_name failed\n"); + return -ENXIO; + } + INDIRECT_DEV_DEBUG("find kallsyms_lookup_name ok\n"); + return platform_driver_register(&wb_indirect_dev_driver); +} + +static void __exit wb_indirect_dev_exit(void) +{ + platform_driver_unregister(&wb_indirect_dev_driver); +} + +module_init(wb_indirect_dev_init); +module_exit(wb_indirect_dev_exit); +MODULE_DESCRIPTION("indirect device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h new file mode 100644 index 000000000000..bc2570f52794 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h @@ -0,0 +1,54 @@ +/* + * A header definition for wb_indirect_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_INDIRECT_DEV_H__ +#define __WB_INDIRECT_DEV_H__ + +#include + +#define DEV_NAME_LEN (64) +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) +#define MAX_RW_LEN (256) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef int (*device_func_write)(const char *, uint32_t, uint8_t *, size_t); +typedef int (*device_func_read)(const char *, uint32_t, uint8_t *, size_t ); + +typedef struct indirect_dev_device_s { + char dev_name[DEV_NAME_LEN]; + char logic_dev_name[DEV_NAME_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t indirect_len; + uint32_t wr_data; + uint32_t wr_data_width; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t rd_data_width; + uint32_t opt_ctl; + uint32_t logic_func_mode; + int device_flag; +} indirect_dev_device_t; + +#endif /* __WB_INDIRECT_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c index 03571871014b..6699397aa4b2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c @@ -1,7 +1,23 @@ /* - * wb_io_dev.c - * ko to read/write ioports through /dev/XXX device + * An wb_io_dev driver for read/write ioports device function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -27,8 +43,8 @@ #define IO_INDIRECT_OP_WRITE (0x2) #define IO_INDIRECT_OP_READ (0X3) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_io_dev_debug = 0; static int g_io_dev_error = 0; @@ -54,9 +70,11 @@ typedef struct wb_io_dev_s { uint32_t io_len; uint32_t indirect_addr; uint32_t wr_data; + uint32_t wr_data_width; uint32_t addr_low; uint32_t addr_high; uint32_t rd_data; + uint32_t rd_data_width; uint32_t opt_ctl; spinlock_t io_dev_lock; struct miscdevice misc; @@ -90,14 +108,15 @@ static int io_dev_release(struct inode *inode, struct file *file) return 0; } -uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) +u32 io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) { - uint8_t addr_l, addr_h, value; + int width; + uint8_t addr_l, addr_h; unsigned long flags; + u32 value; addr_h = IO_INDIRECT_ADDR_H(address); addr_l = IO_INDIRECT_ADDR_L(address); - IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x\n", address); spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); @@ -107,16 +126,32 @@ uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) outb(IO_INDIRECT_OP_READ, wb_io_dev->io_base + wb_io_dev->opt_ctl); - value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + width = wb_io_dev->rd_data_width; + switch (width) { + case IO_DATA_WIDTH_2: + value = inw(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + case IO_DATA_WIDTH_4: + value = inl(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + case IO_DATA_WIDTH_1: + default: + /* default 1 byte mode */ + value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + } spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x, value = 0x%x\n", address, value); + return value; } static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) { - int i; + int width, i, j; + u32 val; if (offset > wb_io_dev->io_len) { IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); @@ -129,8 +164,19 @@ static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf count = wb_io_dev->io_len - offset; } if (wb_io_dev->indirect_addr) { - for (i = 0; i < count; i++) { - buf[i] = io_indirect_addressing_read(wb_io_dev, offset + i); + width = wb_io_dev->rd_data_width; + + if (offset % width) { + IO_DEV_DEBUG_VERBOSE("rd_data_width:%d, offset:0x%x, size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + for (i = 0; i < count; i += width) { + val = io_indirect_addressing_read(wb_io_dev, offset + i); + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } } } else { for (i = 0; i < count; i++) { @@ -171,7 +217,7 @@ static ssize_t io_dev_read(struct file *file, char __user *buf, size_t count, lo } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { IO_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, buf_tmp, read_len)) { @@ -194,7 +240,7 @@ static ssize_t io_dev_read_user(struct file *file, char __user *buf, size_t coun IO_DEV_DEBUG_VERBOSE("io_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = io_dev_read(file, buf, count, offset, USER_SPASE); + ret = io_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -204,22 +250,37 @@ static ssize_t io_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) IO_DEV_DEBUG_VERBOSE("io_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } -void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint8_t reg_val) +void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, u32 reg_val) { + int width; uint8_t addr_l, addr_h; unsigned long flags; addr_h = IO_INDIRECT_ADDR_H(address); addr_l = IO_INDIRECT_ADDR_L(address); - IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x\n", address); + IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x, val = 0x%x\n", address, reg_val); + + width = wb_io_dev->wr_data_width; spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); - outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + switch (width) { + case IO_DATA_WIDTH_2: + outw(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + case IO_DATA_WIDTH_4: + outl(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + case IO_DATA_WIDTH_1: + default: + /* default 1 byte mode */ + outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + } outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); @@ -234,7 +295,8 @@ void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) { - int i; + int width, i, j; + u32 val; if (offset > wb_io_dev->io_len) { IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); @@ -247,8 +309,20 @@ static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *bu count = wb_io_dev->io_len - offset; } if (wb_io_dev->indirect_addr) { - for (i = 0; i < count; i++) { - io_indirect_addressing_write(wb_io_dev, offset + i, buf[i]); + width = wb_io_dev->wr_data_width; + + if (offset % width) { + IO_DEV_DEBUG_VERBOSE("wr_data_width:%d, offset:0x%x, size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + for (i = 0; i < count; i += width) { + val = 0; + for (j = 0; (j < width) && (i + j < count); j++) { + val |= buf[i + j] << (8 * j); + } + io_indirect_addressing_write(wb_io_dev, i + offset, val); } } else { for (i = 0; i < count; i++) { @@ -283,7 +357,7 @@ static ssize_t io_dev_write(struct file *file, const char __user *buf, size_t co mem_clear(buf_tmp, sizeof(buf_tmp)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { IO_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(buf_tmp, buf, count)) { @@ -312,7 +386,7 @@ static ssize_t io_dev_write_user(struct file *file, const char __user *buf, size IO_DEV_DEBUG_VERBOSE("io_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = io_dev_write(file, buf, count, offset, USER_SPASE); + ret = io_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -322,7 +396,7 @@ static ssize_t io_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) IO_DEV_DEBUG_VERBOSE("io_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -455,7 +529,7 @@ int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t wb_io_dev = dev_match(path); if (wb_io_dev == NULL) { - IO_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + IO_DEV_DEBUG_ERROR("io_dev match failed. dev path = %s", path); return -EINVAL; } @@ -488,15 +562,22 @@ static int io_dev_probe(struct platform_device *pdev) ret += of_property_read_u32(pdev->dev.of_node, "io_base", &wb_io_dev->io_base); ret += of_property_read_u32(pdev->dev.of_node, "io_len", &wb_io_dev->io_len); if (of_property_read_bool(pdev->dev.of_node, "indirect_addr")) { - wb_io_dev->indirect_addr = 1; ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &wb_io_dev->wr_data); ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &wb_io_dev->addr_low); ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &wb_io_dev->addr_high); ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &wb_io_dev->rd_data); ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &wb_io_dev->opt_ctl); - } else { + if (of_property_read_u32(pdev->dev.of_node, "wr_data_width", &wb_io_dev->wr_data_width)) { + /* dts have no wr_data_width,set default 1 */ + wb_io_dev->wr_data_width = IO_DATA_WIDTH_1; + } + if (of_property_read_u32(pdev->dev.of_node, "rd_data_width", &wb_io_dev->rd_data_width)) { + /* dts have no rd_data_width,set default 1 */ + wb_io_dev->rd_data_width = IO_DATA_WIDTH_1; + } + } else { wb_io_dev->indirect_addr = 0; } if (ret != 0) { @@ -515,10 +596,18 @@ static int io_dev_probe(struct platform_device *pdev) wb_io_dev->indirect_addr = io_dev_device->indirect_addr; if (wb_io_dev->indirect_addr == 1) { wb_io_dev->wr_data = io_dev_device->wr_data; + wb_io_dev->wr_data_width = io_dev_device->wr_data_width; wb_io_dev->addr_low = io_dev_device->addr_low; wb_io_dev->addr_high = io_dev_device->addr_high; wb_io_dev->rd_data = io_dev_device->rd_data; + wb_io_dev->rd_data_width = io_dev_device->rd_data_width; wb_io_dev->opt_ctl = io_dev_device->opt_ctl; + if (wb_io_dev->wr_data_width == 0) { + wb_io_dev->wr_data_width = IO_DATA_WIDTH_1; + } + if (wb_io_dev->rd_data_width == 0) { + wb_io_dev->rd_data_width = IO_DATA_WIDTH_1; + } } } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h index 3a1a10f0f20c..61cba26a155c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_io_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_IO_DEV_H__ #define __WB_IO_DEV_H__ #include @@ -5,15 +25,21 @@ #define mem_clear(data, size) memset((data), 0, (size)) #define IO_DEV_NAME_MAX_LEN (64) +#define IO_DATA_WIDTH_1 (1) +#define IO_DATA_WIDTH_2 (2) +#define IO_DATA_WIDTH_4 (4) + typedef struct io_dev_device_s { char io_dev_name[IO_DEV_NAME_MAX_LEN]; uint32_t io_base; uint32_t io_len; uint32_t indirect_addr; uint32_t wr_data; + uint32_t wr_data_width; uint32_t addr_low; uint32_t addr_high; uint32_t rd_data; + uint32_t rd_data_width; uint32_t opt_ctl; int device_flag; } io_dev_device_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c index c079dc409696..45290ca843ea 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c @@ -1,7 +1,23 @@ /* - * wb_lpc_drv.c - * ko to set lpc pcie config io addr and enable lpc + * An wb_lpc_drv driver for lpc device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h index 76e8c32c12e9..52c64b187bd5 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_lpc_drv driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_LPC_DRV_H__ #define __WB_LPC_DRV_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c index a94ae020a4b7..ba9cd692f8e8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c @@ -1,6 +1,7 @@ /* + * An wb_mac_bsc driver for mac bsc function * - * Copyright (c) 1998, 1999 Frodo Looijaard + * Copyright (C) 2024 Micas 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c index e3198b378a20..65b8d2a42749 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_mdio_gpio_device driver for mdio gpio device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c index 093d070fd429..83904d7960e0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c @@ -1,7 +1,23 @@ /* - * wb_pcie_dev.c - * ko to read/write pcie iomem and ioports through /dev/XXX device + * An wb_pcie_dev driver for pcie device function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -25,8 +41,14 @@ #define PCIE_BUS_WIDTH_2 (2) #define PCIE_BUS_WIDTH_4 (4) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) + +#define SEARCH_DEV_DEFAULT (0) +#define SEARCH_DEV_BY_BRIDGE (1) + +#define SECBUS (0x19) +#define SUBBUS (0x1a) static int g_pcie_dev_debug = 0; static int g_pcie_dev_error = 0; @@ -65,6 +87,10 @@ typedef struct wb_pci_dev_s { uint32_t bus_width; uint32_t check_pci_id; uint32_t pci_id; + uint32_t search_mode; + uint32_t bridge_bus; + uint32_t bridge_slot; + uint32_t bridge_fn; struct miscdevice misc; void (*setreg)(struct wb_pci_dev_s *wb_pci_dev, int reg, u32 value); u32 (*getreg)(struct wb_pci_dev_s *wb_pci_dev, int reg); @@ -250,7 +276,7 @@ static ssize_t pci_dev_read(struct file *file, char __user *buf, size_t count, l return read_len; } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { PCIE_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, buf_tmp, read_len)) { @@ -273,7 +299,7 @@ static ssize_t pci_dev_read_user(struct file *file, char __user *buf, size_t cou PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = pci_dev_read(file, buf, count, offset, USER_SPASE); + ret = pci_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -283,7 +309,7 @@ static ssize_t pci_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -347,7 +373,7 @@ static ssize_t pci_dev_write(struct file *file, const char __user *buf, size_t c mem_clear(buf_tmp, sizeof(buf_tmp)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { PCIE_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(buf_tmp, buf, count)) { @@ -376,7 +402,7 @@ static ssize_t pci_dev_write_user(struct file *file, const char __user *buf, siz PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = pci_dev_write(file, buf, count, offset, USER_SPASE); + ret = pci_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -386,7 +412,7 @@ static ssize_t pci_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -618,10 +644,11 @@ static int pci_dev_probe(struct platform_device *pdev) int ret, devfn; uint32_t pci_id; wb_pci_dev_t *wb_pci_dev; - struct pci_dev *pci_dev; + struct pci_dev *pci_dev, *pci_bridge_dev; struct miscdevice *misc; firmware_upg_t *firmware_upg; pci_dev_device_t *pci_dev_device; + u8 secbus_val, subbus_val; wb_pci_dev = devm_kzalloc(&pdev->dev, sizeof(wb_pci_dev_t), GFP_KERNEL); if (!wb_pci_dev) { @@ -636,7 +663,6 @@ static int pci_dev_probe(struct platform_device *pdev) ret = 0; ret += of_property_read_string(pdev->dev.of_node, "pci_dev_name", &wb_pci_dev->name); ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_pci_dev->domain); - ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_pci_dev->slot); ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_pci_dev->fn); ret += of_property_read_u32(pdev->dev.of_node, "pci_bar", &wb_pci_dev->bar); @@ -647,6 +673,30 @@ static int pci_dev_probe(struct platform_device *pdev) return -ENXIO; } + wb_pci_dev->search_mode = SEARCH_DEV_DEFAULT; + of_property_read_u32(pdev->dev.of_node, "search_mode", &wb_pci_dev->search_mode); + ret = 0; + if (wb_pci_dev->search_mode == SEARCH_DEV_BY_BRIDGE) { + ret += of_property_read_u32(pdev->dev.of_node, "bridge_bus", &wb_pci_dev->bridge_bus); + ret += of_property_read_u32(pdev->dev.of_node, "bridge_slot", &wb_pci_dev->bridge_slot); + ret += of_property_read_u32(pdev->dev.of_node, "bridge_fn", &wb_pci_dev->bridge_fn); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("get pci bridge config fail, ret:%d.\n", ret); + return -ENXIO; + } else { + PCIE_DEV_DEBUG_VERBOSE("bridge_bus:0x%02x, bridge_slot:0x%02x, bridge_fn:0x%02x.\n", + wb_pci_dev->bridge_bus, wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + } + } else { + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("get pci bus config fail, ret:%d.\n", ret); + return -ENXIO; + } else { + PCIE_DEV_DEBUG_VERBOSE("get pci_bus:0x%02x.\n", wb_pci_dev->bus); + } + } + ret = 0; ret += of_property_read_u32(pdev->dev.of_node, "upg_ctrl_base", &firmware_upg->upg_ctrl_base); ret += of_property_read_u32(pdev->dev.of_node, "upg_flash_base", &firmware_upg->upg_flash_base); @@ -674,31 +724,79 @@ static int pci_dev_probe(struct platform_device *pdev) pci_dev_device = pdev->dev.platform_data; wb_pci_dev->name = pci_dev_device->pci_dev_name; wb_pci_dev->domain = pci_dev_device->pci_domain; - wb_pci_dev->bus = pci_dev_device->pci_bus; wb_pci_dev->slot = pci_dev_device->pci_slot; wb_pci_dev->fn = pci_dev_device->pci_fn; wb_pci_dev->bar = pci_dev_device->pci_bar; wb_pci_dev->bus_width = pci_dev_device->bus_width; wb_pci_dev->check_pci_id = pci_dev_device->check_pci_id; - wb_pci_dev->pci_id = pci_dev_device->pci_id; + wb_pci_dev->search_mode = pci_dev_device->search_mode; firmware_upg->upg_ctrl_base = pci_dev_device->upg_ctrl_base; firmware_upg->upg_flash_base = pci_dev_device->upg_flash_base; + if (wb_pci_dev->search_mode == SEARCH_DEV_BY_BRIDGE) { + PCIE_DEV_DEBUG_VERBOSE("bridge_bus:0x%02x, bridge_slot:0x%02x, bridge_fn:0x%02x.\n", + wb_pci_dev->bridge_bus, wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + } PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); } - PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d.\n", + PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d, search_mode:%d \n", wb_pci_dev->name, wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, - wb_pci_dev->bar, wb_pci_dev->bus_width); + wb_pci_dev->bar, wb_pci_dev->bus_width, wb_pci_dev->search_mode); - devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); - pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); - if (pci_dev == NULL) { - dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", - wb_pci_dev->domain, wb_pci_dev->bus, devfn); - return -ENXIO; + if (wb_pci_dev->search_mode != SEARCH_DEV_DEFAULT && wb_pci_dev->search_mode != SEARCH_DEV_BY_BRIDGE) { + dev_err(&pdev->dev, "Error: unsupported search_mode (%d).\n", wb_pci_dev->search_mode); + return -EINVAL; + } + + if (wb_pci_dev->search_mode == SEARCH_DEV_DEFAULT) { + wb_pci_dev->bus = pci_dev_device->pci_bus; + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } + } else { /* search_mode = SEARCH_DEV_BY_BRIDGE */ + wb_pci_dev->bridge_bus = pci_dev_device->bridge_bus; + wb_pci_dev->bridge_slot = pci_dev_device->bridge_slot; + wb_pci_dev->bridge_fn = pci_dev_device->bridge_fn; + devfn = PCI_DEVFN(wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + pci_bridge_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bridge_bus, devfn); + if (pci_bridge_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_bridge_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bridge_bus, devfn); + return -ENXIO; + } + + ret = pci_read_config_byte(pci_bridge_dev, SECBUS, &secbus_val); + if (ret) { + PCIE_DEV_DEBUG_ERROR("pci_read_config_dword failed reg:%02x ret %d.\n", SECBUS, ret); + return -EIO; + } + ret = pci_read_config_byte(pci_bridge_dev, SUBBUS, &subbus_val); + if (ret) { + PCIE_DEV_DEBUG_ERROR("pci_read_config_dword failed reg:%02x ret %d.\n", SUBBUS, ret); + return -EIO; + } + if (secbus_val != subbus_val) { + /* If the SECBUS register value is different from the SUBBUS register value, a multistage PCIE bridge is available*/ + PCIE_DEV_DEBUG_ERROR("not support ,secbus_val not equal subbus_val secbus_val:%02x secbus_val:%02x.\n", secbus_val, subbus_val); + return -EIO; + } + wb_pci_dev->bus = secbus_val; + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } } + if (wb_pci_dev->check_pci_id == 1) { + wb_pci_dev->pci_id = pci_dev_device->pci_id; pci_id = (pci_dev->vendor << 16) | pci_dev->device; if (wb_pci_dev->pci_id != pci_id) { dev_err(&pdev->dev, "Failed to check pci id, except: 0x%x, really: 0x%x\n", diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h index 33da8d475f91..ef390a1585f3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_pcie_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_PCIE_DEV_H__ #define __WB_PCIE_DEV_H__ #include @@ -23,6 +43,10 @@ typedef struct pci_dev_device_s { int upg_ctrl_base; int upg_flash_base; int device_flag; + int search_mode; + int bridge_bus; + int bridge_slot; + int bridge_fn; } pci_dev_device_t; #endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c index 092c99da2ad8..678a48483bd7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c @@ -1,3 +1,23 @@ +/* + * An wb_platform_i2c_dev driver for i2c platform device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h index b5158c9fec57..f40282176484 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_platform_i2c_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_PLATFORM_I2C_DEV_H__ #define __WB_PLATFORM_I2C_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c index d70424afb0e7..dd13fe9a991b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c @@ -1,6 +1,21 @@ /* - * wb_spi_dev.c - * ko to read/write spi device through /dev/XXX device + * An wb_spi_dev driver for spi device function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -32,8 +47,8 @@ #define OP_READ (0x3) #define OP_WRITE (0x2) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_spi_dev_debug = 0; static int g_spi_dev_error = 0; @@ -346,7 +361,7 @@ static ssize_t spi_dev_read(struct file *file, char __user *buf, size_t count, l } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { SPI_DEV_DEBUG("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, val, read_len)) { @@ -370,7 +385,7 @@ static ssize_t spi_dev_read_user(struct file *file, char __user *buf, size_t cou SPI_DEV_DEBUG("spi_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = spi_dev_read(file, buf, count, offset, USER_SPASE); + ret = spi_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -380,7 +395,7 @@ static ssize_t spi_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) SPI_DEV_DEBUG("spi_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = spi_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = spi_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -409,7 +424,7 @@ static ssize_t spi_dev_write(struct file *file, const char __user *buf, mem_clear(val, sizeof(val)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { SPI_DEV_DEBUG("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(val, buf, count)) { @@ -439,7 +454,7 @@ static ssize_t spi_dev_write_user(struct file *file, const char __user *buf, siz SPI_DEV_DEBUG("spi_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = spi_dev_write(file, buf, count, offset, USER_SPASE); + ret = spi_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -449,7 +464,7 @@ static ssize_t spi_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) SPI_DEV_DEBUG("spi_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = spi_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = spi_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h index fed5237e3860..03ff8f42f7ec 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_spi_dev driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_SPI_DEV_H__ #define __WB_SPI_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c index b073dac08a8a..61551a33d3c1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_spi_gpio_device driver for spi gpio device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c index 5cf3538d88fa..f87dd63ecae4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c @@ -1,6 +1,21 @@ /* - * wb_spi_ocores.c - * ko to create ocores spi adapter + * An wb_spi_ocores driver for spi ocores adapter device function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -109,6 +124,7 @@ struct spioc { uint32_t num_chipselect; uint32_t freq; uint32_t big_endian; + uint32_t irq_flag; struct device *dev; int transfer_busy_flag; }; @@ -870,6 +886,11 @@ static int ocores_spi_config_init(struct spioc *spioc) ret = -ENXIO; return ret; } + ret = of_property_read_u32(dev->of_node, "irq_flag", &spioc->irq_flag); + if (ret != 0) { + spioc->irq_flag = 0; + ret = 0; + } } else { if (spioc->dev->platform_data == NULL) { SPI_OC_ERROR("platform data config error.\n"); @@ -886,12 +907,13 @@ static int ocores_spi_config_init(struct spioc *spioc) spioc->freq = spi_ocores_device->clock_frequency; spioc->reg_access_mode = spi_ocores_device->reg_access_mode; spioc->num_chipselect = spi_ocores_device->num_chipselect; + spioc->irq_flag = spi_ocores_device->irq_flag; } SPI_OC_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, clock-frequency:0x%x.\n", spioc->dev_name, spioc->base_addr, spioc->reg_shift, spioc->reg_io_width, spioc->freq); - SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u.\n", - spioc->reg_access_mode, spioc->num_chipselect); + SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u, irq_flag: %u\n", + spioc->reg_access_mode, spioc->num_chipselect, spioc->irq_flag); return ret; } @@ -921,7 +943,6 @@ static int spioc_probe(struct platform_device *pdev) if (spioc->dev->of_node) { if (of_property_read_u32(spioc->dev->of_node, "big_endian", &spioc->big_endian)) { - be = 0; } else { be = spioc->big_endian; @@ -974,17 +995,24 @@ static int spioc_probe(struct platform_device *pdev) spioc->bitbang.chipselect = spioc_chipselect; spioc->bitbang.txrx_bufs = spioc_spi_txrx_bufs; - /* gooooohi need revision */ - spioc->irq = platform_get_irq(pdev, 0); - if (spioc->irq >= 0) { - SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); - init_completion(&spioc->done); - ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, - pdev->name, spioc); - if (ret) { - dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + if (spioc->irq_flag == 1) { + spioc->irq = platform_get_irq(pdev, 0); + if (spioc->irq >= 0) { + SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); + init_completion(&spioc->done); + ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, + pdev->name, spioc); + if (ret) { + dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + goto free; + } + } else { + ret = spioc->irq; + dev_err(spioc->dev, "Failed to get irq, ret: %d.\n", ret); goto free; } + } else { + spioc->irq = -1; } ret = spi_bitbang_start(&spioc->bitbang); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h index 647ff0c5f9cf..e94a770552ec 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_spi_ocores driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_SPI_OCORES_H__ #define __WB_SPI_OCORES_H__ #include @@ -15,6 +35,7 @@ typedef struct spi_ocores_device_s { uint32_t reg_io_width; uint32_t clock_frequency; uint32_t num_chipselect; + uint32_t irq_flag; int device_flag; } spi_ocores_device_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c new file mode 100644 index 000000000000..2fae45c72ae6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c @@ -0,0 +1,356 @@ +/* + * An wb_ucd9081 driver for ucd9081 adapter device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +#define WB_UCD9081_RAIL1H (0x00) /* Channel 1 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL1L (0x01) /* Channel 1 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL2H (0x02) /* Channel 2 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL2L (0x03) /* Channel 2 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL3H (0x04) /* Channel 3 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL3L (0x05) /* Channel 3 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL4H (0x06) /* Channel 4 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL4L (0x07) /* Channel 4 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL5H (0x08) /* Channel 5 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL5L (0x09) /* Channel 5 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL6H (0x0a) /* Channel 6 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL6L (0x0b) /* Channel 6 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL7H (0x0c) /* Channel 7 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL7L (0x0d) /* Channel 7 voltage address, low 8 bits */ +#define WB_UCD9081_WADDR1 (0x30) /* UCD9081 High address register write address, low 8 bits */ +#define WB_UCD9081_WADDR2 (0x31) /* UCD9081 High address register write address, low 8 bits */ +#define WB_UCD9081_WDATA1 (0x32) /* Write WADDR data,low 8 bits */ +#define WB_UCD9081_WDATA2 (0x33) /* Write WADDR data,low 8 bits */ + +#define WB_UCD9081_FLASHLOCK_REG (0x2E) +#define WB_UCD9081_FLASHUNLOCK_VAL (0x02) +#define WB_UCD9081_FLASHLOCK_VAL (0x0) + +#define WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_H (0xE1) +#define WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_L (0x86) + +/* Voltage definition */ +#define WB_UCD9081_SELREF_OFFSET (13) +#define WB_UCD9081_SELREF_0 (0x0) /* External reference selected (VCC 3.3V) */ +#define WB_UCD9081_SELREF_1 (0x1) /* Internal reference selected (VCC 2.5V) */ +#define WB_UCD9081_VREF_EXTERNAL (3300) /* 3.3V */ +#define WB_UCD9081_VREF_INTERNAL (2500) /* 2.5V */ +#define WB_UCD9081_VOLTAGE_MASK (0x3ff) +#define WB_UCD9081_VOLTAGE_DIVIDE (1024) + +#define WB_I2C_RETRY_TIME (10) +#define WB_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ + +static int g_wb_ucd9081_debug = 0; +static int g_wb_ucd9081_error = 0; + +module_param(g_wb_ucd9081_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ucd9081_error, int, S_IRUGO | S_IWUSR); + +#define WB_UCD9081_VERBOSE(fmt, args...) do { \ + if (g_wb_ucd9081_debug) { \ + printk(KERN_INFO "[WB_UCD9081][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_UCD9081_ERROR(fmt, args...) do { \ + if (g_wb_ucd9081_error) { \ + printk(KERN_ERR "[WB_UCD9081][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct ucd9081_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + u32 vref; /* Voltage unit */ +}; + +static s32 wb_i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_byte_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_word_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, + u16 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_word_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +/* Get 9081 voltage units */ +static int ucd9081_get_vref(struct i2c_client *client) +{ + int ret; + uint16_t wr_val; + uint16_t ori_addr; + uint16_t reference_select_val; + struct ucd9081_data *data; + + data = i2c_get_clientdata(client); + WB_UCD9081_VERBOSE("%d-%04x: enter ucd9081_get_vref\n", client->adapter->nr, + client->addr); + + mutex_lock(&data->update_lock); + /* 0.Backup original WADDR */ + ori_addr = wb_i2c_smbus_read_word_data(client, WB_UCD9081_WADDR1); + if (ori_addr < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 origin addr failed, ret: %d\n", client->adapter->nr, + client->addr, ori_addr); + ret = ori_addr; + goto error; + } + WB_UCD9081_VERBOSE("%d-%04x: save ucd9081 waddr success, ori_addr: 0x%x\n", + client->adapter->nr, client->addr, ori_addr); + + /* 1.Unlock */ + ret = wb_i2c_smbus_write_byte_data(client, WB_UCD9081_FLASHLOCK_REG, WB_UCD9081_FLASHUNLOCK_VAL); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: ucd9081 unlock failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 2. Write Voltage configuration flash register address 0xE186 address to WADDR */ + wr_val = (WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_H << 8) | WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_L; + ret = wb_i2c_smbus_write_word_data(client, WB_UCD9081_WADDR1, wr_val); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: write ucd9081 waddr failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 3. The voltage configuration flash register value is read through WDATA*/ + reference_select_val = wb_i2c_smbus_read_word_data(client, WB_UCD9081_WDATA1); + if (reference_select_val < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 wdata failed, ret: %d\n", client->adapter->nr, + client->addr, ret); + ret = reference_select_val; + goto error; + } + + /* 4.LOCK */ + ret = wb_i2c_smbus_write_byte_data(client, WB_UCD9081_FLASHLOCK_REG, WB_UCD9081_FLASHLOCK_VAL); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: ucd9081 flash lock failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 5.Restore the original WADDR address */ + ret = wb_i2c_smbus_write_word_data(client, WB_UCD9081_WADDR1, ori_addr); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: recover ucd9081 waddr failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 5.Calculated voltage unit*/ + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 reference_select_val: 0x%x\n", + client->adapter->nr, client->addr, reference_select_val); + if ((reference_select_val >> WB_UCD9081_SELREF_OFFSET) == WB_UCD9081_SELREF_0) { + data->vref = WB_UCD9081_VREF_EXTERNAL; + } else { + data->vref = WB_UCD9081_VREF_INTERNAL; + } + + mutex_unlock(&data->update_lock); + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 use vref: %d\n", + client->adapter->nr, client->addr, data->vref); + return 0; + +error: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t ucd9081_voltage_show(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct ucd9081_data *data; + struct i2c_client *client; + uint32_t index, channel, value; + long voltage; + + data = dev_get_drvdata(dev); + client = data->client; + index = to_sensor_dev_attr_2(da)->index; + channel = to_sensor_dev_attr_2(da)->nr; + ret = 0; + + mutex_lock(&data->update_lock); + value = wb_i2c_smbus_read_word_data(client, index); + if (value < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 channel%d voltage reg failed, reg: 0x%x ret: %d\n", client->adapter->nr, + client->addr, channel, index, ret); + ret = value; + goto error; + } + /* Terminal conversion */ + value = ((value & 0xff00) >> 8) | ((value & 0xff) << 8); + WB_UCD9081_VERBOSE("%d-%04x: read ucd9081 channel%d voltage success, reg: 0x%x, value: 0x%x\n", + client->adapter->nr, client->addr, channel, index, value); + + voltage = ((value & WB_UCD9081_VOLTAGE_MASK) * data->vref) / WB_UCD9081_VOLTAGE_DIVIDE; + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 channel%d voltage: %ld\n", client->adapter->nr, client->addr, channel, voltage); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%ld\n", voltage); +error: + mutex_unlock(&data->update_lock); + return ret; +} + +static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, ucd9081_voltage_show, NULL, 1, WB_UCD9081_RAIL1H); +static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, ucd9081_voltage_show, NULL, 2, WB_UCD9081_RAIL2H); +static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, ucd9081_voltage_show, NULL, 3, WB_UCD9081_RAIL3H); +static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, ucd9081_voltage_show, NULL, 4, WB_UCD9081_RAIL4H); +static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, ucd9081_voltage_show, NULL, 5, WB_UCD9081_RAIL5H); +static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, ucd9081_voltage_show, NULL, 6, WB_UCD9081_RAIL6H); +static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, ucd9081_voltage_show, NULL, 7, WB_UCD9081_RAIL7H); + +static struct attribute *ucd9081_hwmon_attrs[] = { + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in5_input.dev_attr.attr, + &sensor_dev_attr_in6_input.dev_attr.attr, + &sensor_dev_attr_in7_input.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(ucd9081_hwmon); + +static int ucd9081_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int ret; + struct ucd9081_data *data; + + WB_UCD9081_VERBOSE("bus: %d, addr: 0x%02x do probe.\n", client->adapter->nr, client->addr); + data = devm_kzalloc(&client->dev, sizeof(struct ucd9081_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + ret = ucd9081_get_vref(client); + if (ret != 0) { + dev_err(&client->dev, "get ucd9081 vref failed, ret: %d\n", ret); + return ret; + } + + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, ucd9081_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(&client->dev, "Failed to register ucd9081 hwmon device, ret: %d\n", ret); + return ret; + } + dev_info(&client->dev, "ucd9081 (addr:0x%x, nr:%d) probe success\n", client->addr, client->adapter->nr); + return 0; +} + +static void ucd9081_remove(struct i2c_client *client) +{ + struct ucd9081_data *data; + + data = i2c_get_clientdata(client); + dev_info(&client->dev, "ucd9081 do remove\n"); + + hwmon_device_unregister(data->hwmon_dev); + return; +} + +static const struct i2c_device_id ucd9081_id[] = { + {"wb_ucd9081", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9081_id); + +static const struct of_device_id ucd9081_dev_of_match[] = { + { .compatible = "ti,wb_ucd9081" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ucd9081_dev_of_match); + +static struct i2c_driver ucd9081_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_ucd9081", + .of_match_table = ucd9081_dev_of_match, + }, + .probe = ucd9081_probe, + .remove = ucd9081_remove, + .id_table = ucd9081_id, +}; + +module_i2c_driver(ucd9081_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("ucd9081 Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c index da2b582443b8..835386127fb0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c @@ -1,3 +1,23 @@ +/* + * An wb_uio_irq driver for uio irq device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c index aa50ef848dde..899886a0390b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c @@ -1,6 +1,21 @@ /* - * wb_wdt.c - * ko for watchdog function + * An wb_wdt driver for watchdog device function + * + * Copyright (C) 2024 Micas 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 + * 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 @@ -69,8 +84,8 @@ enum { enum { WATCHDOG_DEVICE_TYPE = 0, - HRTIMER_TYPE, - THREAD_TYPE, + HRTIMER_TYPE = 1, + THREAD_TYPE = 2, }; typedef struct wb_wdt_priv_s { @@ -427,8 +442,8 @@ static int wdt_thread_timer(void *data) wb_wdt_priv_t *priv = data; while (!kthread_should_stop()) { - schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); wdt_hwping(priv); + schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); } return 0; } @@ -673,6 +688,32 @@ static const struct watchdog_ops wb_wdt_ops = { .get_timeleft = wb_wdt_get_timeleft, }; +static int wb_wdt_register_device(wb_wdt_priv_t *priv) +{ + int ret; + + watchdog_set_drvdata(&priv->wdd, priv); + + priv->wdd.info = &wb_wdt_ident; + priv->wdd.ops = &wb_wdt_ops; + priv->wdd.bootstatus = 0; + priv->wdd.timeout = priv->hw_margin / MS_TO_S; + priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; + priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; + priv->wdd.parent = priv->dev; + + watchdog_stop_on_reboot(&priv->wdd); + + ret = devm_watchdog_register_device(priv->dev, &priv->wdd); + if (ret != 0) { + dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); + return -ENXIO; + } + + return 0; +} + + static int watchdog_device_cfg(wb_wdt_priv_t *priv) { int ret; @@ -712,24 +753,6 @@ static int watchdog_device_cfg(wb_wdt_priv_t *priv) } } - watchdog_set_drvdata(&priv->wdd, priv); - - priv->wdd.info = &wb_wdt_ident; - priv->wdd.ops = &wb_wdt_ops; - priv->wdd.bootstatus = 0; - priv->wdd.timeout = priv->hw_margin / MS_TO_S; - priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; - priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; - priv->wdd.parent = priv->dev; - - watchdog_stop_on_reboot(&priv->wdd); - - ret = devm_watchdog_register_device(priv->dev, &priv->wdd); - if (ret != 0) { - dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); - return -ENXIO; - } - return 0; } @@ -1085,6 +1108,12 @@ static int wb_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "register %s mode, config_mode %u, func_mode %u, %u ms overtime wdt success\n", algo, priv->config_mode, priv->priv_func_mode, priv->hw_margin); + ret = wb_wdt_register_device(priv); + if (ret < 0) { + dev_err(&pdev->dev, "kernel watchdog sysfs register %u failed.\n", ret); + return -ENODEV; + } + if (priv->sysfs_index != SYSFS_NO_CFG) { priv->sysfs_group = wdt_get_attr_group(priv->sysfs_index); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h index d45904ba32ea..431464688878 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_wdt driver + * + * Copyright (C) 2024 Micas 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 + * 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 __WB_WDT_H__ #define __WB_WDT_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c index 51c5b4143df8..3d2b2ff0bab6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c @@ -1,12 +1,21 @@ /* - * xdpe132g5c_i2c_drv.c + * An wb_xdpe132g5c driver for xdpe132g5c avs and hwmon device function * - * This module create sysfs to set AVS and create hwmon to get out power - * through xdpe132g5c I2C address. + * Copyright (C) 2024 Micas Networks Inc. * - * History - * [Version] [Date] [Description] - * * v1.0 2021-09-17 Initial version + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c index d1e0fa220725..493f477a1688 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c @@ -1,3 +1,23 @@ +/* + * An wb_xdpe132g5c_pmbus driver for xdpe132g5c pmbus device function + * + * Copyright (C) 2024 Micas 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 + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py b/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py index 838e64f6b417..e1a781420176 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 . try: import os diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py b/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py index 1f367133a89b..898e528e6f01 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import time @@ -164,7 +180,7 @@ def doAvsCtrol(avs_conf): ret, log = doAvsCtrol_single(avs_conf) if ret is True: return True, log - time.sleep(10) + time.sleep(1) return False, log diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh new file mode 100755 index 000000000000..11ed62e214a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# +# Copyright (C) 2024 Micas 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 +# 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 . + +# SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +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 +} + +start() { + debug "Starting cpodaemon service..." + + platforms=( \ + "x86_64-micas_m2-w6940-128x1-fr4-r0" \ + ) + + result=$(cat /host/machine.conf | grep onie_platform | cut -d = -f 2) + echo $result + + cpo_device=0 + for i in ${platforms[*]}; do + if [ $result == $i ]; + then + cpo_device=1 + break + fi + done + + if [ $cpo_device -eq 1 ]; + then + wait_syncd + cpo_daemon + else + echo "$result not support cpo" + exit 0 + fi +} + +wait() { + debug "wait cpodaemon service... do nothing" +} + +stop() { + debug "Stopping cpodaemon service..." + pkill -9 cpo_daemon + debug "Stopped cpodaemon service..." + exit 0 +} + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py index 8ce06db061bf..23b39d3731a0 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py b/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py index ac7c189f1b8f..aebeeee654e0 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import os import shutil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py b/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py index ff4fed46fa13..fcbebfab6757 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 . + ''' generate board air flow according to fan and psu air flow write resulet to AIRFLOW_RESULT_FILE, file format: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py index 5a12b88ac463..a7bfa03942a8 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 subprocess import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py index c21fd3c1f585..74fc1727ac77 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py @@ -1,9 +1,26 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 time import syslog import traceback from plat_hal.interface import interface from plat_hal.baseutil import baseutil +from platform_util import get_value try: import abc except ImportError as error: @@ -32,7 +49,8 @@ COLOR_GREEN = 1 COLOR_AMBER = 2 COLOR_RED = 3 -LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red"} +COLOR_FLASH = 4 +LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red", COLOR_FLASH: "flash"} def ledcontrol_debug(s): @@ -305,6 +323,8 @@ def __init__(self): self.__board_air_flow = "" self.int_case = interface() self.__config = baseutil.get_monitor_config() + self.__dcdc_whitelist = self.__config.get('dcdc_monitor_whitelist', {}) + self.__fw_upgrade_check = self.__config.get('fw_upgrade_check', []) self.__temps_threshold_config = self.__config["temps_threshold"] for temp_threshold in self.__temps_threshold_config.values(): temp_threshold['temp'] = 0 @@ -320,9 +340,13 @@ def __init__(self): self.__board_sys_led = self.__ledcontrol_para.get("board_sys_led", []) self.__board_psu_led = self.__ledcontrol_para.get("board_psu_led", []) self.__board_fan_led = self.__ledcontrol_para.get("board_fan_led", []) + self.__board_smb_led = self.__ledcontrol_para.get("board_smb_led", []) self.__psu_air_flow_monitor = self.__ledcontrol_para.get("psu_air_flow_monitor", 0) self.__fan_air_flow_monitor = self.__ledcontrol_para.get("fan_air_flow_monitor", 0) self.__fan_mix_list = self.__ledcontrol_para.get("fan_mix_list", []) + self.__sysled_check_temp = self.__ledcontrol_para.get("sysled_check_temp", 1) + self.__sysled_check_fw_up = self.__ledcontrol_para.get("sysled_check_fw_up", 0) + self.__smbled_ctrl = self.__ledcontrol_para.get("smbled_ctrl", 0) @property def na_ret(self): @@ -372,10 +396,26 @@ def board_psu_led(self): def board_fan_led(self): return self.__board_fan_led + @property + def board_smb_led(self): + return self.__board_smb_led + @property def fan_mix_list(self): return self.__fan_mix_list + @property + def sysled_check_temp(self): + return self.__sysled_check_temp + + @property + def sysled_check_fw_up(self): + return self.__sysled_check_fw_up + + @property + def smbled_ctrl(self): + return self.__smbled_ctrl + @property def interval(self): return self.__interval @@ -397,6 +437,15 @@ def set_led_color(self, led_name, color): ret = False return ret + def set_smb_led(self, color): + for led in self.board_smb_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + def set_sys_led(self, color): for led in self.board_sys_led: led_name = led.get("led_name") @@ -533,6 +582,97 @@ def checkTempCrit(self): ledcontrol_error(str(e)) return False + def dcdc_whitelist_check(self, dcdc_name): + try: + check_item = self.__dcdc_whitelist.get(dcdc_name, {}) + if len(check_item) == 0: + ledcontrol_debug("%s whitelist config is None" % dcdc_name) + return False + + checkbit = check_item.get("checkbit", None) + okval = check_item.get("okval", None) + if checkbit is None or okval is None: + ledcontrol_error('%s config error, checkbit:%s, okval:%s' % (dcdc_name, checkbit, okval)) + return False + + ret, retval = get_value(check_item) + if ret is False: + ledcontrol_error("get %s whitelist value error, config: %s, msg: %s" % (dcdc_name, check_item, retval)) + return False + + val_t = retval & (1 << checkbit) >> checkbit + if val_t != okval: + return False + return True + except Exception as e: + ledcontrol_error('%%WHITELIST_CHECK: %s check error, msg: %s.' % (dcdc_name, str(e))) + return False + + def get_voltage_led_status(self): + try: + led_status = COLOR_GREEN + dcdc_dict = self.int_case.get_dcdc_all_info() + for dcdc_name, item in dcdc_dict.items(): + ret = self.dcdc_whitelist_check(dcdc_name) + if ret is False: + if item['Value'] is None or int(item['Value']) == self.int_case.error_ret: + ledcontrol_error('The value of %s read failed.' % (dcdc_name)) + elif float(item['Value']) > float(item['Max']): + led_status = COLOR_AMBER + ledcontrol_debug('%s voltage %.3f%s is larger than max threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Max']), item['Unit'])) + elif float(item['Value']) < float(item['Min']): + led_status = COLOR_AMBER + ledcontrol_debug('%s voltage %.3f%s is lower than min threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Min']), item['Unit'])) + else: + ledcontrol_debug('%s value %s is in range [%s, %s].' % (dcdc_name, item['Value'], item['Min'], item['Max'])) + else: + ledcontrol_debug('%s is in dcdc whitelist, not monitor voltage' % dcdc_name) + except Exception as e: + ledcontrol_error('update dcdc sensors status error, msg: %s.' % (str(e))) + ledcontrol_debug("monitor voltage, set led: %s" % LED_STATUS_DICT.get(led_status)) + return led_status + + def monitor_point_check(self, item): + try: + gettype = item.get('gettype', None) + okval = item.get('okval', None) + compare_mode = item.get('compare_mode', "equal") + ret, value = get_value(item) + if ret is True: + if compare_mode == "equal": + if value == okval: + return True + elif compare_mode == "great": + if value > okval: + return True + elif compare_mode == "ignore": + return True + else: + ledcontrol_debug('compare_mode %s not match error.' % (compare_mode)) + else: + ledcontrol_debug('point check failed, gettype: %s, msg: %s' % (gettype, value)) + except Exception as e: + ledcontrol_error('point check error. msg: %s.' % (str(e))) + return False + + def get_fw_up_led_status(self): + fw_upgrade_flag = False + for item in self.__fw_upgrade_check: + for monitor_point in item: + status = self.monitor_point_check(monitor_point) + if status is False: + fw_upgrade_flag = False + break + fw_upgrade_flag = True + + if fw_upgrade_flag is True: + ledcontrol_debug("Firmware upgrade check: firmware upgrade in progress") + return COLOR_FLASH + ledcontrol_debug("Firmware upgrade check: firmware upgrade not in progress") + return COLOR_GREEN + def check_board_air_flow(self): board_air_flow = self.board_air_flow air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) @@ -697,15 +837,15 @@ def get_monitor_psu_air_flow(self): ledcontrol_debug("monitor psu air flow, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) return psu_led_status - def get_temp_sys_led_status(self): + def get_temp_led_status(self): if self.checkTempCrit() is True: - sys_led_status = COLOR_RED + led_status = COLOR_RED elif self.checkTempWarning() is True: - sys_led_status = COLOR_AMBER + led_status = COLOR_AMBER else: - sys_led_status = COLOR_GREEN - ledcontrol_debug("monitor temperature, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) - return sys_led_status + led_status = COLOR_GREEN + ledcontrol_debug("monitor temperature, set led: %s" % LED_STATUS_DICT.get(led_status)) + return led_status def get_sys_led_follow_fan_status(self): @@ -728,12 +868,17 @@ def get_sys_led_follow_psu_status(self): def dealSysLedStatus(self): sys_led_status_list = [] - # get_monitor_temp - self.get_monitor_temp() - - # monitor temp get sys led status - sys_led_status = self.get_temp_sys_led_status() - sys_led_status_list.append(sys_led_status) + if self.sysled_check_temp == 1: + ledcontrol_debug("sys led check temperature status") + # get_monitor_temp + self.get_monitor_temp() + # monitor temp get sys led status + sys_led_status = self.get_temp_led_status() + ledcontrol_debug("monitor temperature to get sys led status: %s" % + LED_STATUS_DICT.get(sys_led_status)) + sys_led_status_list.append(sys_led_status) + else: + ledcontrol_debug("sys led don't need to check temperature status") # check sys led follow fan led status sys_led_status = self.get_sys_led_follow_fan_status() @@ -743,6 +888,16 @@ def dealSysLedStatus(self): sys_led_status = self.get_sys_led_follow_psu_status() sys_led_status_list.append(sys_led_status) + if self.sysled_check_fw_up == 1: + ledcontrol_debug("sys led check firmware upgrade") + # monitor firmware get sys led status + sys_led_status = self.get_fw_up_led_status() + ledcontrol_debug("monitor firmware upgrade to get sys led status: %s" % + LED_STATUS_DICT.get(sys_led_status)) + sys_led_status_list.append(sys_led_status) + else: + ledcontrol_debug("sys led don't need to check firmware upgrade") + sys_led_status = max(sys_led_status_list) sys_led_color = LED_STATUS_DICT.get(sys_led_status) @@ -789,10 +944,37 @@ def dealPsuLedStatus(self): # set psu led self.set_psu_led(psu_led_color) + def dealSmbLedStatus(self): + if self.smbled_ctrl == 0: + ledcontrol_debug("Don't need to control SMB led") + return + + ledcontrol_debug("Start to control SMB led") + smb_led_status_list = [] + + # get_monitor_temp + self.get_monitor_temp() + # monitor temp get smb led status + smb_led_status = self.get_temp_led_status() + smb_led_status_list.append(smb_led_status) + ledcontrol_debug("monitor temperature to get smb led status: %s" % LED_STATUS_DICT.get(smb_led_status)) + + # monitor volgate get smb led status + smb_led_status = self.get_voltage_led_status() + smb_led_status_list.append(smb_led_status) + ledcontrol_debug("monitor voltage to get smb led status: %s" % LED_STATUS_DICT.get(smb_led_status)) + + smb_led_status = max(smb_led_status_list) + smb_led_color = LED_STATUS_DICT.get(smb_led_status) + + # set smb led + self.set_smb_led(smb_led_color) + def do_ledcontrol(self): self.dealPsuLedStatus() self.dealFanLedStatus() self.dealSysLedStatus() + self.dealSmbLedStatus() def fan_obj_init(self): fan_num = self.get_fan_total_number() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py index 11196f507ef1..aec37de3619c 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 inspect import sys import json @@ -418,7 +433,8 @@ def get_temps_sensor(): print("=================get_temps_sensor======================") temp_list = int_case.get_temps() for temp in temp_list: - print("id: %s, name: %s, API name: %s, value: %s" % (temp.temp_id, temp.name, temp.api_name, temp.Value)) + print("id: %s, name: %s, API name: %s, value: %s, Min: %s, Low: %s, High: %s, Max: %s, Invalid: %s, Error: %s" % + (temp.temp_id, temp.name, temp.api_name, temp.Value, temp.Min, temp.Low, temp.High, temp.Max, temp.temp_invalid, temp.temp_error)) def get_cpu_reset_num(): r'''get_cpu_reset_num''' diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py index 33d5bfba64e6..89c6cc26c274 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py @@ -1,12 +1,26 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 time import syslog from plat_hal.interface import interface from plat_hal.baseutil import baseutil -from platform_util import io_rd, wbi2cget +from platform_util import get_value INTELLIGENT_MONITOR_DEBUG_FILE = "/etc/.intelligent_monitor_debug" @@ -59,39 +73,20 @@ def dcdc_whitelist_check(self, dcdc_name): check_item = self.__dcdc_whitelist.get(dcdc_name, {}) if len(check_item) == 0: return False - gettype = check_item.get("gettype", None) + checkbit = check_item.get("checkbit", None) okval = check_item.get("okval", None) - if gettype is None or checkbit is None or okval is None: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. gettype:%s, checkbit:%s, okval:%s' % - (dcdc_name, gettype, checkbit, okval)) + if checkbit is None or okval is None: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. checkbit:%s, okval:%s' % + (dcdc_name, checkbit, okval)) return False - if gettype == "io": - io_addr = check_item.get('io_addr', None) - val = io_rd(io_addr) - if val is not None: - retval = val - else: - monitor_syslog( - '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s io_rd error. io_addr:%s' % - (dcdc_name, io_addr)) - return False - elif gettype == "i2c": - bus = check_item.get('bus', None) - addr = check_item.get('addr', None) - offset = check_item.get('offset', None) - ind, val = wbi2cget(bus, addr, offset) - if ind is True: - retval = val - else: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s i2cget error. bus:%s, addr:%s, offset:%s' % - (dcdc_name, bus, addr, offset)) - return False - else: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s gettype not support' % dcdc_name) + ret, retval = get_value(check_item) + if ret is False: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s get value failed, msg:%s' % (dcdc_name, retval)) return False - val_t = (int(retval, 16) & (1 << checkbit)) >> checkbit + val_t = retval & (1 << checkbit) >> checkbit if val_t != okval: return False return True diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py index bb596a94cc94..01fbe4046837 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py index 35c16728f72c..025a22ce82cc 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 . __all__ = [ "BLACKLIST_DRIVERS", @@ -15,6 +30,7 @@ "OPTOE", "REBOOT_CAUSE_PARA", "UPGRADE_SUMMARY", + "FW_UPGRADE_STARTED_FLAG", "WARM_UPGRADE_PARAM", "WARM_UPG_FLAG", "WARM_UPGRADE_STARTED_FLAG", @@ -67,7 +83,9 @@ "MONITOR_DEV_STATUS", "MONITOR_DEV_STATUS_DECODE", "DEV_LEDS", - "fanloc" + "fanloc", + "PLATFORM_POWER_CONF", + "POWER_CTRL_CONF" ] # driver blacklist parameter @@ -111,6 +129,7 @@ # upgrade parameter UPGRADE_SUMMARY = {} +FW_UPGRADE_STARTED_FLAG = "/etc/sonic/.doing_fw_upg" # warm_uprade parameter WARM_UPGRADE_PARAM = {} @@ -136,6 +155,12 @@ # driver update config DRVIER_UPDATE_CONF = {} +# platform power config +PLATFORM_POWER_CONF = [] + +# power control config +POWER_CTRL_CONF = {} + ################################ fancontrol parameter################################### MONITOR_TEMP_MIN = 38 MONITOR_K = 11 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py index d6b3151e47cf..762f33dfbcf9 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os @@ -20,6 +35,7 @@ "PMON_SYSLOG_STATUS", "REBOOT_CAUSE_PARA", "UPGRADE_SUMMARY", + "FW_UPGRADE_STARTED_FLAG", "WARM_UPGRADE_PARAM", "WARM_UPG_FLAG", "WARM_UPGRADE_STARTED_FLAG", @@ -43,7 +59,9 @@ "MONITOR_DEV_STATUS", "MONITOR_DEV_STATUS_DECODE", "DEV_LEDS", - "fanloc" + "fanloc", + "PLATFORM_POWER_CONF", + "POWER_CTRL_CONF" ] @@ -115,6 +133,7 @@ def getdeviceplatform(): # upgrade parameter UPGRADE_SUMMARY = module_product.UPGRADE_SUMMARY +FW_UPGRADE_STARTED_FLAG = module_product.FW_UPGRADE_STARTED_FLAG # warm_uprade parameter WARM_UPGRADE_PARAM = module_product.WARM_UPGRADE_PARAM @@ -140,6 +159,12 @@ def getdeviceplatform(): # driver update config DRVIER_UPDATE_CONF = module_product.DRVIER_UPDATE_CONF +# platform power config +PLATFORM_POWER_CONF = module_product.PLATFORM_POWER_CONF + +# power control config +POWER_CTRL_CONF = module_product.POWER_CTRL_CONF + ################################ fancontrol parameter################################### diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py index e27d461bab81..290e3a93a38e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py @@ -1,9 +1,25 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 subprocess import time import click -from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG +from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG, FW_UPGRADE_STARTED_FLAG CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} @@ -40,6 +56,10 @@ def platform_process_file_check(): if os.path.exists(WARM_UPG_FLAG): os.remove(WARM_UPG_FLAG) + # FW_UPGRADE_STARTED_FLAG is used as upgrade.py process start flag + if os.path.exists(FW_UPGRADE_STARTED_FLAG): + os.remove(FW_UPGRADE_STARTED_FLAG) + def startCommon_operation(): platform_process_file_check() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py index 4dafde2701cb..a3b7bb7c5421 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py @@ -1,17 +1,52 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import click -import os +# +# Copyright (C) 2024 Micas 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 +# 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 binascii import sys +import os +import json +import re +import shutil +import click -from eepromutil.fru import ipmifru +from eepromutil.fru import ipmifru, BoardInfoArea, ProductInfoArea from eepromutil.cust_fru import CustFru from eepromutil.fantlv import fan_tlv +from eepromutil.wedge import Wedge +from eepromutil.wedge_v5 import WedgeV5 import eepromutil.onietlv as ot from platform_config import PLATFORM_E2_CONF -from platform_util import byteTostr, dev_file_read +from platform_util import byteTostr, dev_file_read, exec_os_cmd -CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} +PYTHON_VERSION = sys.version_info.major +GENERATE_RAWDATA_NUM = 0 +OUTPUT_DIR = "output/" +SUPPORT_E2_TYPE = ("onie_tlv", "fru", "fantlv", "custfru", "wedge", "wedge_v5") +E2_NAME_CLICK_HELP = "Display eeprom information of specified name, such as " + +for e2_key, e2_conf_list in sorted(PLATFORM_E2_CONF.items()): + E2_NAME_CLICK_HELP += e2_key + ", " + for e2_conf in e2_conf_list: + e2_name = e2_conf["name"] + if e2_name == e2_key: + continue + E2_NAME_CLICK_HELP += e2_name + ", " + +E2_NAME_CLICK_HELP = E2_NAME_CLICK_HELP.rstrip(", ") class AliasedGroup(click.Group): @@ -43,7 +78,6 @@ def decode_mac_number(encodedata): return None return (ord(encodedata[0]) << 8) | (ord(encodedata[1]) & 0x00ff) - @staticmethod @staticmethod def fru_decode_mac_number(params): ipmi_fru = params.get("fru") @@ -52,7 +86,7 @@ def fru_decode_mac_number(params): area_info = getattr(ipmi_fru, area, None) if area_info is not None: raw_mac_number = getattr(area_info, field, None) - mac_number = decode_mac_number(raw_mac_number) + mac_number = ExtraFunc.decode_mac_number(raw_mac_number) ipmi_fru.setValue(area, field, mac_number) @staticmethod @@ -63,7 +97,7 @@ def fru_decode_mac(params): area_info = getattr(ipmi_fru, area, None) if area_info is not None: raw_mac = getattr(area_info, field, None) - decoded_mac = decode_mac(raw_mac) + decoded_mac = ExtraFunc.decode_mac(raw_mac) ipmi_fru.setValue(area, field, decoded_mac) @staticmethod @@ -114,20 +148,22 @@ def onie_eeprom_decode(onie, e2_decode): continue -def onie_eeprom_show(eeprom, e2_decode=None): +def onie_eeprom_show(e2_name, eeprom, e2_decode=None): try: onietlv = ot.onie_tlv() rets = onietlv.decode(eeprom) if e2_decode is not None: onie_eeprom_decode(rets, e2_decode) - print("%-20s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + print("===================%s===================" % e2_name) + print("%-20s %-5s %-5s %s" % ("TLV name", "Code", "lens", "Value")) for item in rets: if item["code"] == 0xfd: - print("%-20s 0x%-02X %-5s" % (item["name"], item["code"], item["lens"])) + print("%-20s 0x%-02X %s" % (item["name"], item["code"], item["lens"])) else: - print("%-20s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + print("%-20s 0x%-02X %-5s %s" % (item["name"], item["code"], item["lens"], item["value"])) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) def set_fantlv_value(params): @@ -166,21 +202,21 @@ def fantlv_eeprom_decode(fantlv_dict, e2_decode): continue -def fantlv_eeprom_show(eeprom, e2_decode=None): +def fantlv_eeprom_show(e2_name, eeprom, e2_decode=None): try: tlv = fan_tlv() rets = tlv.decode(eeprom) if len(rets) == 0: - print("fan tlv eeprom info error.!") - return + return False, "fan tlv eeprom info error." if e2_decode is not None: fantlv_eeprom_decode(rets, e2_decode) - print("%-15s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + print("===================%s===================" % e2_name) + print("%-15s %-5s %-5s %s" % ("TLV name", "Code", "lens", "Value")) for item in rets: - print("%-15s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + print("%-15s 0x%-02X %-5s %s" % (item["name"], item["code"], item["lens"], item["value"])) + return True, "" except Exception as e: - print(str(e)) - return + return False, str(e) def run_func(funcname, params): @@ -227,51 +263,171 @@ def fru_eeprom_decode(ipmi_fru, e2_decode): continue -def fru_eeprom_show(eeprom, e2_decode=None): +def fru_eeprom_show(e2_name, eeprom, e2_decode=None): try: ipmi_fru = ipmifru() ipmi_fru.decodeBin(eeprom) if e2_decode is not None: fru_eeprom_decode(ipmi_fru, e2_decode) + print("===================%s==============" % e2_name) print("=================board=================") print(ipmi_fru.boardInfoArea) print("=================product=================") print(ipmi_fru.productInfoArea) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) -def custfru_eeprom_show(eeprom, e2_decode=None): +def custfru_eeprom_show(e2_name, eeprom, e2_decode=None): try: custfru = CustFru() custfru.decode(eeprom) + print("===================%s==============" % e2_name) print(custfru) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) + + +def wedge_eeprom_show(e2_name, eeprom, e2_decode=None): + try: + wegde = Wedge() + wegde.decode(eeprom) + print("===================%s==============" % e2_name) + print(wegde) + return True, "" + except Exception as e: + return False, str(e) + + +def wedge_v5_eeprom_show(e2_name, eeprom, e2_decode=None): + try: + wegdev5 = WedgeV5() + rets = wegdev5.decode(eeprom) + print("===================%s===================" % e2_name) + print("%-32s %-5s %-5s %s" % ("TLV name","Type","Length","Value")) + for item in rets: + print("%-32s %-5d %-5s %s" % (item["name"],item["code"],item["lens"],item["value"])) + return True, "" + except Exception as e: + return False, str(e) + + +def eeprom_parse_by_type(e2_type, name, binval, e2_decode): + if e2_type == "onie_tlv": + return onie_eeprom_show(name, binval, e2_decode) + + if e2_type == "fru": + return fru_eeprom_show(name, binval, e2_decode) + + if e2_type == "fantlv": + return fantlv_eeprom_show(name, binval, e2_decode) + + if e2_type == "custfru": + return custfru_eeprom_show(name, binval, e2_decode) + + if e2_type == "wedge": + return wedge_eeprom_show(name, binval, e2_decode) + + if e2_type == "wedge_v5": + return wedge_v5_eeprom_show(name, binval, e2_decode) + + return False, "Unsupport e2_type: %s" % e2_type -def eeprom_parase(eeprom_conf): +def eeprom_parse_traverse(name, binval, e2_decode=None): + errmsg = "" + support_e2_type = ("onie_tlv", "fru", "fantlv", "custfru", "wedge", "wedge_v5") + for e2_type in support_e2_type: + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is True: + return True, "" + errmsg = "%s %s\n" % (errmsg, msg) + return False, errmsg + + +def eeprom_parse_file(e2_path, e2_size): + if e2_size is None: + e2_size = os.path.getsize(e2_path) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + return + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_traverse(e2_path, binval) + if status is not True: + print("===================%s===================" % e2_path) + print("parse [%s] eeprom failed, errmsg:" % e2_path) + print("%s" % msg) + return + + +def eeprom_parse_dir(e2_path, e2_size): + for root, dirs, names in os.walk(e2_path): + # root: directory absolute path + # dirs: folder path collection under directory + # names: file path collection under directory + for filename in names: + # file_path is file absolute path + file_path = os.path.join(root, filename) + eeprom_parse_file(file_path, e2_size) + return + + +def eeprom_parse(e2_path, e2_size): + if os.path.isdir(e2_path): + eeprom_parse_dir(e2_path, e2_size) + elif os.path.isfile(e2_path): + eeprom_parse_file(e2_path, e2_size) + else: + msg = "path: %s not found" % e2_path + print(msg) + return + + +def eeprom_parse_by_config(eeprom_conf): + errmsg = "" name = eeprom_conf.get("name") e2_type = eeprom_conf.get("e2_type") e2_path = eeprom_conf.get("e2_path") e2_size = eeprom_conf.get("e2_size", 256) e2_decode = eeprom_conf.get("e2_decode") - print("===================%s===================" % name) ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) if ret is False: + print("===================%s===================" % name) print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) return binval = byteTostr(binval_bytes) - if e2_type == "onie_tlv": - onie_eeprom_show(binval, e2_decode) - elif e2_type == "fru": - fru_eeprom_show(binval, e2_decode) - elif e2_type == "fantlv": - fantlv_eeprom_show(binval, e2_decode) - elif e2_type == "custfru": - custfru_eeprom_show(binval, e2_decode) - else: - print("Unknow eeprom type: %s" % e2_type) + + if e2_type is None: + status, msg = eeprom_parse_traverse(name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg:" % name) + print("%s" % msg) + return + + if isinstance(e2_type, str): + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg: %s" % (name, msg)) + return + + if isinstance(e2_type, list): + for e2_type_item in e2_type: + status, msg = eeprom_parse_by_type(e2_type_item, name, binval, e2_decode) + if status is True: + return + errmsg = "%s %s\n" % (errmsg, msg) + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg:" % name) + print("%s" % errmsg) + return + + print("===================%s===================" % name) + print("Unsupprot e2_type config: %s" % type(e2_type)) return @@ -283,7 +439,7 @@ def get_fans_eeprom_info(param): return if param == 'all': for conf in fan_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -292,7 +448,7 @@ def get_fans_eeprom_info(param): if fan_index < 0 or fan_index >= fan_num: print("param error, total fan number: %d, fan index: %d" % (fan_num, fan_index + 1)) return - eeprom_parase(fan_eeprom_conf[fan_index]) + eeprom_parse_by_config(fan_eeprom_conf[fan_index]) return @@ -304,7 +460,7 @@ def get_psus_eeprom_info(param): return if param == 'all': for conf in psu_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -313,7 +469,7 @@ def get_psus_eeprom_info(param): if psu_index < 0 or psu_index >= psu_num: print("param error, total psu number: %d, psu index: %d" % (psu_num, psu_index + 1)) return - eeprom_parase(psu_eeprom_conf[psu_index]) + eeprom_parse_by_config(psu_eeprom_conf[psu_index]) return @@ -325,7 +481,7 @@ def get_slots_eeprom_info(param): return if param == 'all': for conf in slot_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -334,7 +490,7 @@ def get_slots_eeprom_info(param): if slot_index < 0 or slot_index >= slot_num: print("param error, total slot number: %d, slot index: %d" % (slot_num, slot_index + 1)) return - eeprom_parase(slot_eeprom_conf[slot_index]) + eeprom_parse_by_config(slot_eeprom_conf[slot_index]) return @@ -346,7 +502,7 @@ def get_syseeprom_info(param): return if param == 'all': for conf in syseeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -355,27 +511,501 @@ def get_syseeprom_info(param): if syseeprom_index < 0 or syseeprom_index >= syseeprom_num: print("param error, total syseeprom number: %d, syseeprom index: %d" % (syseeprom_num, syseeprom_index + 1)) return - eeprom_parase(syseeprom_conf[syseeprom_index]) + eeprom_parse_by_config(syseeprom_conf[syseeprom_index]) return -def decode_eeprom_info(e2_type, e2_path, e2_size): - if not e2_size.isdigit(): - print("param error, e2_size %s is not digital" % e2_size) +def get_all_eeprom_info(): + for e2_key, e2_conf in sorted(PLATFORM_E2_CONF.items()): + for conf in e2_conf: + eeprom_parse_by_config(conf) + + +def get_specified_eeprom_info(e2_type): + if e2_type not in SUPPORT_E2_TYPE: + print("Unsupprot e2_type %s" % e2_type) + return + + match_flag = 0 + for e2_key, e2_conf in sorted(PLATFORM_E2_CONF.items()): + for conf in e2_conf: + name = conf.get("name") + conf_e2_type = conf.get("e2_type") + e2_path = conf.get("e2_path") + e2_size = conf.get("e2_size", 256) + e2_decode = conf.get("e2_decode") + if conf_e2_type is None or (isinstance(conf_e2_type, list) and e2_type in conf_e2_type): + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + # Since it is not sure whether the E2 type matches, don't print error logs. + continue + + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is True: + match_flag = 1 + continue + + if isinstance(conf_e2_type, str) and conf_e2_type == e2_type: + match_flag = 1 + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("===================%s===================" % name) + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + continue + + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg: %s" % (name, msg)) + if match_flag == 0: + print("The eeprom type [%s] was not found in the machine" % e2_type) + return + + +def traverse_eeprom_by_name(e2_name): + match_flag = False + for e2_key, e2_conf_list in sorted(PLATFORM_E2_CONF.items()): + for e2_conf in e2_conf_list: + if e2_conf["name"] == e2_name: + match_flag = True + eeprom_parse_by_config(e2_conf) + return match_flag + + +def get_eeprom_info_by_name(e2_name): + e2_conf_list = PLATFORM_E2_CONF.get(e2_name) + if e2_conf_list is not None: # display all the eeprom information of e2_conf_list + for e2_conf in e2_conf_list: + eeprom_parse_by_config(e2_conf) + return + + # e2_conf_list is None, traverse the configuration to display the specified name eeprom information + status = traverse_eeprom_by_name(e2_name) + if status is False: + print("Can't find %s eeprom information" % e2_name) + return + + +def get_eeprom_config_by_json_file(file_path): + if not os.path.isfile(file_path): + msg = "file path: %s not exits" % file_path + return False, msg + with open(file_path, 'r') as jsonfile: + json_dict = json.load(jsonfile) + return True, json_dict + + +def write_rawdata_to_file(rawdata,out_file): + out_file_dir = os.path.dirname(out_file) + if len(out_file_dir) != 0: + cmd = "mkdir -p %s" % out_file_dir + exec_os_cmd(cmd) + data_array = bytearray() + for x in rawdata: + data_array.append(ord(x)) + with open(out_file, 'wb') as fd: + fd.write(data_array) + return + + +def isValidMac(mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + +def mac_addr_decode(origin_mac): + mac = origin_mac.replace("0x", "") + if len(mac) != 12: + msg = "Invalid MAC address: %s" % origin_mac + return False, msg + release_mac = "" + for i in range(len(mac) // 2): + if i == 0: + release_mac += mac[i * 2:i * 2 + 2] + else: + release_mac += ":" + mac[i * 2:i * 2 + 2] + return True, release_mac + + +def json_list_value_decode(list_value): + u'''json file''' + ret = "" + for item in list_value: + value = int(item, 16) + ret += chr(value) + return ret + + +def get_ext_tlv_body(tlv_type, tlv_value): + ret = "" + ret += (chr(tlv_type)) + ret += (chr(len(tlv_value))) + if isinstance(tlv_value, str): + ret += tlv_value + elif isinstance(tlv_value, list): + ret += json_list_value_decode(tlv_value) + else: + msg = "unsupport onie tlv value type: %s, value: %s" % (type(tlv_value), tlv_value) + return False, msg + return True, ret + + +def generate_ext(ext_dict): + ret = "" + iana = ext_dict.get("iana") + if iana is not None: + if isinstance(iana, str): + ret += iana + elif isinstance(iana, list): + ret += json_list_value_decode(iana) + else: + msg = "unsupport iana type: %s, value: %s" % (type(iana), iana) + return False, msg + del ext_dict['iana'] + + key_list = sorted(ext_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = ext_dict[key] + status, ret_tmp= get_ext_tlv_body(tlv_type, tlv_value) + if status is False: + return False, ret_tmp + ret += ret_tmp + return True, ret + + +def check_mac_addr(mac): + if mac.startswith("0x"): + status, mac = mac_addr_decode(mac) + if status is False: + return False, mac + + if isValidMac(mac) is False: + msg = "Invalid MAC address: %s" % mac + return False, msg + return True, mac + + +def generate_onie_tlv_value(onie_tlv_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = onie_tlv_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = onie_tlv_dict.get("e2_size", 256) + e2_name = onie_tlv_dict.get("e2_name") + if e2_name is None: + print("onie tlv config error, e2_name is None, please check") + return + onietlv = ot.onie_tlv() + key_list = sorted(onie_tlv_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = onie_tlv_dict[key] + if tlv_type == onietlv.TLV_CODE_MAC_BASE: + status, ret = check_mac_addr(tlv_value) + if status is False: + print("generate onie tlv eeprom rawdata %s failed, errmsg: %s" % (e2_name, ret)) + return + tlv_value = ret + elif tlv_type == onietlv.TLV_CODE_VENDOR_EXT: + status, ret= generate_ext(tlv_value) + if status is False: + print("generate onie tlv eeprom rawdata %s failed, errmsg: %s" % (e2_name, ret)) + return + tlv_value = ret + _value[tlv_type] = tlv_value + + rawdata, ret = onietlv.generate_value(_value, e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate onie tlv eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate onie tlv eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_fan_tlv_value(fan_tlv_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = fan_tlv_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = fan_tlv_dict.get("e2_size", 256) + e2_name = fan_tlv_dict.get("e2_name") + tlv_terminator = fan_tlv_dict.get("tlv_terminator", 0) + if e2_name is None: + print("fan tlv config error, e2_name is None, please check") + return + + fantlv = fan_tlv() + fantlv.typename = fan_tlv_dict["ProductName"] + fantlv.typesn = fan_tlv_dict["SerialNumber"] + fantlv.typehwinfo = fan_tlv_dict["HardwareInfo"] + fantlv.typedevtype = int(fan_tlv_dict["DevType"], 16) + if tlv_terminator == 1: + fantlv.typename += "\x00" + fantlv.typesn += "\x00" + fantlv.typehwinfo += "\x00" + rawdata = fantlv.generate_fan_value(e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate fan tlv eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate fan tlv eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_fru_value(fru_dict): + global GENERATE_RAWDATA_NUM + try: + generate_flag = fru_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = fru_dict.get("e2_size", 256) + e2_name = fru_dict.get("e2_name") + if e2_name is None: + print("fru config error, e2_name is None, please check") + return + + boradispresent = fru_dict.get("boardinfoarea_ispresent", 0) + productispresent = fru_dict.get("productInfoArea_ispresent", 0) + if boradispresent == 0 and productispresent == 0: + print("fru config error, boradispresent = 0 abd productispresent = 0") + return + + bia = None + pia = None + if boradispresent != 0: + boardinfoarea_conf = fru_dict.get("boardinfoarea") + if boardinfoarea_conf is None: + print("fru config error, boardinfoarea ispresent but boardinfoarea config is None") + return + bia = BoardInfoArea(name="Board Info Area", size=0) + bia.isPresent = True + bia.mfg_date =boardinfoarea_conf.get("mfg_date") + bia.boardManufacturer =boardinfoarea_conf["Manufacturer"] + bia.boardProductName = boardinfoarea_conf["ProductName"] + bia.boardSerialNumber = boardinfoarea_conf["SerialNumber"] + bia.boardPartNumber = boardinfoarea_conf["PartNumber"] + bia.fruFileId = boardinfoarea_conf["FRUFileID"] + for i in range(1,11): + ext_str = "extra%d" % i + valtmp = "boardextra%d" % i + val_t = boardinfoarea_conf.get(ext_str) + if val_t is None: + break + if isinstance(val_t, list): + val_t = json_list_value_decode(val_t) + setattr(bia, valtmp, val_t) + + if productispresent != 0: + productinfoarea_conf = fru_dict.get("productInfoArea") + if productinfoarea_conf is None: + print("fru config error, productinfoarea ispresent but productinfoarea_conf config is None") + return + + pia = ProductInfoArea(name="Product Info Area ", size=0) + pia.isPresent = True + pia.productManufacturer = productinfoarea_conf["Manufacturer"] + pia.productName = productinfoarea_conf["ProductName"] + pia.productPartModelName = productinfoarea_conf["PartModelName"] + pia.productVersion = productinfoarea_conf["Version"] + pia.productSerialNumber = productinfoarea_conf["SerialNumber"] + pia.productAssetTag = productinfoarea_conf.get("AssetTag") + pia.fruFileId = productinfoarea_conf["FRUFileID"] + for i in range(1,11): + ext_str = "extra%d" % i + valtmp = "productextra%d" % i + val_t = productinfoarea_conf.get(ext_str) + if val_t is None: + break + if isinstance(val_t, list): + val_t = json_list_value_decode(val_t) + setattr(pia, valtmp, val_t) + + fru = ipmifru() + if bia is not None: + fru.boardInfoArea = bia + if pia is not None: + fru.productInfoArea = pia + fru.recalcute(e2_size) + write_rawdata_to_file(fru.bindata, OUTPUT_DIR + e2_name) + print("generate fru eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate fru eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) return - e2_size = int(e2_size, 10) - eeprom_conf = {} - eeprom_conf["name"] = e2_type - eeprom_conf["e2_type"] = e2_type - eeprom_conf["e2_path"] = e2_path - eeprom_conf["e2_size"] = e2_size - eeprom_parase(eeprom_conf) + + +def generate_wedge_value(wedge_dict): + global GENERATE_RAWDATA_NUM + try: + generate_flag = wedge_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = wedge_dict.get("e2_size", 256) + e2_name = wedge_dict.get("e2_name") + if e2_name is None: + print("wedge V3 config error, e2_name is None, please check") + return + + wedge = Wedge() + wedge.fbw_product_name = wedge_dict.get("product_name", "") + wedge.fbw_product_number = wedge_dict.get("product_number", "") + wedge.fbw_assembly_number = wedge_dict.get("assembly_number", "") + wedge.fbw_facebook_pcba_number = wedge_dict.get("fb_pcba_number", "") + wedge.fbw_facebook_pcb_number = wedge_dict.get("fb_pcb_number", "") + wedge.fbw_odm_pcba_number = wedge_dict.get("odm_pcba_number", "") + wedge.fbw_odm_pcba_serial = wedge_dict.get("odm_pcba_serial", "") + wedge.fbw_production_state = wedge_dict.get("production_state", 0) + wedge.fbw_product_version = wedge_dict.get("product_version", 0) + wedge.fbw_product_subversion = wedge_dict.get("product_subversion", 0) + wedge.fbw_product_serial = wedge_dict.get("product_serial", "") + wedge.fbw_product_asset = wedge_dict.get("product_asset", "") + wedge.fbw_system_manufacturer = wedge_dict.get("system_manufacturer", "") + wedge.fbw_system_manufacturing_date = wedge_dict.get("system_manufacturing_date", "") + wedge.fbw_pcb_manufacturer = wedge_dict.get("pcb_manufacturer", "") + wedge.fbw_assembled = wedge_dict.get("assembled", "") + wedge.fbw_local_mac = wedge_dict.get("local_mac", "") + wedge.fbw_mac_base = wedge_dict.get("mac_base", "") + wedge.fbw_mac_size = wedge_dict.get("mac_size", 3) + wedge.fbw_location = wedge_dict.get("location", "") + + rawdata = wedge.generate_value(e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate wedge V3 eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate wedge V3 eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_wedge_v5_value(wedge_v5_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = wedge_v5_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = wedge_v5_dict.get("e2_size", 256) + e2_name = wedge_v5_dict.get("e2_name") + if e2_name is None: + print("wedge V5 config error, e2_name is None, please check") + return + wedgetlv = WedgeV5() + key_list = sorted(wedge_v5_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = wedge_v5_dict[key] + if isinstance(tlv_value, list): + tlv_value = json_list_value_decode(tlv_value) + _value[tlv_type] = tlv_value + rawdata = wedgetlv.generate_value(_value, e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate wedge V5 eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate wedge V5 eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def unicode_convert(input): + if isinstance(input, dict): + return {unicode_convert(key): unicode_convert(value) for key, value in input.iteritems()} + if isinstance(input, list): + return [unicode_convert(element) for element in input] + if isinstance(input, unicode): + return input.encode('utf-8') + return input + + +def generate_eeprom_rawdata(file): + status, ret = get_eeprom_config_by_json_file(file) + if status is False: + print(ret) + return + if os.path.exists(OUTPUT_DIR): + shutil.rmtree(OUTPUT_DIR) + os.mkdir(OUTPUT_DIR) + + if PYTHON_VERSION == 2: + ret = unicode_convert(ret) + + onie_tlv_conf_list = ret.get("onie_tlv", []) + rg_tlv_conf_list = ret.get("fan_tlv", []) + fru_conf_list = ret.get("fru", []) + wedge_conf_list = ret.get("wedge", []) + wedge_v5_conf_list = ret.get("wedge_v5", []) + + for onie_tlv_conf in onie_tlv_conf_list: + generate_onie_tlv_value(onie_tlv_conf) + + for fan_tlv_conf in rg_tlv_conf_list: + generate_fan_tlv_value(fan_tlv_conf) + + for fru_conf in fru_conf_list: + generate_fru_value(fru_conf) + + for wedge_conf in wedge_conf_list: + generate_wedge_value(wedge_conf) + + for wedge_v5_conf in wedge_v5_conf_list: + generate_wedge_v5_value(wedge_v5_conf) + + + if GENERATE_RAWDATA_NUM == 0: + print("All generate_flag config is 0, no eeprom rawdata was generated.") return -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): +@click.group(cls=AliasedGroup, invoke_without_command=True) +@click.help_option('-h', '--help', help='show help info') +@click.option('-p', '--parse', help='Parse eeprom rawdata of the specified path, support directory and file') +@click.option('-f', '--file', help='JSON file to generate eeprom rawdata') +@click.option('-t', '--type', help='Display eeprom information of specified type, support onie_tlv/fru/fantlv/custfru/wedge/wedge_v5') +@click.option('-s', '--size', type=int, help='Parse eeprom rawdata of the specified path, support directory and file', hidden=True) +@click.option('-n', '--name', help=E2_NAME_CLICK_HELP) +@click.pass_context +def main(ctx, parse, file, type, size, name): '''platform eeprom display script''' + if ctx.invoked_subcommand is None and parse is None and file is None and type is None and name is None: + cli_ctx = click.Context(main) + click.echo(cli_ctx.get_help()) + return + + if file is not None: + generate_eeprom_rawdata(file) + + if parse is not None: + eeprom_parse(parse, size) + + if type is not None: + get_specified_eeprom_info(type) + + if name is not None: + get_eeprom_info_by_name(name) # fan eeprom info display @@ -410,35 +1040,12 @@ def syseeprom(syseeprom_index): get_syseeprom_info(syseeprom_index) -# fru eeprom info decode -@main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def fru(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("fru", e2_path, e2_size) - - -# fantlv eeprom info decode -@main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def fantlv(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("fantlv", e2_path, e2_size) - - -# onie_tlv eeprom info decode +# all eeprom info display @main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def onie_tlv(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("onie_tlv", e2_path, e2_size) +def all(): + '''get all eeprom info''' + get_all_eeprom_info() if __name__ == '__main__': - if os.geteuid() != 0: - print("Root privileges are required for this operation") - sys.exit(1) main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py index ef27c2392eb4..9015397a5d26 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import glob diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py index c9b72c99cca9..fa3fbc6ece18 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py index b2643da9bce4..c9b7cd1441d8 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 re import mmap @@ -11,6 +26,7 @@ import sys from platform_config import MANUINFO_CONF from monitor import status +from platform_util import * INDENT = 4 @@ -171,16 +187,9 @@ def removedriver(name): def deal_itmes(item_list): for item in item_list: - dealtype = item.get("dealtype") - if dealtype == "shell": - cmd = item.get("cmd") - timeout = item.get("timeout", 10) - exec_os_cmd(cmd, timeout) - elif dealtype == "io_wr": - io_addr = item.get("io_addr") - wr_value = item.get("value") - io_wr(io_addr, wr_value) - + ret, log = set_value(item) + if not ret: + print("deal items error:%s" % log) def get_func_value(funcname, params): func = getattr(ExtraFunc, funcname) @@ -228,7 +237,7 @@ def devfileread(path, offset, length, bit_width): for j in range(0, bit_width): val_str += "%02x" % val_list[i + bit_width - j - 1] except Exception as e: - return str(e) + return "%s-%s" % (path, str(e)) finally: if fd > 0: os.close(fd) @@ -495,7 +504,10 @@ def hunt(self): if self.decode is not None: tmp_version = self.decode.get(version) if tmp_version is None: - version = "ERR decode %s failed" % version + if self.decode.get("default") is not None: + version = self.decode.get("default") + else: + version = "ERR decode %s failed" % version else: version = tmp_version format_str = "{}{:<{}}{}".format(indent, self.key + ':', diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py new file mode 100755 index 000000000000..a624b2087d1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 . + +from platform_config import PLATFORM_POWER_CONF +from platform_util import get_value, get_format_value + + +class Power(object): + def __init__(self, conf): + self.name = None + self.format = None + self.unit = None + self.val_conf = None + self.value = 0 + self.child_list = [] + self.status = True + self.pre_check = None + self.__dict__.update(conf) + + def update_value(self): + try: + if self.pre_check is not None: + ret, val = get_value(self.pre_check) + if ret is False: + self.status = False + self.value = "ERR: %s" % val + return + mask = self.pre_check.get("mask") + if isinstance(val, str): + value = int(val, 16) + else: + value = val + ttt = value & mask + okval = self.pre_check.get("okval") + if ttt != okval: + self.status = False + self.value = "%s" % self.pre_check.get("not_ok_msg") + return + + val_list = [] + for val_conf_item in self.val_conf: + ret, val_tmp = get_value(val_conf_item) + if ret is False: + self.status = False + self.value = "ERR: %s" % val_tmp + return + val_list.append(val_tmp) + val_tuple = tuple(val_list) + value = get_format_value(self.format % (val_tuple)) + self.status = True + self.value = round(float(value), 1) + return + except Exception as e: + self.status = False + self.value = "ERR: %s" % str(e) + return + + +def run(): + if len(PLATFORM_POWER_CONF) == 0: + print("platform_power config error, config len is 0!") + return + + power_obj_list = [] + for power_item in PLATFORM_POWER_CONF: + power_obj = Power(power_item) + tmp_value = 0 + power_obj.child_list = [] + children = power_item.get("children") + # get power value with children + if children is not None: + for child in children: + child_obj = Power(child) + power_obj.child_list.append(child_obj) + child_obj.update_value() + if child_obj.status is True: + tmp_value += child_obj.value + power_obj.value = round(float(tmp_value), 1) + else: + power_obj.update_value() + + if power_obj.status is False: + print("%-34s : %s" % (power_obj.name, power_obj.value)) + else: + print("%-34s : %s %s" % (power_obj.name, power_obj.value, power_obj.unit)) + if len(power_obj.child_list) != 0: + for obj in power_obj.child_list: + if obj.status is False: + print(" %-30s : %s" % (obj.name, obj.value)) + else: + print(" %-30s : %s %s" % (obj.name, obj.value, obj.unit)) + print("") + return + + +if __name__ == "__main__": + run() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py index 6013c5d65853..3c76dd447a7d 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 subprocess import glob diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py index cea20393195f..b7f5ca29d427 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py @@ -1,9 +1,35 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys import importlib.machinery +try: + from platform_sensors_hal import Platoform_sensor_hal + + platform_sensor_hal = Platoform_sensor_hal() + print_src = platform_sensor_hal.get_sensor_print_src() + if print_src == "s3ip": + platform_sensor_hal.getsensors() + sys.exit(0) +except Exception as e: + pass + def get_machine_info(): if not os.path.isfile('/host/machine.conf'): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py new file mode 100755 index 000000000000..7e505b59abe9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys +from plat_hal.interface import interface, getplatform_name +from collections import OrderedDict + +class Platoform_sensor_hal(object): + + # status showed + __STATUS_OK = "OK" + __STATUS_ABSENT = "ABSENT" + __STATUS_NOT_OK = "NOT OK" + __STATUS_FAILED = "GET FAILED" + + def __init__(self): + self.int_case = interface() + + def print_console(self, msg): + print(msg) + + def print_platform(self): + platform_info = getplatform_name() + self.print_console(platform_info) + self.print_console("") + + def print_boardtemp(self): + try: + ''' + eg: cpu temp, mac temp and others + Onboard Temperature Sensors: + BASE_air_inlet : 17.0 C (high = 80.0 C) + MCU_air_inlet0 : 16.5 C (high = 80.0 C) + MCU_air_inlet1 : 16.5 C (high = 80.0 C) + ''' + info_dict = self.int_case.get_temp_info_s3ip() + + monitor_sensor = [] + for sensor_key, sensor_info in info_dict.items(): + monitor_one_sensor_dict = OrderedDict() + monitor_one_sensor_dict['id'] = sensor_key + try: + monitor_one_sensor_dict['temp1_input'] = float(sensor_info["Value"]) / 1000 + monitor_one_sensor_dict['temp1_max'] = float(sensor_info["Max"]) / 1000 + except Exception: + monitor_one_sensor_dict["status"] = self.__STATUS_FAILED + # monitor_one_sensor_dict['temp1_max_hyst'] = sensor_info["High"] + monitor_sensor.append(monitor_one_sensor_dict) + + print_info_str = "" + toptile = "Onboard Temperature Sensors:" + errformat = " {id:<25} : {status}" + # formatstr = " {id:<20} : {temp1_input} C (high = {temp1_max} C, hyst = {temp1_max_hyst} C)" + formatstr = " {id:<25} : {temp1_input} C (high = {temp1_max} C)" + + if len(monitor_sensor) != 0: + print_info_str += toptile + '\n' + for item in monitor_sensor: + realformat = formatstr if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + '\n' + self.print_console(print_info_str) + except Exception: + pass + + def print_fan_sensor(self): + try: + ''' + eg: + Onboard fan Sensors: + fan1 : + fan_type :FAN18K8086-F + sn :0000000000000 + hw_version:00 + Speed : + speed_front :12077 RPM + speed_rear :10231 RPM + status :OK + ''' + fans = self.int_case.get_fans() + fan_dict = self.int_case.get_fan_info_all() + monitor_fans = [] + for fan in fans: + monitor_one_fan_dict = OrderedDict() + monitor_one_fan_dict["id"] = fan.name + present = fan_dict.get(fan.name).get("Present") + if present == "no": + monitor_one_fan_dict["status"] = self.__STATUS_ABSENT + else: + monitor_one_fan_dict["fan_type"] = fan_dict.get(fan.name).get("DisplayName") + monitor_one_fan_dict["sn"] = fan_dict.get(fan.name).get("SN") + monitor_one_fan_dict["hw_version"] = fan_dict.get(fan.name).get("HW") + + all_rotors_ok = True + rotor_speeds = {} + for rotor in fan.rotor_list: + rotor_info = fan_dict.get(fan.name).get(rotor.name) + rotor_speeds[rotor.name] = rotor_info.get("Speed") + running = rotor_info.get("Running") + hw_alarm = rotor_info.get("HwAlarm") + if running != "yes" or hw_alarm != "no": + all_rotors_ok = False + monitor_one_fan_dict.update(rotor_speeds) + monitor_one_fan_dict["status"] = self.__STATUS_OK if all_rotors_ok else self.__STATUS_NOT_OK + monitor_one_fan_dict["rotor_num"] = len(fan.rotor_list) + monitor_fans.append(monitor_one_fan_dict) + + print_info_str = "" + toptile = "Onboard fan Sensors:" + errformat = " {id} : {status}\n" # " {id:<20} : {status}" + fan_signle_rotor_format = " {id} : \n" \ + " fan_type : {fan_type}\n" \ + " sn : {sn}\n" \ + " hw_version: {hw_version}\n" \ + " Speed : {Speed} RPM\n" \ + " status : {status} \n" + fan_double_rotor_format = " {id} : \n" \ + " fan_type : {fan_type}\n" \ + " sn : {sn}\n" \ + " hw_version: {hw_version}\n" \ + " Speed :\n" \ + " speed_front : {Rotor1:<5} RPM\n" \ + " speed_rear : {Rotor2:<5} RPM\n" \ + " status : {status} \n" + + if len(monitor_fans) != 0: + print_info_str += toptile + '\n' + for item in monitor_fans: + if item.get("rotor_num", 1) == 2: + realformat = fan_double_rotor_format if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + else: + realformat = fan_signle_rotor_format if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + self.print_console(print_info_str) + except Exception: + pass + + def print_psu_sensor(self): + try: + ''' + Onboard Power Supply Unit Sensors: + psu1 : + type :PSA2000CRPS-F + sn :R693A3D100003 + in_current :1.8 A + in_voltage :237.8 V + out_current:30.1 A + out_voltage:12.2 V + temp :22.5 C + fan_speed :26656 RPM + in_power :413.0 W + out_power :366.5 W + ''' + psus = self.int_case.get_psus() + psu_dict = self.int_case.get_psu_info_all() + monitor_psus = [] + for psu in psus: + monitor_one_psu_dict = OrderedDict() + monitor_one_psu_dict["id"] = psu.name + present = psu_dict.get(psu.name).get("Present") + if present == "no": + monitor_one_psu_dict["status"] = self.__STATUS_ABSENT + else: + monitor_one_psu_dict["type"] = psu_dict.get(psu.name).get("PN") + monitor_one_psu_dict["sn"] = psu_dict.get(psu.name).get("SN") + monitor_one_psu_dict["in_current"] = psu_dict.get(psu.name).get("Inputs").get("Current").get("Value") + monitor_one_psu_dict["in_voltage"] = psu_dict.get(psu.name).get("Inputs").get("Voltage").get("Value") + monitor_one_psu_dict["out_current"] = psu_dict.get(psu.name).get("Outputs").get("Current").get("Value") + monitor_one_psu_dict["out_voltage"] = psu_dict.get(psu.name).get("Outputs").get("Voltage").get("Value") + monitor_one_psu_dict["temp"] = psu_dict.get(psu.name).get("Temperature").get("Value") + monitor_one_psu_dict["fan_speed"] = psu_dict.get(psu.name).get("FanSpeed").get("Value") + monitor_one_psu_dict["in_power"] = psu_dict.get(psu.name).get("Inputs").get("Power").get("Value") + monitor_one_psu_dict["out_power"] = psu_dict.get(psu.name).get("Outputs").get("Power").get("Value") + monitor_psus.append(monitor_one_psu_dict) + + print_info_str = "" + toptile = "Onboard Power Supply Unit Sensors:" + errformat = " {id} : {status}\n" # " {id:<20} : {status}" + psuformat = " {id} : \n" \ + " type : {type}\n" \ + " sn : {sn}\n" \ + " in_current : {in_current} A\n" \ + " in_voltage : {in_voltage} V\n" \ + " out_current: {out_current} A\n" \ + " out_voltage: {out_voltage} V\n" \ + " temp : {temp} C \n" \ + " fan_speed : {fan_speed} RPM\n" \ + " in_power : {in_power} W\n" \ + " out_power : {out_power} W\n" + + if len(monitor_psus) != 0: + print_info_str += toptile + '\r\n' + for item in monitor_psus: + realformat = psuformat if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + self.print_console(print_info_str) + except Exception: + pass + + def print_boarddcdc(self): + try: + ''' + eg: + Onboard DCDC Sensors: + CPU_VCCIN : 12.187 V (Min = 1.500 V, Max = 2.000 V) + CPU_P1V8 : 1.780 V (Min = 1.710 V, Max = 1.890 V) + CPU_P1V05 : 12.250 V (Min = 1.000 V, Max = 1.120 V) + CPU_VNN_PCH : 1.060 V (Min = 0.600 V, Max = 1.200 V) + CPU_P1V2_VDDQ : 12.125 V (Min = 1.140 V, Max = 1.260 V) + CPU_VNN_NAC : 12.187 V (Min = 0.600 V, Max = 1.200 V) + CPU_VCC_ANA : 0.845 V (Min = 0.950 V, Max = 1.050 V) + CPU_P1V05 : 1.057 V (Min = 0.990 V, Max = 1.130 V) + ''' + + dcdc_dict = self.int_case.get_dcdc_all_info() + monitor_sensor = [] + for sensor_key, sensor_info in dcdc_dict.items(): + monitor_one_sensor_dict = OrderedDict() + monitor_one_sensor_dict['id'] = sensor_key + try: + monitor_one_sensor_dict['dcdc_input'] = float(sensor_info["Value"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict['dcdc_min'] = float(sensor_info["Min"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict['dcdc_max'] = float(sensor_info["Max"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict["status"] = sensor_info["Status"] + except Exception: + monitor_one_sensor_dict["status"] = self.__STATUS_FAILED + monitor_sensor.append(monitor_one_sensor_dict) + + print_info_str = "" + toptile = "Onboard DCDC Sensors:" + errformat = " {id:<26} : {errmsg}" + ok_formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1})" + nok_formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1}) ({status:<6})" + + if len(monitor_sensor) != 0: + print_info_str += toptile + '\n' + for item in monitor_sensor: + if item.get("status", self.__STATUS_OK) == self.__STATUS_OK: + realformat = ok_formatstr + elif item.get("status", self.__STATUS_OK) == self.__STATUS_NOT_OK: + realformat = nok_formatstr + else: + realformat = errformat + print_info_str += realformat.format(**item) + '\n' + self.print_console(print_info_str) + except Exception: + pass + + def getsensors(self): + self.print_platform() + self.print_boardtemp() + # self.print_macpower_sensors() + self.print_fan_sensor() + self.print_psu_sensor() + # self.print_slot_sensor() + self.print_boarddcdc() + + def get_sensor_print_src(self): + return self.int_case.get_sensor_print_src() + +if __name__ == "__main__": + platform_sensor_hal = Platoform_sensor_hal() + platform_sensor_hal.getsensors() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py index da7119a9ce49..a7c39264c791 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py @@ -1,5 +1,19 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 . try: import click diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py index fe4d564ad604..2187b391a230 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os @@ -69,6 +84,8 @@ def get_op_value(self, node): value = node.n elif isinstance(node, ast.Str): # node is Str Constant value = node.s + elif isinstance(node, ast.List): # node is List Constant + value = [element.value for element in node.elts] else: raise NotImplementedError("Unsupport operand type: %s" % type(node)) return value @@ -117,7 +134,7 @@ def visit_Call(self, node): int support one or two parameters, eg: int(xxx) or int(xxx, 16) xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp ''' - calc_tuple = ("float", "int", "str") + calc_tuple = ("float", "int", "str", "max", "min") if node.func.id not in calc_tuple: raise NotImplementedError("Unsupport function call type: %s" % node.func.id) @@ -125,7 +142,10 @@ def visit_Call(self, node): args_val_list = [] for item in node.args: ret = self.get_op_value(item) - args_val_list.append(ret) + if isinstance(ret, list): + args_val_list.extend(ret) + else: + args_val_list.append(ret) if node.func.id == "str": if len(args_val_list) != 1: @@ -140,6 +160,16 @@ def visit_Call(self, node): value = float(args_val_list[0]) self.value = value return value + + if node.func.id == "max": + value = max(args_val_list) + self.value = value + return value + + if node.func.id == "min": + value = min(args_val_list) + self.value = value + return value # int if len(args_val_list) == 1: value = int(args_val_list[0]) @@ -375,14 +405,20 @@ def dev_file_write(path, offset, buf_list): msg = "" fd = -1 - if not isinstance(buf_list, list) or len(buf_list) == 0: - msg = "buf:%s is not list type or is NONE !" % buf_list - return False, msg - if not os.path.exists(path): msg = path + " not found !" return False, msg + if isinstance(buf_list, list): + if len(buf_list) == 0: + msg = "buf_list:%s is NONE !" % buf_list + return False, msg + elif isinstance(buf_list, int): + buf_list = [buf_list] + else: + msg = "buf_list:%s is not list type or not int type !" % buf_list + return False, msg + try: fd = os.open(path, os.O_WRONLY) os.lseek(fd, offset, os.SEEK_SET) @@ -565,6 +601,9 @@ def get_value_once(config): read_len = config.get("read_len") ret, val_list = dev_file_read(path, offset, read_len) if ret is True: + if read_len == 1: + val = val_list[0] + return True, val return True, val_list return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (path, offset, read_len)) if way == 'cmd': @@ -578,7 +617,16 @@ def get_value_once(config): if os.path.exists(judge_file): return True, True return True, False - return False, "not support read type" + if way == 'pci': + pcibus = config.get("pcibus") + slot = config.get("slot") + fn = config.get("fn") + bar = config.get("bar") + offset = config.get("offset") + data = config.get("data") + return wbpcird(pcibus, slot, fn, bar, offset, data) + + return False, ("%s is not support read type" % way) except Exception as e: return False, ("get_value_once exception:%s happen" % str(e)) @@ -668,7 +716,7 @@ def set_value_once(config): ret, log = dev_file_write(path, offset, buf_list) if ret is True: return True, ("devfile write path:%s, offset:0x%x, buf_list:%s success." % (path, offset, buf_list)) - return False, ("devfile read path:%s, offset:0x%x, buf_list:%s failed.log:%s" % + return False, ("devfile write path:%s, offset:0x%x, buf_list:%s failed.log:%s" % (path, offset, buf_list, log)) if way == 'cmd': cmd = config.get("cmd") @@ -703,7 +751,16 @@ def set_value_once(config): return False, ("remove file %s failed, log: %s" % (file_name, log)) exec_os_cmd("sync") return True, ("remove file %s success" % file_name) - return False, "not support write type" + if way == 'pci': + pcibus = config.get("pcibus") + slot = config.get("slot") + fn = config.get("fn") + bar = config.get("bar") + offset = config.get("offset") + data = config.get("data") + return wbpciwr(pcibus, slot, fn, bar, offset, data) + + return False, ("%s not support write type" % way) except Exception as e: return False, ("set_value_once exception:%s happen" % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py b/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py index 8bdceef8c1b5..95c1eebe5ab2 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py @@ -1,8 +1,20 @@ #!/usr/bin/python3 -# * onboard interval check -# * FAN trays -# * PSU -# * SFF +# +# Copyright (C) 2024 Micas 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 +# 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 time import syslog import traceback diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py new file mode 100755 index 000000000000..bc43168c68f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py @@ -0,0 +1,333 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 +# 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 syslog +import click +import os +import fcntl +import time +import sys +from platform_util import get_value, set_value +from platform_config import POWER_CTRL_CONF + + +POWERCTLDEBUG = 0 +OE_SUPPROT_OPERATE = ("status", "off", "on", "reset") +STATUS_OFF = "off" +STATUS_ON = "on" +STATUS_UNKNOWN = "unknown" +CLI_CONFIRM = True +POWER_CTRL_DEBUG_FILE = "/etc/.power_control_debug" +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global POWERCTLDEBUG + if os.path.exists(POWER_CTRL_DEBUG_FILE): + POWERCTLDEBUG = 1 + else: + POWERCTLDEBUG = 0 + + +def powerctrldebug(s): + # s = s.decode('utf-8').encode('gb2312') + if POWERCTLDEBUG == 1: + syslog.openlog("POWERCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def get_status_once(conf): + val_conf = conf.get("val_conf", {}) + ret, val = get_value(val_conf) + if ret is False: + powerctrldebug("get_status_once failure, val_conf: %s, msg: %s" % (val_conf, val)) + return STATUS_UNKNOWN + + if isinstance(val, str): + val_tmp = int(val, 16) + else: + val_tmp = val + + mask = val_conf.get("mask") + if mask is not None: + value = val_tmp & mask + else: + value = val_tmp + + powerctrldebug("val_conf: %s, value: %s, val_tmp: %s, mask: %s" % (val_conf, value, val_tmp, mask)) + off_val_list = conf.get("off", []) + if value in off_val_list: + powerctrldebug("value: %s, is in off_val_list: %s, status is off" % (value, off_val_list)) + return STATUS_OFF + + on_val_list = conf.get("on", []) + if value in on_val_list: + powerctrldebug("value: %s, is in on_val_list: %s, status is on" % (value, on_val_list)) + return STATUS_ON + + powerctrldebug("value: %s, not in off_val_list: %s, and on_val_list: %s" % (value, off_val_list, on_val_list)) + return STATUS_UNKNOWN + + +def get_status(conf): + status_list = [] + for item in conf: + status = get_status_once(item) + break_status = item.get("break_status", []) + if status in break_status: + powerctrldebug("status: %s is in break status: %s, return" % (status, break_status)) + return status + status_list.append(status) + if len(set(status_list)) == 1: # All states are consistent + powerctrldebug("All states are consistent, status_list: %s, return status: %s" % (status_list, status_list[0])) + return status_list[0] + # status list inconsistent + powerctrldebug("The status in the status list is inconsistent, status_list: %s" % status_list) + return STATUS_UNKNOWN + + +def do_power_operation(conf): + for item in conf: + ret, msg = set_value(item) + if ret is False: + powerctrldebug("set value failed, conf: %s, msg %s" % (item, msg)) + return ret, msg + powerctrldebug("set value success, conf: %s" % item) + return True, "" + + +def do_power_off(name, conf, cli_confirm): + power_conf = conf.get("off") + if power_conf is None: + msg = ("power off config is none, can't do power off operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power off %s?" % name): + click.echo('Aborted.') + sys.exit(0) + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_power_on(name, conf, cli_confirm): + power_conf = conf.get("on") + if power_conf is None: + msg = ("power on config is none, can't do power on operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power on %s?" % name): + click.echo('Aborted.') + sys.exit(0) + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_power_cycle(name, conf, cli_confirm): + if cli_confirm is True and not click.confirm("Are you sure you want to power cycle %s?" % name): + click.echo('Aborted.') + sys.exit(0) + + power_conf = conf.get("cycle") + if power_conf is not None: + ret, msg = do_power_operation(power_conf) + return ret, msg + # power cycle config is none, try to power off then power on + ret, msg = do_power_off(name, conf, False) + if ret is False: + return ret, msg + ret, msg = do_power_on(name, conf, False) + return ret, msg + + +def do_power_reset(name, conf, cli_confirm): + power_conf = conf.get("reset") + if power_conf is None: + msg = ("power reset config is none, can't do power reset operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power on %s?" % name): + click.echo('Aborted.') + sys.exit(0) + + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_operation(conf, command): + name = conf.get("name") + + # First get the current status before any operation + curr_status = None + status_conf = conf.get("status") + if status_conf is None: + powerctrldebug("%s status config is None" % name) + else: + curr_status = get_status(status_conf) + powerctrldebug("%s get_status %s" % (name, curr_status)) + + # get status command + if command == "status": + if curr_status is None: + print("Can't get %s %s config" % (name, command)) + else: + print("Power status for %s: %s" % (name, curr_status)) + return + + # power off command + if command == "off": + if curr_status == "off": + print("%s is already powered off..." % name) + return + ret, msg = do_power_off(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered off failure, msg: %s" % (name, msg)) + else: + print("%s powered off successfully" % name) + return + + # power on command + if command == "on": + if curr_status == "on": + print("%s is already powered on..." % name) + return + ret, msg = do_power_on(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered on failure, msg: %s" % (name, msg)) + else: + print("%s powered on successfully" % name) + return + + # power cycle command + if command == "cycle": + if curr_status == "off": + # current status is off, do powered on to powered cycle + powerctrldebug("%s current status is off, try to do powered on" % name) + ret, msg = do_power_on(name, conf, CLI_CONFIRM) + else: + # current status is not off, do powered cycle + powerctrldebug("%s current status is not off, try to do powered cycle" % name) + ret, msg = do_power_cycle(name, conf, CLI_CONFIRM) + + if ret is False: + print("%s powered cycle failure, msg: %s" % (name, msg)) + else: + print("%s powered cycle successfully" % name) + return + + # power reset command + if curr_status == "off": + print("%s is currently powered off. Please power it on before performing the reset operation." % name) + return + ret, msg = do_power_reset(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered reset failure, msg: %s" % (name, msg)) + else: + print("%s powered reset successfully" % name) + return + + +def do_oe_power_ctrl(oe_index, command): + oe_power_conf = POWER_CTRL_CONF.get("oe", []) + oe_num = len(oe_power_conf) + if oe_num == 0: + print("OE power control config is none, don't support oe power control.") + return + + if oe_index < 0 or oe_index >= oe_num: + print("Invalid oe index: %d, oe index must [0~%d]" % (oe_index, oe_num -1)) + return + + if command not in OE_SUPPROT_OPERATE: + print("Unsupported operation command: %s" % command) + return + + oe_power_conf_item = oe_power_conf[oe_index] + + do_operation(oe_power_conf_item, command) + return + + +pidfile = 0 +def ApplicationInstance(): + global pidfile + pidfile = open(os.path.realpath(__file__), "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + return True + except Exception: + return False + + +# Single-process execution only +def cli_ready_check(): + start_time = time.time() + while True: + ret = ApplicationInstance() + if ret is True: + break + + if time.time() - start_time < 0: + start_time = time.time() + + if time.time() - start_time > 10: + print("Please wait for the power_ctrl command to complete before performing further operations") + sys.exit(1) + time.sleep(0.1) + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +@click.help_option('-h', '--help', help='show help info') +@click.option('-y', '--yes', is_flag=True, help='Automatically confirm and skip the prompt.', hidden=True) +def main(yes): + '''power control script''' + global CLI_CONFIRM + if yes is True: + CLI_CONFIRM = False + + +# oe power control +@main.command() +@click.argument('oe_index', required=True, type=int) +@click.argument('command', required=True) +def oe(oe_index, command): + '''OE_INDEX: start from 0, COMMAND: off, on, reset, status''' + do_oe_power_ctrl(oe_index, command) + + +if __name__ == '__main__': + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + cli_ready_check() + debug_init() + main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py index 2f125c5084c2..0020dd32b9d1 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py @@ -1,5 +1,20 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import time @@ -45,8 +60,12 @@ def monitor_point_check(self, item): ret, value = get_value(item) if ret is True: if compare_mode == "equal": - if value == okval: - return True + if isinstance(okval, list): + if value in okval: + return True + else: + if value == okval: + return True elif compare_mode == "great": if value > okval: return True diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py deleted file mode 100755 index 17d3f5902b9d..000000000000 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import time -import syslog -import click -from platform_util import write_sysfs, wbi2cset, io_wr, wbi2csetWord -from platform_config import REBOOT_CTRL_PARAM - - -REBOOTCTLDEBUG = 0 - -CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} - - -class AliasedGroup(click.Group): - def get_command(self, ctx, cmd_name): - rv = click.Group.get_command(self, ctx, cmd_name) - if rv is not None: - return rv - matches = [x for x in self.list_commands(ctx) - if x.startswith(cmd_name)] - if not matches: - return None - if len(matches) == 1: - return click.Group.get_command(self, ctx, matches[0]) - ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) - return None - - -def rebootctrlwarning(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_WARNING, s) - - -def rebootctrlcritical(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_CRIT, s) - - -def rebootctrlerror(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_ERR, s) - - -def rebootctrldebug(s): - # s = s.decode('utf-8').encode('gb2312') - if REBOOTCTLDEBUG == 1: - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_DEBUG, s) - - -class RebootCtrl(): - def __init__(self): - self.config = REBOOT_CTRL_PARAM.copy() - - def set_value(self, config, val): - way = config.get("gettype") - if way == 'sysfs': - loc = config.get("loc") - value = config.get(val) - rebootctrldebug("sysfs type.loc:0x%x, value:0x%x" % (loc, value)) - return write_sysfs(loc, "0x%02x" % value) - if way == "i2c": - bus = config.get("bus") - addr = config.get("loc") - offset = config.get("offset") - value = config.get(val) - rebootctrldebug("i2c type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) - return wbi2cset(bus, addr, offset, value) - if way == "io": - io_addr = config.get('io_addr') - value = config.get(val) - rebootctrldebug("io type.io_addr:0x%x, value:0x%x" % (io_addr, value)) - ret = io_wr(io_addr, value) - if ret is not True: - return False, ("write 0x%x failed" % io_addr) - return True, ("write 0x%x success" % io_addr) - if way == 'i2cword': - bus = config.get("bus") - addr = config.get("loc") - offset = config.get("offset") - value = config.get(val) - rebootctrldebug("i2cword type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) - return wbi2csetWord(bus, addr, offset, value) - return False, "unsupport way: %s" % way - - def reset_operate(self, config): - ret, log = self.set_value(config, "rst_val") - rst_delay = config.get("rst_delay", 0) - time.sleep(rst_delay) - return ret, log - - def unlock_reset_operate(self, config): - ret, log = self.set_value(config, "unlock_rst_val") - unlock_rst_delay = config.get("unlock_rst_delay", 0) - time.sleep(unlock_rst_delay) - return ret, log - - def do_rebootctrl(self, option): - if self.config is None: - rebootctrlerror("Reset failed, REBOOT_CTRL_PARAM cfg get failed.") - return - try: - name_conf = self.config.get(option, None) - if name_conf is None: - print("Reset %s not support" % option) - return - try: - click.confirm("Are you sure you want to reset " + option + "?", - default=False, abort=True, show_default=True) - except Exception as e: - print("Aborted, msg: %s" % str(e)) - return - print("Reset %s start" % option) - ret, log = self.reset_operate(name_conf) - if ret is False: - rebootctrlerror(log) - print("Reset %s failed" % option) - return - if "unlock_rst_val" in name_conf: - ret, log = self.unlock_reset_operate(name_conf) - if ret is False: - rebootctrlerror(log) - print("%s unlock reset failed" % option) - return - print("Reset %s success" % option) - except Exception: - rebootctrlerror("do_rebootctrl Exception error") - return - - -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): - '''reboot_ctrl reset [option]''' - - -@main.command() -@click.argument('option', required=True) -def reset(option): - '''reset device''' - rebootctrldebug("reboot ctrl option %s" % option) - rebootctrl = RebootCtrl() - rebootctrl.do_rebootctrl(option) - - -if __name__ == '__main__': - main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/sensors b/platform/broadcom/sonic-platform-modules-micas/common/script/sensors index a2c72b123a43..f81cc18bfb7a 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/sensors +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/sensors @@ -1,6 +1,21 @@ #!/bin/bash -#docker exec -i pmon sensors "$@" +# +# Copyright (C) 2024 Micas 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 +# 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 . +# docker exec -i pmon sensors "$@" #To probe sensors not part of lm-sensors if [ -r /usr/local/bin/platform_sensors.py ]; then diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py b/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py index f4727d802753..227bc8e00e61 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 syslog import os import re diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py index 4dd98f3a36b3..21e14b048873 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py @@ -1,4 +1,20 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 +# 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 importlib.machinery import time @@ -13,6 +29,10 @@ SFP_TEMP_RECORD_ERROR = 2 debuglevel = 0 +# For TH5 CPO only +cpo_temperature_oe_file = "/etc/sonic/highest_oe_temp" +cpo_temperature_rlm_file = "/etc/sonic/highest_rlm_temp" +cpo_onie_platform = "x86_64-micas_m2-w6940-128x1-fr4-r0" def sfp_temp_debug(s): if SFP_TEMP_RECORD_DEBUG & debuglevel: @@ -25,28 +45,21 @@ def sfp_temp_error(s): syslog.openlog("SFP_TEMP_ERROR", syslog.LOG_PID) syslog.syslog(syslog.LOG_ERR, s) - -pidfile = None - - -def file_rw_lock(): - global pidfile - pidfile = open(sfp_temperature_file, "r") +def file_rw_lock(file_path): + pidfile = open(file_path, "r") try: fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) sfp_temp_debug("file lock success") - return True + return True, pidfile except Exception: if pidfile is not None: pidfile.close() pidfile = None - return False + return False, pidfile -def file_rw_unlock(): +def file_rw_unlock(pidfile): try: - global pidfile - if pidfile is not None: fcntl.flock(pidfile, fcntl.LOCK_UN) pidfile.close() @@ -70,7 +83,7 @@ def get_sfp_highest_temperature(): sfputil_dir = "/usr/share/sonic/platform/" sfputil_path = sfputil_dir + "/plugins/sfputil.py" else: - cmd = "cat /host/machine.conf | grep onie_build_platform" + cmd = "cat /host/machine.conf | grep onie_platform" ret, output = subprocess.getstatusoutput(cmd) if ret != 0: sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) @@ -86,21 +99,22 @@ def get_sfp_highest_temperature(): highest_temperature = int(temperature) * 1000 except Exception as e: sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) - highest_temperature = -9999000 + highest_temperature = -9999000 # fix me in future, should be -99999000 return highest_temperature -def write_sfp_highest_temperature(temperature): +def write_sfp_highest_temperature(temperature, path): loop = 1000 ret = False + pidfile = None try: - if os.path.exists(sfp_temperature_file) is False: - with open(sfp_temperature_file, 'w') as sfp_f: + if os.path.exists(path) is False: + with open(path, 'w') as sfp_f: pass for i in range(0, loop): - ret = file_rw_lock() + ret, pidfile = file_rw_lock(path) if ret is True: break time.sleep(0.001) @@ -109,16 +123,89 @@ def write_sfp_highest_temperature(temperature): sfp_temp_error("take file lock timeout") return - with open(sfp_temperature_file, 'w') as sfp_f: + with open(path, 'w') as sfp_f: sfp_f.write("%s\n" % str(temperature)) - file_rw_unlock() + file_rw_unlock(pidfile) return except Exception as e: sfp_temp_error("write sfp temperature error, msg:%s" % str(e)) - file_rw_unlock() + file_rw_unlock(pidfile) return +def get_cpo_highest_temperature(): + + oe_temp = get_cpo_highest_temperature_oe() + rlm_temp = get_cpo_highest_temperature_rlm() + + return oe_temp, rlm_temp + +def get_cpo_highest_temperature_oe(): + highest_temperature = 0 + platform_sfputil = None + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature_cpo_oe() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -99999000 + + return highest_temperature + +def get_cpo_highest_temperature_rlm(): + highest_temperature = 0 + platform_sfputil = None + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature_cpo_rlm() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -99999000 + + return highest_temperature + +def is_th5_cpo(): + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + if output.split("=")[1] == cpo_onie_platform: + return True + + return False def debug_init(): global debuglevel @@ -132,16 +219,35 @@ def debug_init(): def main(): - while True: - debug_init() - temperature = 0 - try: - temperature = get_sfp_highest_temperature() - write_sfp_highest_temperature(temperature) - except Exception as e: - sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) - write_sfp_highest_temperature(-9999000) - time.sleep(5) + if is_th5_cpo(): + while True: + debug_init() + temperature_oe = 0 + try: + temperature_oe = get_cpo_highest_temperature_oe() + write_sfp_highest_temperature(temperature_oe, cpo_temperature_oe_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-99999000, cpo_temperature_oe_file) + temperature_rlm = 0 + try: + temperature_rlm = get_cpo_highest_temperature_rlm() + write_sfp_highest_temperature(temperature_rlm, cpo_temperature_rlm_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-99999000, cpo_temperature_rlm_file) + time.sleep(5) + else: + while True: + debug_init() + temperature = 0 + try: + temperature = get_sfp_highest_temperature() + write_sfp_highest_temperature(temperature, sfp_temperature_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-9999000, sfp_temperature_file) + time.sleep(5) if __name__ == '__main__': diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py index 0385f50b6f50..633fc028964e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 time import syslog import traceback diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon b/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon index 4290b0a68725..2b79aed0a276 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon @@ -1,9 +1,21 @@ #!/usr/bin/env python3 # -# ssdmon +# Copyright (C) 2024 Micas Networks Inc. # -# Command-line utility to check SSD health and parameters +# 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 . + +# Command-line utility to check SSD health and parameters try: import argparse diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py b/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py index 5f9df14c8696..376da42231be 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 re import subprocess diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py b/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py index 4fae02f5128e..793f9b5aea3e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 logging.handlers import subprocess diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py b/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py index 1b2523198ed8..5e10afd85414 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import time @@ -7,7 +22,7 @@ import signal import click from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log -from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG +from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG, FW_UPGRADE_STARTED_FLAG from warm_upgrade import WarmBasePlatform @@ -679,7 +694,11 @@ def do_test(self, device, slot): def do_test_main(self, device, slot): print("+================================+") print("|Doing upgrade test, please wait.|") + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.do_test(device, slot) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret == FIRMWARE_SUCCESS: print("| test succeeded! |") print("+================================+") @@ -694,8 +713,12 @@ def do_test_main(self, device, slot): def do_bmc_upgrade_main(self, file, chip_select, erase_type): bmc_upgrade_config = self.upgrade_param.get("BMC", {}) + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.upgrading(bmc_upgrade_config, file, self.devtype, self.subtype, chip_select, BMC_UPGRADE, erase_type) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret is True: print("===========upgrade succeeded!============") sys.exit(0) @@ -925,7 +948,11 @@ def do_fw_upg(self, path, slot, upg_type): def fw_upg(self, path, slot, upg_type): print("+================================+") print("| Doing upgrade, please wait... |") + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.do_fw_upg(path, slot, upg_type) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret == FIRMWARE_SUCCESS: print("| upgrade succeeded! |") print("+================================+") diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py b/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py index 69a310faa606..919bed2ec694 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 sys import os import time @@ -199,6 +214,9 @@ def do_fw_upg_finish_cmd(self, finish_cmd_list): return True, msg def access_test(self, config): + skip = config.get("skip", 0) + if skip == 1: + return True # polling execute command polling_cmd_list = config.get("polling_cmd", []) for polling_cmd_config in polling_cmd_list: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py index b0ddc8691f2e..8f07567207a0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -############################################################################# # +# Copyright (C) 2024 Micas 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information +# 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 . try: import time @@ -306,6 +313,8 @@ def get_reboot_cause(self): reboot_cause_type = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC elif "Thermal Overload: Other" in reboot_cause_msg: reboot_cause_type = self.REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER + elif "CPU reboot" in reboot_cause_msg: + reboot_cause_type = self.REBOOT_CAUSE_HARDWARE_CPU elif "Other" in reboot_cause_msg: reboot_cause_type = self.REBOOT_CAUSE_NON_HARDWARE else: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py index fa674a98a6bf..6e775c3045c3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in -# the platform +# Copyright (C) 2024 Micas 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 +# 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 . try: import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py index 494d4aa610dc..920f4c2d3f68 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py @@ -1,11 +1,20 @@ #!/usr/bin/env python3 - -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the Thermals' information which are available in the platform +# Copyright (C) 2024 Micas 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 +# 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 time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py index 05fcc3c25678..7987e3368781 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py @@ -1,16 +1,19 @@ #!/usr/bin/env python3 -######################################################################## # -# Module contains platform specific implementation of SONiC Platform -# Base API and provides the EEPROMs' information. +# Copyright (C) 2024 Micas 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 +# 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. # -# 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. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . ######################################################################## try: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py index f0b039648158..4864f435cf36 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py @@ -1,11 +1,19 @@ #!/usr/bin/env python3 # -# fan_drawer_base.py +# Copyright (C) 2024 Micas Networks Inc. # -# Abstract base class for implementing a platform-specific class with which -# to interact with a fan drawer module in SONiC +# 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 . try: import time from sonic_platform_base.fan_drawer_base import FanDrawerBase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py index 8ea66f339e96..627a43f56a26 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -######################################################################## # -# Module contains a platform specific implementation of SONiC Platform -# Base PCIe class +# Copyright (C) 2024 Micas 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 +# 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 . try: from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py index 4d6fe03d93ac..6d8aaf5ce9ab 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py @@ -1,11 +1,19 @@ #!/usr/bin/env python3 - -############################################################################# # -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information +# Copyright (C) 2024 Micas 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 +# 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 . try: from sonic_platform_base.platform_base import PlatformBase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py index de661dacdff6..63cde88413c9 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py @@ -1,10 +1,19 @@ #!/usr/bin/env python3 -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the PSUs' information which are available in the platform +# Copyright (C) 2024 Micas 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 +# 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 . try: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py index 3fc22b4b6618..4d789d6d4602 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py @@ -1,5 +1,19 @@ #!/usr/bin/python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 +# 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 . ############################################################################# # @@ -34,6 +48,7 @@ ############################################################################# import sys import time +import fcntl import syslog import traceback from abc import abstractmethod @@ -50,8 +65,10 @@ raise ImportError(str(error) + "- required module not found") from error LOG_DEBUG_LEVEL = 1 -LOG_WARNING_LEVEL = 2 -LOG_ERROR_LEVEL = 3 +LOG_INFO_LEVEL = 2 +LOG_NOTICE_LEVEL = 3 +LOG_WARNING_LEVEL = 4 +LOG_ERROR_LEVEL = 5 class Sfp(SfpOptoeBase): @@ -75,6 +92,8 @@ def __init__(self, index): self._sfp_api = SfpV1(index) elif vers == 2: self._sfp_api = SfpV2(index) + elif vers == 3: + self._sfp_api = SfpV3CPO(index) else: self._sfplog(LOG_ERROR_LEVEL, "Get SfpVer Error!") @@ -84,23 +103,35 @@ def get_eeprom_path(self): def read_eeprom(self, offset, num_bytes): return self._sfp_api.read_eeprom(offset, num_bytes) + def write_eeprom(self, offset, num_bytes, write_buffer): + return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) + def get_presence(self): return self._sfp_api.get_presence() def get_transceiver_info(self): - # temporary solution for a sonic202111 bug - transceiver_info = super().get_transceiver_info() - try: - if transceiver_info == None: - return None - if transceiver_info['cable_type'] == None: - transceiver_info['cable_type'] = 'N/A' - if transceiver_info["vendor_rev"] is not None: - transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] - except BaseException: - print(traceback.format_exc()) - return None - return transceiver_info + api_get = self._sfp_api.get_transceiver_info(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_info() + + def get_transceiver_bulk_status(self): + api_get = self._sfp_api.get_transceiver_bulk_status(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_bulk_status() + + def get_transceiver_threshold_info(self): + api_get = self._sfp_api.get_transceiver_threshold_info(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_threshold_info() + + def get_transceiver_status(self): + api_get = self._sfp_api.get_transceiver_status(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_status() + + def get_transceiver_loopback(self): + api_get = self._sfp_api.get_transceiver_loopback(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_loopback() + + def get_transceiver_pm(self): + api_get = self._sfp_api.get_transceiver_pm(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_pm() def get_reset_status(self): if self.get_presence() is False: @@ -142,7 +173,7 @@ def get_lpmode(self): if self.sfp_type is None: self.refresh_xcvr_api() - if self.sfp_type == 'QSFP' or self.sfp_type == 'QSFP-DD': + if self.sfp_type == 'QSFP' or self.sfp_type == 'QSFP_DD': return SfpOptoeBase.get_lpmode(self) self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') @@ -155,7 +186,7 @@ def set_lpmode(self, lpmode): if self.sfp_type is None or self._xcvr_api is None: self.refresh_xcvr_api() - if self.sfp_type == 'QSFP-DD' or self.sfp_type == 'QSFP': + if self.sfp_type == 'QSFP_DD' or self.sfp_type == 'QSFP': return SfpOptoeBase.set_lpmode(self, lpmode) self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') @@ -226,7 +257,7 @@ def refresh_xcvr_api(self): optoe_type = None # set sfp_type if 'CmisApi' in class_name: - self.sfp_type = 'QSFP-DD' + self.sfp_type = 'QSFP_DD' optoe_type = self.OPTOE_DRV_TYPE3 elif 'Sff8472Api' in class_name: self.sfp_type = 'SFP' @@ -244,8 +275,12 @@ def _sfplog(self, log_level, msg): syslog.openlog("Sfp") if log_level == LOG_DEBUG_LEVEL: syslog.syslog(syslog.LOG_DEBUG, msg) + if log_level == LOG_INFO_LEVEL: + syslog.syslog(syslog.LOG_INFO, msg) + if log_level == LOG_NOTICE_LEVEL: + syslog.syslog(syslog.LOG_NOTICE, msg) elif log_level == LOG_WARNING_LEVEL: - syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.syslog(syslog.LOG_WARNING, msg) elif log_level == LOG_ERROR_LEVEL: syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() @@ -269,10 +304,44 @@ def _init_config(self, index): def _get_eeprom_path(self): return self.eeprom_path or None + @abstractmethod + def _pre_get_transceiver_info(self): + pass + @abstractmethod def get_presence(self): pass + def get_transceiver_info(self, class_optoeBase, class_sfp): + # temporary solution for a sonic202111 bug + transceiver_info = class_optoeBase.get_transceiver_info(class_sfp) + try: + if transceiver_info == None: + return None + if transceiver_info['cable_type'] == None: + transceiver_info['cable_type'] = 'N/A' + if transceiver_info["vendor_rev"] is not None: + transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + return transceiver_info + + def get_transceiver_bulk_status(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_threshold_info(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_status(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_loopback(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_pm(self, class_optoeBase, class_sfp): + pass + def read_eeprom(self, offset, num_bytes): try: for i in range(self.eeprom_retry_times): @@ -292,18 +361,16 @@ def read_eeprom(self, offset, num_bytes): return None def write_eeprom(self, offset, num_bytes, write_buffer): - try: - for i in range(self.eeprom_retry_times): - ret = SfpOptoeBase.write_eeprom(self, offset, num_bytes, write_buffer) - if ret is False: - time.sleep(self.eeprom_retry_break_sec) - continue - break - - return ret - except BaseException: - self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) - return False + for i in range(self.eeprom_retry_times): + try: + with open(self._get_eeprom_path(), mode='r+b', buffering=0) as f: + f.seek(offset) + f.write(write_buffer[0:num_bytes]) + return True + except (OSError, IOError): + time.sleep(self.eeprom_retry_break_sec) + pass + return False @abstractmethod def set_optoe_type(self, optoe_type): @@ -337,8 +404,12 @@ def _sfplog(self, log_level, msg): syslog.openlog("SfpCust") if log_level == LOG_DEBUG_LEVEL: syslog.syslog(syslog.LOG_DEBUG, msg) + if log_level == LOG_INFO_LEVEL: + syslog.syslog(syslog.LOG_INFO, msg) + if log_level == LOG_NOTICE_LEVEL: + syslog.syslog(syslog.LOG_NOTICE, msg) elif log_level == LOG_WARNING_LEVEL: - syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.syslog(syslog.LOG_WARNING, msg) elif log_level == LOG_ERROR_LEVEL: syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() @@ -382,10 +453,12 @@ def get_presence(self): if dev_id == -1: return False ret, info = platform_reg_read(0, dev_id, offset, 1) - if (ret is False - or info is None): + if ((ret is False) or (info is None)): return False return info[0] & (1 << offset_bit) == self.presence_val_is_present + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -405,6 +478,9 @@ def get_reset_status(self): return False return (info[0] & (1 << offset_bit) == self.reset_val_is_reset) + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -428,6 +504,9 @@ def get_tx_disable(self): tx_disable_list.append(info[0] & (1 << offset_bit) != 0) else: tx_disable_list.append(info[0] & (1 << offset_bit) == 0) + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return None except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return None @@ -506,7 +585,9 @@ def set_reset(self, reset): if ret is False: self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") return False - + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -543,7 +624,9 @@ def set_tx_disable(self, tx_disable): if ret is False: self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") return False - + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -632,3 +715,197 @@ def set_optoe_type(self, optoe_type): self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False return True + +class SfpV3CPO(SfpCust): + def _init_config(self, index): + super()._init_config(index) + sfp_config = baseutil.get_config().get("sfps", None) + + eeprom_path_config = sfp_config.get("eeprom_path", None) + eeprom_path_key = sfp_config.get("eeprom_path_key")[self._port_id - 1] + self.eeprom_path = None if eeprom_path_config is None else eeprom_path_config % ( + eeprom_path_key, eeprom_path_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init eeprom path: %s" % self.eeprom_path) + + # CPO always present + def get_presence(self): + return True + + def read_eeprom(self, offset, num_bytes): + # temp solution for CPO byte0 bug, remove me when it fixed + if offset == 0: + if self._file_rw_lock() is False: + return None + self._switch_page(0) + result = self._read_eeprom(offset, num_bytes) + self._file_rw_unlock() + return result + + if offset < 128: # page 0L + return self._read_eeprom(offset, num_bytes) + + if self._file_rw_lock() is False: + return None + + # for other page, need to convert flat_mem offset to single page offset + result = self._convert_to_single_page_offset_read(offset, num_bytes) + self._file_rw_unlock() + return result + + def write_eeprom(self, offset, num_bytes, write_buffer): + # temp solution for CPO byte0 bug, remove me when it fixed + if offset == 0: + if self._file_rw_lock() is False: + return None + self._switch_page(0) + result = self._write_eeprom(offset, num_bytes, write_buffer) + self._file_rw_unlock() + return result + + if offset < 128: # page 0L + return self._write_eeprom(offset, num_bytes, write_buffer) + + if self._file_rw_lock() is False: + return None + + # for other page, need to convert flat_mem offset to single page offset + result = self._convert_to_single_page_offset_write(offset, num_bytes, write_buffer) + self._file_rw_unlock() + return result + + def set_optoe_type(self, optoe_type): + ret, info = platform_get_optoe_type(self._port_id) + if ret is True and info != optoe_type: + try: + ret, _ = platform_set_optoe_type(self._port_id, optoe_type) + except Exception as err: + self._sfplog(LOG_ERROR_LEVEL, "Set optoe err %s" % err) + + def _read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + with open(self._get_eeprom_path(), mode='rb', buffering=0) as f: + f.seek(offset) + result = f.read(num_bytes) + # temporary solution for a sonic202111 bug + if len(result) < num_bytes: + result = result[::-1].zfill(num_bytes)[::-1] + if result is not None: + return bytearray(result) + time.sleep(self.eeprom_retry_break_sec) + continue + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def _write_eeprom(self, offset, num_bytes, write_buffer): + for i in range(self.eeprom_retry_times): + try: + with open(self._get_eeprom_path(), mode='r+b', buffering=0) as f: + f.seek(offset) + f.write(write_buffer[0:num_bytes]) + return True + except BaseException: + print(traceback.format_exc()) + time.sleep(self.eeprom_retry_break_sec) + pass + return False + + def _switch_page(self, page): + page_offset = 127 #0x7f + num_bytes = 1 + cur_page = self._read_eeprom(page_offset, num_bytes)[0] + if cur_page is None: + self._sfplog(LOG_ERROR_LEVEL, "CPO read PAGE ERROR!") + return False + + if cur_page == page: + return True + + return self._write_eeprom(page_offset, num_bytes, bytearray([page])) + + def _switch_bank(self, bank): + bank_offset = 126 #0x7e + num_bytes = 1 + cur_bank = self._read_eeprom(bank_offset, num_bytes)[0] + if cur_bank is None: + self._sfplog(LOG_ERROR_LEVEL, "CPO read BANK ERROR!") + return False + + if cur_bank == bank: + return True + + return self._write_eeprom(bank_offset, num_bytes, bytearray([bank])) + + def _convert_to_single_page_offset_read(self, offset, num_bytes): + page_list = [0, 1, 2, 16, 17, 19, 20, 159] # page 0 1 2 10h 11h 13h 14h 9Fh + for p in page_list: + if (256 + (p - 1) * 128) <= offset < (256 + 128 * p): + self._switch_page(p) + single_page_offset = offset - 128 * p + + if p in [16, 17, 19, 20]: # need to switch Bank + port_id_abs = (self._port_id - 1) % 16 + bank_id = port_id_abs // 2 + self._switch_bank(bank_id) + + return self._read_eeprom(single_page_offset, num_bytes) + + self._sfplog(LOG_WARNING_LEVEL, "cannot find page! offset: %d num_bytes: %d" % (offset, num_bytes)) + return None + + def _convert_to_single_page_offset_write(self, offset, num_bytes, write_buffer): + page_list = [0, 1, 2, 16, 17, 19, 20, 159] # page 0 1 2 10h 11h 13h 14h 9Fh + for p in page_list: + if (256 + (p - 1) * 128) <= offset < (256 + 128 * p): + self._switch_page(p) + single_page_offset = offset - 128 * p + + if p in [16, 17, 19, 20]: # need to switch Bank + port_id_abs = (self._port_id - 1) % 16 + bank_id = port_id_abs // 2 + self._switch_bank(bank_id) + + return self._write_eeprom(single_page_offset, num_bytes, write_buffer) + + self._sfplog(LOG_WARNING_LEVEL, "cannot find page! offset: %d num_bytes: %d" % (offset, num_bytes)) + return None + + pidfile = None + + def _file_rw_lock(self): + global pidfile + pidfile = open(self._get_eeprom_path(), "r") + file_lock_flag = False + # Retry 100 times to lock file + for i in range(0, 100): + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + file_lock_flag = True + self._sfplog(LOG_DEBUG_LEVEL, "file lock success") + return True + except Exception: + time.sleep(0.001) + continue + + if file_lock_flag == False: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + def _file_rw_unlock(self): + try: + global pidfile + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + self._sfplog(LOG_DEBUG_LEVEL, "file unlock success") + else: + self._sfplog(LOG_DEBUG_LEVEL, "pidfile is invalid, do nothing") + return True + except Exception as e: + self._sfplog(LOG_ERROR_LEVEL, "file unlock err, msg:%s" % (str(e))) + return False \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py index 948337f47a9a..1326d1671e6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -######################################################################## # +# Copyright (C) 2024 Micas 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# Abstract base class for implementing a platform-specific class with -# which to interact with a hardware watchdog module in SONiC +# 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 fcntl import os diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/control b/platform/broadcom/sonic-platform-modules-micas/debian/control index 8a4fbd115814..819647fdbfc3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/control +++ b/platform/broadcom/sonic-platform-modules-micas/debian/control @@ -10,4 +10,8 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-micas-m2-w6510-48gt4v Architecture: amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-micas-m2-w6520-24dc8qc +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install new file mode 100644 index 000000000000..3a94db8f4428 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install @@ -0,0 +1 @@ +m2-w6520-24dc8qc/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-micas_m2-w6520-24dc8qc-r0 diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst new file mode 100644 index 000000000000..a8132f4f65a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk index b6b2cd492660..4ed55c469bc7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk +++ b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk @@ -2,5 +2,6 @@ currentdir = $(shell pwd) MODULE_DIRS := m2-w6510-48v8c MODULE_DIRS += m2-w6510-48gt4v +MODULE_DIRS += m2-w6520-24dc8qc export MODULE_DIRS diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile new file mode 100644 index 000000000000..052a5a6a0773 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile @@ -0,0 +1,25 @@ +PWD = $(shell pwd) +DIR_KERNEL_SRC = $(PWD)/modules/driver +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUB_BUILD_DIR = $(PWD)/build +INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) +INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg + +all: + $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules + @if [ ! -d ${INSTALL_DIR} ]; then mkdir -p ${INSTALL_DIR} ;fi + cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) + @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi + cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi +clean: + rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd + rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order + rm -rf ${DIR_KERNEL_SRC}/.tmp_versions + rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py new file mode 100644 index 000000000000..6cbadc907a0d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py @@ -0,0 +1,1424 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +from platform_common import * + +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 0, + "dev_monitor": 1, + "tty_console": 1, + "reboot_cause": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "generate_airflow": 0, +} + +DEV_MONITOR_PARAM = { + "polling_time": 10, + "psus": [ + { + "name": "psu1", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x1d, "offset": 0x34, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 41, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "24c02", "bus": 41, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "psu2", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x1d, "offset": 0x34, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 42, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "24c02", "bus": 42, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 5, "okval": 0}, + "device": [ + {"id": "fan1frue2", "name": "24c64", "bus": 35, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "fan2frue2", "name": "24c64", "bus": 34, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 3, "okval": 0}, + "device": [ + {"id": "fan3frue2", "name": "24c64", "bus": 33, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan4frue2", "name": "24c64", "bus":32, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan5", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 1, "okval": 0}, + "device": [ + {"id": "fan5frue2", "name": "24c64", "bus": 31, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan6", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "fan6frue2", "name": "24c64", "bus": 30, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "lm75", "bus": 36, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_2", "name": "lm75", "bus": 36, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_3", "name": "lm75", "bus": 39, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_4", "name": "lm75", "bus": 40, "loc": 0x4e, "attr": "hwmon"}, + {"id": "lm75_5", "name": "lm75", "bus": 40, "loc": 0x4f, "attr": "hwmon"}, + ], + }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_td4", "bus": 44, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name":"tmp411", + "device":[ + {"id":"tmp411_1", "name":"tmp411","bus":39, "loc":0x4c, "attr":"hwmon"}, + {"id":"tmp411_2", "name":"tmp411","bus":40, "loc":0x4c, "attr":"hwmon"}, + ], + }, + { + "name": "ina3221", + "device": [ + {"id": "ina3221_1", "name": "ina3221", "bus": 25, "loc": 0x43, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "tps53688", "bus": 25, "loc": 0x67, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "tps53688", "bus": 25, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "ucd90160", + "device": [ + {"id": "ucd90160_1", "name": "ucd90160", "bus": 24, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_2", "name": "ucd90160", "bus": 45, "loc": 0x5b, "attr": "hwmon"}, + ], + }, + ], +} + +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "CONNECT_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLDA", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "i2c": { + "bus": "2", + "loc": "0x1d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLDB", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "2", + "loc": "0x2d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "FAN_CPLD", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "4", + "loc": "0x3d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, + + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "fan5": { + "key": "FAN5", + "parent": "fan", + "arrt_index": 5, + }, + "fan5_hw_version": { + "key": "Hardware Version", + "parent": "fan5", + "extra": { + "funcname": "checkFan", + "id": "fan5", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan5_fw_version": { + "key": "Firmware Version", + "parent": "fan5", + "config": "NA", + "arrt_index": 2, + }, + + "fan6": { + "key": "FAN6", + "parent": "fan", + "arrt_index": 6, + }, + "fan6_hw_version": { + "key": "Hardware Version", + "parent": "fan6", + "extra": { + "funcname": "checkFan", + "id": "fan6", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan6_fw_version": { + "key": "Firmware Version", + "parent": "fan6", + "config": "NA", + "arrt_index": 2, + }, + + "i210": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + + "fpga": { + "key": "FPGA", + }, + "fpga_model": { + "parent": "fpga", + "config": "XC7A100T-2FGG484C", + "key": "Device Model", + "arrt_index": 1, + }, + "fpga_vendor": { + "parent": "fpga", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga_desc": { + "parent": "fpga", + "config": "NA", + "key": "Description", + "arrt_index": 3, + }, + "fpga_hw_version": { + "parent": "fpga", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga_fw_version": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 0 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga_date": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + "others": { + "key": "OTHERS", + }, + "5387": { + "parent": "others", + "key": "CPU-BMC-SWITCH", + "arrt_index": 1, + }, + "5387_model": { + "parent": "5387", + "config": "BCM5387", + "key": "Device Model", + "arrt_index": 1, + }, + "5387_vendor": { + "parent": "5387", + "config": "Broadcom", + "key": "Vendor", + "arrt_index": 2, + }, + "5387_hw_version": { + "parent": "5387", + "key": "Hardware Version", + "func": { + "funcname": "get_bcm5387_version", + "params": { + "before": [ + {"gettype": "io", "io_addr": 0x94d, "value": 0xfe}, # enable 5387 + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio_device sck=67 miso=32 mosi=65 bus=0"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_93xx46 spi_bus_num=0 spi_cs_gpio=6"}, + ], + "get_version": "md5sum /sys/bus/spi/devices/spi0.0/eeprom | awk '{print $1}'", + "after": [], + "finally": [ + {"gettype": "cmd", "cmd": "rmmod wb_spi_93xx46"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio_device"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio"}, + {"gettype": "io", "io_addr": 0x94d, "value": 0xff}, # disable 5387 + ], + }, + }, + "arrt_index": 3, + }, +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6" + } + }, + "psus": { + "present": {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/psu/%s/output", "okval": 1}, + {"path": "/sys/wb_plat/psu/%s/alert", "okval": 0}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2" + } + } +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x82, # default value, if rov value not in range + "sdkreg": "TOP_AVS_SEL_REG", # SDK register name + "sdktype": 0, # 0: No shift operation required, 1: shift operation required + "macregloc": 24, # Shift right 24 bits + "mask": 0xff, # Use with macregloc + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"bus":2, "loc":0x2d, "offset":0x3f, "gettype":"i2c"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/43-005b/avs_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x72:0.90000, + 0x73:0.89375, + 0x74:0.88750, + 0x75:0.88125, + 0x76:0.87500, + 0x77:0.86875, + 0x78:0.86250, + 0x79:0.85625, + 0x7a:0.85000, + 0x7b:0.84375, + 0x7c:0.83750, + 0x7d:0.83125, + 0x7e:0.82500, + 0x7f:0.81875, + 0x80:0.81250, + 0x81:0.80625, + 0x82:0.80000, + 0x83:0.79375, + 0x84:0.78750, + 0x85:0.78125, + 0x86:0.77500, + 0x87:0.76875, + 0x88:0.76250, + 0x89:0.75625, + 0x8A:0.75000, + 0x8B:0.74375, + 0x8C:0.73750, + 0x8D:0.73125, + 0x8E:0.72500, + } + } +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "i2c_i801", "delay": 1}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "i2c_algo_bit", "delay": 0}, + {"name": "i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type=0x20000056", "delay": 0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_spi_dev", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_fpga_i2c_bus_drv", "delay": 0}, + {"name": "wb_fpga_i2c_bus_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + {"name": "wb_fpga_pca954x_drv", "delay": 0}, + {"name": "wb_fpga_pca954x_device", "delay": 0}, + {"name": "wb_wdt", "delay": 0}, + {"name": "lm75", "delay": 0}, + {"name": "tmp401", "delay": 0}, + {"name": "optoe", "delay": 0}, + {"name": "at24", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "pmbus_core", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "ina3221", "delay": 0}, + {"name": "tps53679", "delay": 0}, + {"name": "ucd9000", "delay": 0}, + {"name": "wb_xdpe132g5c", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, +] + +DEVICE = [ + {"name": "24c02", "bus": 1, "loc": 0x56}, + {"name": "wb_mac_bsc_td4", "bus": 44, "loc": 0x44}, + # fan + {"name": "24c64", "bus": 30, "loc": 0x50}, + {"name": "24c64", "bus": 31, "loc": 0x50}, + {"name": "24c64", "bus": 32, "loc": 0x50}, + {"name": "24c64", "bus": 33, "loc": 0x50}, + {"name": "24c64", "bus": 34, "loc": 0x50}, + {"name": "24c64", "bus": 35, "loc": 0x50}, + # psu + {"name": "24c02", "bus": 41, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 41, "loc": 0x58}, + {"name": "24c02", "bus": 42, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 42, "loc": 0x58}, + # temp + {"name": "lm75", "bus": 36, "loc": 0x48}, + {"name": "lm75", "bus": 36, "loc": 0x49}, + {"name": "lm75", "bus": 39, "loc": 0x4b}, + {"name": "tmp411", "bus": 39, "loc": 0x4c}, + {"name": "tmp411", "bus": 40, "loc": 0x4c}, + {"name": "lm75", "bus": 40, "loc": 0x4e}, + {"name": "lm75", "bus": 40, "loc": 0x4f}, + # dcdc + {"name": "ucd90160", "bus": 24, "loc": 0x5b}, + {"name": "ucd90160", "bus": 45, "loc": 0x5b}, + {"name": "ina3221", "bus": 25, "loc": 0x43}, + {"name": "tps53688", "bus": 25, "loc": 0x67}, + {"name": "tps53688", "bus": 25, "loc": 0x6c}, + #avs + {"name": "wb_xdpe132g5c", "bus": 43, "loc": 0x5b}, +] + +OPTOE = [ + {"name": "optoe1", "startbus": 46, "endbus": 69}, + {"name": "optoe3", "startbus": 70, "endbus": 77}, +] + +REBOOT_CTRL_PARAM = { + "cpu": {"io_addr": 0x920, "rst_val": 0xfe, "rst_delay": 0, "gettype": "io"}, + "mac": {"bus": 2, "loc": 0x1d, "offset": 0x20, "rst_val": 0xfd, "rst_delay": 0, "gettype": "i2c"}, + "phy": {"io_addr": 0x923, "rst_val": 0xef, "rst_delay": 1, "unlock_rst_val": 0xff, "unlock_rst_delay": 1, "gettype": "io"}, + "power": {"io_addr": 0x9ce, "rst_val": 0, "rst_delay": 0, "gettype": "io"}, +} + +# INIT_PARAM_PRE = [ +# {"loc": "43-005b/avs_vout_max", "value": "900000"}, +# {"loc": "43-005b/avs_vout_min", "value": "725000"}, +# ] + +INIT_PARAM = [] + +INIT_COMMAND_PRE = [ + # sfp power enable + "i2cset -f -y 2 0x2d 0x45 0xff", + "i2cset -f -y 2 0x2d 0x46 0xff", + "i2cset -f -y 2 0x2d 0x34 0xff", + "i2cset -f -y 2 0x2d 0x35 0xff", + "i2cset -f -y 2 0x1d 0x39 0xff", + "i2cset -f -y 2 0x1d 0x3a 0xff", + # enable tty_console monitor + "dfd_debug io_wr 0x956 0x01", +] + +INIT_COMMAND = [ + # led enable + "i2cset -f -y 2 0x2d 0x3a 0xff", + "i2cset -f -y 2 0x1d 0x3b 0xff", + + # port led off + "i2cset -f -y 2 0x2d 0x3b 0x0", + "i2cset -f -y 2 0x2d 0x3c 0x0", + "i2cset -f -y 2 0x2d 0x3d 0x0", + "i2cset -f -y 2 0x2d 0x3e 0x0", + "i2cset -f -y 2 0x1d 0x3c 0x0", + "i2cset -f -y 2 0x1d 0x3d 0x0", + "i2cset -f -y 2 0x1d 0x3e 0x0", + "i2cset -f -y 2 0x1d 0x3f 0x0", +] + +WARM_UPGRADE_PARAM = { + "slot0": { + "VME": { + "chain1": [ + {"name": "CPU_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_cpu_cpld_header.vme", + "init_cmd": [ + {"cmd": "echo 7 > /sys/class/gpio/export", "gettype": "cmd"}, + {"cmd": "echo high > /sys/class/gpio/gpio7/direction", "gettype": "cmd"}, + {"io_addr": 0x7cc, "value": 0, "gettype": "io"}, + ], + "rw_recover_reg": [ + {"io_addr": 0x705, "value": None, "gettype": "io"}, + {"io_addr": 0x713, "value": None, "gettype": "io"}, + {"io_addr": 0x715, "value": None, "gettype": "io"}, + {"io_addr": 0x721, "value": None, "gettype": "io"}, + {"io_addr": 0x722, "value": None, "gettype": "io"}, + {"io_addr": 0x772, "value": None, "gettype": "io"}, + {"io_addr": 0x774, "value": None, "gettype": "io"}, + {"io_addr": 0x776, "value": None, "gettype": "io"}, + {"io_addr": 0x778, "value": None, "gettype": "io"}, + {"io_addr": 0x77a, "value": None, "gettype": "io"}, + {"io_addr": 0x77c, "value": None, "gettype": "io"}, + {"io_addr": 0x780, "value": None, "gettype": "io"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "access_check_reg": {"io_addr": 0x705, "value": 0x5a, "gettype": "io"}, + "finish_cmd": [ + {"io_addr": 0x7cc, "value": 0xff, "gettype": "io"}, + {"cmd": "echo 0 > /sys/class/gpio/gpio7/value", "gettype": "cmd"}, + {"cmd": "echo 7 > /sys/class/gpio/unexport", "gettype": "cmd"}, + ], + }, + {"name": "CONNECT_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_base_cpld_header.vme", + "init_cmd": [ + {"bus": 2, "loc": 0x2d, "offset": 0xcd, "value": 1, "gettype": "i2c"}, + {"io_addr": 0x9cc, "value": 0, "gettype": "io"}, + ], + "rw_recover_reg": [ + {"io_addr": 0x9aa, "value": None, "gettype": "io"}, + {"io_addr": 0x955, "value": None, "gettype": "io"}, + {"io_addr": 0x911, "value": None, "gettype": "io"}, + {"io_addr": 0x923, "value": None, "gettype": "io"}, + {"io_addr": 0x924, "value": None, "gettype": "io"}, + {"io_addr": 0x930, "value": None, "gettype": "io"}, + {"io_addr": 0x932, "value": None, "gettype": "io"}, + {"io_addr": 0x933, "value": None, "gettype": "io"}, + {"io_addr": 0x934, "value": None, "gettype": "io"}, + {"io_addr": 0x937, "value": None, "gettype": "io"}, + {"io_addr": 0x938, "value": None, "gettype": "io"}, + {"io_addr": 0x939, "value": None, "gettype": "io"}, + {"io_addr": 0x93a, "value": None, "gettype": "io"}, + {"io_addr": 0x941, "value": None, "gettype": "io"}, + {"io_addr": 0x942, "value": None, "gettype": "io"}, + {"io_addr": 0x947, "value": None, "gettype": "io"}, + {"io_addr": 0x948, "value": None, "gettype": "io"}, + {"io_addr": 0x949, "value": None, "gettype": "io"}, + {"io_addr": 0x94d, "value": None, "gettype": "io"}, + {"io_addr": 0x94e, "value": None, "gettype": "io"}, + {"io_addr": 0x94f, "value": None, "gettype": "io"}, + {"io_addr": 0x950, "value": None, "gettype": "io"}, + {"io_addr": 0x951, "value": None, "gettype": "io"}, + {"io_addr": 0x952, "value": None, "gettype": "io"}, + {"io_addr": 0x953, "value": None, "gettype": "io"}, + ], + "after_upgrade_delay": 30, + "after_upgrade_delay_timeout": 60, + "refresh_finish_flag_check": {"io_addr": 0x9cb, "value": 0x5a, "gettype": "io"}, + "access_check_reg": {"io_addr": 0x9aa, "value": 0x5a, "gettype": "io"}, + "finish_cmd": [ + {"bus": 2, "loc": 0x2d, "offset": 0xcd, "value": 0, "gettype": "i2c"}, + ], + }, + + {"name": "MACA_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_maca_cpld_header.vme", + "init_cmd": [ + {"cmd": "touch /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + {"path": "/dev/fpga0", "offset": 0xb4, "value": [0x1], "gettype":"devfile", "delay":0.1}, + {"bus": 2, "loc": 0x1d, "offset": 0xcc, "value": 0, "gettype": "i2c"}, + ], + "rw_recover_reg": [ + {"bus": 2, "loc": 0x1d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x14, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x21, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x22, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x36, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x37, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x38, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x39, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x41, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x42, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x44, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "refresh_finish_flag_check": {"bus": 2, "loc": 0x1d, "offset": 0xcb, "value": 0x5a, "gettype": "i2c"}, + "access_check_reg": {"bus": 2, "loc": 0x1d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + "finish_cmd": [ + {"path": "/dev/fpga0", "offset": 0xb4, "value": [0x0], "gettype":"devfile"}, + {"cmd": "rm -rf /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + ], + }, + + {"name": "MACB_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_macb_cpld_header.vme", + "init_cmd": [ + {"cmd": "touch /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + {"path": "/dev/fpga0", "offset": 0xb0, "value": [0x1], "gettype":"devfile", "delay":0.1}, + {"bus": 2, "loc": 0x2d, "offset": 0xcc, "value": 0, "gettype": "i2c"}, + ], + "rw_recover_reg": [ + {"bus": 2, "loc": 0x2d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x14, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x21, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x22, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x23, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x30, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x31, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x32, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x33, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x34, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x42, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x43, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x44, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x45, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x46, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x4c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x4d, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "refresh_finish_flag_check": {"bus": 2, "loc": 0x2d, "offset": 0xcb, "value": 0x5a, "gettype": "i2c"}, + "access_check_reg": {"bus": 2, "loc": 0x2d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + "finish_cmd": [ + {"path": "/dev/fpga0", "offset": 0xb0, "value": [0x0], "gettype":"devfile"}, + {"cmd": "rm -rf /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + ], + }, + + {"name": "FAN_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_fan_cpld_header.vme", + "rw_recover_reg": [ + {"bus": 4, "loc": 0x3d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x13, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x17, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x19, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x30, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x31, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x33, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3f, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x41, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x60, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x61, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x62, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x63, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x64, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x65, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "access_check_reg": {"bus": 4, "loc": 0x3d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + }, + ], + }, + + "SPI-LOGIC-DEV": { + "chain1": [ + {"name": "FPGA", + "init_cmd": [ + {"file": WARM_UPG_FLAG, "gettype": "creat_file"}, + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0050", "gettype": "cmd"}, # link_disable + {"io_addr": 0x9cd, "value": 0, "gettype": "io"}, + ], + "after_upgrade_delay": 10, + "after_upgrade_delay_timeout": 180, + "refresh_finish_flag_check": {"io_addr": 0x9cd, "value": 0xff, "gettype": "io"}, + "access_check_reg": { + "path": "/dev/fpga0", "offset": 0x8, "value": [0x55, 0xaa, 0x5a, 0xa5], "read_len":4, "gettype":"devfile", + "polling_cmd":[ + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0060", "gettype": "cmd"},# retrain_link + {"cmd": "rmmod wb_fpga_pcie", "gettype": "cmd"}, + {"cmd": "modprobe wb_fpga_pcie", "gettype": "cmd", "delay": 0.1}, + ], + "polling_delay": 0.1 + }, + "finish_cmd": [ + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0060", "gettype": "cmd"},# retrain_link + {"file": WARM_UPG_FLAG, "gettype": "remove_file"}, + ], + }, + ], + }, + }, + "stop_services_cmd": [ + "/usr/local/bin/platform_process.py stop", + ], + "start_services_cmd": [ + "/usr/local/bin/platform_process.py start", + ], +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ + { + "name": "cold_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x988, "okval": 0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ] + }, + { + "name": "wdt_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x989, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Watchdog, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Watchdog, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size":1*1024*1024} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xfc}, + ] + }, + { + "name": "bmc_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x98a, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC reboot, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xfa}, + ] + }, + { + "name": "bmc_powerdown", + "monitor_point": {"gettype": "io", "io_addr": 0x98b, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC powerdown, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xf6}, + ] + }, + { + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, + ] + }, + { + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, + ] + }, + ], + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], +} + +UPGRADE_SUMMARY = { + "devtype": 0x20000056, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "CPLD", + "is_support_warm_upg": 1, + }, + }, + + "SPI-LOGIC-DEV": { + "chain1": { + "name": "FPGA", + "is_support_warm_upg": 1, + }, + }, + + "SYSFS": { + "chain2": { + "name": "BCM5387", + "is_support_warm_upg": 0, + "init_cmd": [ + {"cmd": "modprobe wb_spi_gpio", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_gpio_device sck=67 miso=32 mosi=65 bus=0", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_93xx46 spi_bus_num=0 spi_cs_gpio=6", "gettype": "cmd", "delay": 0.1}, + ], + "finish_cmd": [ + {"cmd": "rmmod wb_spi_93xx46", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio_device", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio", "gettype": "cmd", "delay": 0.1}, + ], + }, + }, + + "MTD": { + "chain3": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, + + "TEST": { + "fpga": [ + {"chain": 1, "file": "/etc/.upgrade_test/fpga_test_header.bin", "display_name": "FPGA"}, + ], + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpld_test_header.vme", "display_name": "CPLD"}, + ], + }, + }, + + "BMC": { + "name": "BMC", + "init_cmd": [ + # stop BMC stack watchdog + {"cmd": "ipmitool raw 0x32 0x03 0x02", "gettype": "cmd", "ignore_result": 1}, + ], + "finish_cmd": [], + }, +} + +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/35-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/34-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/33-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/32-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/31-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/30-0050/eeprom"}, + ], + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/41-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/42-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py new file mode 100644 index 000000000000..fccc59402891 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 32, + "optoe_start_bus": 46, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py new file mode 100644 index 000000000000..6adf2ef004b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py @@ -0,0 +1,1190 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['DPS-1300AB-6 S', 'GW-CRPS1300D'], + "exhaust": [] +} + +fanairflow = { + "intake": ['M1HFAN II-F'], + "exhaust": [], +} + +psu_display_name = { + "PA1300I-F": ['GW-CRPS1300D', 'DPS-1300AB-6 S'], +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + +class threshold: + PSU_TEMP_MIN = -10 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 28000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 1300 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 1444 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 2 * 1000 + PSU_OUTPUT_CURRENT_MAX = 107 * 1000 + + PSU_INPUT_CURRENT_MIN = 0.2 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 25000 + REAR_FAN_SPEED_MAX = 22000 + FAN_SPEED_MIN = 2000 + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + "airflow": "intake" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/41-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 41, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus":41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 41, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/42-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 42, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 42, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "BOARD_TEMP", + "temp_id": "TEMP1", + "api_name": "Board", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/40-004e/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 70000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "api_name": "CPU", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 104000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "api_name": "Inlet", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/40-004f/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 40000, + "Max": 50000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "api_name": "Outlet", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/36-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 70000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP5", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -15000, + "Low": 0, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x40, "way":"i2c"}, + "led_attrs": { + "off": 0x0, "green": 0x01, "red": 0x02,"default":0x01, + "amber": 0x03, "green_flash": 0x41, "red_flash": 0x42, + "amber_flash": 0x43, "mask": 0xff + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x43, "way":"i2c"}, + "led_attrs": { + "green":0x04, "red":0x02, "amber":0x06, "default":0x04, + "flash":0xff, "light":0xff, "off": 0, "mask":0x07 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x42, "way":"i2c"}, + "led_attrs": { + "green":0x04, "red":0x02, "amber":0x06, "default":0x04, + "flash":0xff, "light":0xff, "off": 0, "mask":0x07 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-35/35-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x41, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x65, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x65, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-34/34-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x40, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x64, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x64, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-33/33-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3f, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x63, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x63, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-32/32-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x62, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x62, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-31/31-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan5/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x61, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x61, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-30/30-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan6/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x60, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x60, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + "warm": 1, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDA", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDB", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld5", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "FAN_CPLD", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + "warm": 1, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "BIOS", + "cpld_id": "CPLD7", + "VersionFile": {"cmd": "dmidecode -s bios-version", "way": "cmd"}, + "desc": "Performs initialization of hardware components during booting", + "slot": 0, + "type": "str", + "warm": 0, + }, + ], + "dcdc": [ + { + "name": "VDD5V_CLK_MCU", + "dcdc_id": "DCDC1", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 4250, + "Max": 5750, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD3.3_CLK", + "dcdc_id": "DCDC2", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.0V", + "dcdc_id": "DCDC3", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 850, + "Max": 1150, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.8V", + "dcdc_id": "DCDC4", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in4_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_BOARD_VDD3.3V", + "dcdc_id": "DCDC5", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in5_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.2V", + "dcdc_id": "DCDC6", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in6_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD_CORE", + "dcdc_id": "DCDC7", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in7_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 600, + "Max": 1100, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "ANALOG0.75V", + "dcdc_id": "DCDC8", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in8_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 615, + "Max": 1000, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_VDD1.2V", + "dcdc_id": "DCDC9", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in9_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDDO1.8V", + "dcdc_id": "DCDC10", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in10_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_ANA1.2V", + "dcdc_id": "DCDC11", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in11_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_ANA1.8V", + "dcdc_id": "DCDC12", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in12_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFP56_VDD3.3V_A", + "dcdc_id": "DCDC13", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in13_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFP56_VDD3.3V_B", + "dcdc_id": "DCDC14", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in14_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFPDD_VDD3.3V_A", + "dcdc_id": "DCDC15", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in15_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFPDD_VDD3.3V_B", + "dcdc_id": "DCDC16", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in16_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD5.0V", + "dcdc_id": "DCDC17", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 4250, + "Max": 5750, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "SW_VDD1.2V", + "dcdc_id": "DCDC18", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD2.5V", + "dcdc_id": "DCDC19", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2125, + "Max": 2875, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "CONNECT_BOARD_VDD3.3V", + "dcdc_id": "DCDC20", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in4_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD12V", + "dcdc_id": "DCDC21", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in6_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 10200, + "Max": 13800, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD3.3_STBY", + "dcdc_id": "DCDC22", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in7_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "SSD_VDD3.3V", + "dcdc_id": "DCDC23", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in8_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCIN", + "dcdc_id": "DCDC24", + "value": { + "loc": "/sys/bus/i2c/devices/25-0067/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1368, + "Max": 2244, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P1V05", + "dcdc_id": "DCDC25", + "value": { + "loc": "/sys/bus/i2c/devices/25-0067/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 882, + "Max": 1232, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCD_V", + "dcdc_id": "DCDC26", + "value": { + "loc": "/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 990, + "Max": 1452, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCSCSUS_V", + "dcdc_id": "DCDC27", + "value": { + "loc": "/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 855, + "Max": 1265, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P3V3_STBY_V", + "dcdc_id": "DCDC28", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2682, + "Max": 4004, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P5V_AUX_IN", + "dcdc_id": "DCDC29", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 3852, + "Max": 6347, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P1V7_VCCSCFUSESUS_IN", + "dcdc_id": "DCDC30", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1377, + "Max": 2057, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"loc": "/dev/cpld1", "offset": 0x88, "len": 1, "way": "devfile_ascii"}, + "reboot_cause_path": "/etc/sonic/.reboot/.previous-reboot-cause.txt" + } + ], + "sfps": { + "ver": '1.0', + "port_index_start": 0, + "port_num": 32, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 4: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + 0x33: "25-32" + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(46, 78)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(46, 78)), + "reset_cpld": { + "dev_id": { + 5: { + "offset": { + 0x22: "1-8", + 0x23: "9-16" + }, + }, + 4: { + "offset": { + 0x21: "17-24", + 0x22: "25-32" + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py new file mode 100644 index 000000000000..58388d5875f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py @@ -0,0 +1,207 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 1, + "pwm_min": 0x80, + "pwm_max": 0xff, + "a": 0.369, + "b": -15.657, + "c": 289, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 80, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "BOARD_TEMP": { + "name": "BOARD_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 60, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105, "invalid": -100000, "error": -99999}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 40, "critical": 50, "fix": -3}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 70, "critical": 75}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 75}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 100, "critical": 102}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "fan_status_interval": 0.5, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "warning_pwm": 0xff, + "temp_invalid_pid_pwm": 0x80, + "temp_error_pid_pwm": 0x80, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 2, # fan rotor error 2 times continuously + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + "psu_fan_control": 1, + "fan_plug_in_default_countdown": 0, # no use + "fan_plug_in_pwm": 0x80, # fan plug in pwd + "deal_fan_error": 1, + "deal_fan_error_conf": { + "countdown": 2, + "FAN1": [ + {"name": "FAN1", "pwm": 0xff}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN2": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0xff}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN3": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0xff}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN4": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0xff}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN5": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0xff}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN6": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0xff}, + ], + }, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + "psu_air_flow_monitor": 0, + "fan_air_flow_monitor": 0, + "psu_air_flow_amber_num": 0, + "fan_air_flow_amber_num": 0, + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile new file mode 100644 index 000000000000..cbb6fe83c013 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile @@ -0,0 +1,12 @@ +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) + +obj-m := wb_pcie_dev_device.o +obj-m += wb_fpga_pca954x_device.o +obj-m += wb_fpga_i2c_bus_device.o +obj-m += wb_lpc_drv_device.o +obj-m += wb_i2c_dev_device.o +obj-m += wb_io_dev_device.o + diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c new file mode 100644 index 000000000000..71bfc520e801 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c @@ -0,0 +1,874 @@ +/* + * An wb_fpga_i2c_bus_device driver for fpga i2c device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_fpga_i2c_debug = 0; +static int g_wb_fpga_i2c_error = 0; + +module_param(g_wb_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_i2c_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_I2C_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_i2c_debug) { \ + printk(KERN_INFO "[WB_FPGA_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_I2C_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_i2c_error) { \ + printk(KERN_ERR "[WB_FPGA_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data0 = { + .adap_nr = 2, + .i2c_timeout = 3000, + .i2c_scale = 0x500, + .i2c_filter = 0x504, + .i2c_stretch = 0x508, + .i2c_ext_9548_exits_flag = 0x50c, + .i2c_ext_9548_addr = 0x510, + .i2c_ext_9548_chan = 0x514, + .i2c_in_9548_chan = 0x518, + .i2c_slave = 0x51c, + .i2c_reg = 0x520, + .i2c_reg_len = 0x530, + .i2c_data_len = 0x534, + .i2c_ctrl = 0x538, + .i2c_status = 0x53c, + .i2c_data_buf = 0x580, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x80, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data1 = { + .adap_nr = 3, + .i2c_timeout = 3000, + .i2c_scale = 0x600, + .i2c_filter = 0x604, + .i2c_stretch = 0x608, + .i2c_ext_9548_exits_flag = 0x60c, + .i2c_ext_9548_addr = 0x610, + .i2c_ext_9548_chan = 0x614, + .i2c_in_9548_chan = 0x618, + .i2c_slave = 0x61c, + .i2c_reg = 0x620, + .i2c_reg_len = 0x630, + .i2c_data_len = 0x634, + .i2c_ctrl = 0x638, + .i2c_status = 0x63c, + .i2c_data_buf = 0x680, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x84, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data2 = { + .adap_nr = 4, + .i2c_timeout = 3000, + .i2c_scale = 0x700, + .i2c_filter = 0x704, + .i2c_stretch = 0x708, + .i2c_ext_9548_exits_flag = 0x70c, + .i2c_ext_9548_addr = 0x710, + .i2c_ext_9548_chan = 0x714, + .i2c_in_9548_chan = 0x718, + .i2c_slave = 0x71c, + .i2c_reg = 0x720, + .i2c_reg_len = 0x730, + .i2c_data_len = 0x734, + .i2c_ctrl = 0x738, + .i2c_status = 0x73c, + .i2c_data_buf = 0x780, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x88, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data3 = { + .adap_nr = 5, + .i2c_timeout = 3000, + .i2c_scale = 0x800, + .i2c_filter = 0x804, + .i2c_stretch = 0x808, + .i2c_ext_9548_exits_flag = 0x80c, + .i2c_ext_9548_addr = 0x810, + .i2c_ext_9548_chan = 0x814, + .i2c_in_9548_chan = 0x818, + .i2c_slave = 0x81c, + .i2c_reg = 0x820, + .i2c_reg_len = 0x830, + .i2c_data_len = 0x834, + .i2c_ctrl = 0x838, + .i2c_status = 0x83c, + .i2c_data_buf = 0x880, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x8c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data0 = { + .adap_nr = 6, + .i2c_timeout = 3000, + .i2c_scale = 0x2c00, + .i2c_filter = 0x2c04, + .i2c_stretch = 0x2c08, + .i2c_ext_9548_exits_flag = 0x2c0c, + .i2c_ext_9548_addr = 0x2c10, + .i2c_ext_9548_chan = 0x2c14, + .i2c_in_9548_chan = 0x2c18, + .i2c_slave = 0x2c1c, + .i2c_reg = 0x2c20, + .i2c_reg_len = 0x2c30, + .i2c_data_len = 0x2c34, + .i2c_ctrl = 0x2c38, + .i2c_status = 0x2c3c, + .i2c_data_buf = 0x2c80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data1 = { + .adap_nr = 7, + .i2c_timeout = 3000, + .i2c_scale = 0x2d00, + .i2c_filter = 0x2d04, + .i2c_stretch = 0x2d08, + .i2c_ext_9548_exits_flag = 0x2d0c, + .i2c_ext_9548_addr = 0x2d10, + .i2c_ext_9548_chan = 0x2d14, + .i2c_in_9548_chan = 0x2d18, + .i2c_slave = 0x2d1c, + .i2c_reg = 0x2d20, + .i2c_reg_len = 0x2d30, + .i2c_data_len = 0x2d34, + .i2c_ctrl = 0x2d38, + .i2c_status = 0x2d3c, + .i2c_data_buf = 0x2d80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000002, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data2 = { + .adap_nr = 8, + .i2c_timeout = 3000, + .i2c_scale = 0x2e00, + .i2c_filter = 0x2e04, + .i2c_stretch = 0x2e08, + .i2c_ext_9548_exits_flag = 0x2e0c, + .i2c_ext_9548_addr = 0x2e10, + .i2c_ext_9548_chan = 0x2e14, + .i2c_in_9548_chan = 0x2e18, + .i2c_slave = 0x2e1c, + .i2c_reg = 0x2e20, + .i2c_reg_len = 0x2e30, + .i2c_data_len = 0x2e34, + .i2c_ctrl = 0x2e38, + .i2c_status = 0x2e3c, + .i2c_data_buf = 0x2e80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000004, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data3 = { + .adap_nr = 9, + .i2c_timeout = 3000, + .i2c_scale = 0x2f00, + .i2c_filter = 0x2f04, + .i2c_stretch = 0x2f08, + .i2c_ext_9548_exits_flag = 0x2f0c, + .i2c_ext_9548_addr = 0x2f10, + .i2c_ext_9548_chan = 0x2f14, + .i2c_in_9548_chan = 0x2f18, + .i2c_slave = 0x2f1c, + .i2c_reg = 0x2f20, + .i2c_reg_len = 0x2f30, + .i2c_data_len = 0x2f34, + .i2c_ctrl = 0x2f38, + .i2c_status = 0x2f3c, + .i2c_data_buf = 0x2f80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000008, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data4 = { + .adap_nr = 10, + .i2c_timeout = 3000, + .i2c_scale = 0x3000, + .i2c_filter = 0x3004, + .i2c_stretch = 0x3008, + .i2c_ext_9548_exits_flag = 0x300c, + .i2c_ext_9548_addr = 0x3010, + .i2c_ext_9548_chan = 0x3014, + .i2c_in_9548_chan = 0x3018, + .i2c_slave = 0x301c, + .i2c_reg = 0x3020, + .i2c_reg_len = 0x3030, + .i2c_data_len = 0x3034, + .i2c_ctrl = 0x3038, + .i2c_status = 0x303c, + .i2c_data_buf = 0x3080, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000010, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data5 = { + .adap_nr = 11, + .i2c_timeout = 3000, + .i2c_scale = 0x3100, + .i2c_filter = 0x3104, + .i2c_stretch = 0x3108, + .i2c_ext_9548_exits_flag = 0x310c, + .i2c_ext_9548_addr = 0x3110, + .i2c_ext_9548_chan = 0x3114, + .i2c_in_9548_chan = 0x3118, + .i2c_slave = 0x311c, + .i2c_reg = 0x3120, + .i2c_reg_len = 0x3130, + .i2c_data_len = 0x3134, + .i2c_ctrl = 0x3138, + .i2c_status = 0x313c, + .i2c_data_buf = 0x3180, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000020, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data6 = { + .adap_nr = 12, + .i2c_timeout = 3000, + .i2c_scale = 0x3200, + .i2c_filter = 0x3204, + .i2c_stretch = 0x3208, + .i2c_ext_9548_exits_flag = 0x320c, + .i2c_ext_9548_addr = 0x3210, + .i2c_ext_9548_chan = 0x3214, + .i2c_in_9548_chan = 0x3218, + .i2c_slave = 0x321c, + .i2c_reg = 0x3220, + .i2c_reg_len = 0x3230, + .i2c_data_len = 0x3234, + .i2c_ctrl = 0x3238, + .i2c_status = 0x323c, + .i2c_data_buf = 0x3280, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000040, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data7 = { + .adap_nr = 13, + .i2c_timeout = 3000, + .i2c_scale = 0x3300, + .i2c_filter = 0x3304, + .i2c_stretch = 0x3308, + .i2c_ext_9548_exits_flag = 0x330c, + .i2c_ext_9548_addr = 0x3310, + .i2c_ext_9548_chan = 0x3314, + .i2c_in_9548_chan = 0x3318, + .i2c_slave = 0x331c, + .i2c_reg = 0x3320, + .i2c_reg_len = 0x3330, + .i2c_data_len = 0x3334, + .i2c_ctrl = 0x3338, + .i2c_status = 0x333c, + .i2c_data_buf = 0x3380, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000080, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data8 = { + .adap_nr = 14, + .i2c_timeout = 3000, + .i2c_scale = 0x3400, + .i2c_filter = 0x3404, + .i2c_stretch = 0x3408, + .i2c_ext_9548_exits_flag = 0x340c, + .i2c_ext_9548_addr = 0x3410, + .i2c_ext_9548_chan = 0x3414, + .i2c_in_9548_chan = 0x3418, + .i2c_slave = 0x341c, + .i2c_reg = 0x3420, + .i2c_reg_len = 0x3430, + .i2c_data_len = 0x3434, + .i2c_ctrl = 0x3438, + .i2c_status = 0x343c, + .i2c_data_buf = 0x3480, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000100, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data9 = { + .adap_nr = 15, + .i2c_timeout = 3000, + .i2c_scale = 0x3500, + .i2c_filter = 0x3504, + .i2c_stretch = 0x3508, + .i2c_ext_9548_exits_flag = 0x350c, + .i2c_ext_9548_addr = 0x3510, + .i2c_ext_9548_chan = 0x3514, + .i2c_in_9548_chan = 0x3518, + .i2c_slave = 0x351c, + .i2c_reg = 0x3520, + .i2c_reg_len = 0x3530, + .i2c_data_len = 0x3534, + .i2c_ctrl = 0x3538, + .i2c_status = 0x353c, + .i2c_data_buf = 0x3580, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000200, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data10 = { + .adap_nr = 16, + .i2c_timeout = 3000, + .i2c_scale = 0x3600, + .i2c_filter = 0x3604, + .i2c_stretch = 0x3608, + .i2c_ext_9548_exits_flag = 0x360c, + .i2c_ext_9548_addr = 0x3610, + .i2c_ext_9548_chan = 0x3614, + .i2c_in_9548_chan = 0x3618, + .i2c_slave = 0x361c, + .i2c_reg = 0x3620, + .i2c_reg_len = 0x3630, + .i2c_data_len = 0x3634, + .i2c_ctrl = 0x3638, + .i2c_status = 0x363c, + .i2c_data_buf = 0x3680, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000400, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data11 = { + .adap_nr = 17, + .i2c_timeout = 3000, + .i2c_scale = 0x3700, + .i2c_filter = 0x3704, + .i2c_stretch = 0x3708, + .i2c_ext_9548_exits_flag = 0x370c, + .i2c_ext_9548_addr = 0x3710, + .i2c_ext_9548_chan = 0x3714, + .i2c_in_9548_chan = 0x3718, + .i2c_slave = 0x371c, + .i2c_reg = 0x3720, + .i2c_reg_len = 0x3730, + .i2c_data_len = 0x3734, + .i2c_ctrl = 0x3738, + .i2c_status = 0x373c, + .i2c_data_buf = 0x3780, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000800, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data12 = { + .adap_nr = 18, + .i2c_timeout = 3000, + .i2c_scale = 0x3800, + .i2c_filter = 0x3804, + .i2c_stretch = 0x3808, + .i2c_ext_9548_exits_flag = 0x380c, + .i2c_ext_9548_addr = 0x3810, + .i2c_ext_9548_chan = 0x3814, + .i2c_in_9548_chan = 0x3818, + .i2c_slave = 0x381c, + .i2c_reg = 0x3820, + .i2c_reg_len = 0x3830, + .i2c_data_len = 0x3834, + .i2c_ctrl = 0x3838, + .i2c_status = 0x383c, + .i2c_data_buf = 0x3880, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00001000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data13 = { + .adap_nr = 19, + .i2c_timeout = 3000, + .i2c_scale = 0x3900, + .i2c_filter = 0x3904, + .i2c_stretch = 0x3908, + .i2c_ext_9548_exits_flag = 0x390c, + .i2c_ext_9548_addr = 0x3910, + .i2c_ext_9548_chan = 0x3914, + .i2c_in_9548_chan = 0x3918, + .i2c_slave = 0x391c, + .i2c_reg = 0x3920, + .i2c_reg_len = 0x3930, + .i2c_data_len = 0x3934, + .i2c_ctrl = 0x3938, + .i2c_status = 0x393c, + .i2c_data_buf = 0x3980, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00002000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data14 = { + .adap_nr = 20, + .i2c_timeout = 3000, + .i2c_scale = 0x3a00, + .i2c_filter = 0x3a04, + .i2c_stretch = 0x3a08, + .i2c_ext_9548_exits_flag = 0x3a0c, + .i2c_ext_9548_addr = 0x3a10, + .i2c_ext_9548_chan = 0x3a14, + .i2c_in_9548_chan = 0x3a18, + .i2c_slave = 0x3a1c, + .i2c_reg = 0x3a20, + .i2c_reg_len = 0x3a30, + .i2c_data_len = 0x3a34, + .i2c_ctrl = 0x3a38, + .i2c_status = 0x3a3c, + .i2c_data_buf = 0x3a80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00004000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data15 = { + .adap_nr = 21, + .i2c_timeout = 3000, + .i2c_scale = 0x3b00, + .i2c_filter = 0x3b04, + .i2c_stretch = 0x3b08, + .i2c_ext_9548_exits_flag = 0x3b0c, + .i2c_ext_9548_addr = 0x3b10, + .i2c_ext_9548_chan = 0x3b14, + .i2c_in_9548_chan = 0x3b18, + .i2c_slave = 0x3b1c, + .i2c_reg = 0x3b20, + .i2c_reg_len = 0x3b30, + .i2c_data_len = 0x3b34, + .i2c_ctrl = 0x3b38, + .i2c_status = 0x3b3c, + .i2c_data_buf = 0x3b80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00008000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static void wb_fpga_i2c_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device fpga_i2c_bus_device[] = { + { + .name = "wb-fpga-i2c", + .id = 1, + .dev = { + .platform_data = &fpga_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 2, + .dev = { + .platform_data = &fpga_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 3, + .dev = { + .platform_data = &fpga_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 4, + .dev = { + .platform_data = &fpga_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 5, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 6, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 7, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 8, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 9, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 10, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 11, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 12, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 13, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data8, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 14, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data9, + .release = wb_fpga_i2c_bus_device_release, + } + }, + { + .name = "wb-fpga-i2c", + .id = 15, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data10, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 16, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data11, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 17, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data12, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 18, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data13, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 19, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data14, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 20, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data15, + .release = wb_fpga_i2c_bus_device_release, + }, + }, +}; + +static int __init wb_fpga_i2c_bus_device_init(void) +{ + int i; + int ret = 0; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_i2c_bus_device); i++) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + ret = platform_device_register(&fpga_i2c_bus_device[i]); + if (ret < 0) { + fpga_i2c_bus_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "rg-fpga-i2c.%d register failed!\n", i + 1); + } else { + fpga_i2c_bus_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_fpga_i2c_bus_device_exit(void) +{ + int i; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_i2c_bus_device) - 1; i >= 0; i--) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + if (fpga_i2c_bus_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&fpga_i2c_bus_device[i]); + } + } +} + +module_init(wb_fpga_i2c_bus_device_init); +module_exit(wb_fpga_i2c_bus_device_exit); +MODULE_DESCRIPTION("FPGA I2C Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c new file mode 100644 index 000000000000..94a4ca54e512 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c @@ -0,0 +1,329 @@ +/* + * An wb_fpga_pca954x_device driver for fpga pca954x device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_fpga_pca954x_device_debug = 0; +static int g_wb_fpga_pca954x_device_error = 0; + +module_param(g_wb_fpga_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_FPGA_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_error) { \ + printk(KERN_ERR "[WB_FPGA_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static fpga_pca954x_device_t fpga_pca954x_device_data0 = { + .i2c_bus = 3, + .i2c_addr = 0x77, + .pca9548_base_nr = 22, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x71, + .pca9548_base_nr = 30, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data2 = { + .i2c_bus = 5, + .i2c_addr = 0x77, + .pca9548_base_nr = 38, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data3 = { + .i2c_bus = 6, + .i2c_addr = 0x70, + .pca9548_base_nr = 46, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data4 = { + .i2c_bus = 7, + .i2c_addr = 0x70, + .pca9548_base_nr = 48, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data5 = { + .i2c_bus = 8, + .i2c_addr = 0x70, + .pca9548_base_nr = 50, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data6 = { + .i2c_bus = 9, + .i2c_addr = 0x70, + .pca9548_base_nr = 52, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data7 = { + .i2c_bus = 10, + .i2c_addr = 0x70, + .pca9548_base_nr = 54, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data8 = { + .i2c_bus = 11, + .i2c_addr = 0x70, + .pca9548_base_nr = 56, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data9 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .pca9548_base_nr = 58, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data10 = { + .i2c_bus = 13, + .i2c_addr = 0x70, + .pca9548_base_nr = 60, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data11 = { + .i2c_bus = 14, + .i2c_addr = 0x70, + .pca9548_base_nr = 62, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data12 = { + .i2c_bus = 15, + .i2c_addr = 0x70, + .pca9548_base_nr = 64, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data13 = { + .i2c_bus = 16, + .i2c_addr = 0x70, + .pca9548_base_nr = 66, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data14 = { + .i2c_bus = 17, + .i2c_addr = 0x70, + .pca9548_base_nr = 68, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data15 = { + .i2c_bus = 18, + .i2c_addr = 0x70, + .pca9548_base_nr = 70, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data16 = { + .i2c_bus = 19, + .i2c_addr = 0x70, + .pca9548_base_nr = 72, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data17 = { + .i2c_bus = 20, + .i2c_addr = 0x70, + .pca9548_base_nr = 74, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data18 = { + .i2c_bus = 21, + .i2c_addr = 0x70, + .pca9548_base_nr = 76, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +struct i2c_board_info fpga_pca954x_device_info[] = { + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data0, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data1, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data2, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data3, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data4, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data5, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data6, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data7, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data8, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data9, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data10, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data11, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data12, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data13, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data14, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data15, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data16, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data17, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data18, + }, +}; + +static int __init wb_fpga_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_pca954x_device_info); i++) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + fpga_pca954x_device_info[i].addr = fpga_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(fpga_pca954x_device_data->i2c_bus); + if (adap == NULL) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", fpga_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); + if (!client) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", + fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); + } else { + fpga_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_fpga_pca954x_device_exit(void) +{ + int i; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_pca954x_device_info) - 1; i >= 0; i--) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + if (fpga_pca954x_device_data->client) { + i2c_unregister_device(fpga_pca954x_device_data->client); + fpga_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_fpga_pca954x_device_init); +module_exit(wb_fpga_pca954x_device_exit); +MODULE_DESCRIPTION("FPGA PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..89e8f3221300 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,175 @@ +/* + * An wb_i2c_dev_device driver for i2c dev device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x1d, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 2, + .i2c_addr = 0x2d, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 2, + .i2c_addr = 0x1e, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 2, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 0x2000, +}; + +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 4, + .i2c_addr = 0x3d, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data4 = { + .i2c_bus = 4, + .i2c_addr = 0x3e, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 2, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 0x2000, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data4, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..ae7ff5523f63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c @@ -0,0 +1,138 @@ +/* + * An wb_io_dev_device driver for io device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data2 = { + .io_dev_name = "cpld2", + .io_base = 0xb00, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 3, + .dev = { + .platform_data = &io_dev_device_data2, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..27dbd87d71b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,150 @@ +/* + * An wb_lpc_drv_device driver for lpc device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..561e64d449b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,113 @@ +/* + * An wb_pcie_dev_device driver for pcie device function + * + * Copyright (C) 2024 Micas 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 + * 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 + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x2f0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..54364261adbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,37 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x1d +cpld_i2c_dev.bus_0_3=2 +cpld_i2c_dev.addr_0_3=0x2d +cpld_i2c_dev.bus_0_4=4 +cpld_i2c_dev.addr_0_4=0x3d + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=5 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..bcbfa1d77bbb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,437 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=6 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00040037 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=5 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00040037 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=4 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00040037 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=3 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00040037 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=2 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x00040037 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=1 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=cpld +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.addr_1_6=0x00040037 +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=0 + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00040038 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=5 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00040039 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=5 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00040038 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=4 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00040039 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=4 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00040038 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=3 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00040039 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=3 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00040038 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=2 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00040039 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=2 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x00040038 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=1 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x00040039 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=1 + +fan_roll_status.mode_6_0=config +fan_roll_status.int_cons_6_0= +fan_roll_status.src_6_0=cpld +fan_roll_status.frmt_6_0=bit +fan_roll_status.pola_6_0=positive +fan_roll_status.fpath_6_0= +fan_roll_status.addr_6_0=0x00040038 +fan_roll_status.len_6_0=1 +fan_roll_status.bit_offset_6_0=0 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=cpld +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1= +fan_roll_status.addr_6_1=0x00040039 +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=0 + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x00040070 +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x0004007c +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0004006e +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x0004007a +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0004006c +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00040078 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x0004006a +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x00040076 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x00040068 +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x00040074 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_6_0=config +fan_speed.int_cons_6_0= +fan_speed.src_6_0=cpld +fan_speed.frmt_6_0=num_bytes +fan_speed.pola_6_0=negative +fan_speed.fpath_6_0= +fan_speed.addr_6_0=0x00040066 +fan_speed.len_6_0=2 +fan_speed.bit_offset_6_0= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=cpld +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1=negative +fan_speed.fpath_6_1= +fan_speed.addr_6_1=0x00040072 +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00040065 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00040065 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00040064 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00040064 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00040063 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00040063 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00040062 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00040062 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x00040061 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x00040061 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= + +fan_ratio.mode_6_0=config +fan_ratio.int_cons_6_0= +fan_ratio.src_6_0=cpld +fan_ratio.frmt_6_0=byte +fan_ratio.pola_6_0= +fan_ratio.fpath_6_0= +fan_ratio.addr_6_0=0x00040060 +fan_ratio.len_6_0=1 +fan_ratio.bit_offset_6_0= + +fan_ratio.mode_6_1=config +fan_ratio.int_cons_6_1= +fan_ratio.src_6_1=cpld +fan_ratio.frmt_6_1=byte +fan_ratio.pola_6_1= +fan_ratio.fpath_6_1= +fan_ratio.addr_6_1=0x00040060 +fan_ratio.len_6_1=1 +fan_ratio.bit_offset_6_1= \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..26a838bfcfa5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00020034 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00020034 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00020034 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00020034 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00020034 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00020034 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..fa45f76b9323 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,383 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=32 + + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00020030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00020030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00020030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00020030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00020030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00020030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00020030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00020030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00020031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00020031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00020031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00020031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00020031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00020031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00020031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00020031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00020032 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00020032 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00020032 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00020032 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00020032 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00020032 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00020032 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00020032 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00020033 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00020033 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00020033 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00020033 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00020033 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00020033 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00020033 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00020033 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +# configuration item: Optical module polling data size +sff_polling_size=1024 + +# configuration item: Optical module polling data register offset +# sff_polling_data_base_addr_[sff_index]=value +# sff_index: start from 1 +# value : directory name +sff_polling_data_base_addr_1 =0x8000 +sff_polling_data_base_addr_2 =0x8400 +sff_polling_data_base_addr_3 =0x8800 +sff_polling_data_base_addr_4 =0x8c00 +sff_polling_data_base_addr_5 =0x9000 +sff_polling_data_base_addr_6 =0x9400 +sff_polling_data_base_addr_7 =0x9800 +sff_polling_data_base_addr_8 =0x9c00 +sff_polling_data_base_addr_9 =0xa000 +sff_polling_data_base_addr_10 =0xa400 +sff_polling_data_base_addr_11 =0xa800 +sff_polling_data_base_addr_12 =0xac00 +sff_polling_data_base_addr_13 =0xb000 +sff_polling_data_base_addr_14 =0xb400 +sff_polling_data_base_addr_15 =0xb800 +sff_polling_data_base_addr_16 =0xbc00 +sff_polling_data_base_addr_17 =0xc000 +sff_polling_data_base_addr_18 =0xc400 +sff_polling_data_base_addr_19 =0xc800 +sff_polling_data_base_addr_20 =0xcc00 +sff_polling_data_base_addr_21 =0xd000 +sff_polling_data_base_addr_22 =0xd400 +sff_polling_data_base_addr_23 =0xd800 +sff_polling_data_base_addr_24 =0xdc00 +sff_polling_data_base_addr_25 =0xe000 +sff_polling_data_base_addr_26 =0xe400 +sff_polling_data_base_addr_27 =0xe800 +sff_polling_data_base_addr_28 =0xec00 +sff_polling_data_base_addr_29 =0xf000 +sff_polling_data_base_addr_30 =0xf400 +sff_polling_data_base_addr_31 =0xf800 +sff_polling_data_base_addr_32 =0xfc00 + +# configuration item: Optical module polling data device path +# sff_polling_logic_dev_path_[sff_index]=value +# sff_index: start from 1 +# value : directory name +sff_polling_logic_dev_path_1 =/dev/fpga0 +sff_polling_logic_dev_path_2 =/dev/fpga0 +sff_polling_logic_dev_path_3 =/dev/fpga0 +sff_polling_logic_dev_path_4 =/dev/fpga0 +sff_polling_logic_dev_path_5 =/dev/fpga0 +sff_polling_logic_dev_path_6 =/dev/fpga0 +sff_polling_logic_dev_path_7 =/dev/fpga0 +sff_polling_logic_dev_path_8 =/dev/fpga0 +sff_polling_logic_dev_path_9 =/dev/fpga0 +sff_polling_logic_dev_path_10 =/dev/fpga0 +sff_polling_logic_dev_path_11 =/dev/fpga0 +sff_polling_logic_dev_path_12 =/dev/fpga0 +sff_polling_logic_dev_path_13 =/dev/fpga0 +sff_polling_logic_dev_path_14 =/dev/fpga0 +sff_polling_logic_dev_path_15 =/dev/fpga0 +sff_polling_logic_dev_path_16 =/dev/fpga0 +sff_polling_logic_dev_path_17 =/dev/fpga0 +sff_polling_logic_dev_path_18 =/dev/fpga0 +sff_polling_logic_dev_path_19 =/dev/fpga0 +sff_polling_logic_dev_path_20 =/dev/fpga0 +sff_polling_logic_dev_path_21 =/dev/fpga0 +sff_polling_logic_dev_path_22 =/dev/fpga0 +sff_polling_logic_dev_path_23 =/dev/fpga0 +sff_polling_logic_dev_path_24 =/dev/fpga0 +sff_polling_logic_dev_path_25 =/dev/fpga0 +sff_polling_logic_dev_path_26 =/dev/fpga0 +sff_polling_logic_dev_path_27 =/dev/fpga0 +sff_polling_logic_dev_path_28 =/dev/fpga0 +sff_polling_logic_dev_path_29 =/dev/fpga0 +sff_polling_logic_dev_path_30 =/dev/fpga0 +sff_polling_logic_dev_path_31 =/dev/fpga0 +sff_polling_logic_dev_path_32 =/dev/fpga0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py new file mode 100644 index 000000000000..6c3916921abb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py @@ -0,0 +1,39 @@ +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='support', + url='', + maintainer='support', + maintainer_email='', + packages=[ + 'sonic_platform', + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', + ], + 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 :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +)