-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DellEMC: N3248PXE Initial platform commit (#8562)
Why I did it Added support for the device N3248PXE How I did it Implemented the support for the platform N3248PXE n3248pxe_unit_test_log.txt Switch Vendor: DellEMC * Switch SKU: N3248PXE * ASIC Vendor: Broadcom * SONiC Image: sonic-broadcom.bin How to verify it Verified the show platform commands
1 parent
5324ce8
commit b0b0ba8
Showing
54 changed files
with
6,876 additions
and
1 deletion.
There are no files selected for viewing
2 changes: 2 additions & 0 deletions
2
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/buffers.json.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
{%- set default_topo = 't0' %} | ||
{%- include 'buffers_config.j2' %} |
41 changes: 41 additions & 0 deletions
41
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/buffers_defaults_t0.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{%- set default_cable = '5m' %} | ||
|
||
{%- macro generate_port_lists(PORT_ALL) %} | ||
{# Generate list of ports #} | ||
{% for port_idx in range(0,32) %} | ||
{% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} | ||
{% endfor %} | ||
{%- endmacro %} | ||
|
||
{%- macro generate_buffer_pool_and_profiles() %} | ||
"BUFFER_POOL": { | ||
"ingress_lossless_pool": { | ||
"size": "8192000", | ||
"type": "ingress", | ||
"mode": "dynamic", | ||
"xoff": "196608" | ||
}, | ||
"egress_lossless_pool": { | ||
"size": "8388608", | ||
"type": "egress", | ||
"mode": "static" | ||
} | ||
}, | ||
"BUFFER_PROFILE": { | ||
"ingress_lossy_profile": { | ||
"pool":"[BUFFER_POOL|ingress_lossless_pool]", | ||
"size":"0", | ||
"dynamic_th":"3" | ||
}, | ||
"egress_lossless_profile": { | ||
"pool":"[BUFFER_POOL|egress_lossless_pool]", | ||
"size":"0", | ||
"static_th":"8388608" | ||
}, | ||
"egress_lossy_profile": { | ||
"pool":"[BUFFER_POOL|egress_lossless_pool]", | ||
"size":"1518", | ||
"dynamic_th":"3" | ||
} | ||
}, | ||
{%- endmacro %} |
41 changes: 41 additions & 0 deletions
41
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/buffers_defaults_t1.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{%- set default_cable = '300m' %} | ||
|
||
{%- macro generate_port_lists(PORT_ALL) %} | ||
{# Generate list of ports #} | ||
{% for port_idx in range(0,32) %} | ||
{% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} | ||
{% endfor %} | ||
{%- endmacro %} | ||
|
||
{%- macro generate_buffer_pool_and_profiles() %} | ||
"BUFFER_POOL": { | ||
"ingress_lossless_pool": { | ||
"size": "8192000", | ||
"type": "ingress", | ||
"mode": "dynamic", | ||
"xoff": "196608" | ||
}, | ||
"egress_lossless_pool": { | ||
"size": "8388608", | ||
"type": "egress", | ||
"mode": "static" | ||
} | ||
}, | ||
"BUFFER_PROFILE": { | ||
"ingress_lossy_profile": { | ||
"pool":"[BUFFER_POOL|ingress_lossless_pool]", | ||
"size":"0", | ||
"dynamic_th":"3" | ||
}, | ||
"egress_lossless_profile": { | ||
"pool":"[BUFFER_POOL|egress_lossless_pool]", | ||
"size":"0", | ||
"static_th":"8388608" | ||
}, | ||
"egress_lossy_profile": { | ||
"pool":"[BUFFER_POOL|egress_lossless_pool]", | ||
"size":"1518", | ||
"dynamic_th":"3" | ||
} | ||
}, | ||
{%- endmacro %} |
Binary file added
BIN
+606 Bytes
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/custom_led.bin
Binary file not shown.
Binary file added
BIN
+5.96 KB
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/linkscan_led_fw.bin
Binary file not shown.
17 changes: 17 additions & 0 deletions
17
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/pg_profile_lookup.ini
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# PG lossless profiles. | ||
# speed cable size xon xoff threshold xon_offset | ||
10000 5m 9427 0 50176 1 3584 | ||
25000 5m 9427 0 50176 1 3584 | ||
40000 5m 9427 0 50176 1 3584 | ||
50000 5m 9427 0 50176 1 3584 | ||
100000 5m 9427 0 50176 1 3584 | ||
10000 40m 9427 0 50176 1 3584 | ||
25000 40m 9427 0 50176 1 3584 | ||
40000 40m 9427 0 50176 1 3584 | ||
50000 40m 9427 0 50176 1 3584 | ||
100000 40m 9427 0 50176 1 3584 | ||
10000 300m 9427 0 50176 1 3584 | ||
25000 300m 9427 0 50176 1 3584 | ||
40000 300m 9427 0 50176 1 3584 | ||
50000 300m 9427 0 50176 1 3584 | ||
100000 300m 9427 0 50176 1 3584 |
55 changes: 55 additions & 0 deletions
55
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/port_config.ini
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# name lanes alias index speed | ||
Ethernet0 62 tenGigE1/1 1 10000 | ||
Ethernet1 61 tenGigE1/2 2 10000 | ||
Ethernet2 64 tenGigE1/3 3 10000 | ||
Ethernet3 63 tenGigE1/4 4 10000 | ||
Ethernet4 66 tenGigE1/5 5 10000 | ||
Ethernet5 65 tenGigE1/6 6 10000 | ||
Ethernet6 68 tenGigE1/7 7 10000 | ||
Ethernet7 67 tenGigE1/8 8 10000 | ||
Ethernet8 70 tenGigE1/9 9 10000 | ||
Ethernet9 69 tenGigE1/10 10 10000 | ||
Ethernet10 72 tenGigE1/11 11 10000 | ||
Ethernet11 71 tenGigE1/12 12 10000 | ||
Ethernet12 74 tenGigE1/13 13 10000 | ||
Ethernet13 73 tenGigE1/14 14 10000 | ||
Ethernet14 76 tenGigE1/15 15 10000 | ||
Ethernet15 75 tenGigE1/16 16 10000 | ||
Ethernet16 78 tenGigE1/17 17 10000 | ||
Ethernet17 77 tenGigE1/18 18 10000 | ||
Ethernet18 80 tenGigE1/19 19 10000 | ||
Ethernet19 79 tenGigE1/20 20 10000 | ||
Ethernet20 3 tenGigE1/21 21 10000 | ||
Ethernet21 4 tenGigE1/22 22 10000 | ||
Ethernet22 1 tenGigE1/23 23 10000 | ||
Ethernet23 2 tenGigE1/24 24 10000 | ||
Ethernet24 7 tenGigE1/25 25 10000 | ||
Ethernet25 8 tenGigE1/26 26 10000 | ||
Ethernet26 5 tenGigE1/27 27 10000 | ||
Ethernet27 6 tenGigE1/28 28 10000 | ||
Ethernet28 11 tenGigE1/29 29 10000 | ||
Ethernet29 12 tenGigE1/30 30 10000 | ||
Ethernet30 9 tenGigE1/31 31 10000 | ||
Ethernet31 10 tenGigE1/32 32 10000 | ||
Ethernet32 15 tenGigE1/33 33 10000 | ||
Ethernet33 16 tenGigE1/34 34 10000 | ||
Ethernet34 13 tenGigE1/35 35 10000 | ||
Ethernet35 14 tenGigE1/36 36 10000 | ||
Ethernet36 19 tenGigE1/37 37 10000 | ||
Ethernet37 20 tenGigE1/38 38 10000 | ||
Ethernet38 17 tenGigE1/39 39 10000 | ||
Ethernet39 18 tenGigE1/40 40 10000 | ||
Ethernet40 23 tenGigE1/41 41 10000 | ||
Ethernet41 24 tenGigE1/42 42 10000 | ||
Ethernet42 21 tenGigE1/43 43 10000 | ||
Ethernet43 22 tenGigE1/44 44 10000 | ||
Ethernet44 27 tenGigE1/45 45 10000 | ||
Ethernet45 28 tenGigE1/46 46 10000 | ||
Ethernet46 25 tenGigE1/47 47 10000 | ||
Ethernet47 26 tenGigE1/48 48 10000 | ||
Ethernet48 40 twentyfiveGigE1/49 49 25000 | ||
Ethernet49 39 twentyfiveGigE1/50 50 25000 | ||
Ethernet50 38 twentyfiveGigE1/51 51 25000 | ||
Ethernet51 37 twentyfiveGigE1/52 52 25000 | ||
Ethernet52 41,42,43,44 hundredGigE1/53 53 100000 | ||
Ethernet56 45,46,47,48 hundredGigE1/54 54 100000 |
1 change: 1 addition & 0 deletions
1
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/qos.json.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{%- include 'qos_config_t1.j2' %} |
175 changes: 175 additions & 0 deletions
175
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/qos_config_t1.j2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
{%- set PORT_ALL = [] %} | ||
{%- for port in PORT %} | ||
{%- if PORT_ALL.append(port) %}{% endif %} | ||
{%- endfor %} | ||
{%- if PORT_ALL | sort_by_port_index %}{% endif %} | ||
|
||
{%- set port_names_list_all = [] %} | ||
{%- for port in PORT_ALL %} | ||
{%- if port_names_list_all.append(port) %}{% endif %} | ||
{%- endfor %} | ||
{%- set port_names_all = port_names_list_all | join(',') -%} | ||
|
||
|
||
{%- set PORT_ACTIVE = [] %} | ||
{%- if DEVICE_NEIGHBOR is not defined %} | ||
{%- set PORT_ACTIVE = PORT_ALL %} | ||
{%- else %} | ||
{%- for port in DEVICE_NEIGHBOR.keys() %} | ||
{%- if PORT_ACTIVE.append(port) %}{%- endif %} | ||
{%- endfor %} | ||
{%- endif %} | ||
{%- if PORT_ACTIVE | sort_by_port_index %}{% endif %} | ||
|
||
{%- set port_names_list_active = [] %} | ||
{%- for port in PORT_ACTIVE %} | ||
{%- if port_names_list_active.append(port) %}{%- endif %} | ||
{%- endfor %} | ||
{%- set port_names_active = port_names_list_active | join(',') -%} | ||
|
||
|
||
{%- set pfc_to_pg_map_supported_asics = ['mellanox', 'barefoot', 'marvell'] -%} | ||
|
||
|
||
{ | ||
{% if generate_tc_to_pg_map is defined %} | ||
{{- generate_tc_to_pg_map() }} | ||
{% else %} | ||
"TC_TO_PRIORITY_GROUP_MAP": { | ||
"AZURE": { | ||
"0": "0", | ||
"1": "0", | ||
"2": "0", | ||
"3": "3", | ||
"4": "4", | ||
"5": "0", | ||
"6": "0", | ||
"7": "7" | ||
} | ||
}, | ||
{% endif %} | ||
"MAP_PFC_PRIORITY_TO_QUEUE": { | ||
"AZURE": { | ||
"0": "0", | ||
"1": "1", | ||
"2": "2", | ||
"3": "3", | ||
"4": "4", | ||
"5": "5", | ||
"6": "6", | ||
"7": "7" | ||
} | ||
}, | ||
"TC_TO_QUEUE_MAP": { | ||
"AZURE": { | ||
"0": "0", | ||
"1": "1", | ||
"2": "2", | ||
"3": "3", | ||
"4": "4", | ||
"5": "5", | ||
"6": "6", | ||
"7": "7" | ||
} | ||
}, | ||
"DSCP_TO_TC_MAP": { | ||
"AZURE": { | ||
"0" : "1", | ||
"1" : "1", | ||
"2" : "1", | ||
"3" : "3", | ||
"4" : "4", | ||
"5" : "2", | ||
"6" : "1", | ||
"7" : "1", | ||
"8" : "0", | ||
"9" : "1", | ||
"10": "1", | ||
"11": "1", | ||
"12": "1", | ||
"13": "1", | ||
"14": "1", | ||
"15": "1", | ||
"16": "1", | ||
"17": "1", | ||
"18": "1", | ||
"19": "1", | ||
"20": "1", | ||
"21": "1", | ||
"22": "1", | ||
"23": "1", | ||
"24": "1", | ||
"25": "1", | ||
"26": "1", | ||
"27": "1", | ||
"28": "1", | ||
"29": "1", | ||
"30": "1", | ||
"31": "1", | ||
"32": "1", | ||
"33": "1", | ||
"34": "1", | ||
"35": "1", | ||
"36": "1", | ||
"37": "1", | ||
"38": "1", | ||
"39": "1", | ||
"40": "1", | ||
"41": "1", | ||
"42": "1", | ||
"43": "1", | ||
"44": "1", | ||
"45": "1", | ||
"46": "5", | ||
"47": "1", | ||
"48": "6", | ||
"49": "1", | ||
"50": "1", | ||
"51": "1", | ||
"52": "1", | ||
"53": "1", | ||
"54": "1", | ||
"55": "1", | ||
"56": "1", | ||
"57": "1", | ||
"58": "1", | ||
"59": "1", | ||
"60": "1", | ||
"61": "1", | ||
"62": "1", | ||
"63": "1" | ||
} | ||
}, | ||
"SCHEDULER": { | ||
"scheduler.0": { | ||
"type" : "DWRR", | ||
"weight": "14" | ||
}, | ||
"scheduler.1": { | ||
"type" : "DWRR", | ||
"weight": "15" | ||
} | ||
}, | ||
{% if asic_type in pfc_to_pg_map_supported_asics %} | ||
"PFC_PRIORITY_TO_PRIORITY_GROUP_MAP": { | ||
"AZURE": { | ||
"3": "3", | ||
"4": "4" | ||
} | ||
}, | ||
{% endif %} | ||
"PORT_QOS_MAP": { | ||
{% for port in PORT_ACTIVE %} | ||
"{{ port }}": { | ||
"dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]", | ||
"tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]", | ||
"tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]", | ||
"pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]", | ||
{% if asic_type in pfc_to_pg_map_supported_asics %} | ||
"pfc_to_pg_map" : "[PFC_PRIORITY_TO_PRIORITY_GROUP_MAP|AZURE]", | ||
{% endif %} | ||
"pfc_enable" : "3,4" | ||
}{% if not loop.last %},{% endif %} | ||
{% endfor %} | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/sai.profile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-x5-n3248pxe-48x10GCU+4x25G-2x100G.config.bcm |
2 changes: 2 additions & 0 deletions
2
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/sai_preinit_cmd.soc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin | ||
m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin |
389 changes: 389 additions & 0 deletions
389
...llemc_n3248pxe_c3338-r0/DELLEMC-N3248PXE/td3-x5-n3248pxe-48x10GCU+4x25G-2x100G.config.bcm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,389 @@ | ||
pbmp_xport_xe=0x1FFFFFFFFFFFFFFE | ||
|
||
# PM 4x25: CLP0 | ||
portmap_1=1:10 | ||
portmap_2=2:10 | ||
portmap_3=3:10 | ||
portmap_4=4:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{1}=0x1 | ||
phy_chain_tx_polarity_flip_physical{2}=0x0 | ||
phy_chain_tx_polarity_flip_physical{3}=0x1 | ||
phy_chain_tx_polarity_flip_physical{4}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{1}=0x0 | ||
phy_chain_rx_polarity_flip_physical{2}=0x1 | ||
phy_chain_rx_polarity_flip_physical{3}=0x0 | ||
phy_chain_rx_polarity_flip_physical{4}=0x1 | ||
|
||
# PM 4x25: CLP1 | ||
portmap_5=5:10 | ||
portmap_6=6:10 | ||
portmap_7=7:10 | ||
portmap_8=8:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{5}=0x0 | ||
phy_chain_tx_polarity_flip_physical{6}=0x1 | ||
phy_chain_tx_polarity_flip_physical{7}=0x0 | ||
phy_chain_tx_polarity_flip_physical{8}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{5}=0x1 | ||
phy_chain_rx_polarity_flip_physical{6}=0x0 | ||
phy_chain_rx_polarity_flip_physical{7}=0x1 | ||
phy_chain_rx_polarity_flip_physical{8}=0x0 | ||
|
||
|
||
# PM 4x25: CLP2 | ||
portmap_9=9:10 | ||
portmap_10=10:10 | ||
portmap_11=11:10 | ||
portmap_12=12:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{9}=0x1 | ||
phy_chain_tx_polarity_flip_physical{10}=0x0 | ||
phy_chain_tx_polarity_flip_physical{11}=0x1 | ||
phy_chain_tx_polarity_flip_physical{12}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{9}=0x1 | ||
phy_chain_rx_polarity_flip_physical{10}=0x0 | ||
phy_chain_rx_polarity_flip_physical{11}=0x1 | ||
phy_chain_rx_polarity_flip_physical{12}=0x0 | ||
|
||
|
||
|
||
# PM 4x25: CLP3 | ||
portmap_13=13:10 | ||
portmap_14=14:10 | ||
portmap_15=15:10 | ||
portmap_16=16:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{13}=0x0 | ||
phy_chain_tx_polarity_flip_physical{14}=0x1 | ||
phy_chain_tx_polarity_flip_physical{15}=0x0 | ||
phy_chain_tx_polarity_flip_physical{16}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{13}=0x1 | ||
phy_chain_rx_polarity_flip_physical{14}=0x0 | ||
phy_chain_rx_polarity_flip_physical{15}=0x1 | ||
phy_chain_rx_polarity_flip_physical{16}=0x0 | ||
|
||
|
||
# PM 4x25: CLP4 | ||
portmap_17=17:10 | ||
portmap_18=18:10 | ||
portmap_19=19:10 | ||
portmap_20=20:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{17}=0x1 | ||
phy_chain_tx_polarity_flip_physical{18}=0x0 | ||
phy_chain_tx_polarity_flip_physical{19}=0x1 | ||
phy_chain_tx_polarity_flip_physical{20}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{17}=0x0 | ||
phy_chain_rx_polarity_flip_physical{18}=0x1 | ||
phy_chain_rx_polarity_flip_physical{19}=0x0 | ||
phy_chain_rx_polarity_flip_physical{20}=0x1 | ||
|
||
# PM 4x25: CLP5 | ||
portmap_21=21:10 | ||
portmap_22=22:10 | ||
portmap_23=23:10 | ||
portmap_24=24:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{21}=0x0 | ||
phy_chain_tx_polarity_flip_physical{22}=0x1 | ||
phy_chain_tx_polarity_flip_physical{23}=0x0 | ||
phy_chain_tx_polarity_flip_physical{24}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{21}=0x1 | ||
phy_chain_rx_polarity_flip_physical{22}=0x0 | ||
phy_chain_rx_polarity_flip_physical{23}=0x1 | ||
phy_chain_rx_polarity_flip_physical{24}=0x0 | ||
|
||
|
||
# PM 4x25: CLP6 | ||
portmap_25=25:10 | ||
portmap_26=26:10 | ||
portmap_27=27:10 | ||
portmap_28=28:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{25}=0x1 | ||
phy_chain_tx_polarity_flip_physical{26}=0x0 | ||
phy_chain_tx_polarity_flip_physical{27}=0x1 | ||
phy_chain_tx_polarity_flip_physical{28}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{25}=0x1 | ||
phy_chain_rx_polarity_flip_physical{26}=0x0 | ||
phy_chain_rx_polarity_flip_physical{27}=0x1 | ||
phy_chain_rx_polarity_flip_physical{28}=0x0 | ||
|
||
|
||
|
||
|
||
# PM 4x25: CLP9 4x25G ports | ||
portmap_29=37:25 | ||
portmap_30=38:25 | ||
portmap_31=39:25 | ||
portmap_32=40:25 | ||
|
||
phy_chain_tx_polarity_flip_physical{37}=0x1 | ||
phy_chain_tx_polarity_flip_physical{38}=0x0 | ||
phy_chain_tx_polarity_flip_physical{39}=0x1 | ||
phy_chain_tx_polarity_flip_physical{40}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{37}=0x1 | ||
phy_chain_rx_polarity_flip_physical{38}=0x0 | ||
phy_chain_rx_polarity_flip_physical{39}=0x1 | ||
phy_chain_rx_polarity_flip_physical{40}=0x1 | ||
|
||
|
||
|
||
# PM 4x25: CLP15 | ||
portmap_33=61:10 | ||
portmap_34=62:10 | ||
portmap_35=63:10 | ||
portmap_36=64:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{61}=0x0 | ||
phy_chain_tx_polarity_flip_physical{62}=0x1 | ||
phy_chain_tx_polarity_flip_physical{63}=0x0 | ||
phy_chain_tx_polarity_flip_physical{64}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{61}=0x0 | ||
phy_chain_rx_polarity_flip_physical{62}=0x1 | ||
phy_chain_rx_polarity_flip_physical{63}=0x0 | ||
phy_chain_rx_polarity_flip_physical{64}=0x1 | ||
|
||
# PM 4x25: CLP16 | ||
portmap_37=65:10 | ||
portmap_38=66:10 | ||
portmap_39=67:10 | ||
portmap_40=68:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{65}=0x1 | ||
phy_chain_tx_polarity_flip_physical{66}=0x0 | ||
phy_chain_tx_polarity_flip_physical{67}=0x1 | ||
phy_chain_tx_polarity_flip_physical{68}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{65}=0x1 | ||
phy_chain_rx_polarity_flip_physical{66}=0x0 | ||
phy_chain_rx_polarity_flip_physical{67}=0x1 | ||
phy_chain_rx_polarity_flip_physical{68}=0x0 | ||
|
||
|
||
# PM 4x25: CLP17 | ||
portmap_41=69:10 | ||
portmap_42=70:10 | ||
portmap_43=71:10 | ||
portmap_44=72:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{69}=0x0 | ||
phy_chain_tx_polarity_flip_physical{70}=0x1 | ||
phy_chain_tx_polarity_flip_physical{71}=0x0 | ||
phy_chain_tx_polarity_flip_physical{72}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{69}=0x1 | ||
phy_chain_rx_polarity_flip_physical{70}=0x0 | ||
phy_chain_rx_polarity_flip_physical{71}=0x1 | ||
phy_chain_rx_polarity_flip_physical{72}=0x0 | ||
|
||
# PM 4x25: CLP18 | ||
portmap_45=73:10 | ||
portmap_46=74:10 | ||
portmap_47=75:10 | ||
portmap_48=76:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{73}=0x1 | ||
phy_chain_tx_polarity_flip_physical{74}=0x0 | ||
phy_chain_tx_polarity_flip_physical{75}=0x1 | ||
phy_chain_tx_polarity_flip_physical{76}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{73}=0x1 | ||
phy_chain_rx_polarity_flip_physical{74}=0x0 | ||
phy_chain_rx_polarity_flip_physical{75}=0x1 | ||
phy_chain_rx_polarity_flip_physical{76}=0x0 | ||
|
||
|
||
|
||
# PM 4x25: CLP19 | ||
portmap_49=77:10 | ||
portmap_50=78:10 | ||
portmap_51=79:10 | ||
portmap_52=80:10 | ||
|
||
phy_chain_tx_polarity_flip_physical{77}=0x0 | ||
phy_chain_tx_polarity_flip_physical{78}=0x1 | ||
phy_chain_tx_polarity_flip_physical{79}=0x0 | ||
phy_chain_tx_polarity_flip_physical{80}=0x1 | ||
|
||
phy_chain_rx_polarity_flip_physical{77}=0x0 | ||
phy_chain_rx_polarity_flip_physical{78}=0x1 | ||
phy_chain_rx_polarity_flip_physical{79}=0x0 | ||
phy_chain_rx_polarity_flip_physical{80}=0x1 | ||
|
||
portmap_53=41:100 | ||
phy_chain_tx_lane_map_physical{41.0}=0x2130 | ||
phy_chain_rx_lane_map_physical{41.0}=0x0312 | ||
|
||
|
||
phy_chain_tx_polarity_flip_physical{41.0}=0x0 | ||
phy_chain_tx_polarity_flip_physical{42.0}=0x1 | ||
phy_chain_tx_polarity_flip_physical{43.0}=0x1 | ||
phy_chain_tx_polarity_flip_physical{44.0}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{41.0}=0x0 | ||
phy_chain_rx_polarity_flip_physical{42.0}=0x1 | ||
phy_chain_rx_polarity_flip_physical{43.0}=0x1 | ||
phy_chain_rx_polarity_flip_physical{44.0}=0x0 | ||
|
||
# PM 4x25: CLP11 | ||
portmap_57=45:100 | ||
phy_chain_tx_lane_map_physical{45.0}=0x2130 | ||
phy_chain_rx_lane_map_physical{45.0}=0x0312 | ||
|
||
|
||
phy_chain_tx_polarity_flip_physical{45.0}=0x0 | ||
phy_chain_tx_polarity_flip_physical{46.0}=0x1 | ||
phy_chain_tx_polarity_flip_physical{47.0}=0x1 | ||
phy_chain_tx_polarity_flip_physical{48.0}=0x0 | ||
|
||
phy_chain_rx_polarity_flip_physical{45.0}=0x0 | ||
phy_chain_rx_polarity_flip_physical{46.0}=0x1 | ||
phy_chain_rx_polarity_flip_physical{47.0}=0x1 | ||
phy_chain_rx_polarity_flip_physical{48.0}=0x0 | ||
|
||
|
||
dport_map_port_34=1 | ||
dport_map_port_33=2 | ||
dport_map_port_36=3 | ||
dport_map_port_35=4 | ||
dport_map_port_38=5 | ||
dport_map_port_37=6 | ||
dport_map_port_40=7 | ||
dport_map_port_39=8 | ||
dport_map_port_42=9 | ||
dport_map_port_41=10 | ||
dport_map_port_44=11 | ||
dport_map_port_43=12 | ||
dport_map_port_46=13 | ||
dport_map_port_45=14 | ||
dport_map_port_48=15 | ||
dport_map_port_47=16 | ||
dport_map_port_50=17 | ||
dport_map_port_49=18 | ||
dport_map_port_52=19 | ||
dport_map_port_51=20 | ||
dport_map_port_3=21 | ||
dport_map_port_4=22 | ||
dport_map_port_1=23 | ||
dport_map_port_2=24 | ||
dport_map_port_7=25 | ||
dport_map_port_8=26 | ||
dport_map_port_5=27 | ||
dport_map_port_6=28 | ||
dport_map_port_11=29 | ||
dport_map_port_12=30 | ||
dport_map_port_9=31 | ||
dport_map_port_10=32 | ||
dport_map_port_15=33 | ||
dport_map_port_16=34 | ||
dport_map_port_13=35 | ||
dport_map_port_14=36 | ||
dport_map_port_19=37 | ||
dport_map_port_20=38 | ||
dport_map_port_17=39 | ||
dport_map_port_18=40 | ||
dport_map_port_23=41 | ||
dport_map_port_24=42 | ||
dport_map_port_21=43 | ||
dport_map_port_22=44 | ||
dport_map_port_27=45 | ||
dport_map_port_28=46 | ||
dport_map_port_25=47 | ||
dport_map_port_26=48 | ||
dport_map_port_32=49 | ||
dport_map_port_31=50 | ||
dport_map_port_30=51 | ||
dport_map_port_29=52 | ||
dport_map_port_53=53 | ||
dport_map_port_54=54 | ||
dport_map_port_55=55 | ||
dport_map_port_56=56 | ||
dport_map_port_57=57 | ||
dport_map_port_58=58 | ||
dport_map_port_59=59 | ||
dport_map_port_60=60 | ||
|
||
|
||
|
||
#pbmp_oversubscribe=0x7fff9fffffffffffffffe | ||
#pbmp_xport_xe=0x7fff9fffffffffffffffe | ||
port_flex_enable=1 | ||
phy_an_c73=3 | ||
oversubscribe_mode=1 | ||
core_clock_frequency=1525 | ||
|
||
#25G,10G and 1G support | ||
serdes_10g_at_25g_vco=1 | ||
serdes_1000x_at_25g_vco=1 | ||
|
||
l2xmsg_mode=1 | ||
|
||
l2xmsg_hostbuf_size=16384 | ||
module_64ports=0 | ||
|
||
#Interrupts and Parity | ||
max_vp_lags=0 | ||
|
||
schan_intr_enable=0 | ||
tdma_timeout_usec=5000000 | ||
|
||
stable_size=0x5500000 | ||
|
||
#Default L3 profile | ||
l2_mem_entries=40960 | ||
l3_alpm_enable=2 | ||
l3_alpm_ipv6_128b_bkt_rsvd=1 | ||
l3_mem_entries=40960 | ||
|
||
#Tunnels | ||
use_all_splithorizon_groups=1 | ||
sai_tunnel_support=1 | ||
bcm_tunnel_term_compatible_mode=1 | ||
|
||
#RIOT Enable | ||
riot_enable=1 | ||
riot_overlay_l3_intf_mem_size=8192 | ||
riot_overlay_l3_egress_mem_size=32768 | ||
l3_ecmp_levels=2 | ||
riot_overlay_ecmp_resilient_hash_size=16384 | ||
|
||
#sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc | ||
|
||
#New Additions | ||
pfc_deadlock_seq_control=1 | ||
|
||
#Common configs from broadcom/x86_64-broadcom_common/x86_64-broadcom_b77/broadcom-sonic-td3.config.bcm (Lower version of Td3 (0xb771)) | ||
mem_cache_enable=0 | ||
ifp_inports_support_enable=1 | ||
ipv6_lpm_128b_enable=0x1 | ||
l3_max_ecmp_mode=1 | ||
lpm_scaling_enable=0 | ||
bcm_num_cos=10 | ||
default_cpu_tx_queue=9 | ||
mmu_lossless=0 | ||
host_as_route_disable=1 | ||
sai_eapp_config_file=/etc/broadcom/eapps_cfg.json | ||
sai_fast_convergence_support=1 | ||
flow_init_mode=1 | ||
sai_interface_type_auto_detect=0 | ||
mpls_mem_entries=16384 | ||
vlan_xlate_1_mem_entries=65536 | ||
vlan_xlate_2_mem_entries=16384 | ||
sai_load_hw_config=/usr/lib/cancun/ | ||
sai_nbr_bcast_ifp_optimized=1 | ||
sai_brcm_sonic_acl_enhancements=1 | ||
# Reduced Trap Group QSET for BRCM Sonic | ||
sai_brcm_sonic_trap_group=1 | ||
l2_entry_used_as_my_station=1 | ||
multi_hash_recurse_depth_l3=2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DELLEMC-N3248PXE t1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
CONSOLE_PORT=0x3f8 | ||
CONSOLE_DEV=0 | ||
VAR_LOG_SIZE=512 |
7 changes: 7 additions & 0 deletions
7
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/led_proc_init.soc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# LED microprocessor initialization for Dell N3248TE | ||
# | ||
# | ||
#Led0 | ||
#led auto on | ||
m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin | ||
led start |
22 changes: 22 additions & 0 deletions
22
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/plugins/eeprom.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/python3 | ||
|
||
############################################################################# | ||
# Dell S3000 | ||
# | ||
# Platform and model specific eeprom subclass, inherits from the base class, | ||
# and provides the followings: | ||
# - the eeprom format definition | ||
# - specific encoder/decoder if there is special need | ||
############################################################################# | ||
|
||
try: | ||
from sonic_eeprom import eeprom_tlvinfo | ||
except ImportError as e: | ||
raise ImportError (str(e) + "- required module not found") | ||
|
||
|
||
class board(eeprom_tlvinfo.TlvInfoDecoder): | ||
|
||
def __init__(self, name, path, cpld_root, ro): | ||
self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" | ||
super(board, self).__init__(self.eeprom_path, 0, '', True) |
72 changes: 72 additions & 0 deletions
72
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/plugins/fanutil.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# | ||
# fanutil.py | ||
# Platform-specific FAN status interface for SONiC | ||
# | ||
|
||
import commands | ||
import sys | ||
|
||
SENSORS_CMD = "docker exec -i pmon /usr/bin/sensors" | ||
DOCKER_SENSORS_CMD = "/usr/bin/sensors" | ||
|
||
|
||
try: | ||
from sonic_fan.fan_base import FanBase | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class FanUtil(FanBase): | ||
"""Platform-specific FanUtil class""" | ||
_fan_mapping = { | ||
1 : '0', | ||
2 : '1', | ||
3 : '2' | ||
} | ||
|
||
def __init__(self): | ||
FanBase.__init__(self) | ||
|
||
def isDockerEnv(self): | ||
num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") | ||
if num_docker > 0: | ||
return True | ||
|
||
def get_num_fans(self): | ||
n3248pxe_MAX_FANTRAYS = 3 | ||
return n3248pxe_MAX_FANTRAYS | ||
|
||
def get_presence(self, idx): | ||
sysfs_path = "/sys/devices/platform/dell-n3248pxe-cpld.0/fan" + self._fan_mapping[idx] + "_prs" | ||
return int(open(sysfs_path).read(), 16) | ||
|
||
def get_direction(self, idx): | ||
sysfs_path = "/sys/devices/platform/dell-n3248pxe-cpld.0/fan" + self._fan_mapping[idx] + "_dir" | ||
return open(sysfs_path).read() | ||
|
||
def get_speed(self, idx): | ||
dockerenv = self.isDockerEnv() | ||
if not dockerenv: | ||
status, cmd_output = commands.getstatusoutput(SENSORS_CMD) | ||
else : | ||
status, cmd_output = commands.getstatusoutput(DOCKER_SENSORS_CMD) | ||
|
||
if status: | ||
print('Failed to execute sensors command') | ||
sys.exit(0) | ||
fan_id = 'Fan ' + str(idx) | ||
found = False | ||
for line in cmd_output.splitlines(): | ||
if line.startswith('emc2305-i2c-7-2c'): | ||
found = True | ||
if found and line.startswith(fan_id): | ||
return line.split()[3] | ||
return 0.0 | ||
|
||
def get_status(self, idx): | ||
sysfs_path = "/sys/devices/platform/dell-n3248pxe-cpld.0/fan" + self._fan_mapping[idx] + "_prs" | ||
return int(open(sysfs_path).read(), 16) | ||
|
||
|
||
def set_speed(self, idx): | ||
return False |
191 changes: 191 additions & 0 deletions
191
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/plugins/psuutil.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
# | ||
# psuutil.py | ||
# Platform-specific PSU status interface for SONiC | ||
# | ||
|
||
import commands | ||
import os | ||
import sys | ||
|
||
SENSORS_CMD = "docker exec -i pmon /usr/bin/sensors" | ||
DOCKER_SENSORS_CMD = "/usr/bin/sensors" | ||
|
||
try: | ||
from sonic_psu.psu_base import PsuBase | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class PsuUtil(PsuBase): | ||
"""Platform-specific PSUutil class""" | ||
_psu_mapping = { | ||
1 : '0', | ||
2 : '1' | ||
} | ||
|
||
def __init__(self): | ||
PsuBase.__init__(self) | ||
|
||
def isDockerEnv(self): | ||
num_docker = open('/proc/self/cgroup', 'r').read().count(":/docker") | ||
if num_docker > 0: | ||
return True | ||
else: | ||
return False | ||
|
||
def remove_nonnumeric(self, text): | ||
digits='0123456789.' | ||
return ''.join(c for c in text if c in digits) | ||
|
||
def get_cpld_register(self, reg_name): | ||
cpld_dir = "/sys/devices/platform/dell-n3248pxe-cpld.0/" | ||
retval = 'ERR' | ||
reg_file = cpld_dir +'/' + reg_name | ||
if (not os.path.isfile(reg_file)): | ||
return retval | ||
|
||
try: | ||
with open(reg_file, 'r') as fd: | ||
retval = fd.read() | ||
except Exception: | ||
print("Unable to open ", reg_file, "file !") | ||
|
||
retval = retval.rstrip('\r\n') | ||
return retval | ||
|
||
def get_num_psus(self): | ||
""" | ||
Retrieves the number of PSUs available on the device | ||
:return: An integer, the number of PSUs available on the device | ||
""" | ||
N3248PXE_MAX_PSUS = 2 | ||
return N3248PXE_MAX_PSUS | ||
|
||
def get_psu_status(self, index): | ||
""" | ||
Retrieves the oprational status of power supply unit (PSU) defined | ||
by index <index> | ||
:param index: An integer, index of the PSU of which to query status | ||
:return: Boolean, True if PSU is operating properly, False if PSU is\ | ||
faulty | ||
""" | ||
status = 0 | ||
psu_status = self.get_cpld_register('psu'+self._psu_mapping[index]+'_status') | ||
if (psu_status != 'ERR'): | ||
status = int(psu_status, 10) | ||
|
||
presence = self.get_psu_presence(index) | ||
|
||
return (status & presence) | ||
|
||
def get_psu_presence(self, index): | ||
""" | ||
Retrieves the presence status of power supply unit (PSU) defined | ||
by index <index> | ||
:param index: An integer, index of the PSU of which to query status | ||
:return: Boolean, True if PSU is plugged, False if not | ||
""" | ||
status = 0 | ||
psu_presence = self.get_cpld_register('psu'+self._psu_mapping[index]+'_prs') | ||
if (psu_presence != 'ERR'): | ||
status = int(psu_presence, 10) | ||
|
||
return status | ||
|
||
def get_sensor(self): | ||
dockerenv = self.isDockerEnv() | ||
if not dockerenv: | ||
status, cmd_output = commands.getstatusoutput(SENSORS_CMD) | ||
else : | ||
status, cmd_output = commands.getstatusoutput(DOCKER_SENSORS_CMD) | ||
|
||
if status: | ||
print('Failed to execute sensors command') | ||
sys.exit(0) | ||
return cmd_output | ||
|
||
def get_output_current(self, index): | ||
cmd_output= self.get_sensor() | ||
sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11' | ||
found = False | ||
for line in cmd_output.splitlines(): | ||
if line.startswith(sensor_name): | ||
found = True | ||
if found: | ||
if 'Output Current' in line : | ||
return float(self.remove_nonnumeric(line.split()[2])) | ||
return 0.0 | ||
|
||
def get_output_voltage(self, index): | ||
cmd_output= self.get_sensor() | ||
sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11' | ||
found = False | ||
for line in cmd_output.splitlines(): | ||
if line.startswith(sensor_name): | ||
found = True | ||
if found: | ||
if 'Output Voltage' in line : | ||
return float(self.remove_nonnumeric(line.split()[2])) | ||
return 0.0 | ||
|
||
def get_fan_rpm(self, index, fan_index): | ||
if fan_index > 1 : return 0.0 | ||
cmd_output= self.get_sensor() | ||
sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11' | ||
found = False | ||
for line in cmd_output.splitlines(): | ||
if line.startswith(sensor_name): | ||
found = True | ||
if found: | ||
if 'Fan RPM' in line : | ||
return self.remove_nonnumeric(line.split()[2]) | ||
return 0.0 | ||
|
||
def get_output_power(self, index): | ||
cmd_output= self.get_sensor() | ||
sensor_name = 'dps460-i2c-10' if index == 1 else 'dps460-i2c-11' | ||
found = False | ||
for line in cmd_output.splitlines(): | ||
if line.startswith(sensor_name): | ||
found = True | ||
if found: | ||
if 'Output Power' in line : | ||
return float(self.remove_nonnumeric(line.split()[2])) | ||
return 0.0 | ||
|
||
def get_direction(self, index): | ||
psuid = '0' if index == 1 else '1' | ||
sysfs_path = '/sys/devices/platform/dell-n3248pxe-cpld.0/psu' + psuid + '_prs' | ||
found_psu = int(open(sysfs_path).read()) | ||
if not found_psu : return '' | ||
bus_no = '10' if index == 1 else '11' | ||
sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom" | ||
val = (open(sysfs_path, "rb").read())[0xe1:0xe8] | ||
dir = 'F2B' if 'FORWARD' == val else 'B2F' | ||
return dir | ||
|
||
def get_serial(self, index): | ||
psuid = '0' if index == 1 else '1' | ||
sysfs_path = '/sys/devices/platform/dell-n3248pxe-cpld.0/psu' + psuid + '_prs' | ||
found_psu = int(open(sysfs_path).read()) | ||
if not found_psu : return '' | ||
bus_no = '10' if index == 1 else '11' | ||
sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom" | ||
val = (open(sysfs_path, "rb").read())[0xc4:0xd9] | ||
return val | ||
|
||
def get_model(self, index): | ||
psuid = '0' if index == 1 else '1' | ||
sysfs_path = '/sys/devices/platform/dell-n3248pxe-cpld.0/psu' + psuid + '_prs' | ||
found_psu = int(open(sysfs_path).read()) | ||
if not found_psu : return '' | ||
bus_no = '10' if index == 1 else '11' | ||
sysfs_path = "/sys/bus/i2c/devices/" + bus_no + "-0056/eeprom" | ||
val = (open(sysfs_path, "rb").read())[0x50:0x62] | ||
return val | ||
|
||
def get_mfr_id(self, index): | ||
psuid = '0' if index == 1 else '1' | ||
sysfs_path = '/sys/devices/platform/dell-n3248pxe-cpld.0/psu' + psuid + '_prs' | ||
found_psu = int(open(sysfs_path).read()) | ||
return 'DELTA' if found_psu else '' |
172 changes: 172 additions & 0 deletions
172
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/plugins/sfputil.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
# sfputil.py | ||
# | ||
# Platform-specific SFP transceiver interface for SONiC | ||
# | ||
|
||
try: | ||
import time | ||
from socket import * | ||
from select import * | ||
from sonic_sfp.sfputilbase import SfpUtilBase | ||
except ImportError as e: | ||
raise ImportError("%s - required module not found" % str(e)) | ||
|
||
class SfpUtil(SfpUtilBase): | ||
"""Platform-specific SfpUtil class""" | ||
|
||
PORT_START = 1 | ||
PORT_END = 52 | ||
PORTS_IN_BLOCK = 52 | ||
SFP_PORT_START = 49 | ||
SFP_PORT_END = 52 | ||
|
||
EEPROM_OFFSET = 14 | ||
|
||
_port_to_eeprom_mapping = {} | ||
_sfpp_port_i2c_mapping = { | ||
49 : 20, | ||
50 : 21, | ||
51 : 22, | ||
52 : 23 | ||
} | ||
port_dict = {} | ||
|
||
@property | ||
def port_start(self): | ||
return self.PORT_START | ||
|
||
@property | ||
def port_end(self): | ||
return self.PORT_END | ||
|
||
@property | ||
def qsfp_ports(self) : | ||
return range(self.SFP_PORT_END+1, self.SFP_PORT_END+1) | ||
|
||
@property | ||
def port_to_eeprom_mapping(self): | ||
return self._port_to_eeprom_mapping | ||
|
||
@property | ||
def get_transceiver_status(self): | ||
|
||
try: | ||
sfp_modprs_path = "/sys/devices/platform/dell-n3248pxe-cpld.0/sfp_modprs" | ||
reg_file = open(sfp_modprs_path) | ||
|
||
except IOError as e: | ||
print ("Error: unable to open file: %s" % str(e)) | ||
return False | ||
|
||
content = reg_file.readline().rstrip() | ||
|
||
reg_file.close() | ||
|
||
return int(content, 16) | ||
|
||
|
||
def __init__(self): | ||
|
||
sfpplus_eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" | ||
|
||
for x in range(self.SFP_PORT_START, self.SFP_PORT_END + 1): | ||
self.port_to_eeprom_mapping[x] = sfpplus_eeprom_path.format(self._sfpp_port_i2c_mapping[x]) | ||
# Get Transceiver status | ||
self.modprs_register = self.get_transceiver_status | ||
|
||
SfpUtilBase.__init__(self) | ||
|
||
def get_presence(self, port_num): | ||
# Check for invalid port_num | ||
if port_num < self.port_start or port_num > self.port_end: | ||
return False | ||
|
||
if port_num < self.SFP_PORT_START : | ||
return False | ||
port_num -= self.SFP_PORT_START | ||
try: | ||
sfp_modprs_path = "/sys/devices/platform/dell-n3248pxe-cpld.0/sfp_modprs" | ||
reg_file = open(sfp_modprs_path) | ||
except IOError as e: | ||
print ("Error: unable to open file: %s" % str(e)) | ||
return False | ||
|
||
content = reg_file.readline().rstrip() | ||
|
||
# content is a string containing the hex representation of the register | ||
reg_value = int(content, 16) | ||
|
||
# Mask off the bit corresponding to our port | ||
mask = (1 << port_num) | ||
|
||
# ModPrsL is active low | ||
if (reg_value & mask) == 0: | ||
return True | ||
|
||
return False | ||
|
||
def get_low_power_mode(self, port_num): | ||
return False | ||
|
||
def set_low_power_mode(self, port_num, lpmode): | ||
return False | ||
|
||
def reset(self, port_num): | ||
return False | ||
|
||
def get_transceiver_change_event(self, timeout=0): | ||
|
||
start_time = time.time() | ||
port = self.SFP_PORT_START | ||
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 | ||
reg_value = self.get_transceiver_status | ||
if reg_value != self.modprs_register: | ||
changed_ports = self.modprs_register ^ reg_value | ||
while port >= self.SFP_PORT_START and port <= self.SFP_PORT_END: | ||
|
||
# Mask off the bit corresponding to our port | ||
mask = (1 << (port - self.SFP_PORT_START)) | ||
|
||
if changed_ports & mask: | ||
# ModPrsL is active low | ||
if reg_value & mask == 0: | ||
self.port_dict[port] = '1' | ||
else: | ||
self.port_dict[port] = '0' | ||
|
||
port += 1 | ||
|
||
# Update reg value | ||
self.modprs_register = reg_value | ||
return True, 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, {} | ||
print ("get_transceiver_change_event: Should not reach here.") | ||
return False, {} |
3 changes: 3 additions & 0 deletions
3
device/dell/x86_64-dellemc_n3248pxe_c3338-r0/pmon_daemon_control.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"skip_ledd": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# libsensors configuration file for Dell N3248TE | ||
# The i2c bus portion is omit because adapter name | ||
# changes every time when system boot up. | ||
|
||
bus "i2c-7" "i2c-0-mux (chan_id 5)" | ||
bus "i2c-5" "i2c-0-mux (chan_id 3)" | ||
bus "i2c-10" "i2c-5-mux (chan_id 0)" | ||
bus "i2c-11" "i2c-5-mux (chan_id 1)" | ||
|
||
chip "tmp75-i2c-7-49" | ||
label temp1 "Switch Near Temperature" | ||
chip "tmp75-i2c-7-4a" | ||
label temp1 "Switch Rear Temperature" | ||
chip "tmp75-i2c-7-4b" | ||
label temp1 "Front Panel PHY Temperature" | ||
chip "tmp75-i2c-7-4c" | ||
label temp1 "Near Front Panel Temperature" | ||
chip "tmp75-i2c-7-4f" | ||
label temp1 "Middle Fan Tray Temperature" | ||
|
||
|
||
chip "emc2305-i2c-7-2c" | ||
ignore fan4 | ||
ignore fan5 | ||
label fan1 "Fan 1 " | ||
label fan2 "Fan 2 " | ||
label fan3 "Fan 3 " | ||
|
||
chip "dps460-i2c-10-5e" | ||
label power1 "Input Power" | ||
label power2 "Output Power" | ||
label curr1 "Input Current" | ||
label curr2 "Output Current" | ||
label in1 "Input Voltage" | ||
ignore in2 | ||
label in3 "Output Voltage" | ||
label fan1 "Fan RPM" | ||
ignore fan2 | ||
ignore fan3 | ||
ignore temp1 | ||
label temp2 "FAN Airflow Temperature" | ||
label temp3 "FAN Normal Temperature" | ||
|
||
|
||
chip "dps460-i2c-11-5e" | ||
label power1 "Input Power" | ||
label power2 "Output Power" | ||
label curr1 "Input Current" | ||
label curr2 "Output Current" | ||
label in1 "Input Voltage" | ||
ignore in2 | ||
label in3 "Output Voltage" | ||
label fan1 "Fan RPM" | ||
ignore fan2 | ||
ignore fan3 | ||
ignore temp1 | ||
label temp2 "FAN Airflow Temperature" | ||
label temp3 "FAN Normal Temperature" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248pxe.init
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#!/bin/bash | ||
|
||
### BEGIN INIT INFO | ||
# Provides: setup-board | ||
# Required-Start: | ||
# Required-Stop: | ||
# Should-Start: | ||
# Should-Stop: | ||
# Default-Start: S | ||
# Default-Stop: 0 6 | ||
# Short-Description: Setup N32xx board. | ||
### END INIT INFO | ||
|
||
case "$1" in | ||
start) | ||
echo -n "Setting up board... " | ||
|
||
/usr/local/bin/n3248pxe_platform.sh init | ||
|
||
echo "done." | ||
;; | ||
|
||
stop) | ||
/usr/local/bin/n3248pxe_platform.sh deinit | ||
echo "done." | ||
|
||
;; | ||
|
||
force-reload|restart) | ||
echo "Not supported" | ||
;; | ||
|
||
*) | ||
echo "Usage: /etc/init.d/platform-modules-n3248pxe.init {start|stop}" | ||
exit 1 | ||
;; | ||
esac | ||
|
||
exit 0 |
12 changes: 12 additions & 0 deletions
12
platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248pxe.install
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
n3248pxe/scripts/n3248pxe_platform.sh usr/local/bin | ||
n3248pxe/scripts/platform_sensors.py usr/local/bin | ||
n3248pxe/scripts/sensors usr/bin | ||
n3248pxe/scripts//portiocfg.py usr/local/bin | ||
n3248pxe/scripts//ports_xcvrd_notify.py usr/local/bin | ||
n3248pxe/systemd/platform-modules-n3248pxe.service etc/systemd/system | ||
n3248pxe/cfg/n3248pxe-modules.conf etc/modules-load.d | ||
common/dell_i2c_utils.sh usr/local/bin | ||
n3248pxe/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-dellemc_n3248pxe_c3338-r0 | ||
common/platform_reboot usr/share/sonic/device/x86_64-dellemc_n3248pxe_c3338-r0 | ||
common/fw-updater usr/local/bin | ||
common/onie_mode_set usr/local/bin |
7 changes: 7 additions & 0 deletions
7
platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-n3248pxe.postinst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# postinst script for n3248pxe | ||
|
||
# Enable Dell-n3248pxe-platform-service | ||
depmod -a | ||
systemctl enable platform-modules-n3248pxe.service | ||
systemctl start platform-modules-n3248pxe.service | ||
#DEBHELPER# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
platform/broadcom/sonic-platform-modules-dell/n3248pxe/cfg/n3248pxe-modules.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# /etc/modules: kernel modules to load at boot time. | ||
# | ||
# This file contains the names of kernel modules that should be loaded | ||
# at boot time, one per line. Lines beginning with "#" are ignored. | ||
|
||
i2c-isch | ||
i2c-ismt | ||
i2c-dev | ||
i2c-mux | ||
i2c-smbus | ||
|
||
i2c-mux-pca954x | ||
dell_n3248pxe_platform | ||
|
2 changes: 2 additions & 0 deletions
2
platform/broadcom/sonic-platform-modules-dell/n3248pxe/modules/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
obj-m := dell_n3248pxe_platform.o emc2305.o | ||
|
1,207 changes: 1,207 additions & 0 deletions
1,207
platform/broadcom/sonic-platform-modules-dell/n3248pxe/modules/dell_n3248pxe_platform.c
Large diffs are not rendered by default.
Oops, something went wrong.
877 changes: 877 additions & 0 deletions
877
platform/broadcom/sonic-platform-modules-dell/n3248pxe/modules/emc2305.c
Large diffs are not rendered by default.
Oops, something went wrong.
425 changes: 425 additions & 0 deletions
425
platform/broadcom/sonic-platform-modules-dell/n3248pxe/modules/pmbus.h
Large diffs are not rendered by default.
Oops, something went wrong.
78 changes: 78 additions & 0 deletions
78
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/fancontrol.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
#! /bin/sh | ||
|
||
### BEGIN INIT INFO | ||
# Provides: fancontrol | ||
# Required-Start: $remote_fs | ||
# Required-Stop: $remote_fs | ||
# Default-Start: 2 3 4 5 | ||
# Default-Stop: | ||
# Short-Description: fancontrol | ||
# Description: fan speed regulator | ||
### END INIT INFO | ||
|
||
. /lib/lsb/init-functions | ||
|
||
[ -f /etc/default/rcS ] && . /etc/default/rcS | ||
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin | ||
DAEMON=/usr/local/bin/fancontrol | ||
DESC="fan speed regulator" | ||
NAME="fancontrol" | ||
PIDFILE=/var/run/fancontrol.pid | ||
PLATFORMPATH=/sys/devices/platform/LPC | ||
MAIN_CONF=/usr/share/sonic/device/x86_64-dell_s3000_c2338-r0/fancontrol | ||
DEVPATH=/sys/devices/pci0000:00/0000:00:13.0/i2c-0/i2c-8/i2c-23/23-004d | ||
|
||
test -x $DAEMON || exit 0 | ||
|
||
for i in 1 2 3 | ||
do | ||
j=$i | ||
[ $i -eq 3 ] && j=4 | ||
FANFAULT=$(cat ${DEVPATH}/fan${j}_fault) | ||
[ $FANFAULT = 1 ] && continue | ||
FANDIR=$(cat ${PLATFORMPATH}/fan${i}_dir) | ||
done | ||
CONF=${MAIN_CONF}-${FANDIR} | ||
|
||
case "$1" in | ||
start) | ||
if [ -f $CONF ] ; then | ||
if $DAEMON --check $CONF 1>/dev/null 2>/dev/null ; then | ||
log_daemon_msg "Starting $DESC" "$NAME\n" | ||
start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON $CONF | ||
log_end_msg $? | ||
else | ||
log_failure_msg "Not starting fancontrol, broken configuration file; please re-run pwmconfig." | ||
fi | ||
else | ||
if [ "$VERBOSE" != no ]; then | ||
log_warning_msg "Not starting fancontrol; run pwmconfig first." | ||
fi | ||
fi | ||
;; | ||
stop) | ||
log_daemon_msg "Stopping $DESC" "$NAME" | ||
start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --startas $DAEMON $CONF | ||
rm -f $PIDFILE | ||
log_end_msg $? | ||
;; | ||
restart) | ||
$0 stop | ||
sleep 3 | ||
$0 start | ||
;; | ||
force-reload) | ||
if start-stop-daemon --stop --test --quiet --pidfile $PIDFILE --startas $DAEMON $CONF ; then | ||
$0 restart | ||
fi | ||
;; | ||
status) | ||
status_of_proc $DAEMON $NAME $CONF && exit 0 || exit $? | ||
;; | ||
*) | ||
log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload|status}" | ||
exit 1 | ||
;; | ||
esac | ||
|
||
exit 0 |
141 changes: 141 additions & 0 deletions
141
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/n3248pxe_platform.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
#!/bin/bash | ||
|
||
#platform init script for Dell n3248pxe | ||
|
||
source dell_i2c_utils.sh | ||
|
||
#Attach/Detach the system devices | ||
sys_devices() { | ||
case $1 in | ||
"new_device") #syseeprom | ||
i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-2/$1" | ||
#Attach Fan Controller | ||
i2c_config "echo emc2305 0x2c > /sys/bus/i2c/devices/i2c-7/$1" | ||
#Attach temperature monitor | ||
i2c_config "echo tmp75 0x49 > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo tmp75 0x4a > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo tmp75 0x4b > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo tmp75 0x4c > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo tmp75 0x4f > /sys/bus/i2c/devices/i2c-7/$1" | ||
#Attach PSU Controller | ||
i2c_config "echo dps460 0x5e > /sys/bus/i2c/devices/i2c-10/$1" | ||
i2c_config "echo dps460 0x5e > /sys/bus/i2c/devices/i2c-11/$1" | ||
#Attach PSU EEPROM | ||
i2c_config "echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-10/$1" | ||
i2c_config "echo 24c02 0x56 > /sys/bus/i2c/devices/i2c-11/$1" | ||
#Attach Fan EEPROM | ||
i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-15/$1" | ||
i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-16/$1" | ||
i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-17/$1" | ||
;; | ||
"delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-2/$1" | ||
i2c_config "echo 0x2c > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x49 > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x4a > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x4b > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x4c > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x4f > /sys/bus/i2c/devices/i2c-7/$1" | ||
i2c_config "echo 0x5e > /sys/bus/i2c/devices/i2c-10/$1" | ||
i2c_config "echo 0x5e > /sys/bus/i2c/devices/i2c-11/$1" | ||
i2c_config "echo 0x56 > /sys/bus/i2c/devices/i2c-10/$1" | ||
i2c_config "echo 0x56 > /sys/bus/i2c/devices/i2c-11/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-15/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-16/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-17/$1" | ||
;; | ||
*) echo "n3248pxe_platform: main_board_mux : invalid command !" | ||
;; | ||
esac | ||
} | ||
|
||
#Attach/Detach the SFP modules on PCA9548_2 | ||
switch_board_sfp() { | ||
case $1 in | ||
"new_device") i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-20/$1" | ||
i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-21/$1" | ||
i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-22/$1" | ||
i2c_config "echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-23/$1" | ||
;; | ||
"delete_device") i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-20/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-21/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-22/$1" | ||
i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-23/$1" | ||
;; | ||
*) echo "n3248pxe_platform: switch_board_sfp: invalid command !" | ||
;; | ||
esac | ||
} | ||
|
||
#Forcibly bring quad-port phy out of reset for 48-1G port functionality | ||
|
||
platform_firmware_versions() { | ||
|
||
FIRMWARE_VERSION_FILE=/var/log/firmware_versions | ||
rm -rf ${FIRMWARE_VERSION_FILE} | ||
# Get BIOS version | ||
echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE | ||
# Get CPU CPLD version | ||
echo "CPU CPLD: $((`cat /sys/devices/platform/dell-n3248pxe-cpld.0/cpu_cpld_mjr_ver`)).$((`cat /sys/devices/platform/dell-n3248pxe-cpld.0/cpu_cpld_mnr_ver`))" >> $FIRMWARE_VERSION_FILE | ||
# Get SYS CPLD version | ||
echo "SYS CPLD: $((`cat /sys/devices/platform/dell-n3248pxe-cpld.0/sys_cpld_mjr_ver`)).$((`cat /sys/devices/platform/dell-n3248pxe-cpld.0/sys_cpld_mnr_ver`))" >> $FIRMWARE_VERSION_FILE | ||
|
||
} | ||
|
||
install_python_api_package() { | ||
device="/usr/share/sonic/device" | ||
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform) | ||
|
||
rv=$(pip3 install $device/$platform/sonic_platform-1.0-py3-none-any.whl) | ||
} | ||
|
||
remove_python_api_package() { | ||
rv=$(pip show sonic-platform > /dev/null 2>/dev/null) | ||
|
||
rv=$(pip3 show sonic-platform > /dev/null 2>/dev/null) | ||
if [ $? -eq 0 ]; then | ||
rv=$(pip3 uninstall -y sonic-platform > /dev/null 2>/dev/null) | ||
fi | ||
} | ||
|
||
get_reboot_cause() { | ||
REBOOT_REASON_FILE="/host/reboot-cause/platform/reboot_reason" | ||
mkdir -p $(dirname $REBOOT_REASON_FILE) | ||
|
||
# Handle First Boot into software version with reboot cause determination support | ||
if [[ ! -e $REBOOT_REASON_FILE ]]; then | ||
echo "0x0" > $REBOOT_REASON_FILE | ||
else | ||
cat /sys/devices/platform/dell-n3248pxe-cpld.0/reboot_cause > $REBOOT_REASON_FILE | ||
fi | ||
} | ||
|
||
|
||
if [[ "$1" == "init" ]]; then | ||
modprobe i2c-dev | ||
modprobe i2c-mux-pca954x force_deselect_on_exit=1 | ||
modprobe pmbus | ||
modprobe emc2305 | ||
modprobe dps200 | ||
modprobe dell_n3248pxe_platform | ||
|
||
sys_devices "new_device" | ||
get_reboot_cause | ||
switch_board_sfp "new_device" | ||
echo 0xf0 > /sys/devices/platform/dell-n3248pxe-cpld.0/sfp_txdis | ||
install_python_api_package | ||
platform_firmware_versions | ||
elif [[ "$1" == "deinit" ]]; then | ||
switch_board_sfp "delete_device" | ||
sysdevices "delete_device" | ||
|
||
modprobe -r dell_n3248pxe_platform | ||
|
||
modprobe -r dps200 | ||
modprobe -r emc2305 | ||
modprobe -r pmbus | ||
modprobe -r i2c-mux-pca954x | ||
modprobe -r i2c-dev | ||
remove_python_api_package | ||
else | ||
echo "n3248pxe_platform : Invalid option !" | ||
fi |
135 changes: 135 additions & 0 deletions
135
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/platform_sensors.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#!/usr/bin/python | ||
# This provies support for the following objects: | ||
# * Onboard temperature sensors | ||
# * FAN trays | ||
# * PSU | ||
|
||
import subprocess | ||
|
||
output = "" | ||
try: | ||
rc = 0 | ||
output = subprocess.check_output('/usr/bin/sensors').splitlines() | ||
|
||
valid = False | ||
for line in output: | ||
if line.startswith(b'acpitz') or line.startswith(b'coretemp'): | ||
valid = True | ||
if valid: | ||
print (line) | ||
if line == '': valid = False | ||
|
||
print ("Onboard Temperature Sensors:") | ||
idx = 0 | ||
for line in output: | ||
if line.startswith(b'tmp75'): | ||
print ('\t' + output[idx+2].split('(')[0]) | ||
idx += 1 | ||
|
||
print ("\nFanTrays:") | ||
idx = 0 | ||
found_emc = False | ||
for line in output: | ||
if line.startswith(b'emc'): | ||
found_emc = True | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan0_prs') as f: | ||
line = f.readline() | ||
present = int(line, 0) | ||
if present : | ||
print ('\t' + 'FanTray1:') | ||
print ('\t\t' + 'Fan Speed:' + (output[idx+2].split('(')[0]).split(':')[1]) | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan0_dir') as f: | ||
line = f.readline() | ||
dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust' | ||
print ('\t\t' + 'Airflow:\t' + dir) | ||
else : print ('\t' + 'FanTray1:\tNot Present') | ||
|
||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan1_prs') as f: | ||
line = f.readline() | ||
present = int(line, 0) | ||
if present : | ||
print ('\t' + 'FanTray2:') | ||
print ('\t\t' + 'Fan Speed:' + (output[idx+3].split('(')[0]).split(':')[1]) | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan1_dir') as f: | ||
line = f.readline() | ||
dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust' | ||
print ('\t\t' + 'Airflow:\t' + dir) | ||
else : print ('\t' + 'FanTray2:\tNot Present') | ||
|
||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan2_prs') as f: | ||
line = f.readline() | ||
present = int(line, 0) | ||
if present : | ||
print ('\t' + 'FanTray3:') | ||
print ('\t\t' + 'Fan Speed:' + (output[idx+4].split('(')[0]).split(':')[1]) | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/fan2_dir') as f: | ||
line = f.readline() | ||
dir = 'Intake' if line[:-1] == 'B2F' else 'Exhaust' | ||
print ('\t\t' + 'Airflow:\t' + dir) | ||
else : print ('\t' + 'FanTray3:\tNot Present') | ||
idx += 1 | ||
if not found_emc : | ||
print ('\t' + 'FanTray1:\tNot Present') | ||
print ('\t' + 'FanTray2:\tNot Present') | ||
print ('\t' + 'FanTray3:\tNot Present') | ||
|
||
print ('\nPSUs:') | ||
idx = 0 | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/psu0_prs') as f: | ||
line = f.readline() | ||
found_psu1 = int(line, 0) | ||
if not found_psu1 : | ||
print ('\tPSU1:\tNot Present') | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/psu1_prs') as f: | ||
line = f.readline() | ||
found_psu2 = int(line, 0) | ||
for line in output: | ||
if line.startswith(b'dps460-i2c-10'): | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/psu0_status') as f: | ||
line = f.readline() | ||
status = int(line, 0) | ||
if not status : | ||
print ('\tPSU1:\tNot OK') | ||
break | ||
with open('/sys/bus/i2c/devices/10-0056/eeprom') as f: | ||
line = f.readline() | ||
dir = 'Exhaust' if 'FORWARD' in line else 'Intake' | ||
print ('\tPSU1:') | ||
print ('\t\t' + output[idx+2].split('(')[0]) | ||
print ('\t\t' + output[idx+4].split('(')[0]) | ||
print ('\t\t' + output[idx+6].split('(')[0]) | ||
print ('\t\t' + output[idx+7].split('(')[0]) | ||
print ('\t\t' + output[idx+9].split('(')[0]) | ||
print ('\t\t' + output[idx+11].split('(')[0]) | ||
print ('\t\t' + output[idx+12].split('(')[0]) | ||
print ('\t\t' + output[idx+14].split('(')[0]) | ||
print ('\t\t' + output[idx+15].split('(')[0]) | ||
print ('\t\t' + 'Airflow:\t\t ' + dir) | ||
if line.startswith(b'dps460-i2c-11'): | ||
with open('/sys/devices/platform/dell-n3248pxe-cpld.0/psu1_status') as f: | ||
line = f.readline() | ||
status = int(line, 0) | ||
if not status : | ||
print ('\tPSU2:\tNot OK') | ||
break | ||
print ('\tPSU2:') | ||
with open('/sys/bus/i2c/devices/11-0056/eeprom') as f: | ||
line = f.readline() | ||
dir = 'Exhaust' if 'FORWARD' in line else 'Intake' | ||
print ('\t\t' + output[idx+2].split('(')[0]) | ||
print ('\t\t' + output[idx+4].split('(')[0]) | ||
print ('\t\t' + output[idx+6].split('(')[0]) | ||
print ('\t\t' + output[idx+7].split('(')[0]) | ||
print ('\t\t' + output[idx+9].split('(')[0]) | ||
print ('\t\t' + output[idx+11].split('(')[0]) | ||
print ('\t\t' + output[idx+12].split('(')[0]) | ||
print ('\t\t' + output[idx+14].split('(')[0]) | ||
print ('\t\t' + output[idx+15].split('(')[0]) | ||
print ('\t\t' + 'Airflow:\t\t ' + dir) | ||
idx += 1 | ||
if not found_psu2 : | ||
print ('\tPSU2:\tNot Present') | ||
|
||
except subprocess.CalledProcessError as err: | ||
print ("Exception when calling get_sonic_error -> %s\n" %(err)) | ||
rc = err.returncode |
105 changes: 105 additions & 0 deletions
105
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/portiocfg.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/usr/bin/python | ||
# Copyright (c) 2015 Dell Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
# not use this file except in compliance with the License. You may obtain | ||
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR | ||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT | ||
# LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS | ||
# FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. | ||
# | ||
# See the Apache Version 2.0 License for specific language governing | ||
# permissions and limitations under the License. | ||
#Script to read/write the portio based registers | ||
|
||
import sys | ||
import os | ||
import getopt | ||
import struct | ||
|
||
resource='/dev/port' | ||
|
||
def usage(): | ||
''' This is the Usage Method ''' | ||
|
||
print ('\t\t portiocfg.py --default') | ||
print ('\t\t portiocfg.py --get --offset <offset>') | ||
print ('\t\t portiocfg.py --set --val <val> --offset <offset>') | ||
sys.exit(1) | ||
|
||
def portio_reg_read(resource,offset): | ||
fd=os.open(resource, os.O_RDONLY) | ||
if(fd<0): | ||
print ('file open failed %s"%resource') | ||
return | ||
if(os.lseek(fd, offset, os.SEEK_SET) != offset): | ||
print ('lseek failed on %s'%resource) | ||
return | ||
buf=os.read(fd,1) | ||
reg_val1=ord(buf) | ||
print ('reg value %x'%reg_val1) | ||
os.close(fd) | ||
|
||
def portio_reg_write(resource,offset,val): | ||
fd=os.open(resource,os.O_RDWR) | ||
if(fd<0): | ||
print ('file open failed %s"%resource') | ||
return | ||
if(os.lseek(fd, offset, os.SEEK_SET) != offset): | ||
print ('lseek failed on %s'%resource) | ||
return | ||
ret=os.write(fd,struct.pack('B',val)) | ||
if(ret != 1): | ||
print ('write failed %d'%ret) | ||
return | ||
os.close(fd) | ||
|
||
def main(argv): | ||
|
||
''' The main function will read the user input from the | ||
command line argument and process the request ''' | ||
|
||
opts = '' | ||
val = '' | ||
choice = '' | ||
offset = '' | ||
|
||
try: | ||
opts, args = getopt.getopt(argv, "hgs:" , \ | ||
["val=","offset=","help", "get", "set"]) | ||
|
||
except getopt.GetoptError: | ||
usage() | ||
|
||
for opt,arg in opts: | ||
|
||
if opt in ('-h','--help'): | ||
choice = 'help' | ||
|
||
elif opt in ('-g', '--get'): | ||
choice = 'get' | ||
|
||
elif opt in ('-s', '--set'): | ||
choice = 'set' | ||
|
||
elif opt == '--offset': | ||
offset = int(arg,16) | ||
|
||
elif opt == '--val': | ||
val = int(arg,16) | ||
|
||
if choice == 'get' and offset != '': | ||
portio_reg_read(resource,offset) | ||
|
||
elif choice == 'set' and offset != '' and val != '': | ||
portio_reg_write(resource,offset,val) | ||
|
||
else: | ||
usage() | ||
|
||
#Calling the main method | ||
if __name__ == "__main__": | ||
main(sys.argv[1:]) | ||
|
107 changes: 107 additions & 0 deletions
107
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/ports_xcvrd_notify.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env python2 | ||
|
||
""" | ||
port_notify | ||
port notify status change for SONiC | ||
""" | ||
|
||
try: | ||
from datetime import datetime | ||
from swsscommon import swsscommon | ||
from sonic_py_common import daemon_base, logger | ||
except ImportError as e: | ||
raise ImportError (str(e) + " - required module not found") | ||
|
||
# | ||
# Constants ==================================================================== | ||
# | ||
|
||
SYSLOG_IDENTIFIER = "port_notify" | ||
|
||
|
||
STATE_PORT_TABLE = 'PORT_TABLE' | ||
|
||
|
||
RJ45_PORT_START = 0; | ||
RJ45_PORT_END = 47; | ||
|
||
# Global logger class instance | ||
helper_logger = logger.Logger(SYSLOG_IDENTIFIER) | ||
|
||
XCVR_STATE_EMPTY = 0 | ||
XCVR_STATE_ERROR = 1 | ||
XCVR_STATE_INCOMP = 2 | ||
XCVR_STATE_CONFIG = 3 | ||
XCVR_STATE_READY = 4 | ||
XCVR_STATE_TIMEOUT = 5 | ||
|
||
xcvr_state_tbl = { | ||
XCVR_STATE_EMPTY: { "xcvr_state": "N/A", "xcvr_app_status": "down" }, | ||
XCVR_STATE_ERROR: { "xcvr_state": "Error", "xcvr_app_status": "down" }, | ||
XCVR_STATE_INCOMP: { "xcvr_state": "Incompatible", "xcvr_app_status": "up" }, | ||
XCVR_STATE_CONFIG: { "xcvr_state": "Config", "xcvr_app_status": "down" }, | ||
XCVR_STATE_TIMEOUT: { "xcvr_state": "Timeout", "xcvr_app_status": "up" }, | ||
XCVR_STATE_READY: { "xcvr_state": "Ready", "xcvr_app_status": "up" } | ||
} | ||
|
||
# Wait for port init is done | ||
def wait_for_port_init_done(): | ||
# Connect to APPL_DB and subscribe to PORT table notifications | ||
appl_db = daemon_base.db_connect("APPL_DB") | ||
|
||
sel = swsscommon.Select() | ||
sst = swsscommon.SubscriberStateTable(appl_db, swsscommon.APP_PORT_TABLE_NAME) | ||
sel.addSelectable(sst) | ||
|
||
# Make sure this daemon started after all port configured | ||
while True: | ||
(state, c) = sel.select(1000) | ||
if state == swsscommon.Select.TIMEOUT: | ||
continue | ||
if state != swsscommon.Select.OBJECT: | ||
helper_logger.log_warning("sel.select() did not return swsscommon.Select.OBJECT") | ||
continue | ||
|
||
(key, op, fvp) = sst.pop() | ||
|
||
# Wait until PortInitDone | ||
if key in ["PortInitDone"]: | ||
break | ||
|
||
def notify_port_xcvr_status(port_name, app_status_port_tbl, state_port_tbl, flag): | ||
|
||
fvs = swsscommon.FieldValuePairs([("xcvr_status", xcvr_state_tbl[flag]["xcvr_app_status"])]) | ||
tm = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | ||
state_fvs = swsscommon.FieldValuePairs([("xcvr_status", xcvr_state_tbl[flag]["xcvr_state"]), ("xcvr_time", tm)]) | ||
|
||
state_port_tbl.set(port_name, state_fvs) | ||
|
||
app_status_port_tbl.set(port_name, fvs) | ||
|
||
helper_logger.log_notice("Port {} xcvr_app_status change to {}".format(port_name, xcvr_state_tbl[flag]["xcvr_app_status"])) | ||
return True | ||
|
||
|
||
def main(): | ||
helper_logger.log_notice("Start port_notify") | ||
# Connect to APP_DB and create transceiver dom info table | ||
appl_db = daemon_base.db_connect("APPL_DB") | ||
|
||
app_status_port_tbl = swsscommon.ProducerStateTable(appl_db, | ||
swsscommon.APP_PORT_APP_STATUS_TABLE_NAME) | ||
|
||
state_db = daemon_base.db_connect("STATE_DB") | ||
state_port_tbl = swsscommon.Table(state_db, STATE_PORT_TABLE) | ||
|
||
# Wait for PortInitDone | ||
wait_for_port_init_done() | ||
|
||
for port in range(RJ45_PORT_START, RJ45_PORT_END+1): | ||
#print "Ethernet{}".format(port) | ||
notify_port_xcvr_status("Ethernet{}".format(port), app_status_port_tbl, state_port_tbl, XCVR_STATE_READY) | ||
|
||
helper_logger.log_notice("End port_notify") | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
8 changes: 8 additions & 0 deletions
8
platform/broadcom/sonic-platform-modules-dell/n3248pxe/scripts/sensors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/bash | ||
#docker exec -i pmon sensors "$@" | ||
docker exec -i pmon /usr/bin/platform_sensors.py "$@" | ||
|
||
#To probe sensors not part of lm-sensors | ||
#if [ -r /usr/local/bin/platform_sensors.py ]; then | ||
# python /usr/local/bin/platform_sensors.py | ||
#fi |
1 change: 1 addition & 0 deletions
1
platform/broadcom/sonic-platform-modules-dell/n3248pxe/setup.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../s6100/setup.py |
8 changes: 8 additions & 0 deletions
8
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
""" | ||
Module sonic_platform provides the platform dependent population of | ||
platform.py, chassis.py, component.py, sfp.py, thermal.py, psu.py, | ||
fan.py and watchdog.py | ||
""" | ||
__all__ = ["platform", "chassis", "sfp", "eeprom", "component", "thermal", "psu", "fan", "fan_drawer", "watchdog"] | ||
from sonic_platform import * | ||
|
344 changes: 344 additions & 0 deletions
344
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/chassis.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,344 @@ | ||
#!/usr/bin/env python | ||
|
||
############################################################################# | ||
# DELLEMC N3248PXE | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the platform information | ||
# | ||
############################################################################# | ||
|
||
try: | ||
import os | ||
import sys | ||
import time | ||
from sonic_platform_base.chassis_base import ChassisBase | ||
from sonic_platform.sfp import Sfp | ||
from sonic_platform.eeprom import Eeprom | ||
from sonic_platform.component import Component | ||
from sonic_platform.psu import Psu | ||
from sonic_platform.thermal import Thermal | ||
from sonic_platform.watchdog import Watchdog | ||
from sonic_platform.fan import Fan | ||
from sonic_platform.fan_drawer import FanDrawer | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
MAX_N3248PXE_FANTRAY = 3 | ||
MAX_N3248PXE_FAN = 1 | ||
MAX_N3248PXE_PSU = 2 | ||
MAX_N3248PXE_THERMAL = 5 | ||
MAX_N3248PXE_COMPONENT = 3 # BIOS, CPU CPLD and SYS CPLD | ||
|
||
media_part_num_list = set([ \ | ||
"8T47V","XTY28","MHVPK","GF76J","J6FGD","F1KMV","9DN5J","H4DHD","6MCNV","0WRX0","X7F70","5R2PT","WTRD1","WTRD1","WTRD1","WTRD1","5250G","WTRD1","C5RNH","C5RNH","FTLX8571D3BCL-FC", | ||
"C5RNH","5250G","N8TDR","7D64H","7D64H","RN84N","RN84N","HMTNW","6K3Y6","6K3Y6","TY5FM","50M0R","PGYJT","WP2PP","85Y13","1HCGH","FP9R1","FYD0M","C6Y7M","C6Y7M","V250M","V250M", | ||
"5CWK6","5CWK6","53HVN","53HVN","358VV","358VV","MV799","MV799","YJF03","P9GND","T1KCN","1DXKP","MT7R2","K0T7R","W5G04","7TCDN","7TCDN","7TCDN","7TCDN","7TCDN","V3XJK","0MV31", | ||
"5FVP7","N6KM9","C41MF","77KC3","XW7J0","V4NJV","2XJHY","H93DH","H93DH","F8CG0","F8CG0","F8CG0","119N6","WFMF5","794RX","288F6","1M31V","1M31V","5NP8R","5NP8R","4TC09","4TC09", | ||
"FC6KV","FC6KV","J90VN","J90VN","05RH0","05RH0","YDN52","0C2YV","YDN52","0C2YV","9JT65","D7M6H","6GW14","FYVFW","0VF5H","P4YPY","P4YPY","TCPM2","TCPM2","JNPF8","JNPF8","27GG5", | ||
"27GG5","P8T4W","P8T4W","JR54Y","M6N0J","XJYD0","K44H9","035KG","P7C7N","76V43","3CC35","FN4FC","26FN3","YFNDD","YFNDD","7R9N9","035KG","P7C7N","76V43","3CC35","PLRXPLSCS43811", | ||
"FN4FC","26FN3","YFNDD","YFNDD","7R9N9","G86YJ","V407F","V407F","9KH6T","G86YJ","V407F","9KH6T","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY","9X8JP","2JVDD","D0R73","VXFJY", | ||
"9X8JP","GMFC5","GMFC5","GMFC5","D7P80","3MFXG","3MFXG","0GWXJ","THPF3","THPF3","THPF3","THPF3","THPF3","PJ62G","3XCX1","JJYKG","RRRTK","16K56","86JM2","K5R6C","7MG2C","WTPPN","9HTT2", | ||
"NKM4F","VXGGG","JC9W6","6MR8M","RP3GV","M5PPJ","XKY55","TKCXT","05J8P","5WGKD","XFDRT","NW8DM","YPKH3","5WGKD","XFDRT","NW8DM","YPKH3","71XXK","MVCX6","0XYP6","HPPVW","3GHRT","71XXK", | ||
"MVCX6","0XYP6","HPPVW","3GHRT","2X5T6","135V2","KD5MV","2X5T6","KD5MV","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","HHFK0","3YWG7","5CMT2","RCVP5","X5DH4","3YWG7","5CMT2","RCVP5","X5DH4", | ||
"4WJ41","4WJ41","14NV5","14NV5","14NV5","4WGYD","YKMH7","X7CCC","X7CCC","0X9CT","0CY8V","P7D7R","W4GPP","W4GPP","W4GPP","HHHCHC","07RN7","07RN7","0YR96","0YR96","JCYM9","FTLX8571D3BCL", | ||
"DDW0X","VPFDJ","229KM","9FC7D","DDW0X","VPFDJ","6FMR5","J7K20","N3K9W","6FMR5","8R4VM","7VN5T","D9YM8","8R4VM","VYXPW","87TPX","WY6FK","VYXPW","87TPX","WY6FK","WG8C4","N8K82","2DV6Y", | ||
"77C3C","RC0HM","77C3C","RC0HM","JHXTN","3P3PG","92YVM","4VX5M","4VX5M","6RRGD","W4JWV","22V6R","XR11M","9GMDY","JMCWK","TP2F0","6MGDY","78RHK", "C0TP5","0WDNV","FCLF8522P2BTL"\ | ||
]) | ||
class Chassis(ChassisBase): | ||
""" | ||
DELLEMC Platform-specific Chassis class | ||
""" | ||
CPLD_DIR = '/sys/devices/platform/dell-n3248pxe-cpld.0/' | ||
|
||
_global_port_pres_dict = {} | ||
|
||
_sfpp_port_to_i2c_mapping = { | ||
49: 20, | ||
50: 21, | ||
51: 22, | ||
52: 23, | ||
53: 24, | ||
54: 25, | ||
} | ||
|
||
def __init__(self): | ||
ChassisBase.__init__(self) | ||
# sfp.py will read eeprom contents and retrive the eeprom data. | ||
# We pass the eeprom path from chassis.py | ||
self.PORT_START = 1 | ||
self.PORT_END = 54 | ||
self.PORTS_IN_BLOCK = (self.PORT_END + 1) | ||
self.SFP_PORT_START = 49 | ||
self._sfp_port = range(self.SFP_PORT_START, self.PORTS_IN_BLOCK) | ||
eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom" | ||
for index in range(self.PORT_START, self.PORTS_IN_BLOCK): | ||
eeprom_path = '' | ||
if index in self._sfp_port: | ||
eeprom_path = eeprom_base.format(self._sfpp_port_to_i2c_mapping[index]) | ||
sfp_node = Sfp(index, 'SFP', eeprom_path) | ||
self._sfp_list.append(sfp_node) | ||
|
||
self._eeprom = Eeprom() | ||
self._watchdog = Watchdog() | ||
self._num_sfps = 54 | ||
self._num_fans = MAX_N3248PXE_FANTRAY * MAX_N3248PXE_FAN | ||
self._fan_list = [Fan(i, j) for i in range(MAX_N3248PXE_FANTRAY) \ | ||
for j in range(MAX_N3248PXE_FAN)] | ||
for k in range(MAX_N3248PXE_FANTRAY): | ||
fandrawer = FanDrawer(k) | ||
self._fan_drawer_list.append(fandrawer) | ||
self._fan_list.extend(fandrawer._fan_list) | ||
|
||
self._psu_list = [Psu(i) for i in range(MAX_N3248PXE_PSU)] | ||
self._thermal_list = [Thermal(i) for i in range(MAX_N3248PXE_THERMAL)] | ||
self._component_list = [Component(i) for i in range(MAX_N3248PXE_COMPONENT)] | ||
for port_num in self._sfp_port: | ||
# sfp get uses zero-indexing, but port numbers start from 1 | ||
presence = self.get_sfp(port_num).get_presence() | ||
self._global_port_pres_dict[port_num] = '1' if presence else '0' | ||
|
||
self._watchdog = Watchdog() | ||
self.locator_led_reg = "locator_led" | ||
self.LOCATOR_LED_ON = "blink_blue" | ||
self.LOCATOR_LED_OFF = self.STATUS_LED_COLOR_OFF | ||
|
||
def _get_cpld_register(self, reg_name): | ||
# On successful read, returns the value read from given | ||
# reg name and on failure rethrns 'ERR' | ||
cpld_reg_file = self.CPLD_DIR + '/' + reg_name | ||
try: | ||
rv = open(cpld_reg_file, 'r').read() | ||
except IOError : return 'ERR' | ||
return rv.strip('\r\n').lstrip(' ') | ||
|
||
def _set_cpld_register(self, reg_name, value): | ||
# On successful write, returns the value will be written on | ||
# reg_name and on failure returns 'ERR' | ||
rv = 'ERR' | ||
cpld_reg_file = self.CPLD_DIR + '/' + reg_name | ||
|
||
if (not os.path.isfile(cpld_reg_file)): | ||
return rv | ||
|
||
try: | ||
with open(cpld_reg_file, 'w') as fd: | ||
rv = fd.write(str(value)) | ||
except Exception: | ||
rv = 'ERR' | ||
|
||
return rv | ||
|
||
# check for this event change for sfp / do we need to handle timeout/sleep | ||
|
||
def get_change_event(self, timeout=0): | ||
""" | ||
Returns a nested dictionary containing all devices which have | ||
experienced a change at chassis level | ||
""" | ||
port_dict = {} | ||
change_dict = {} | ||
change_dict['sfp'] = port_dict | ||
while True: | ||
for port_num in self._sfp_port: | ||
# sfp get uses zero-indexing, but port numbers start from 1 | ||
presence = self.get_sfp(port_num).get_presence() | ||
if(presence and self._global_port_pres_dict[port_num] == '0'): | ||
self._global_port_pres_dict[port_num] = '1' | ||
port_dict[port_num] = '1' | ||
elif(not presence and self._global_port_pres_dict[port_num] == '1'): | ||
self._global_port_pres_dict[port_num] = '0' | ||
port_dict[port_num] = '0' | ||
|
||
if(len(port_dict) > 0): | ||
return True, change_dict | ||
|
||
time.sleep(0.5) | ||
|
||
|
||
|
||
def get_sfp(self, index): | ||
""" | ||
Retrieves sfp represented by (0-based) index <index> | ||
Args: | ||
index: An integer, the index (0-based) of the sfp to retrieve. | ||
The index should be the sequence of a physical port in a chassis, | ||
starting from 0. | ||
For example, 0 for Ethernet0, 1 for Ethernet4 and so on. | ||
Returns: | ||
An object dervied from SfpBase representing the specified sfp | ||
""" | ||
sfp = None | ||
|
||
try: | ||
# The index will start from 0 | ||
sfp = self._sfp_list[index-1] | ||
except IndexError: | ||
sys.stderr.write("SFP index {} out of range (0-{})\n".format( | ||
index, len(self._sfp_list)-1)) | ||
return sfp | ||
|
||
def get_name(self): | ||
""" | ||
Retrieves the name of the chassis | ||
Returns: | ||
string: The name of the chassis | ||
""" | ||
return self._eeprom.modelstr().decode() | ||
|
||
def get_presence(self): | ||
""" | ||
Retrieves the presence of the chassis | ||
Returns: | ||
bool: True if chassis is present, False if not | ||
""" | ||
return True | ||
|
||
def get_model(self): | ||
""" | ||
Retrieves the model number (or part number) of the chassis | ||
Returns: | ||
string: Model/part number of chassis | ||
""" | ||
return self._eeprom.part_number_str() | ||
|
||
def get_serial(self): | ||
""" | ||
Retrieves the serial number of the chassis (Service tag) | ||
Returns: | ||
string: Serial number of chassis | ||
""" | ||
return self._eeprom.serial_str() | ||
|
||
def get_status(self): | ||
""" | ||
Retrieves the operational status of the chassis | ||
Returns: | ||
bool: A boolean value, True if chassis is operating properly | ||
False if not | ||
""" | ||
return True | ||
|
||
def get_base_mac(self): | ||
""" | ||
Retrieves the base MAC address for the chassis | ||
Returns: | ||
A string containing the MAC address in the format | ||
'XX:XX:XX:XX:XX:XX' | ||
""" | ||
return self._eeprom.base_mac_addr('') | ||
|
||
def get_serial_number(self): | ||
""" | ||
Retrieves the hardware serial number for the chassis | ||
Returns: | ||
A string containing the hardware serial number for this chassis. | ||
""" | ||
return self._eeprom.serial_number_str() | ||
|
||
def get_system_eeprom_info(self): | ||
""" | ||
Retrieves the full content of system EEPROM information for the chassis | ||
Returns: | ||
A dictionary where keys are the type code defined in | ||
OCP ONIE TlvInfo EEPROM format and values are their corresponding | ||
values. | ||
""" | ||
return self._eeprom.system_eeprom_info() | ||
|
||
def get_reboot_cause(self): | ||
""" | ||
Retrieves the cause of the previous reboot | ||
Returns: | ||
A tuple (string, string) where the first element is a string | ||
containing the cause of the previous reboot. This string must be | ||
one of the predefined strings in this class. If the first string | ||
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used | ||
to pass a description of the reboot cause. | ||
""" | ||
|
||
reset_reason = int(self._get_cpld_register('reboot_cause'), 16) | ||
|
||
if (reset_reason & 0x02) : | ||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Shutdown by CPU') | ||
elif (reset_reason & 0x04) : | ||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, "Failed to boot from configured boot device") | ||
elif (reset_reason & 0x8) : | ||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, "Booted from Backup BIOS") | ||
elif (reset_reason & 0x10) : | ||
return(ChassisBase.REBOOT_CAUSE_WATCHDOG, None) | ||
elif (reset_reason & 0x20): | ||
return(ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU) | ||
elif (reset_reason & 0x40) : | ||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Warm Reset') | ||
elif (reset_reason & 0x80) : | ||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, 'Cold Reset') | ||
elif (reset_reason & 0x01) : | ||
return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None) | ||
|
||
def get_eeprom(self): | ||
""" | ||
Retrieves the Sys Eeprom instance for the chassis. | ||
Returns : | ||
The instance of the Sys Eeprom | ||
""" | ||
return self._eeprom | ||
|
||
def get_num_fans(self): | ||
""" | ||
Retrives the number of Fans on the chassis. | ||
Returns : | ||
An integer represents the number of Fans on the chassis. | ||
""" | ||
return self._num_fans | ||
|
||
def get_num_sfps(self): | ||
""" | ||
Retrives the numnber of Media on the chassis. | ||
Returns: | ||
An integer represences the number of SFPs on the chassis. | ||
""" | ||
return self._num_sfps | ||
|
||
def get_qualified_media_list(self): | ||
return media_part_num_list | ||
|
||
def set_locator_led(self, color): | ||
""" | ||
Sets the state of the Chassis Locator LED | ||
Args: | ||
color: A string representing the color with which to set the Chassis Locator LED | ||
Returns: | ||
bool: True if the Chassis Locator LED state is set successfully, False if not | ||
""" | ||
if color == self.LOCATOR_LED_ON or color == self.LOCATOR_LED_OFF: | ||
rv = self._set_cpld_register(self.locator_led_reg, color) | ||
if (rv != 'ERR'): | ||
return True | ||
else: | ||
return False | ||
|
||
def get_locator_led(self): | ||
""" | ||
Gets the state of the Chassis Locator LED | ||
Returns: | ||
LOCATOR_LED_ON or LOCATOR_LED_OFF | ||
""" | ||
loc_led = self._get_cpld_register(self.locator_led_reg) | ||
if (loc_led != 'ERR'): | ||
# Actually driver returns the color code 'blink_blue' | ||
# Returning "blue_blink" to make it common to all platforms output | ||
if (loc_led == self.LOCATOR_LED_ON): | ||
self.LOCATOR_LED_ON = self.STATUS_LED_COLOR_BLUE_BLINK | ||
return self.LOCATOR_LED_ON | ||
else: | ||
return self.LOCATOR_LED_OFF | ||
else: | ||
return self.LOCATOR_LED_OFF |
82 changes: 82 additions & 0 deletions
82
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/component.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#!/usr/bin/env python | ||
|
||
######################################################################## | ||
# DELLEMC N3248PXE | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the Components' (e.g., BIOS, CPLD, FPGA, BMC etc.) available in | ||
# the platform | ||
# | ||
######################################################################## | ||
|
||
try: | ||
import subprocess | ||
from sonic_platform_base.component_base import ComponentBase | ||
|
||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
def get_bios_version(): | ||
return subprocess.check_output(['dmidecode', '-s', 'system-version']).strip().decode() | ||
|
||
def get_cpld_version(cpld): | ||
mjr_ver=subprocess.check_output('cat /sys/devices/platform/dell-n3248pxe-cpld.0/' + cpld + '_mjr_ver', shell=True).strip()[2:].decode() | ||
mnr_ver=subprocess.check_output('cat /sys/devices/platform/dell-n3248pxe-cpld.0/' + cpld + '_mnr_ver', shell=True).strip()[2:].decode() | ||
return (str(mjr_ver) + '.' + str(mnr_ver)) | ||
|
||
class Component(ComponentBase): | ||
"""DellEMC Platform-specific Component class""" | ||
|
||
CHASSIS_COMPONENTS = [ | ||
['BIOS', | ||
'Performs initialization of hardware components during booting', | ||
get_bios_version() | ||
], | ||
['CPU CPLD', | ||
'Used for managing the CPU power sequence and CPU states', | ||
get_cpld_version('cpu_cpld') | ||
], | ||
['SYS CPLD', | ||
'Used for managing FAN, PSU, SFP modules (1-48) SFP Plus modules (49-62)', | ||
get_cpld_version('sys_cpld') | ||
] | ||
] | ||
|
||
def __init__(self, component_index=0): | ||
self.index = component_index | ||
self.name = self.CHASSIS_COMPONENTS[self.index][0] | ||
self.description = self.CHASSIS_COMPONENTS[self.index][1] | ||
self.version = self.CHASSIS_COMPONENTS[self.index][2] | ||
|
||
def get_name(self): | ||
""" | ||
Retrieves the name of the component | ||
Returns: | ||
A string containing the name of the component | ||
""" | ||
return self.name | ||
|
||
def get_description(self): | ||
""" | ||
Retrieves the description of the component | ||
Returns: | ||
A string containing the description of the component | ||
""" | ||
return self.description | ||
|
||
def get_firmware_version(self): | ||
""" | ||
Retrieves the firmware version of the component | ||
Returns: | ||
A string containing the firmware version of the component | ||
""" | ||
return self.version | ||
|
||
def install_firmware(self, image_path): | ||
""" | ||
Installs firmware to the component | ||
Args: | ||
image_path: A string, path to firmware image | ||
Returns: | ||
A boolean, True if install was successful, False if not | ||
""" | ||
return False |
134 changes: 134 additions & 0 deletions
134
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/eeprom.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#!/usr/bin/env python | ||
|
||
############################################################################# | ||
# DellEmc N3248PXE | ||
# | ||
# Platform and model specific eeprom subclass, inherits from the base class, | ||
# and provides the followings: | ||
# - the eeprom format definition | ||
# - specific encoder/decoder if there is special need | ||
############################################################################# | ||
try: | ||
import os.path | ||
from sonic_eeprom import eeprom_tlvinfo | ||
import binascii | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): | ||
|
||
def __init__(self): | ||
self.eeprom_path = None | ||
f = '/sys/class/i2c-adapter/i2c-2/2-0050/eeprom' | ||
if not os.path.exists(f): | ||
return | ||
self.eeprom_path = f | ||
super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) | ||
self.eeprom_tlv_dict = dict() | ||
try: | ||
self.eeprom_data = self.read_eeprom() | ||
except Exception: | ||
self.eeprom_data = "N/A" | ||
raise RuntimeError("Eeprom is not Programmed") | ||
|
||
eeprom = self.eeprom_data | ||
|
||
if not self.is_valid_tlvinfo_header(eeprom): | ||
return | ||
|
||
total_length = ((eeprom[9]) << 8) | (eeprom[10]) | ||
tlv_index = self._TLV_INFO_HDR_LEN | ||
tlv_end = self._TLV_INFO_HDR_LEN + total_length | ||
|
||
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end: | ||
if not self.is_valid_tlv(eeprom[tlv_index:]): | ||
break | ||
|
||
tlv = eeprom[tlv_index:tlv_index + 2 | ||
+ (eeprom[tlv_index + 1])] | ||
code = "0x%02X" % ((tlv[0])) | ||
|
||
|
||
name, value = self.decoder(None, tlv) | ||
|
||
self.eeprom_tlv_dict[code] = value | ||
if (eeprom[tlv_index]) == self._TLV_CODE_CRC_32: | ||
break | ||
|
||
tlv_index += (eeprom[tlv_index+1]) + 2 | ||
|
||
def serial_number_str(self): | ||
""" | ||
Returns the serial number | ||
""" | ||
(is_valid, results) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_SERIAL_NUMBER) | ||
if not is_valid: | ||
return "N/A" | ||
return results[2] | ||
|
||
def base_mac_addr(self, e): | ||
""" | ||
Returns the base mac address found in the system EEPROM | ||
""" | ||
(is_valid, t) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_MAC_BASE) | ||
if not is_valid or t[1] != 6: | ||
return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(t) | ||
|
||
return ":".join([binascii.b2a_hex(T) for T in t[2]]) | ||
|
||
def modelstr(self): | ||
""" | ||
Returns the Model name | ||
""" | ||
(is_valid, results) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) | ||
if not is_valid: | ||
return "N/A" | ||
|
||
return results[2] | ||
|
||
def part_number_str(self): | ||
""" | ||
Returns the part number | ||
""" | ||
(is_valid, results) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_PART_NUMBER) | ||
if not is_valid: | ||
return "N/A" | ||
|
||
return results[2] | ||
|
||
def serial_str(self): | ||
""" | ||
Returns the servicetag number | ||
""" | ||
(is_valid, results) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_SERVICE_TAG) | ||
if not is_valid: | ||
return "N/A" | ||
|
||
return results[2] | ||
|
||
def revision_str(self): | ||
""" | ||
Returns the device revision | ||
""" | ||
(is_valid, results) = self.get_tlv_field( | ||
self.eeprom_data, self._TLV_CODE_DEVICE_VERSION) | ||
if not is_valid: | ||
return "N/A" | ||
|
||
return results[2] | ||
|
||
def system_eeprom_info(self): | ||
""" | ||
Returns a dictionary, where keys are the type code defined in | ||
ONIE EEPROM format and values are their corresponding values | ||
found in the system EEPROM. | ||
""" | ||
return self.eeprom_tlv_dict | ||
|
||
|
171 changes: 171 additions & 0 deletions
171
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/fan.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
#!/usr/bin/env python | ||
|
||
######################################################################## | ||
# DellEMC N3248PXE | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the Fans' information which are available in the platform. | ||
# | ||
######################################################################## | ||
try: | ||
import os | ||
from sonic_platform_base.fan_base import FanBase | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class Fan(FanBase): | ||
"""DellEMC Platform-specific Fan class""" | ||
|
||
def __init__(self, fantray_index=0, fan_index=0, psu_fan=False, dependency=None): | ||
self.is_psu_fan = psu_fan | ||
|
||
if not self.is_psu_fan: | ||
# API index is starting from 0, DellEMC platform index is | ||
# starting from 1 | ||
self.presence_reg = "fan{}_prs".format(fantray_index) | ||
self.dir_reg = "fan{}_dir".format(fantray_index) | ||
self.rpm_file = "/sys/bus/i2c/devices/7-002c/fan{}_input".format(fantray_index+1) | ||
self.eeprom = "/sys/bus/i2c/devices/{}-0050/eeprom".format(15 + fantray_index) | ||
self.fantray_index = fantray_index | ||
else: | ||
self.psu_index = fantray_index | ||
self.dependancy = dependency | ||
self.dir_reg = "" | ||
self.dps_hwmon = "/sys/bus/i2c/devices/{}-005e/hwmon/".format(fantray_index+10) | ||
self.eeprom = "/sys/bus/i2c/devices/{}-0056/eeprom".format(10 + fantray_index) | ||
self.max_speed = 0 | ||
|
||
def _get_cpld_register(self, reg_name): | ||
# On successful read, returns the value read from given | ||
# reg name and on failure rethrns 'ERR' | ||
cpld_dir = "/sys/devices/platform/dell-n3248pxe-cpld.0/" | ||
cpld_reg_file = cpld_dir + '/' + reg_name | ||
try: | ||
buf = open(cpld_reg_file, 'r').read() | ||
except (IOError, AttributeError): | ||
return 'ERR' | ||
return buf.strip('\r\n').lstrip(' ') | ||
|
||
def get_name(self): | ||
""" | ||
Retrieves the name of the device | ||
Returns: | ||
String: The name of the device | ||
""" | ||
if self.is_psu_fan: | ||
return "PSU{} Fan".format(self.psu_index) | ||
else: | ||
return "Fan{}".format(self.fantray_index+1) | ||
|
||
def get_model(self): | ||
""" | ||
Retrieves the part number of the FAN | ||
Returns: | ||
String: Part number of FAN | ||
""" | ||
try: | ||
val = open(self.eeprom, "rb").read()[13:19] | ||
except Exception: | ||
val = None | ||
return val.decode() | ||
|
||
def get_serial(self): | ||
""" | ||
Retrieves the serial number of the FAN | ||
Returns: | ||
String: Serial number of FAN | ||
""" | ||
try: | ||
val = open(self.eeprom, "rb").read()[21:41] | ||
except Exception: | ||
val = None | ||
return val.decode() | ||
|
||
def get_presence(self): | ||
""" | ||
Retrieves the presence of the FAN | ||
Returns: | ||
bool: True if fan is present, False if not | ||
""" | ||
|
||
if self.is_psu_fan: | ||
return False #--- TBD --- # | ||
|
||
presence = self._get_cpld_register(self.presence_reg) | ||
if presence == 'ERR': | ||
return False | ||
if int(presence,0) == 1: | ||
return True | ||
|
||
def get_status(self): | ||
""" | ||
Retrieves the operational status of the FAN | ||
Returns: | ||
bool: True if FAN is operating properly, False if not | ||
""" | ||
return True | ||
|
||
def get_direction(self): | ||
""" | ||
Retrieves the fan airfow direction | ||
Returns: | ||
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST | ||
depending on fan direction | ||
Notes: | ||
In DellEMC platforms, | ||
- Forward/Exhaust : Air flows from Port side to Fan side. | ||
- Reverse/Intake : Air flows from Fan side to Port side. | ||
""" | ||
if not self.is_psu_fan: | ||
val = self._get_cpld_register(self.dir_reg) | ||
direction = 'Exhaust' if val == 'F2B' else 'Intake' | ||
if direction == 'ERR': | ||
return None | ||
else: | ||
try: | ||
val = open(self.eeprom, "rb").read()[0xe1:0xe8] | ||
except Exception: | ||
return None | ||
direction = 'Exhaust' if val == 'FORWARD' else 'Intake' | ||
return direction | ||
|
||
def get_speed(self): | ||
""" | ||
Retrieves the speed of the fan | ||
Returns: | ||
int: percentage of the max fan speed | ||
""" | ||
if self.max_speed == 0: | ||
self.max_speed = 23500 | ||
fan_speed = 0 | ||
try: | ||
if not self.is_psu_fan: | ||
rpm_file = self.rpm_file | ||
else: | ||
dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0] | ||
rpm_file = dps_dir + '/' + 'fan1_input' | ||
fan_speed = int(open(rpm_file, "rb").read()) | ||
except Exception: | ||
return None | ||
speed = (100 * fan_speed)//self.max_speed | ||
return speed | ||
|
||
def get_speed_rpm(self): | ||
""" | ||
Retrieves the speed of the fan | ||
Returns: | ||
int: percentage of the max fan speed | ||
""" | ||
fan_speed = 0 | ||
try: | ||
if not self.is_psu_fan: | ||
rpm_file = self.rpm_file | ||
else: | ||
dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0] | ||
rpm_file = dps_dir + '/' + 'fan1_input' | ||
fan_speed = int(open(rpm_file, "rb").read()) | ||
except Exception: | ||
return None | ||
return fan_speed |
37 changes: 37 additions & 0 deletions
37
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/fan_drawer.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#!/usr/bin/env python | ||
|
||
######################################################################## | ||
# DellEMC N3248PXE | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the Fan-Drawers' information available in the platform. | ||
# | ||
######################################################################## | ||
|
||
try: | ||
from sonic_platform_base.fan_drawer_base import FanDrawerBase | ||
from sonic_platform.fan import Fan | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
N3248PXE_FANS_PER_FANTRAY = 2 | ||
|
||
|
||
class FanDrawer(FanDrawerBase): | ||
"""DellEMC Platform-specific Fan class""" | ||
|
||
def __init__(self, fantray_index): | ||
|
||
FanDrawerBase.__init__(self) | ||
# FanTray is 1-based in DellEMC platforms | ||
self.fantrayindex = fantray_index + 1 | ||
for i in range(N3248PXE_FANS_PER_FANTRAY): | ||
self._fan_list.append(Fan(fantray_index, i)) | ||
|
||
def get_name(self): | ||
""" | ||
Retrieves the fan drawer name | ||
Returns: | ||
string: The name of the device | ||
""" | ||
return "FanTray{}".format(self.fantrayindex) |
269 changes: 269 additions & 0 deletions
269
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/ipmihelper.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
#!/usr/bin/python3 | ||
|
||
######################################################################## | ||
# DellEMC | ||
# | ||
# Module contains implementation of IpmiSensor and IpmiFru classes that | ||
# provide Sensor's and FRU's information respectively. | ||
# | ||
######################################################################## | ||
|
||
import subprocess | ||
import re | ||
|
||
# IPMI Request Network Function Codes | ||
NetFn_SensorEvent = 0x04 | ||
NetFn_Storage = 0x0A | ||
|
||
# IPMI Sensor Device Commands | ||
Cmd_GetSensorReadingFactors = 0x23 | ||
Cmd_GetSensorThreshold = 0x27 | ||
Cmd_GetSensorReading = 0x2D | ||
|
||
# IPMI FRU Device Commands | ||
Cmd_ReadFRUData = 0x11 | ||
|
||
def get_ipmitool_raw_output(args): | ||
""" | ||
Returns a list the elements of which are the individual bytes of | ||
ipmitool raw <cmd> command output. | ||
""" | ||
result_bytes = list() | ||
result = "" | ||
command = "ipmitool raw {}".format(args) | ||
try: | ||
proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, | ||
universal_newlines=True, stderr=subprocess.STDOUT) | ||
stdout = proc.communicate()[0] | ||
proc.wait() | ||
if not proc.returncode: | ||
result = stdout.rstrip('\n') | ||
except EnvironmentError: | ||
pass | ||
|
||
for i in result.split(): | ||
result_bytes.append(int(i, 16)) | ||
|
||
return result_bytes | ||
|
||
class IpmiSensor(object): | ||
|
||
# Sensor Threshold types and their respective bit masks | ||
THRESHOLD_BIT_MASK = { | ||
"LowerNonCritical" : 0, | ||
"LowerCritical" : 1, | ||
"LowerNonRecoverable" : 2, | ||
"UpperNonCritical" : 3, | ||
"UpperCritical" : 4, | ||
"UpperNonRecoverable" : 5 | ||
} | ||
|
||
def __init__(self, sensor_id, is_discrete=False): | ||
self.id = sensor_id | ||
self.is_discrete = is_discrete | ||
|
||
def _get_converted_sensor_reading(self, raw_value): | ||
""" | ||
Returns a 2 element tuple(bool, int) in which first element | ||
provides the validity of the reading and the second element is | ||
the converted sensor reading | ||
""" | ||
# Get Sensor Reading Factors | ||
cmd_args = "{} {} {} {}".format(NetFn_SensorEvent, | ||
Cmd_GetSensorReadingFactors, | ||
self.id, raw_value) | ||
factors = get_ipmitool_raw_output(cmd_args) | ||
|
||
if len(factors) != 7: | ||
return False, 0 | ||
|
||
# Compute Twos complement | ||
def get_twos_complement(val, bits): | ||
if val & (1 << (bits - 1)): | ||
val = val - (1 << bits) | ||
return val | ||
|
||
# Calculate actual sensor value from the raw sensor value | ||
# using the sensor reading factors. | ||
M = get_twos_complement(((factors[2] & 0xC0) << 8) | factors[1], 10) | ||
B = get_twos_complement(((factors[4] & 0xC0) << 8) | factors[3], 10) | ||
R_exp = get_twos_complement((factors[6] & 0xF0) >> 4, 4) | ||
B_exp = get_twos_complement(factors[6] & 0x0F, 4) | ||
|
||
converted_reading = ((M * raw_value) + (B * 10**B_exp)) * 10**R_exp | ||
|
||
return True, converted_reading | ||
|
||
def get_reading(self): | ||
""" | ||
For Threshold sensors, returns the sensor reading. | ||
For Discrete sensors, returns the state value. | ||
Returns: | ||
A tuple (bool, int) where the first element provides the | ||
validity of the reading and the second element provides the | ||
sensor reading/state value. | ||
""" | ||
# Get Sensor Reading | ||
cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorReading, | ||
self.id) | ||
output = get_ipmitool_raw_output(cmd_args) | ||
if len(output) != 4: | ||
return False, 0 | ||
|
||
# Check reading/state unavailable | ||
if output[1] & 0x20: | ||
return False, 0 | ||
|
||
if self.is_discrete: | ||
state = ((output[3] & 0x7F) << 8) | output[2] | ||
return True, state | ||
else: | ||
return self._get_converted_sensor_reading(output[0]) | ||
|
||
def get_threshold(self, threshold_type): | ||
""" | ||
Returns the sensor's threshold value for a given threshold type. | ||
Args: | ||
threshold_type (str) - one of the below mentioned | ||
threshold type strings | ||
"LowerNonCritical" | ||
"LowerCritical" | ||
"LowerNonRecoverable" | ||
"UpperNonCritical" | ||
"UpperCritical" | ||
"UpperNonRecoverable" | ||
Returns: | ||
A tuple (bool, int) where the first element provides the | ||
validity of that threshold and second element provides the | ||
threshold value. | ||
""" | ||
# Thresholds are not valid for discrete sensors | ||
if self.is_discrete: | ||
raise TypeError("Threshold is not applicable for Discrete Sensor") | ||
|
||
if threshold_type not in list(self.THRESHOLD_BIT_MASK.keys()): | ||
raise ValueError("Invalid threshold type {} provided. Valid types " | ||
"are {}".format(threshold_type, | ||
list(self.THRESHOLD_BIT_MASK.keys()))) | ||
|
||
bit_mask = self.THRESHOLD_BIT_MASK[threshold_type] | ||
|
||
# Get Sensor Threshold | ||
cmd_args = "{} {} {}".format(NetFn_SensorEvent, Cmd_GetSensorThreshold, | ||
self.id) | ||
thresholds = get_ipmitool_raw_output(cmd_args) | ||
if len(thresholds) != 7: | ||
return False, 0 | ||
|
||
valid_thresholds = thresholds.pop(0) | ||
# Check whether particular threshold is readable | ||
if valid_thresholds & (1 << bit_mask): | ||
return self._get_converted_sensor_reading(thresholds[bit_mask]) | ||
else: | ||
return False, 0 | ||
|
||
class IpmiFru(object): | ||
|
||
def __init__(self, fru_id): | ||
self.id = fru_id | ||
|
||
def _get_ipmitool_fru_print(self): | ||
result = "" | ||
command = "ipmitool fru print {}".format(self.id) | ||
try: | ||
proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, | ||
universal_newlines=True, stderr=subprocess.STDOUT) | ||
stdout = proc.communicate()[0] | ||
proc.wait() | ||
if not proc.returncode: | ||
result = stdout.rstrip('\n') | ||
except EnvironmentError: | ||
pass | ||
|
||
return result | ||
|
||
def _get_from_fru(self, info): | ||
""" | ||
Returns a string containing the info from FRU | ||
""" | ||
fru_output = self._get_ipmitool_fru_print() | ||
if not fru_output: | ||
return "NA" | ||
|
||
info_req = re.search(r"%s\s*:(.*)" % info, fru_output) | ||
if not info_req: | ||
return "NA" | ||
|
||
return info_req.group(1).strip() | ||
|
||
def get_board_serial(self): | ||
""" | ||
Returns a string containing the Serial Number of the device. | ||
""" | ||
return self._get_from_fru('Board Serial') | ||
|
||
def get_board_part_number(self): | ||
""" | ||
Returns a string containing the Part Number of the device. | ||
""" | ||
return self._get_from_fru('Board Part Number') | ||
|
||
def get_board_mfr_id(self): | ||
""" | ||
Returns a string containing the manufacturer id of the FRU. | ||
""" | ||
return self._get_from_fru('Board Mfg') | ||
|
||
def get_board_product(self): | ||
""" | ||
Returns a string containing the manufacturer id of the FRU. | ||
""" | ||
return self._get_from_fru('Board Product') | ||
|
||
def get_fru_data(self, offset, count=1): | ||
""" | ||
Reads and returns the FRU data at the provided offset. | ||
Args: | ||
offset (int) - FRU offset to read | ||
count (int) - Number of bytes to read [optional, default = 1] | ||
Returns: | ||
A tuple (bool, list(int)) where the first element provides | ||
the validity of the data read and the second element is a | ||
list, the elements of which are the individual bytes of the | ||
FRU data read. | ||
""" | ||
result_bytes = list() | ||
is_valid = True | ||
result = "" | ||
|
||
offset_LSB = offset & 0xFF | ||
offset_MSB = offset & 0xFF00 | ||
command = "ipmitool raw {} {} {} {} {} {}".format(NetFn_Storage, | ||
Cmd_ReadFRUData, | ||
self.id, offset_LSB, | ||
offset_MSB, count) | ||
try: | ||
proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, | ||
universal_newlines=True, stderr=subprocess.STDOUT) | ||
stdout = proc.communicate()[0] | ||
proc.wait() | ||
if not proc.returncode: | ||
result = stdout.rstrip('\n') | ||
except EnvironmentError: | ||
is_valid = False | ||
|
||
if (not result) or (not is_valid): | ||
return False, result_bytes | ||
|
||
for i in result.split(): | ||
result_bytes.append(int(i, 16)) | ||
|
||
read_count = result_bytes.pop(0) | ||
if read_count != count: | ||
return False, result_bytes | ||
else: | ||
return True, result_bytes |
24 changes: 24 additions & 0 deletions
24
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/platform.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env python | ||
|
||
############################################################################# | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the platform information | ||
# | ||
############################################################################# | ||
|
||
try: | ||
from sonic_platform_base.platform_base import PlatformBase | ||
from sonic_platform.chassis import Chassis | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class Platform(PlatformBase): | ||
""" | ||
DELLEMC Platform-specific class | ||
""" | ||
|
||
def __init__(self): | ||
PlatformBase.__init__(self) | ||
self._chassis = Chassis() |
207 changes: 207 additions & 0 deletions
207
platform/broadcom/sonic-platform-modules-dell/n3248pxe/sonic_platform/psu.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
#!/usr/bin/env python | ||
|
||
######################################################################## | ||
# DellEMC N3248PXE | ||
# | ||
# Module contains an implementation of SONiC Platform Base API and | ||
# provides the PSUs' information which are available in the platform | ||
# | ||
######################################################################## | ||
|
||
try: | ||
import os | ||
from sonic_platform_base.psu_base import PsuBase | ||
from sonic_platform.fan import Fan | ||
except ImportError as e: | ||
raise ImportError(str(e) + "- required module not found") | ||
|
||
|
||
class Psu(PsuBase): | ||
"""DellEMC Platform-specific PSU class""" | ||
|
||
def __init__(self, psu_index): | ||
PsuBase.__init__(self) | ||
self.index = psu_index + 1 # PSU is 1-based in DellEMC platforms | ||
self.psu_presence_reg = "psu{}_prs".format(psu_index) | ||
self.psu_status = "psu{}_status".format(psu_index) | ||
self.eeprom = "/sys/bus/i2c/devices/{}-0056/eeprom".format(10+psu_index) | ||
self.psu_voltage_reg = 'in3_input' | ||
self.psu_current_reg = 'curr2_input' | ||
self.psu_power_reg = 'power2_input' | ||
self.dps_hwmon = "/sys/bus/i2c/devices/{}-005e/hwmon/".format(10 + psu_index) | ||
self.dps_hwmon_exist = os.path.exists(self.dps_hwmon) | ||
self._fan_list.append(Fan(fan_index=self.index, psu_fan=True, dependency=self)) | ||
|
||
def _get_cpld_register(self, reg_name): | ||
# On successful read, returns the value read from given | ||
# reg name and on failure rethrns 'ERR' | ||
cpld_dir = "/sys/devices/platform/dell-n3248pxe-cpld.0/" | ||
cpld_reg_file = cpld_dir + '/' + reg_name | ||
try: | ||
rv = open(cpld_reg_file, 'r').read() | ||
except IOError : return 'ERR' | ||
return rv.strip('\r\n').lstrip(' ') | ||
|
||
def _get_dps_register(self, reg_name): | ||
try : | ||
dps_dir = self.dps_hwmon + '/' + os.listdir(self.dps_hwmon)[0] | ||
dps_reg_file = dps_dir + '/' + reg_name | ||
rv = open(dps_reg_file, 'r').read() | ||
except (IOError, OSError) : return 'ERR' | ||
return rv | ||
|
||
def get_name(self): | ||
""" | ||
Retrieves the name of the device | ||
Returns: | ||
string: The name of the device | ||
""" | ||
return "PSU{}".format(self.index) | ||
|
||
def _reload_dps_module(self): | ||
try: | ||
del_cmd = "echo 0x56 > /sys/bus/i2c/devices/i2c-{}/delete_device".format(10 + self.index - 1) | ||
os.system(del_cmd) | ||
except (IOError, OSError): | ||
pass | ||
try: | ||
del_cmd = "echo 0x5e > /sys/bus/i2c/devices/i2c-{}/delete_device".format(10 + self.index - 1) | ||
os.system(del_cmd) | ||
except (IOError, OSError): | ||
pass | ||
try: | ||
ins_cmd = "echo '24c02 0x56' > /sys/bus/i2c/devices/i2c-{}/new_device".format(10 + self.index - 1) | ||
os.system(ins_cmd) | ||
ins_cmd = "echo 'dps460 0x5e' > /sys/bus/i2c/devices/i2c-{}/new_device".format(10 + self.index - 1) | ||
os.system(ins_cmd) | ||
except (IOError, OSError): | ||
pass | ||
|
||
def get_presence(self): | ||
""" | ||
Retrieves the presence of the Power Supply Unit (PSU) | ||
Returns: | ||
bool: True if PSU is present, False if not | ||
""" | ||
presence = self._get_cpld_register(self.psu_presence_reg).strip() | ||
if presence == 'ERR' : return False | ||
if not self.dps_hwmon_exist and int(presence, 0): | ||
self.dps_hwmon_exist = os.path.exists(self.dps_hwmon) | ||
if not self.dps_hwmon_exist: | ||
self._reload_dps_module() | ||
return int(presence, 0) | ||
|
||
def get_model(self): | ||
""" | ||
Retrieves the part number of the PSU | ||
Returns: | ||
string: Part number of PSU | ||
""" | ||
try: val = open(self.eeprom, "rb").read()[0x50:0x62] | ||
except Exception: | ||
val = None | ||
return val.decode() | ||
|
||
def get_serial(self): | ||
""" | ||
Retrieves the serial number of the PSU | ||
Returns: | ||
string: Serial number of PSU | ||
""" | ||
try: val = open(self.eeprom, "rb").read()[0xc4:0xd9] | ||
except Exception: | ||
val = None | ||
return val.decode() | ||
|
||
def get_status(self): | ||
""" | ||
Retrieves the operational status of the PSU | ||
Returns: | ||
bool: True if PSU is operating properly, False if not | ||
""" | ||
status = self._get_cpld_register(self.psu_status).strip() | ||
if status == 'ERR' : return False | ||
return int(status, 0) | ||
|
||
def get_voltage(self): | ||
""" | ||
Retrieves current PSU voltage output | ||
Returns: | ||
A float number, the output voltage in volts, | ||
e.g. 12.1 | ||
""" | ||
volt_reading = self._get_dps_register(self.psu_voltage_reg) | ||
try: | ||
voltage = int(volt_reading)/1000 | ||
except Exception: | ||
return None | ||
return "{:.1f}".format(voltage) | ||
|
||
def get_current(self): | ||
""" | ||
Retrieves present electric current supplied by PSU | ||
Returns: | ||
A float number, electric current in amperes, | ||
e.g. 15.4 | ||
""" | ||
curr_reading = self._get_dps_register(self.psu_current_reg) | ||
try: | ||
current = int(curr_reading)/1000 | ||
except Exception: | ||
return None | ||
return "{:.1f}".format(current) | ||
|
||
def get_power(self): | ||
""" | ||
Retrieves current energy supplied by PSU | ||
Returns: | ||
A float number, the power in watts, | ||
e.g. 302.6 | ||
""" | ||
power_reading = self._get_dps_register(self.psu_power_reg) | ||
try: | ||
power = int(power_reading)/1000 | ||
except Exception: | ||
return None | ||
return "{:.1f}".format(power) | ||
|
||
def get_powergood_status(self): | ||
""" | ||
Retrieves the powergood status of PSU | ||
Returns: | ||
A boolean, True if PSU has stablized its output voltages and | ||
passed all its internal self-tests, False if not. | ||
""" | ||
power_good = self._get_cpld_register(self.psu_status).strip() | ||
if power_good == 'ERR' : return False | ||
return int(power_good, 0) | ||
|
||
def get_mfr_id(self): | ||
""" | ||
Retrives the Manufacturer Id of PSU | ||
Returns: | ||
A string, the manunfacturer id. | ||
""" | ||
return 'DELTA' | ||
|
||
def get_type(self): | ||
""" | ||
Retrives the Power Type of PSU | ||
Returns : | ||
A string, PSU power type | ||
""" | ||
try: val = open(self.eeprom, "rb").read()[0xe8:0xea] | ||
except Exception: | ||
return None | ||
return val.decode() |
Oops, something went wrong.