[Netberg][Barefoot] Added support for Aurora 610 (#10579)

Why I did it
Support Intel Tofino based platforms Netberg Aurora 610
ASIC: Intel Tofino BFN-T10-032D-020
Pors: 48x 25G + 8x 100G

How I did it
Added specification to device/netberg directory
Added platform/barefoot/sonic-platform-modules-netberg contains kernel modules, scripts and sonic_platform packages.
Modified the platform/barefoot/one-image.mk and platform/barefoot/rule.mk to include Aurora 610 related ID and files.

How to verify it
Build SONiC

Install the image on the device and verify the related components are installed and shown correctly.
This commit is contained in:
Andrew Sapronov 2022-06-30 20:40:47 +03:00 committed by GitHub
parent 9a6da79c40
commit 7f10b6bc35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 22794 additions and 0 deletions

View File

@ -0,0 +1,2 @@
{%- set default_topo = 't0' %}
{%- include 'buffers_config.j2' %}

View File

@ -0,0 +1,86 @@
{% set default_cable = '5m' %}
{% set ingress_lossless_pool_size = '4194304' %}
{% set ingress_lossy_pool_size = '7340032' %}
{% set egress_lossless_pool_size = '16777152' %}
{% set egress_lossy_pool_size = '7340032' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
{%- for port_idx in range(0,47) %}
{%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
{%- endfor %}
{% for port_idx in range(48,55) %}
{% if PORT.append("Ethernet%d" % (48 + ( port_idx - 48 )*4)) %}{% endif %}
{% endfor %}
{%- endmacro %}
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
"size": "{{ ingress_lossless_pool_size }}",
"type": "ingress",
"mode": "dynamic"
},
"ingress_lossy_pool": {
"size": "{{ ingress_lossy_pool_size }}",
"type": "ingress",
"mode": "dynamic"
},
"egress_lossless_pool": {
"size": "{{ egress_lossless_pool_size }}",
"type": "egress",
"mode": "dynamic"
},
"egress_lossy_pool": {
"size": "{{ egress_lossy_pool_size }}",
"type": "egress",
"mode": "dynamic"
}
},
"BUFFER_PROFILE": {
"ingress_lossless_profile": {
"pool":"ingress_lossless_pool",
"size":"4096",
"dynamic_th":"0",
"xon":"18432",
"xoff":"18432"
},
"ingress_lossy_profile": {
"pool":"ingress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"egress_lossless_pool",
"size":"4096",
"dynamic_th":"7",
"xon":"18432",
"xoff":"18432"
},
"egress_lossy_profile": {
"pool":"egress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
},
"q_lossy_profile": {
"pool":"egress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
}
},
{%- endmacro %}
{%- macro generate_queue_buffers(port_names) %}
"BUFFER_QUEUE": {
{% for port in port_names.split(',') %}
"{{ port }}|0-2": {
"profile" : "q_lossy_profile"
},
{% endfor %}
{% for port in port_names.split(',') %}
"{{ port }}|3-4": {
"profile" : "egress_lossless_profile"
}{% if not loop.last %},{% endif %}
{% endfor %}
}
{%- endmacro %}

View File

@ -0,0 +1,86 @@
{% set default_cable = '5m' %}
{% set ingress_lossless_pool_size = '2097152' %}
{% set ingress_lossy_pool_size = '5242880' %}
{% set egress_lossless_pool_size = '16777152' %}
{% set egress_lossy_pool_size = '5242880' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
{%- for port_idx in range(0,47) %}
{%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
{%- endfor %}
{% for port_idx in range(48,55) %}
{% if PORT.append("Ethernet%d" % (48+(port_idx-48)*4)) %}{% endif %}
{% endfor %}
{%- endmacro %}
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
"size": "{{ ingress_lossless_pool_size }}",
"type": "ingress",
"mode": "dynamic"
},
"ingress_lossy_pool": {
"size": "{{ ingress_lossy_pool_size }}",
"type": "ingress",
"mode": "dynamic"
},
"egress_lossless_pool": {
"size": "{{ egress_lossless_pool_size }}",
"type": "egress",
"mode": "dynamic"
},
"egress_lossy_pool": {
"size": "{{ egress_lossy_pool_size }}",
"type": "egress",
"mode": "dynamic"
}
},
"BUFFER_PROFILE": {
"ingress_lossless_profile": {
"pool":"ingress_lossless_pool",
"size":"4096",
"dynamic_th":"0",
"xon":"18432",
"xoff":"18432"
},
"ingress_lossy_profile": {
"pool":"ingress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"egress_lossless_pool",
"size":"4096",
"dynamic_th":"7",
"xon":"18432",
"xoff":"18432"
},
"egress_lossy_profile": {
"pool":"egress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
},
"q_lossy_profile": {
"pool":"egress_lossy_pool",
"size":"4096",
"dynamic_th":"3"
}
},
{%- endmacro %}
{%- macro generate_queue_buffers(port_names) %}
"BUFFER_QUEUE": {
{% for port in port_names.split(',') %}
"{{ port }}|0-2": {
"profile" : "q_lossy_profile"
},
{% endfor %}
{% for port in port_names.split(',') %}
"{{ port }}|3-4": {
"profile" : "egress_lossless_profile"
}{% if not loop.last %},{% endif %}
{% endfor %}
}
{%- endmacro %}

View File

@ -0,0 +1,284 @@
{
"interfaces": {
"Ethernet1": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet2": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet3": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet4": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet5": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet6": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet7": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet8": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet9": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet10": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet11": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet12": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet13": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet14": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet15": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet16": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet17": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet18": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet19": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet20": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet21": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet22": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet23": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet24": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet25": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet26": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet27": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet28": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet29": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet30": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet31": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet32": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet33": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet34": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet35": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet36": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet37": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet38": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet39": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet40": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet41": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet42": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet43": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet44": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet45": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet46": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet47": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet48": {
"default_brkout_mode": "1x25G[10G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet49": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet53": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet57": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet61": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet65": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet69": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet73": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
},
"Ethernet77": {
"default_brkout_mode": "1x100G[40G]",
"autoneg": "off",
"fec": "rs"
}
}
}

View File

@ -0,0 +1,17 @@
# PG lossless profiles.
# speed cable size xon xoff threshold
10000 5m 34816 18432 16384 0
25000 5m 34816 18432 16384 0
40000 5m 34816 18432 16384 0
50000 5m 34816 18432 16384 0
100000 5m 36864 18432 18432 0
10000 40m 36864 18432 18432 0
25000 40m 39936 18432 21504 0
40000 40m 41984 18432 23552 0
50000 40m 41984 18432 23552 0
100000 40m 54272 18432 35840 0
10000 300m 49152 18432 30720 0
25000 300m 71680 18432 53248 0
40000 300m 94208 18432 75776 0
50000 300m 94208 18432 75776 0
100000 300m 184320 18432 165888 0

View File

@ -0,0 +1,57 @@
# name lanes alias index speed autoneg fec
Ethernet1 0 Ethernet1 0 25000 off rs
Ethernet2 1 Ethernet2 1 25000 off rs
Ethernet3 2 Ethernet3 2 25000 off rs
Ethernet4 3 Ethernet4 3 25000 off rs
Ethernet5 4 Ethernet5 4 25000 off rs
Ethernet6 5 Ethernet6 5 25000 off rs
Ethernet7 6 Ethernet7 6 25000 off rs
Ethernet8 7 Ethernet8 7 25000 off rs
Ethernet9 8 Ethernet9 8 25000 off rs
Ethernet10 9 Ethernet10 9 25000 off rs
Ethernet11 10 Ethernet11 10 25000 off rs
Ethernet12 11 Ethernet12 11 25000 off rs
Ethernet13 12 Ethernet13 12 25000 off rs
Ethernet14 13 Ethernet14 13 25000 off rs
Ethernet15 14 Ethernet15 14 25000 off rs
Ethernet16 15 Ethernet16 15 25000 off rs
Ethernet17 16 Ethernet17 16 25000 off rs
Ethernet18 17 Ethernet18 17 25000 off rs
Ethernet19 18 Ethernet19 18 25000 off rs
Ethernet20 19 Ethernet20 19 25000 off rs
Ethernet21 20 Ethernet21 20 25000 off rs
Ethernet22 21 Ethernet22 21 25000 off rs
Ethernet23 22 Ethernet23 22 25000 off rs
Ethernet24 23 Ethernet24 23 25000 off rs
Ethernet25 24 Ethernet25 24 25000 off rs
Ethernet26 25 Ethernet26 25 25000 off rs
Ethernet27 26 Ethernet27 26 25000 off rs
Ethernet28 27 Ethernet28 27 25000 off rs
Ethernet29 28 Ethernet29 28 25000 off rs
Ethernet30 29 Ethernet30 29 25000 off rs
Ethernet31 30 Ethernet31 30 25000 off rs
Ethernet32 31 Ethernet32 31 25000 off rs
Ethernet33 32 Ethernet33 32 25000 off rs
Ethernet34 33 Ethernet34 33 25000 off rs
Ethernet35 34 Ethernet35 34 25000 off rs
Ethernet36 35 Ethernet36 35 25000 off rs
Ethernet37 36 Ethernet37 36 25000 off rs
Ethernet38 37 Ethernet38 37 25000 off rs
Ethernet39 38 Ethernet39 38 25000 off rs
Ethernet40 39 Ethernet40 39 25000 off rs
Ethernet41 40 Ethernet41 40 25000 off rs
Ethernet42 41 Ethernet42 41 25000 off rs
Ethernet43 42 Ethernet43 42 25000 off rs
Ethernet44 43 Ethernet44 43 25000 off rs
Ethernet45 44 Ethernet45 44 25000 off rs
Ethernet46 45 Ethernet46 45 25000 off rs
Ethernet47 46 Ethernet47 46 25000 off rs
Ethernet48 47 Ethernet48 47 25000 off rs
Ethernet49 48,49,50,51 Ethernet49 48 100000 off rs
Ethernet53 52,53,54,55 Ethernet53 49 100000 off rs
Ethernet57 56,57,58,59 Ethernet57 50 100000 off rs
Ethernet61 60,61,62,63 Ethernet61 51 100000 off rs
Ethernet65 64,65,66,67 Ethernet65 52 100000 off rs
Ethernet69 68,69,70,71 Ethernet69 53 100000 off rs
Ethernet73 72,73,74,75 Ethernet73 54 100000 off rs
Ethernet77 76,77,78,79 Ethernet77 55 100000 off rs

View File

@ -0,0 +1,10 @@
{%- macro generate_tc_to_pg_map() %}
"TC_TO_PRIORITY_GROUP_MAP": {
"AZURE": {
"3": "3",
"4": "4"
}
},
{%- endmacro %}
{%- include 'qos_config.j2' %}

View File

@ -0,0 +1,2 @@
SAI_KEY_WARM_BOOT_WRITE_FILE=/var/warmboot/sai-warmboot.bin
SAI_KEY_WARM_BOOT_READ_FILE=/var/warmboot/sai-warmboot.bin

View File

@ -0,0 +1,39 @@
{
"chip_list": [
{
"chip_family": "Tofino",
"sds_fw_path": "share/tofino_sds_fw/avago/firmware",
"instance": 0
}
],
"p4_devices": [
{
"device-id": 0,
"agent0": "lib/platform/x86_64-netberg_aurora_610-r0/libpltfm_mgr.so",
"p4_programs": [
{
"p4_pipelines": [
{
"p4_pipeline_name": "pipe",
"config": "share/switch/pipe/tofino.bin",
"context": "share/switch/pipe/context.json"
}
],
"program-name": "switch",
"bfrt-config": "share/switch/bf-rt.json",
"model_json_path" : "share/switch/aug_model.json",
"switchapi_port_add": false,
"non_default_port_ppgs": 5
}
]
}
],
"switch_options": [
{
"device-id": 0,
"model_json_path": "share/switch/aug_model.json",
"non_default_port_ppgs": 5,
"switchapi_port_add": false
}
]
}

View File

@ -0,0 +1 @@
aurora-610 t1

View File

@ -0,0 +1,4 @@
CONSOLE_PORT=0x3f8
CONSOLE_DEV=0
CONSOLE_SPEED=115200
VAR_LOG_SIZE=1024

View File

@ -0,0 +1,453 @@
- bus: '00'
dev: '00'
fn: '0'
id: 6f00
name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2
(rev 03)'
- bus: '00'
dev: '01'
fn: '0'
id: 6f02
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 1 (rev 03)'
- bus: '00'
dev: '01'
fn: '1'
id: 6f03
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 1 (rev 03)'
- bus: '00'
dev: '02'
fn: '0'
id: 6f04
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 2 (rev 03)'
- bus: '00'
dev: '02'
fn: '2'
id: 6f06
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 2 (rev 03)'
- bus: '00'
dev: '03'
fn: '0'
id: 6f08
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 3 (rev 03)'
- bus: '00'
dev: '03'
fn: '1'
id: 6f09
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 3 (rev 03)'
- bus: '00'
dev: '03'
fn: '2'
id: 6f0a
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 3 (rev 03)'
- bus: '00'
dev: '03'
fn: '3'
id: 6f0b
name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
Express Root Port 3 (rev 03)'
- bus: '00'
dev: '05'
fn: '0'
id: 6f28
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Map/VTd_Misc/System Management (rev 03)'
- bus: '00'
dev: '05'
fn: '1'
id: 6f29
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D IIO Hot Plug (rev 03)'
- bus: '00'
dev: '05'
fn: '2'
id: 6f2a
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D IIO RAS/Control Status/Global Errors (rev 03)'
- bus: '00'
dev: '05'
fn: '4'
id: 6f2c
name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev
03)'
- bus: '00'
dev: '14'
fn: '0'
id: 8c31
name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB
xHCI (rev 05)'
- bus: '00'
dev: '16'
fn: '0'
id: 8c3a
name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset
Family MEI Controller #1 (rev 04)'
- bus: '00'
dev: '16'
fn: '1'
id: 8c3b
name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset
Family MEI Controller #2 (rev 04)'
- bus: '00'
dev: 1d
fn: '0'
id: 8c26
name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB
EHCI #1 (rev 05)'
- bus: '00'
dev: 1f
fn: '0'
id: 8c54
name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard
SKU LPC Controller (rev 05)'
- bus: '00'
dev: 1f
fn: '2'
id: 8c02
name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port
SATA Controller 1 [AHCI mode] (rev 05)'
- bus: '00'
dev: 1f
fn: '3'
id: 8c22
name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller
(rev 05)'
- bus: '00'
dev: 1f
fn: '6'
id: 8c24
name: 'Signal processing controller: Intel Corporation 8 Series Chipset Family Thermal
Management Controller (rev 05)'
- bus: '01'
dev: '00'
fn: '0'
id: '1533'
name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
03)'
- bus: '02'
dev: '00'
fn: '0'
id: '1533'
name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev
03)'
- bus: '03'
dev: '00'
fn: '0'
id: 6f50
name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology
Register DMA Channel 0'
- bus: '03'
dev: '00'
fn: '1'
id: 6f51
name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology
Register DMA Channel 1'
- bus: '03'
dev: '00'
fn: '2'
id: 6f52
name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology
Register DMA Channel 2'
- bus: '03'
dev: '00'
fn: '3'
id: 6f53
name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology
Register DMA Channel 3'
- bus: '04'
dev: '00'
fn: '0'
id: 15ab
name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane'
- bus: '04'
dev: '00'
fn: '1'
id: 15ab
name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane'
- bus: '06'
dev: '00'
fn: '0'
id: '0010'
name: 'Unassigned class [ff00]: Device 1d1c:0010 (rev 10)'
- bus: ff
dev: 0b
fn: '0'
id: 6f81
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R3 QPI Link 0/1 (rev 03)'
- bus: ff
dev: 0b
fn: '1'
id: 6f36
name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R3 QPI Link 0/1 (rev 03)'
- bus: ff
dev: 0b
fn: '2'
id: 6f37
name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R3 QPI Link 0/1 (rev 03)'
- bus: ff
dev: 0b
fn: '3'
id: 6f76
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R3 QPI Link Debug (rev 03)'
- bus: ff
dev: 0c
fn: '0'
id: 6fe0
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0c
fn: '1'
id: 6fe1
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0c
fn: '2'
id: 6fe2
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0c
fn: '3'
id: 6fe3
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0f
fn: '0'
id: 6ff8
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0f
fn: '4'
id: 6ffc
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0f
fn: '5'
id: 6ffd
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: 0f
fn: '6'
id: 6ffe
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Caching Agent (rev 03)'
- bus: ff
dev: '10'
fn: '0'
id: 6f1d
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R2PCIe Agent (rev 03)'
- bus: ff
dev: '10'
fn: '1'
id: 6f34
name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D R2PCIe Agent (rev 03)'
- bus: ff
dev: '10'
fn: '5'
id: 6f1e
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Ubox (rev 03)'
- bus: ff
dev: '10'
fn: '6'
id: 6f7d
name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Ubox (rev 03)'
- bus: ff
dev: '10'
fn: '7'
id: 6f1f
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Ubox (rev 03)'
- bus: ff
dev: '12'
fn: '0'
id: 6fa0
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Home Agent 0 (rev 03)'
- bus: ff
dev: '12'
fn: '1'
id: 6f30
name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Home Agent 0 (rev 03)'
- bus: ff
dev: '13'
fn: '0'
id: 6fa8
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)'
- bus: ff
dev: '13'
fn: '1'
id: 6f71
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)'
- bus: ff
dev: '13'
fn: '2'
id: 6faa
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel Target Address Decoder (rev 03)'
- bus: ff
dev: '13'
fn: '3'
id: 6fab
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel Target Address Decoder (rev 03)'
- bus: ff
dev: '13'
fn: '4'
id: 6fac
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel Target Address Decoder (rev 03)'
- bus: ff
dev: '13'
fn: '5'
id: 6fad
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel Target Address Decoder (rev 03)'
- bus: ff
dev: '13'
fn: '6'
id: 6fae
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Channel 0/1 Broadcast (rev 03)'
- bus: ff
dev: '13'
fn: '7'
id: 6faf
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Global Broadcast (rev 03)'
- bus: ff
dev: '14'
fn: '0'
id: 6fb0
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 0 Thermal Control (rev 03)'
- bus: ff
dev: '14'
fn: '1'
id: 6fb1
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 1 Thermal Control (rev 03)'
- bus: ff
dev: '14'
fn: '2'
id: 6fb2
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 0 Error (rev 03)'
- bus: ff
dev: '14'
fn: '3'
id: 6fb3
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 1 Error (rev 03)'
- bus: ff
dev: '14'
fn: '4'
id: 6fbc
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Channel 0/1 Interface (rev 03)'
- bus: ff
dev: '14'
fn: '5'
id: 6fbd
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Channel 0/1 Interface (rev 03)'
- bus: ff
dev: '14'
fn: '6'
id: 6fbe
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Channel 0/1 Interface (rev 03)'
- bus: ff
dev: '14'
fn: '7'
id: 6fbf
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D DDRIO Channel 0/1 Interface (rev 03)'
- bus: ff
dev: '15'
fn: '0'
id: 6fb4
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 2 Thermal Control (rev 03)'
- bus: ff
dev: '15'
fn: '1'
id: 6fb5
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 3 Thermal Control (rev 03)'
- bus: ff
dev: '15'
fn: '2'
id: 6fb6
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 2 Error (rev 03)'
- bus: ff
dev: '15'
fn: '3'
id: 6fb7
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Memory Controller 0 - Channel 3 Error (rev 03)'
- bus: ff
dev: 1e
fn: '0'
id: 6f98
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1e
fn: '1'
id: 6f99
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1e
fn: '2'
id: 6f9a
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1e
fn: '3'
id: 6fc0
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1e
fn: '4'
id: 6f9c
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1f
fn: '0'
id: 6f88
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'
- bus: ff
dev: 1f
fn: '2'
id: 6f8a
name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon
D Power Control Unit (rev 03)'

View File

@ -0,0 +1,485 @@
{
"chassis" : {
"components" : [ ],
"fans" : [ ],
"fan_drawers" : [
{
"fans" : [
{ "name" : "fan1" },
{ "name" : "fan2" }
],
"name" : "drawer1"
},
{
"fans" : [
{ "name" : "fan3" },
{ "name" : "fan4" }
],
"name" : "drawer2"
},
{
"fans" : [
{ "name" : "fan5" },
{ "name" : "fan6" }
],
"name" : "drawer3"
},
{
"fans" : [
{ "name" : "fan7" },
{ "name" : "fan8" }
],
"name" : "drawer4"
}
],
"name" : "aurora-610",
"psus" : [
{
"fans" : [ { "name" : "psu1_fan1" } ],
"name" : "PSU 1",
"thermals" : [ { "name" : "PSU-1 Temp" } ]
},
{
"fans" : [ { "name" : "psu2_fan1" } ],
"name" : "PSU 2",
"thermals" : [ { "name" : "PSU-2 Temp" } ]
}
],
"sfps" : [
{ "name" : "sfp1" },
{ "name" : "sfp2" },
{ "name" : "sfp3" },
{ "name" : "sfp4" },
{ "name" : "sfp5" },
{ "name" : "sfp6" },
{ "name" : "sfp7" },
{ "name" : "sfp8" },
{ "name" : "sfp9" },
{ "name" : "sfp10" },
{ "name" : "sfp11" },
{ "name" : "sfp12" },
{ "name" : "sfp13" },
{ "name" : "sfp14" },
{ "name" : "sfp15" },
{ "name" : "sfp16" },
{ "name" : "sfp17" },
{ "name" : "sfp18" },
{ "name" : "sfp19" },
{ "name" : "sfp20" },
{ "name" : "sfp21" },
{ "name" : "sfp22" },
{ "name" : "sfp23" },
{ "name" : "sfp24" },
{ "name" : "sfp25" },
{ "name" : "sfp26" },
{ "name" : "sfp27" },
{ "name" : "sfp28" },
{ "name" : "sfp29" },
{ "name" : "sfp30" },
{ "name" : "sfp31" },
{ "name" : "sfp32" },
{ "name" : "sfp33" },
{ "name" : "sfp34" },
{ "name" : "sfp35" },
{ "name" : "sfp36" },
{ "name" : "sfp37" },
{ "name" : "sfp38" },
{ "name" : "sfp39" },
{ "name" : "sfp40" },
{ "name" : "sfp41" },
{ "name" : "sfp42" },
{ "name" : "sfp43" },
{ "name" : "sfp44" },
{ "name" : "sfp45" },
{ "name" : "sfp46" },
{ "name" : "sfp48" },
{ "name" : "qsfp49" },
{ "name" : "qsfp50" },
{ "name" : "qsfp51" },
{ "name" : "qsfp52" },
{ "name" : "qsfp53" },
{ "name" : "qsfp54" },
{ "name" : "qsfp55" },
{ "name" : "qsfp56" }
],
"thermals" : [ ]
},
"interfaces" : {
"Ethernet1" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet1" ] },
"index" : "0",
"lanes" : "0"
},
"Ethernet2" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet2" ] },
"index" : "1",
"lanes" : "1"
},
"Ethernet3" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet3" ] },
"index" : "2",
"lanes" : "2"
},
"Ethernet4" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet4" ] },
"index" : "3",
"lanes" : "3"
},
"Ethernet5" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet5" ] },
"index" : "4",
"lanes" : "4"
},
"Ethernet6" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet6" ] },
"index" : "5",
"lanes" : "5"
},
"Ethernet7" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet7" ] },
"index" : "6",
"lanes" : "6"
},
"Ethernet8" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet8" ] },
"index" : "7",
"lanes" : "7"
},
"Ethernet9" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet9" ] },
"index" : "8",
"lanes" : "8"
},
"Ethernet10" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet10" ] },
"index" : "9",
"lanes" : "9"
},
"Ethernet11" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet11" ] },
"index" : "10",
"lanes" : "10"
},
"Ethernet12" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet12" ] },
"index" : "11",
"lanes" : "11"
},
"Ethernet13" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet13" ] },
"index" : "12",
"lanes" : "12"
},
"Ethernet14" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet14" ] },
"index" : "13",
"lanes" : "13"
},
"Ethernet15" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet15" ] },
"index" : "14",
"lanes" : "14"
},
"Ethernet16" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet16" ] },
"index" : "15",
"lanes" : "15"
},
"Ethernet17" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet17" ] },
"index" : "16",
"lanes" : "16"
},
"Ethernet18" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet18" ] },
"index" : "17",
"lanes" : "17"
},
"Ethernet19" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet19" ] },
"index" : "18",
"lanes" : "18"
},
"Ethernet20" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet20" ] },
"index" : "19",
"lanes" : "19"
},
"Ethernet21" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet21" ] },
"index" : "20",
"lanes" : "20"
},
"Ethernet22" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet22" ] },
"index" : "21",
"lanes" : "21"
},
"Ethernet23" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet23" ] },
"index" : "22",
"lanes" : "22"
},
"Ethernet24" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet24" ] },
"index" : "23",
"lanes" : "23"
},
"Ethernet25" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet25" ] },
"index" : "24",
"lanes" : "24"
},
"Ethernet26" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet26" ] },
"index" : "25",
"lanes" : "25"
},
"Ethernet27" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet27" ] },
"index" : "26",
"lanes" : "26"
},
"Ethernet28" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet28" ] },
"index" : "27",
"lanes" : "27"
},
"Ethernet29" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet29" ] },
"index" : "28",
"lanes" : "28"
},
"Ethernet30" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet30" ] },
"index" : "29",
"lanes" : "29"
},
"Ethernet31" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet31" ] },
"index" : "30",
"lanes" : "30"
},
"Ethernet32" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet32" ] },
"index" : "31",
"lanes" : "31"
},
"Ethernet33" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet33" ] },
"index" : "32",
"lanes" : "32"
},
"Ethernet34" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet34" ] },
"index" : "33",
"lanes" : "33"
},
"Ethernet35" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet35" ] },
"index" : "34",
"lanes" : "34"
},
"Ethernet36" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet36" ] },
"index" : "35",
"lanes" : "35"
},
"Ethernet37" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet37" ] },
"index" : "36",
"lanes" : "36"
},
"Ethernet38" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet38" ] },
"index" : "37",
"lanes" : "37"
},
"Ethernet39" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet39" ] },
"index" : "38",
"lanes" : "38"
},
"Ethernet40" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet40" ] },
"index" : "39",
"lanes" : "39"
},
"Ethernet41" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet41" ] },
"index" : "40",
"lanes" : "40"
},
"Ethernet42" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet42" ] },
"index" : "41",
"lanes" : "41"
},
"Ethernet43" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet43" ] },
"index" : "42",
"lanes" : "42"
},
"Ethernet44" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet44" ] },
"index" : "43",
"lanes" : "43"
},
"Ethernet45" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet45" ] },
"index" : "44",
"lanes" : "44"
},
"Ethernet46" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet46" ] },
"index" : "45",
"lanes" : "45"
},
"Ethernet47" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet47" ] },
"index" : "46",
"lanes" : "46"
},
"Ethernet48" : {
"breakout_modes" : { "1x25G[10G]" : [ "Ethernet48" ] },
"index" : "47",
"lanes" : "47"
},
"Ethernet49" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet49" ],
"2x50G" : [
"Ethernet49",
"Ethernet51"
],
"4x25G[10G]" : [
"Ethernet49",
"Ethernet50",
"Ethernet51",
"Ethernet52"
]
},
"index" : "48,48,48,48",
"lanes" : "48,49,50,51"
},
"Ethernet53" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet53" ],
"2x50G" : [
"Ethernet53",
"Ethernet55"
],
"4x25G[10G]" : [
"Ethernet53",
"Ethernet54",
"Ethernet55",
"Ethernet56"
]
},
"index" : "49,49,49,49",
"lanes" : "52,53,54,55"
},
"Ethernet57" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet57" ],
"2x50G" : [
"Ethernet57",
"Ethernet59"
],
"4x25G[10G]" : [
"Ethernet57",
"Ethernet58",
"Ethernet59",
"Ethernet60"
]
},
"index" : "50,50,50,50",
"lanes" : "56,57,58,59"
},
"Ethernet61" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet61" ],
"2x50G" : [
"Ethernet61",
"Ethernet63"
],
"4x25G[10G]" : [
"Ethernet61",
"Ethernet62",
"Ethernet63",
"Ethernet64"
]
},
"index" : "51,51,51,51",
"lanes" : "60,61,62,63"
},
"Ethernet65" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet65" ],
"2x50G" : [
"Ethernet65",
"Ethernet67"
],
"4x25G[10G]" : [
"Ethernet65",
"Ethernet66",
"Ethernet67",
"Ethernet68"
]
},
"index" : "52,52,52,52",
"lanes" : "64,65,66,67"
},
"Ethernet69" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet69" ],
"2x50G" : [
"Ethernet69",
"Ethernet71"
],
"4x25G[10G]" : [
"Ethernet69",
"Ethernet70",
"Ethernet71",
"Ethernet72"
]
},
"index" : "53,53,53,53",
"lanes" : "68,69,70,71"
},
"Ethernet73" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet73" ],
"2x50G" : [
"Ethernet73",
"Ethernet75"
],
"4x25G[10G]" : [
"Ethernet73",
"Ethernet74",
"Ethernet75",
"Ethernet76"
]
},
"index" : "54,54,54,54",
"lanes" : "72,73,74,75"
},
"Ethernet77" : {
"breakout_modes" : {
"1x100G[40G]" : [ "Ethernet77" ],
"2x50G" : [
"Ethernet77",
"Ethernet79"
],
"4x25G[10G]" : [
"Ethernet77",
"Ethernet78",
"Ethernet79",
"Ethernet80"
]
},
"index" : "55,55,55,55",
"lanes" : "76,77,78,79"
}
}
}

View File

@ -0,0 +1 @@
barefoot

View File

@ -0,0 +1,3 @@
{
"skip_ledd": true
}

View File

@ -0,0 +1,44 @@
# libsensors configuration file
chip "net_psoc-*"
ignore temp6
label temp1 "FrontSide Temperature"
label temp2 "FanBoard Temperature"
label temp3 "ASIC Temperature"
label temp4 "Center Temperature"
label temp5 "CPU Board Temperature"
label temp6 "Switch die temperature"
label temp7 "PSU1 Temperature1"
label temp8 "PSU2 Temperature1"
label temp9 "PSU1 Temperature2"
label temp10 "PSU2 Temperature2"
label fan1 "FanModule1 Front RPM"
label fan2 "FanModule1 Rear RPM"
label fan3 "FanModule2 Front RPM"
label fan4 "FanModule2 Rear RPM"
label fan5 "FanModule3 Front RPM"
label fan6 "FanModule3 Rear RPM"
label fan7 "FanModule4 Front RPM"
label fan8 "FanModule4 Rear RPM"
label fan9 "FanModule5 Front RPM"
label fan10 "FanModule5 Rear RPM"
label pwm6 "PSU1 FAN PWM"
label pwm7 "PSU2 FAN PWM"
label fan11 "PSU1 FAN RPM"
label fan12 "PSU2 FAN RPM"
label in1 "PSU1 Input Voltage"
label in2 "PSU2 Input Voltage"
label curr1 "PSU1 Input Current"
label curr2 "PSU2 Input Current"
label power1 "PSU1 Input Power"
label power2 "PSU2 Input Power"
label in3 "PSU1 Output Voltage"
label in4 "PSU2 Output Voltage"
label curr3 "PSU1 Output Current"
label curr4 "PSU2 Output Current"
label power3 "PSU1 Output Power"
label power4 "PSU2 Output Power"
compute power1 @*1000,@/1000
compute power2 @*1000,@/1000
compute power3 @*1000,@/1000
compute power4 @*1000,@/1000

View File

@ -13,6 +13,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(WNC_OSW1800_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9180_32X_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9280_64X_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(BFN_MONTARA_QS_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(NETBERG_AURORA_610_PLATFORM_MODULE)
ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)
$(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES))

View File

@ -0,0 +1,16 @@
# Netberg Aurora 610 Platform modules
NETBERG_AURORA_610_PLATFORM_MODULE_VERSION = 1.1.0
export NETBERG_AURORA_610_PLATFORM_MODULE_VERSION
NETBERG_AURORA_610_PLATFORM_MODULE = sonic-platform-netberg-aurora-610_$(NETBERG_AURORA_610_PLATFORM_MODULE_VERSION)_amd64.deb
$(NETBERG_AURORA_610_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-netberg
$(NETBERG_AURORA_610_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
$(NETBERG_AURORA_610_PLATFORM_MODULE)_PLATFORM = x86_64-netberg_aurora_610-r0
SONIC_DPKG_DEBS += $(NETBERG_AURORA_610_PLATFORM_MODULE)
export NETBERG_AURORA_610_PLATFORM_MODULE
#$(eval $(call add_extra_package,$(NETBERG_AURORA_610_PLATFORM_MODULE)))

View File

@ -5,6 +5,7 @@ include $(PLATFORM_PATH)/platform-modules-accton.mk
include $(PLATFORM_PATH)/platform-modules-bfn-newport.mk
include $(PLATFORM_PATH)/platform-modules-wnc-osw1800.mk
include $(PLATFORM_PATH)/platform-modules-ingrasys.mk
include $(PLATFORM_PATH)/platform-modules-netberg.mk
include $(PLATFORM_PATH)/bfn-sai.mk
include $(PLATFORM_PATH)/docker-syncd-bfn.mk
include $(PLATFORM_PATH)/docker-syncd-bfn-rpc.mk

View File

@ -0,0 +1,23 @@
# kernel module build
*.o
*.ko
*.mod.c
*.mod.o
*.cmd
Module.symvers
modules.order
# debian packaging
*.debhelper
*.log
DEBIAN
.tmp_versions
.finished.build
*.substvars
# python
*.pyc
/build
/*.egg-info
/venv
/.pybuild

View File

@ -0,0 +1,6 @@
obj-m += net_cpld.o
obj-m += net_platform.o
obj-m += net_psoc.o
obj-m += swps.o
swps-objs := net_swps.o net_mux.o io_expander.o transceiver.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,165 @@
#ifndef IO_EXPANDER_H
#define IO_EXPANDER_H
#include <linux/types.h>
/* IOEXP type define (SFP series) */
#define IOEXP_TYPE_AURORA_610_GA_NABC (10105)
#define IOEXP_TYPE_AURORA_610_NABC (10106)
#define IOEXP_TYPE_AURORA_610_1ABC (10108)
#define IOEXP_TYPE_AURORA_610_3ABC (10109)
/* IOEXP type define (QSFP series) */
#define IOEXP_TYPE_AURORA_610_GA_7ABC (10213)
#define IOEXP_TYPE_AURORA_610_7ABC (10214)
#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215)
/* CPLD type define */
#define CPLD_TYPE_COTTONWOOD (10301)
/* IOEXP mode define */
#define IOEXP_MODE_POLLING (19000)
#define IOEXP_MODE_DIRECT (19001)
/* IOEXP state define */
#define STATE_IOEXP_NORMAL (0)
#define STATE_IOEXP_INIT (-1)
#define STATE_IOEXP_ABNORMAL (-2)
/* IOEXP error code define */
#define ERR_IOEXP_NOTSUPPORT (-100)
#define ERR_IOEXP_UNINIT (-101)
#define ERR_IOEXP_BADCONF (-102)
#define ERR_IOEXP_ABNORMAL (-103)
#define ERR_IOEXP_NOSTATE (-104)
#define ERR_IOEXP_BADINPUT (-105)
#define ERR_IOEXP_UNEXCPT (-199)
#define SWPS_INFO(fmt, args...) printk( KERN_INFO "[SWPS] " fmt, ##args)
#define SWPS_WARN(fmt, args...) printk( KERN_WARNING "[SWPS] " fmt, ##args)
#define SWPS_ERR(fmt, args...) printk( KERN_ERR "[SWPS] " fmt, ##args)
#ifdef DEBUG_SWPS
# define SWPS_DEBUG(fmt, args...) printk( KERN_DEBUG "[SWPS] " fmt, ##args)
#else
# define SWPS_DEBUG(fmt, args...)
#endif
struct ioexp_addr_s {
int chan_id;
int chip_addr;
int read_offset[8];
int write_offset[8];
int conf_offset[8];
uint8_t data_default[8];
uint8_t conf_default[8];
};
struct ioexp_i2c_s {
int chip_id;
struct i2c_client *i2c_client_p;
struct ioexp_i2c_s *next;
};
struct ioexp_bitmap_s {
int chip_id; /* IOEXP chip id */
int ioexp_voffset; /* IOEXP virtual offset */
int bit_shift;
};
struct ioexp_map_s {
int chip_amount; /* Number of chips that IOEXP object content */
int data_width; /* Number of (Read/Write/Config) bytes */
struct ioexp_addr_s *map_addr; /* Chip address info */
struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */
struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_tx_fault[10]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_rxlos[10]; /* IOEXP for SFP */
struct ioexp_bitmap_s map_reset[10]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_lpmod[10]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_modsel[10]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs0[10]; /* IOEXP for QSFP */
struct ioexp_bitmap_s map_hard_rs1[10]; /* IOEXP for QSFP */
};
struct ioexp_data_s {
uint8_t data[8];
};
struct ioexp_obj_s {
/* ============================
* Object public property
* ============================
*/
int ioexp_id;
int ioexp_type;
/* ============================
* Object private property
* ============================
*/
struct ioexp_data_s chip_data[16]; /* Max: 8-ioexp in one virt-ioexp(ioexp_obj) */
struct ioexp_map_s *ioexp_map_p;
struct ioexp_obj_s *next;
struct ioexp_i2c_s *i2c_head_p;
struct mutex lock;
int mode;
int state;
/* ===========================================
* Object public functions
* ===========================================
*/
int (*get_present)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_fault)(struct ioexp_obj_s *self, int virt_offset);
int (*get_rxlos)(struct ioexp_obj_s *self, int virt_offset);
int (*get_tx_disable)(struct ioexp_obj_s *self, int virt_offset);
int (*get_reset)(struct ioexp_obj_s *self, int virt_offset);
int (*get_lpmod)(struct ioexp_obj_s *self, int virt_offset);
int (*get_modsel)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs0)(struct ioexp_obj_s *self, int virt_offset);
int (*get_hard_rs1)(struct ioexp_obj_s *self, int virt_offset);
int (*set_tx_disable)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_reset)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_lpmod)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_modsel)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs0)(struct ioexp_obj_s *self, int virt_offset, int input_val);
int (*set_hard_rs1)(struct ioexp_obj_s *self, int virt_offset, int input_val);
/* ===========================================
* Object private functions
* ===========================================
*/
int (*init)(struct ioexp_obj_s *self);
int (*check)(struct ioexp_obj_s *self);
int (*update_all)(struct ioexp_obj_s *self, int show_err, char *caller_name);
int (*fsm_4_direct)(struct ioexp_obj_s* self);
int (*fsm_4_polling)(struct ioexp_obj_s* self);
};
struct ioexp_obj_s* get_ioexp_obj(int ioexp_id);
int create_ioexp_obj(int ioexp_id,
int ioexp_type,
struct ioexp_addr_s *addr_map_p,
int run_mode);
int init_ioexp_objs(void);
int check_ioexp_objs(void);
void clean_ioexp_objs(void);
void unlock_ioexp_all(void);
int lock_ioexp_all(void);
int check_channel_tier_1(void);
int resync_channel_tier_1(void);
/* Macro for bit control */
#define SWP_BIT_SET(byte_val,bit_shift) ((byte_val) |= (1<<(bit_shift)))
#define SWP_BIT_CLEAR(byte_val,bit_shift) ((byte_val) &= ~(1<<(bit_shift)))
#endif /* IO_EXPANDER_H */

View File

@ -0,0 +1,471 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
//#include "I2CHostCommunication.h"
#define USE_SMBUS 1
/* definition */
#define CPLD_INFO_OFFSET 0x00
#define CPLD_PSU_OFFSET 0x08
#define CPLD_LED_OFFSET 0x0E
#define CPLD_LED_STATU_OFFSET 0x0D
#define CPLD_CTL_OFFSET 0x0C
#define CPLD_BIOSCS_OFFSET 0x04
/* Each client has this additional data */
struct cpld_data {
struct device *hwmon_dev;
struct mutex update_lock;
};
/*-----------------------------------------------------------------------*/
static ssize_t cpld_i2c_read(struct i2c_client *client, u8 *buf, u8 offset, size_t count)
{
#if USE_SMBUS
int i;
for(i=0; i<count; i++) {
buf[i] = i2c_smbus_read_byte_data(client, offset+i);
}
return count;
#else
struct i2c_msg msg[2];
char msgbuf[2];
int status;
memset(msg, 0, sizeof(msg));
msgbuf[0] = offset;
msg[0].addr = client->addr;
msg[0].buf = msgbuf;
msg[0].len = 1;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].buf = buf;
msg[1].len = count;
status = i2c_transfer(client->adapter, msg, 2);
if(status == 2)
status = count;
return status;
#endif
}
static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned offset, size_t count)
{
#if USE_SMBUS
int i;
for(i=0; i<count; i++) {
i2c_smbus_write_byte_data(client, offset+i, buf[i]);
}
return count;
#else
struct i2c_msg msg;
int status;
u8 writebuf[64];
int i = 0;
msg.addr = client->addr;
msg.flags = 0;
/* msg.buf is u8 and casts will mask the values */
msg.buf = writebuf;
msg.buf[i++] = offset;
memcpy(&msg.buf[i], buf, count);
msg.len = i + count;
status = i2c_transfer(client->adapter, &msg, 1);
if (status == 1)
status = count;
return status;
#endif
}
/*-----------------------------------------------------------------------*/
/* sysfs attributes for hwmon */
static ssize_t show_info(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[4];
memset(b, 0, 4);
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, b, CPLD_INFO_OFFSET, 4);
mutex_unlock(&data->update_lock);
if(status != 4) return sprintf(buf, "read cpld info fail\n");
status = sprintf (buf, "The CPLD release date is %02d/%02d/%d.\n", b[2] & 0xf, (b[3] & 0x1f), 2014+(b[2] >> 4)); /* mm/dd/yyyy*/
status = sprintf (buf, "%sThe PCB version is %X%X\n", buf, b[0]>>4, b[0]&0xf);
status = sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, b[1]>>4, b[1]&0xf);
return strlen(buf);
}
static ssize_t show_ctl(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[1];
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, b, CPLD_CTL_OFFSET, 1);
mutex_unlock(&data->update_lock);
if(status != 1) return sprintf(buf, "read cpld ctl fail\n");
status = sprintf (buf, "0x%X\n", b[0]);
return strlen(buf);
}
static ssize_t set_ctl(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
u8 temp = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
cpld_i2c_read(client, &byte, CPLD_CTL_OFFSET, 1);
if(temp) byte |= (1<<0);
else byte &= ~(1<<0);
cpld_i2c_write(client, &byte, CPLD_CTL_OFFSET, 1);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_bios_cs(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
//struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 b[1];
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, b, CPLD_BIOSCS_OFFSET, 1);
mutex_unlock(&data->update_lock);
if(status != 1) return sprintf(buf, "read cpld BIOS_CS fail\n");
status = sprintf (buf, "0x%X\n", b[0] & 0x01);
return strlen(buf);
}
static ssize_t set_bios_cs(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
//struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
u8 temp = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
cpld_i2c_read(client, &byte, CPLD_BIOSCS_OFFSET, 1);
if(temp) byte |= 0x01;
else byte &= ~(0x01);
cpld_i2c_write(client, &byte, CPLD_BIOSCS_OFFSET, 1);
mutex_unlock(&data->update_lock);
return count;
}
static char* led_str[] = {
"OFF", //000
"0.5 Hz", //001
"1 Hz", //010
"2 Hz", //011
"4 Hz", //100
"NA", //101
"NA", //110
"ON", //111
};
static ssize_t show_led(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
int shift = (attr->index == 0)?3:0;
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1);
mutex_unlock(&data->update_lock);
if(status != 1) return sprintf(buf, "read cpld offset 0x%x\n", CPLD_LED_OFFSET);
byte = (byte >> shift) & 0x7;
status = sprintf (buf, "%d: %s\n", byte, led_str[byte]);
return strlen(buf);
}
static ssize_t set_led(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 temp = simple_strtol(buf, NULL, 16);
u8 byte;
int shift = (attr->index == 0)?3:0;
temp &= 0x7;
//validate temp value: 0,1,2,3,7, TBD
mutex_lock(&data->update_lock);
cpld_i2c_read(client, &byte, CPLD_LED_OFFSET, 1);
byte &= ~(0x7<<shift);
byte |= (temp<<shift);
cpld_i2c_write(client, &byte, CPLD_LED_OFFSET, 1);
mutex_unlock(&data->update_lock);
return count;
}
/*
CPLD report the PSU0 status
000 = PSU normal operation
100 = PSU fault
010 = PSU unpowered
111 = PSU not installed
7 6 | 5 4 3 | 2 1 0
----------------------
| psu0 | psu1
*/
static char* psu_str[] = {
"normal", //000
"NA", //001
"unpowered", //010
"NA", //011
"fault", //100
"NA", //101
"NA", //110
"not installed", //111
};
static ssize_t show_psu(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
int shift = (attr->index == 1)?0:3;
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, &byte, CPLD_PSU_OFFSET, 1);
mutex_unlock(&data->update_lock);
byte = (byte >> shift) & 0x7;
status = sprintf (buf, "%d : %s\n", byte, psu_str[byte]);
return strlen(buf);
}
static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0);
static SENSOR_DEVICE_ATTR(ctl, S_IWUSR|S_IRUGO, show_ctl, set_ctl, 0);
static SENSOR_DEVICE_ATTR(grn_led, S_IWUSR|S_IRUGO, show_led, set_led, 0);
static SENSOR_DEVICE_ATTR(red_led, S_IWUSR|S_IRUGO, show_led, set_led, 1);
static SENSOR_DEVICE_ATTR(psu0, S_IRUGO, show_psu, 0, 0);
static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 1);
static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_bios_cs, 0);
static struct attribute *cpld_attributes[] = {
//info
&sensor_dev_attr_info.dev_attr.attr,
&sensor_dev_attr_ctl.dev_attr.attr,
&sensor_dev_attr_grn_led.dev_attr.attr,
&sensor_dev_attr_red_led.dev_attr.attr,
&sensor_dev_attr_psu0.dev_attr.attr,
&sensor_dev_attr_psu1.dev_attr.attr,
&sensor_dev_attr_bios_cs.dev_attr.attr,
NULL
};
static const struct attribute_group cpld_group = {
.attrs = cpld_attributes,
};
static struct attribute *cpld2_attributes[] = {
//info
&sensor_dev_attr_info.dev_attr.attr,
NULL
};
static const struct attribute_group cpld2_group = {
.attrs = cpld2_attributes,
};
/*-----------------------------------------------------------------------*/
/* device probe and removal */
static int
cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct cpld_data *data;
int status;
// printk("+%s \n", __func__);
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -EIO;
data = kzalloc(sizeof(struct cpld_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Register sysfs hooks */
if(id->driver_data==1) // CPLD2
status = sysfs_create_group(&client->dev.kobj, &cpld2_group);
else // default CPLD1
status = sysfs_create_group(&client->dev.kobj, &cpld_group);
if (status)
goto exit_free;
data->hwmon_dev = hwmon_device_register_with_info(&client->dev, "net_cpld", NULL, NULL, NULL);
if (IS_ERR(data->hwmon_dev)) {
status = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "%s: sensor '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &cpld_group);
exit_free:
i2c_set_clientdata(client, NULL);
kfree(data);
return status;
}
static int cpld_remove(struct i2c_client *client)
{
struct cpld_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &cpld_group);
i2c_set_clientdata(client, NULL);
kfree(data);
return 0;
}
static const struct i2c_device_id cpld_ids[] = {
{ "net_cpld" , 0, },
{ "net_cpld2", 1, },
{ /* LIST END */ }
};
MODULE_DEVICE_TABLE(i2c, cpld_ids);
static struct i2c_driver cpld_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "net_cpld",
},
.probe = cpld_probe,
.remove = cpld_remove,
.id_table = cpld_ids,
};
/*-----------------------------------------------------------------------*/
/* module glue */
static int __init net_cpld_init(void)
{
return i2c_add_driver(&cpld_driver);
}
static void __exit net_cpld_exit(void)
{
i2c_del_driver(&cpld_driver);
}
MODULE_AUTHOR("Netberg <support@netbergtw.com>");
MODULE_DESCRIPTION("Netberg cpld driver");
MODULE_LICENSE("GPL");
module_init(net_cpld_init);
module_exit(net_cpld_exit);

View File

@ -0,0 +1,544 @@
#include <asm/io.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include "io_expander.h"
#include "net_mux.h"
/* For build single module using (Ex: ONL platform) */
#include <linux/module.h>
static struct mux_obj_s *mux_head_p = NULL;
/* ========== MUX object functions ==========
*/
static int
_setup_i2c_value(struct mux_obj_s *self, int offset, int value){
return i2c_smbus_write_byte_data(self->i2c_client_p, offset, value);
}
static int
_setup_i2c_client(struct mux_obj_s *self, int chan_id, int addr){
struct i2c_adapter *adap = NULL;
char *emsg = "ERR";
adap = i2c_get_adapter(chan_id);
if (!adap){
emsg = "can't get adapter";
goto err_setup_i2c_client;
}
self->i2c_client_p = kzalloc(sizeof(*self->i2c_client_p), GFP_KERNEL);
if (!self->i2c_client_p){
emsg = "can't kzalloc client";
goto err_setup_i2c_client;
}
self->i2c_client_p->adapter = adap;
self->i2c_client_p->addr = addr;
return 0;
err_setup_i2c_client:
SWPS_ERR("%s: %s\n", __func__, emsg);
return ERR_MUX_UNEXCPT;
}
int
_common_force_pull_gpio(int mem_addr,
int input,
int bit_offset){
unsigned int val = 0;
unsigned int targ = 0;
/* Get current value */
val = inl(mem_addr);
if (val == 0) {
SWPS_ERR("%s: inl:%d fail!\n", __func__, val);
return -1;
}
/* Count target value */
switch (input) {
case 0: /* Pull Low */
targ = (val & (~(1 << bit_offset)));
break;
case 1: /* Pull high */
targ = (val | (1 << bit_offset));
break;
default:
SWPS_ERR("%s: input state:%d incorrect!\n",
__func__, input);
return -1;
}
/* Setup gpio */
outl(targ, mem_addr);
if (targ != inl(mem_addr)){
SWPS_ERR("%s: outl:%d fail!\n", __func__, targ);
return -1;
}
SWPS_DEBUG("%s: done.\n", __func__);
return 0;
}
int
rangeley_force_pull_high(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
rangeley_force_pull_low(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
hedera_force_pull_high(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 1, 5);
}
int
hedera_force_pull_low(struct mux_obj_s *self){
return _common_force_pull_gpio(MUX_RST_MEM_ADDR_HEDERA, 0, 5);
}
int
normal_gpio_pull_high(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 1);
}
int
normal_gpio_pull_low(struct mux_obj_s *self){
return gpio_direction_output(self->gpio_num, 0);
}
int
cpld_rst_all_4_pull_low(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_cpld_rst_all_4_pull_low;
setlow_cpld_rst_all_4_c0_a77_70_74_rst_all:
err = _setup_i2c_value(self, 0x70, 0x0);
if (err < 0) {
emsg = "setup 0x70 fail";
goto err_cpld_rst_all_4_pull_low;
}
err = _setup_i2c_value(self, 0x74, 0x01);
if (err < 0) {
emsg = "setup 0x74 fail";
goto err_cpld_rst_all_4_pull_low;
}
return 0;
err_cpld_rst_all_4_pull_low:
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
__func__, emsg, self->gpio_num, err);
return ERR_MUX_UNEXCPT;
}
int
cpld_rst_all_4_pull_high(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_cpld_rst_all_4_pull_high;
sethigh_cpld_rst_all_4_c0_a77_70_74_rst_all:
err = _setup_i2c_value(self, 0x70, 0xfe);
if (err < 0) {
emsg = "setup 0x70 fail";
goto err_cpld_rst_all_4_pull_high;
}
err = _setup_i2c_value(self, 0x74, 0x03);
if (err < 0) {
emsg = "setup 0x74 fail";
goto err_cpld_rst_all_4_pull_high;
}
return 0;
err_cpld_rst_all_4_pull_high:
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
__func__, emsg, self->gpio_num, err);
return ERR_MUX_UNEXCPT;
}
int
pca9548_reset_mux_all(struct mux_obj_s *self){
/* [Note] Power-on reset (PCA9548A-NXP)
* When power is applied to VDD, an internal Power-On Reset (POR)
* holds the PCA9548A in a reset condition until VDD has reached
* VPOR. At this point, the reset condition is released and the
* PCA9548A register and I2C-bus state machine are initialized to
* their default states (all zeroes) causing all the channels to
* be deselected. Thereafter, VDD must be lowered below 0.2 V for
* at least 5 us in order to reset the device.
*/
if (self->_pull_low(self) < 0) {
SWPS_ERR("%s: _pull_low fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS_PCA9548);
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: _pull_high fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS_PCA9548);
return 0;
}
int
cpld_reset_mux_all(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_cpld_reset_mux_all;
reset_cpld_rst_all_4_c0_a77_70_74_rst_all:
if (self->_pull_low(self) < 0) {
emsg = "_pull_low fail";
goto err_cpld_reset_mux_all;
}
mdelay(MUX_RST_WAIT_MS_CPLD);
return 0;
err_cpld_reset_mux_all:
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
__func__, emsg, self->gpio_num, err);
return ERR_MUX_UNEXCPT;
}
int
common_reset_mux_all(struct mux_obj_s *self){
SWPS_ERR("%s: not ready!\n", __func__);
return -1;
}
int
init_gpio_4_force(struct mux_obj_s *self){
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: setup default fail!\n", __func__);
return -1;
}
return 0;
}
int
init_gpio_4_normal(struct mux_obj_s *self){
int err = 0;
char *emsg = "ERR";
if (!gpio_is_valid(self->gpio_num)) {
emsg = "GPIO invalid";
goto err_init_gpio_4_normal;
}
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
if (err < 0) {
emsg = "gpio_request fail";
goto err_init_gpio_4_normal;
}
err = self->_pull_high(self);
if (err < 0) {
emsg = "setup default fail";
goto err_init_gpio_4_normal;
}
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
return 0;
err_init_gpio_4_normal:
SWPS_ERR("%s: %s <gpio>:%d <err>:%d\n",
__func__, emsg, self->gpio_num, err);
return -1;
}
int
init_cpld_4_rst_all(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
int chan = ERR_MUX_UNEXCPT;
int addr = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto init_cpld_i2c_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_init_cpld_4_rst_all;
init_cpld_i2c_c0_a77_70_74_rst_all:
chan = 0;
addr = 0x77;
err = _setup_i2c_client(self, chan, addr);
if (err < 0) {
emsg = "_setup_i2c_client fail";
goto err_init_cpld_4_rst_all;
}
err = self->_pull_high(self);
if (err < 0) {
emsg = "setup default value fail";
goto err_init_cpld_4_rst_all;
}
SWPS_DEBUG("%s: init_cpld_i2c_c0_a77_70_74_rst_all ok", __func__);
return 0;
err_init_cpld_4_rst_all:
SWPS_INFO("%s: %s <type>:%d <err>:%d\n",
__func__, emsg, self->gpio_num, err);
return ERR_MUX_UNEXCPT;
}
int
clean_gpio_4_common(struct mux_obj_s *self){
if (!self) return 0;
if (!gpio_is_valid(self->gpio_num)) return 0;
self->_pull_high(self);
gpio_free(mux_head_p->gpio_num);
return 0;
}
int
clean_cpld_4_rst_all(struct mux_obj_s *self){
if (!self) return 0;
self->_pull_high(self);
if (self->i2c_client_p) {
i2c_put_adapter(self->i2c_client_p->adapter);
kfree(self->i2c_client_p);
}
return 0;
}
static int
_setup_muxctl_cb(struct mux_obj_s *self,
unsigned gpio){
char mod_dsc[32] = "ERR";
switch (gpio) {
case MUX_RST_GPIO_FORCE_RANGELEY:
self->gpio_num = gpio;
self->_pull_low = rangeley_force_pull_low;
self->_pull_high = rangeley_force_pull_high;
self->_init = init_gpio_4_force;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Rangeley force mode");
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_FORCE_HEDERA:
self->gpio_num = gpio;
self->_pull_low = hedera_force_pull_low;
self->_pull_high = hedera_force_pull_high;
self->_init = init_gpio_4_force;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Hedera force mode");
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_48_PCA9548:
case MUX_RST_GPIO_69_PCA9548:
case MUX_RST_GPIO_249_PCA9548:
case MUX_RST_GPIO_500_PCA9548:
case MUX_RST_GPIO_505_PCA9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Normal mode <gpio>:%d", (int)gpio);
goto ok_setup_muxctl_cb;
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
self->gpio_num = gpio;
self->_pull_low = cpld_rst_all_4_pull_low;
self->_pull_high = cpld_rst_all_4_pull_high;
self->_init = init_cpld_4_rst_all;
self->_clean = clean_cpld_4_rst_all;
self->reset = cpld_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "CPLD mode <type>:%d", (int)gpio);
goto ok_setup_muxctl_cb;
default:
break;
}
SWPS_ERR("%s: Unexpected GPIO:%d\n", __func__, gpio);
return -1;
ok_setup_muxctl_cb:
SWPS_INFO("muxctl: %s.\n", mod_dsc);
return 0;
}
/* ========== MUX public functions ==========
*/
void
clean_mux_objs(void){
struct mux_obj_s *curr_p = mux_head_p;
struct mux_obj_s *next_p = NULL;
if (!curr_p) {
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
return;
}
while (curr_p) {
next_p = curr_p->next;
curr_p->_clean(curr_p);
kfree(curr_p);
curr_p = next_p;
}
SWPS_DEBUG("%s: done.\n", __func__);
}
EXPORT_SYMBOL(clean_mux_objs);
int
reset_mux_objs(void){
if (!mux_head_p) {
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
return -1;
}
if (mux_head_p->reset(mux_head_p) < 0){
SWPS_ERR("%s: reset fail!\n", __func__);
return -1;
}
return 0;
}
EXPORT_SYMBOL(reset_mux_objs);
struct mux_obj_s *
_create_mux_obj(unsigned gpio){
char *emsg = "ERR";
struct mux_obj_s *obj_p = NULL;
obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
if (!obj_p) {
emsg = "kzalloc fail!";
goto err_create_mux_obj_1;
}
if (_setup_muxctl_cb(obj_p, gpio) < 0){
emsg = "_setup_muxctl_cb fail!";
goto err_create_mux_obj_2;
}
if (obj_p->_init(obj_p) < 0) {
emsg = "_init() fail!";
goto err_create_mux_obj_2;
}
SWPS_DEBUG("%s: created MUX object <id>:%d\n", __func__, gpio);
return obj_p;
err_create_mux_obj_2:
kfree(obj_p);
err_create_mux_obj_1:
SWPS_ERR("%s: %s <type>:%d\n", __func__, emsg, gpio);
return NULL;
}
int
init_mux_objs(unsigned gpio){
struct mux_obj_s *curr_p = NULL;
char *emsg = "ERR";
/* Create MUX control object */
if (mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
clean_mux_objs();
}
/* Currently, it is using single muxctl architecture.
* In the future, it may use the multi-muxctl.
* (Ex: Aurora 610's advance I2C control)
*/
curr_p = _create_mux_obj(gpio);
if (!curr_p) {
emsg = "_create_mux_obj fail";
goto err_init_mux_objs;
}
curr_p->next = NULL;
mux_head_p = curr_p;
SWPS_DEBUG("%s: all done. <type>:%d\n", __func__, gpio);
return 0;
err_init_mux_objs:
clean_mux_objs();
SWPS_ERR("%s: %s\n", __func__, emsg);
return -1;
}
EXPORT_SYMBOL(init_mux_objs);
/* For single ko module
* => You need to declare MODULE_LICENSE If you want to build single module along.
* => Ex: For ONL platform
*/
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,51 @@
#ifndef NET_MUX_H
#define NET_MUX_H
#include <linux/types.h>
/* MUX basic information */
#define MUX_GPIO_LABEL "SWPS_RST_MUX"
/* MUX reset GPIO define */
#define MUX_RST_GPIO_FORCE (30100)
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
#define MUX_RST_GPIO_48_PCA9548 (48)
#define MUX_RST_GPIO_69_PCA9548 (69)
#define MUX_RST_GPIO_249_PCA9548 (249)
#define MUX_RST_GPIO_500_PCA9548 (500)
#define MUX_RST_GPIO_505_PCA9548 (505)
#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201)
/* MUX relate value define */
#define MUX_RST_WAIT_MS_PCA9548 (1)
#define MUX_RST_WAIT_MS_CPLD (10)
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
/* MUX error code define */
#define ERR_MUX_UNEXCPT (-399)
struct mux_obj_s {
struct i2c_client *i2c_client_p;
struct mux_obj_s *next;
unsigned gpio_num;
int (*_pull_high)(struct mux_obj_s *self);
int (*_pull_low)(struct mux_obj_s *self);
int (*_init)(struct mux_obj_s *self);
int (*_clean)(struct mux_obj_s *self);
int (*reset)(struct mux_obj_s *self);
};
void clean_mux_objs(void);
int reset_mux_objs(void);
int init_mux_objs(unsigned gpio);
#endif /* NET_MUX_H */

View File

@ -0,0 +1,281 @@
#include <linux/i2c.h>
#include <linux/platform_data/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
// #include <linux/platform_data/pca954x.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
// #define GPIO_BASE 0 // in kernel 4.x GPIO_BASE =0 ; in kernel 3.16.x , GPIO_BASE=180
struct net_i2c_board_info {
int ch;
int size;
struct i2c_board_info *board_info;
int probe;
};
#define bus_id(id) (id)
#define SCL_PIN 58
#define SDA_PIN 75
struct pca954x_platform_mode {
int adap_id;
unsigned int deselect_on_exit:1;
unsigned int class;
};
/* Per mux/switch data, used with i2c_register_board_info */
struct pca954x_platform_data {
struct pca954x_platform_mode *modes;
int num_modes;
};
static struct pca954x_platform_mode mux_modes_0[] = {
{.adap_id = bus_id(2),}, {.adap_id = bus_id(3),},
{.adap_id = bus_id(4),}, {.adap_id = bus_id(5),},
{.adap_id = bus_id(6),}, {.adap_id = bus_id(7),},
{.adap_id = bus_id(8),}, {.adap_id = bus_id(9),},
};
static struct pca954x_platform_mode mux_modes_0_0[] = {
{.adap_id = bus_id(10),}, {.adap_id = bus_id(11),},
{.adap_id = bus_id(12),}, {.adap_id = bus_id(13),},
{.adap_id = bus_id(14),}, {.adap_id = bus_id(15),},
{.adap_id = bus_id(16),}, {.adap_id = bus_id(17),},
};
static struct pca954x_platform_mode mux_modes_0_1[] = {
{.adap_id = bus_id(18),}, {.adap_id = bus_id(19),},
{.adap_id = bus_id(20),}, {.adap_id = bus_id(21),},
{.adap_id = bus_id(22),}, {.adap_id = bus_id(23),},
{.adap_id = bus_id(24),}, {.adap_id = bus_id(25),},
};
static struct pca954x_platform_mode mux_modes_0_2[] = {
{.adap_id = bus_id(26),}, {.adap_id = bus_id(27),},
{.adap_id = bus_id(28),}, {.adap_id = bus_id(29),},
{.adap_id = bus_id(30),}, {.adap_id = bus_id(31),},
{.adap_id = bus_id(32),}, {.adap_id = bus_id(33),},
};
static struct pca954x_platform_mode mux_modes_0_3[] = {
{.adap_id = bus_id(34),}, {.adap_id = bus_id(35),},
{.adap_id = bus_id(36),}, {.adap_id = bus_id(37),},
{.adap_id = bus_id(38),}, {.adap_id = bus_id(39),},
{.adap_id = bus_id(40),}, {.adap_id = bus_id(41),},
};
static struct pca954x_platform_mode mux_modes_0_4[] = {
{.adap_id = bus_id(42),}, {.adap_id = bus_id(43),},
{.adap_id = bus_id(44),}, {.adap_id = bus_id(45),},
{.adap_id = bus_id(46),}, {.adap_id = bus_id(47),},
{.adap_id = bus_id(48),}, {.adap_id = bus_id(49),},
};
static struct pca954x_platform_mode mux_modes_0_5[] = {
{.adap_id = bus_id(50),}, {.adap_id = bus_id(51),},
{.adap_id = bus_id(52),}, {.adap_id = bus_id(53),},
{.adap_id = bus_id(54),}, {.adap_id = bus_id(55),},
{.adap_id = bus_id(56),}, {.adap_id = bus_id(57),},
};
static struct pca954x_platform_mode mux_modes_0_6[] = {
{.adap_id = bus_id(58),}, {.adap_id = bus_id(59),},
{.adap_id = bus_id(60),}, {.adap_id = bus_id(61),},
{.adap_id = bus_id(62),}, {.adap_id = bus_id(63),},
{.adap_id = bus_id(64),}, {.adap_id = bus_id(65),},
};
//no i2c device driver attach to mux 7
static struct pca954x_platform_data mux_data_0 = {
.modes = mux_modes_0,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_0 = {
.modes = mux_modes_0_0,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_1 = {
.modes = mux_modes_0_1,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_2 = {
.modes = mux_modes_0_2,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_3 = {
.modes = mux_modes_0_3,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_4 = {
.modes = mux_modes_0_4,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_5 = {
.modes = mux_modes_0_5,
.num_modes = 8,
};
static struct pca954x_platform_data mux_data_0_6 = {
.modes = mux_modes_0_6,
.num_modes = 8,
};
static struct i2c_board_info i2c_device_info0[] __initdata = {
// {"net_cpld", 0, 0x77, 0, 0, 0},//cpld
{"pca9548", 0, 0x70, "pca9548-1", (void *)&mux_data_0, 0, 0},
};
static struct i2c_board_info i2c_device_info2[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-2", (void *)&mux_data_0_0, 0, 0},
};
static struct i2c_board_info i2c_device_info3[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-3", (void *)&mux_data_0_1, 0, 0},
};
static struct i2c_board_info i2c_device_info4[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-4", (void *)&mux_data_0_2, 0, 0},
};
static struct i2c_board_info i2c_device_info5[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-5", (void *)&mux_data_0_3, 0, 0},
};
static struct i2c_board_info i2c_device_info6[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-6", (void *)&mux_data_0_4, 0, 0},
};
static struct i2c_board_info i2c_device_info7[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-7", (void *)&mux_data_0_5, 0, 0},
};
static struct i2c_board_info i2c_device_info8[] __initdata = {
{"pca9548", 0, 0x72, "pca9548-8", (void *)&mux_data_0_6, 0, 0},
};
static struct net_i2c_board_info i2cdev_list[] = {
{bus_id(0), ARRAY_SIZE(i2c_device_info0), i2c_device_info0, 1}, //mux root
{bus_id(1), ARRAY_SIZE(i2c_device_info0), i2c_device_info0, 1}, //mux root
{bus_id(2), ARRAY_SIZE(i2c_device_info2), i2c_device_info2, 0}, //mux 0
{bus_id(3), ARRAY_SIZE(i2c_device_info3), i2c_device_info3, 0}, //mux 1
{bus_id(4), ARRAY_SIZE(i2c_device_info4), i2c_device_info4, 0}, //mux 2
{bus_id(5), ARRAY_SIZE(i2c_device_info5), i2c_device_info5, 0}, //mux 3
{bus_id(6), ARRAY_SIZE(i2c_device_info6), i2c_device_info6, 0}, //mux 4
{bus_id(7), ARRAY_SIZE(i2c_device_info7), i2c_device_info7, 0}, //mux 5
{bus_id(8), ARRAY_SIZE(i2c_device_info8), i2c_device_info8, 0}, //mux 6
};
static struct gpiod_lookup_table net_i2c_gpiod_table = {
.dev_id = "i2c-gpio.1",
.table = {
GPIO_LOOKUP_IDX("gpio_ich", SDA_PIN, NULL, 0, GPIO_OPEN_DRAIN), //I2C_SDA
GPIO_LOOKUP_IDX("gpio_ich", SCL_PIN, NULL, 1, GPIO_OPEN_DRAIN), //I2C_SCL
},
};
#define NET_PLATFORM_CLIENT_MAX_NUM 100 /*A big enough number for sum of i2cdev_list[i].size */
static int client_list_index = 0;
static struct i2c_client *client_list[NET_PLATFORM_CLIENT_MAX_NUM] = {0};
static void i2cgpio_device_release(struct device *dev)
{
gpiod_remove_lookup_table(&net_i2c_gpiod_table);
}
static struct i2c_gpio_platform_data i2c_platform_data = {
.udelay = 5, //5:100kHz
// .sda_is_open_drain = 0,
// .scl_is_open_drain = 0,
// .scl_is_output_only = 0
};
static struct platform_device device_i2c_gpio0 = {
.name = "i2c-gpio",
.id = 1,
.dev = {
.platform_data = &i2c_platform_data,
.release = i2cgpio_device_release,
},
};
static int __init net_platform_init(void)
{
struct i2c_adapter *adap = NULL;
struct i2c_client *e = NULL;
int ret = 0;
int i,j,k;
//printk("%s \n", __func__);
//use i2c-gpio
//register i2c gpio
//config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5
outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58)
outl( inl(0x541) | (1<<3), 0x541); //i2c-gpio sda (GPIO75)
outl( inl(0x540) | (1<<5), 0x540); //RST_I2C_MUX_N (GPIO69)
outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7)
outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15)
outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27)
gpiod_add_lookup_table(&net_i2c_gpiod_table);
ret = platform_device_register(&device_i2c_gpio0);
if (ret) {
printk(KERN_ERR "i2c-gpio: platform_device_register fail %d\n", ret);
}
msleep(10);
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
adap = i2c_get_adapter( i2cdev_list[i].ch );
if (adap == NULL) {
printk("platform get channel %d adapter fail\n", i);
continue;
}
// i2c_put_adapter(adap);
for(j=0; j<i2cdev_list[i].size; j++) {
for(k=0; k<300; k++) {
if (i2cdev_list[i].probe == 1) {
short unsigned int i2c_address[2]={i2cdev_list[i].board_info[j].addr, I2C_CLIENT_END};
e = i2c_new_scanned_device(adap, &i2cdev_list[i].board_info[j] ,i2c_address, NULL);
} else {
e = i2c_new_client_device(adap, &i2cdev_list[i].board_info[j]);
}
if(e == NULL) {
msleep(10);
} else {
client_list[client_list_index] = e;
client_list_index++;
break;
}
}
if(k==300) {
printk("[%d][%d] i2c device load fail\n",i,j);
}
}
i2c_put_adapter(adap);
}
printk("net_platform module initialized\n");
return ret;
}
static void __exit net_platform_exit(void)
{
int i;
for(i=client_list_index-1; i>=0; i--) {
i2c_unregister_device(client_list[i]);
}
device_i2c_gpio0.dev.platform_data = NULL;
platform_device_unregister(&device_i2c_gpio0);
printk("net_platform_exit done\n");
}
module_init(net_platform_init);
module_exit(net_platform_exit);
MODULE_AUTHOR("Netberg <support@netbergtw.com>");
MODULE_DESCRIPTION("Netberg Platform devices");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,996 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#define SWITCH_TEMPERATURE_SOCK "/proc/switch/temp"
#define PSOC_POLLING_PERIOD 1000
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#define IPMI_MAX_INTF (4)
#define NETFN_OEM 0x30
#define CMD_GETDATA 0x31
#define CMD_SETDATA 0x32
#define FAN_NUM 4
#define PSU_NUM 2
#define FAN_CLEI_SUPPORT 1
#define PSU_CLEI_SUPPORT 0
#define PSU1 0x5800
#define PSU2 0x5900
#define BMC_PMBusNumber 3
#define PMBus_Vendor 0x99
#define PMBus_Serial 0x9E
#define PMBus_Temp2 0x8E
#define PMBus_Version 0x9B
#define MaxLeng_Result 0x40
#define BMC_FanCLEIBusNumber 9
#define DEVICE_CLEI_ADDR 0x52,0x53,0x54,0x55,0x56,0x50,0x51
#define MAX_IPMI_RECV_LENGTH 0xff
static char CLEI_ADDR[]={DEVICE_CLEI_ADDR};
struct task_struct *kthread_auto_update;
static long pmbus_reg2data_linear(int data, int linear16);
struct ipmi_result{
char result[MAX_IPMI_RECV_LENGTH];
int result_length;
};
DEFINE_MUTEX(ipmi_mutex);
DEFINE_MUTEX(ipmi2_mutex);
static struct ipmi_result ipmiresult;
static struct device *hwmon_dev;
static struct kobject *device_kobj;
static struct ipmi_user *ipmi_mh_user = NULL;
static void msg_handler(struct ipmi_recv_msg *msg,void* handler_data);
static struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = msg_handler,};
static atomic_t dummy_count = ATOMIC_INIT(0);
static void dummy_smi_free(struct ipmi_smi_msg *msg)
{
atomic_dec(&dummy_count);
}
static void dummy_recv_free(struct ipmi_recv_msg *msg)
{
atomic_dec(&dummy_count);
}
static struct ipmi_smi_msg halt_smi_msg = {
.done = dummy_smi_free
};
static struct ipmi_recv_msg halt_recv_msg = {
.done = dummy_recv_free
};
struct __attribute__ ((__packed__)) psoc_psu_layout {
u16 psu1_iin;
u16 psu2_iin;
u16 psu1_iout;
u16 psu2_iout;
u16 psu1_pin;
u16 psu2_pin;
u16 psu1_pout;
u16 psu2_pout;
u16 psu1_vin;
u16 psu2_vin;
u16 psu1_vout;
u16 psu2_vout;
};
struct __attribute__ ((__packed__)) clei {
u8 issue_number[3];
u8 abbreviation_number[9];
u8 fc_number[10];
u8 clei_code[10];
u8 product_year_and_month[5];
u8 label_location_code[2];
u8 serial_number[5];
u8 pcb_revision[5];
u8 vendor_name[10];
u8 reserved[5];
};
struct __attribute__ ((__packed__)) psoc_layout {
u8 ctl; //offset: 0
u16 switch_temp; //offset: 1
// BYTE[03:20] - voltage
u16 voltage[15]; //offset: 0x03-0x20
// BYTE[21:27] - ExtFan
u8 led_ctl2; //offset: 21
u8 ext_pwm; //offset: 22
u16 ext_rpm[2]; //offset: 23
u8 gpi_fan2; //offset: 27
//gpo
u8 led_ctl; //offset: 28
u8 gpio; //offset: 29
//pwm duty
u8 pwm[4]; //offset: 2a
u8 pwm_psu[2]; //offset: 2e
//fan rpm
u16 fan[4*2]; //offset: 30
u8 reserve1[4]; //offset: 40
//gpi
u8 gpi_fan; //offset: 44
//psu state
u8 psu_state; //offset: 45
//temperature
u16 temp[5]; //offset: 46
u16 temp_psu[2]; //offset: 50
//version
u8 version[2]; //offset: 54
u8 reserve2[4]; //offset: 56
struct psoc_psu_layout psu_info; //offset: 5a
};
/* definition */
#define PSOC_OFF(m) offsetof(struct psoc_layout, m)
#define PSOC_PSU_OFF(m) offsetof(struct psoc_psu_layout, m)
#define SWITCH_TMP_OFFSET PSOC_OFF(switch_temp)
#define PWM_OFFSET PSOC_OFF(pwm)
#define THERMAL_OFFSET PSOC_OFF(temp)
#define RPM_OFFSET PSOC_OFF(fan)
#define DIAG_FLAG_OFFSET PSOC_OFF(ctl)
#define FAN_LED_OFFSET PSOC_OFF(led_ctl)
#define FAN_GPI_OFFSET PSOC_OFF(gpi_fan)
#define PSOC_PSU_OFFSET PSOC_OFF(psu_state)
#define VERSION_OFFSET PSOC_OFF(version)
#define PSU_INFO_OFFSET PSOC_OFF(psu_info)
#define PWM2_OFFSET PSOC_OFF(ext_pwm)
#define RPM2_OFFSET PSOC_OFF(ext_rpm)
#define FAN_LED2_OFFSET PSOC_OFF(led_ctl2)
#define FAN_GPI2_OFFSET PSOC_OFF(gpi_fan2)
#define CLEI_OFF(m) offsetof(struct clei, m)
#define FAN1_CLEI_INDEX 0
#define FAN2_CLEI_INDEX 1
#define FAN3_CLEI_INDEX 2
#define FAN4_CLEI_INDEX 3
#define FAN5_CLEI_INDEX 4
#define PSU1_CLEI_INDEX 5
#define PSU2_CLEI_INDEX 6
static void msg_handler(struct ipmi_recv_msg *recv_msg,void* handler_data)
{
struct ipmi_result *msg_result = recv_msg->user_msg_data;
if(recv_msg->msg.data[0]==0 && recv_msg->msg.data_len>0) {
msg_result->result_length=recv_msg->msg.data_len-1;
memcpy(msg_result->result, &recv_msg->msg.data[1], recv_msg->msg.data_len-1);
}
ipmi_free_recv_msg(recv_msg);
mutex_unlock(&ipmi_mutex);
return;
}
int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* result, int* result_length)
{
int rv=0,i;
int timeout;
//wait previous command finish at least 50msec
timeout=50;
while((mutex_is_locked(&ipmi_mutex) == 1 || (mutex_is_locked(&ipmi2_mutex) == 1)) && (--timeout)>0) { usleep_range(1000,1010); }
if(timeout==0) { return -1; }
mutex_lock(&ipmi_mutex);
mutex_lock(&ipmi2_mutex);
if(ipmi_mh_user == NULL) {
for (i=0,rv=1; i<IPMI_MAX_INTF && rv; i++) {
rv = ipmi_create_user(i, &ipmi_hndlrs, NULL, &ipmi_mh_user);
}
}
if (rv < 0) {
mutex_unlock(&ipmi_mutex);
mutex_unlock(&ipmi2_mutex);
return rv;
}
else {
struct ipmi_system_interface_addr addr;
struct kernel_ipmi_msg msg;
uint8_t msg_data[data_length];
memcpy(msg_data,data,data_length);
addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
addr.channel = IPMI_BMC_CHANNEL;
addr.lun = 0;
msg.netfn = NetFn;
msg.cmd = cmd;
msg.data = msg_data;
msg.data_len = data_length;
rv = ipmi_request_supply_msgs(ipmi_mh_user, (struct ipmi_addr*)&addr, 0,&msg, &ipmiresult, &halt_smi_msg, &halt_recv_msg, 0);
if (rv) {
mutex_unlock(&ipmi_mutex);
mutex_unlock(&ipmi2_mutex);
return -6;
}
//skip command if 1sec no response from remote
timeout=1000;
while(mutex_is_locked(&ipmi_mutex) == 1 && (--timeout)>0) { usleep_range(1000,1100);}
if(timeout==0) {
mutex_unlock(&ipmi2_mutex);
return -1;
}
else {
*result_length=ipmiresult.result_length;
memcpy(result,ipmiresult.result,*result_length);
mutex_unlock(&ipmi2_mutex);
return 0;
}
}
return 0;
}
EXPORT_SYMBOL(start_ipmi_command);
static ssize_t psoc_ipmi_read(u8 *buf, u8 offset, size_t count)
{
uint8_t data[2];
int result_len=0;
int rv;
data[0] = offset;
data[1] = count;
rv=start_ipmi_command(NETFN_OEM, CMD_GETDATA,data,2, buf, &result_len);
return result_len;
}
static ssize_t psoc_ipmi_write(char *buf, unsigned offset, size_t count)
{
uint8_t data[count+1],result[1];
int result_len;
data[0] = offset;
memcpy(&data[1],buf,count);
start_ipmi_command(NETFN_OEM, CMD_SETDATA,data,count+1, result, &result_len);
return count;
}
static u16 psoc_read16(u8 offset)
{
u16 value = 0;
u8 buf[]={0,0};
if(psoc_ipmi_read(buf, offset, 2) == 2){
value = (buf[0]<<8 | buf[1]<<0);
}
return value;
}
static u8 psoc_read8(u8 offset)
{
u8 value = 0;
u8 buf = 0;
if(psoc_ipmi_read(&buf, offset, 1) == 1){
value = buf;
}
return value;
}
/*
CPLD report the PSU0 status
000 = PSU normal operation
100 = PSU fault
010 = PSU unpowered
111 = PSU not installed
7 6 | 5 4 3 | 2 1 0
----------------------
| psu1 | psu0
*/
static char* psu_str[] = {
"normal", //000
"NA", //001
"unpowered", //010
"NA", //011
"fault", //100
"NA", //101
"NA", //110
"not installed", //111
};
static ssize_t show_psu_st(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 byte=0;
int shift = (attr->index == 0)?3:0;
status = psoc_ipmi_read(&byte, PSOC_PSU_OFFSET, 1);
byte = (byte >> shift) & 0x7;
status = sprintf (buf, "%d : %s\n", byte, psu_str[byte]);
return strlen(buf);
}
static ssize_t show_ipmi_pmbus(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
uint8_t data[4],result[MaxLeng_Result];
int result_len=0;
data[0] = BMC_PMBusNumber;
data[1] = (attr->index & 0xFF00 ) >>7;
data[3] = attr->index & 0xff;
if(data[3]==PMBus_Temp2)
{data[2]=2;}
else
{data[2]=MaxLeng_Result;}
if(start_ipmi_command(0x06, 0x52,data,4, result, &result_len)==0)
{
if(data[3]==PMBus_Temp2)
{
return sprintf(buf, "%ld \n", pmbus_reg2data_linear(result[0] | (result[1]<<8), 0 ));
}
result[result[0]+1]='\0';
return sprintf(buf, "%s\n",&result[1] );
}
else
{
return 0;
}
}
static ssize_t show_clei(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 device_index = attr->index & 0xFF;
uint8_t data[5],result[MaxLeng_Result];
int result_len=0;
data[0] = (device_index<=FAN5_CLEI_INDEX) ? BMC_FanCLEIBusNumber:BMC_PMBusNumber;
data[1] = CLEI_ADDR[device_index]<<1;
data[2] = sizeof(struct clei);
data[3] = (device_index<=FAN5_CLEI_INDEX) ? 0x00 : 0x01; //PSU CLEI will start from 0x0100
data[4] = 0;
if(start_ipmi_command(0x06, 0x52,data,5, result, &result_len)==0)
{
if(result_len < sizeof(struct clei)) memset(result, 0, sizeof(struct clei));
sprintf (buf, "Issue Number: %.3s\n", &result[CLEI_OFF(issue_number)]);
sprintf (buf, "%sAbbreviation Number: %.9s\n", buf, &result[CLEI_OFF(abbreviation_number)]);
sprintf (buf, "%sFC Number: %.10s\n", buf, &result[CLEI_OFF(fc_number)]);
sprintf (buf, "%sCLEI Code: %.10s\n", buf, &result[CLEI_OFF(clei_code)]);
sprintf (buf, "%sProduct Year and Month: %.5s\n", buf, &result[CLEI_OFF(product_year_and_month)]);
sprintf (buf, "%s2D Label Location Code: %.2s\n", buf, &result[CLEI_OFF(label_location_code)]);
sprintf (buf, "%sSerial Number: %.5s\n", buf, &result[CLEI_OFF(serial_number)]);
sprintf (buf, "%sPCB Revision: %.5s\n", buf, &result[CLEI_OFF(pcb_revision)]);
sprintf (buf, "%sVendor Name: %.10s\n", buf, &result[CLEI_OFF(vendor_name)]);
return strlen(buf);
}
else
{
return sprintf(buf, "NONE\n");
}
}
static ssize_t show_thermal(struct device *dev, struct device_attribute *da,
char *buf)
{
int status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index * 2 + THERMAL_OFFSET;
status = psoc_read16(offset);
return sprintf(buf, "%d\n",
(s8)(status>>8) * 1000 );
}
static ssize_t show_pwm(struct device *dev, struct device_attribute *da,
char *buf)
{
int status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index;
status = psoc_read8(offset);
return sprintf(buf, "%d\n",
status);
}
static ssize_t set_pwm(struct device *dev,
struct device_attribute *da,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index;
u8 pwm = simple_strtol(buf, NULL, 10);
if(pwm > 255) pwm = 255;
psoc_ipmi_write(&pwm, offset, 1);
return count;
}
static ssize_t show_rpm(struct device *dev, struct device_attribute *da,
char *buf)
{
int status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index;
status = psoc_read16(offset);
return sprintf(buf, "%d\n",
status);
}
static ssize_t show_switch_tmp(struct device *dev, struct device_attribute *da,
char *buf)
{
u16 status=0;
u16 temp = 0;
status = psoc_ipmi_read((u8*)&temp, SWITCH_TMP_OFFSET, 2);
status = sprintf (buf, "%d\n", (s8)(temp>>8) * 1000 );
return strlen(buf);
}
static ssize_t set_switch_tmp(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
long temp = simple_strtol(buf, NULL, 10);
u16 temp2 = ( (temp/1000) <<8 ) & 0xFF00 ;
psoc_ipmi_write((u8*)&temp2, SWITCH_TMP_OFFSET, 2);
return count;
}
static ssize_t show_diag(struct device *dev, struct device_attribute *da,
char *buf)
{
u16 status=0;
u8 diag_flag = 0;
status = psoc_ipmi_read((u8*)&diag_flag, DIAG_FLAG_OFFSET, 1);
status = sprintf (buf, "%d\n", ((diag_flag & 0x80)?1:0));
return strlen(buf);
}
static ssize_t set_diag(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
u8 value = 0;
u8 diag = simple_strtol(buf, NULL, 10);
diag = diag?1:0;
psoc_ipmi_read((u8*)&value, DIAG_FLAG_OFFSET, 1);
if(diag) value |= (1<<7);
else value &= ~(1<<7);
psoc_ipmi_write((u8*)&value, DIAG_FLAG_OFFSET, 1);
return count;
}
static ssize_t show_version(struct device *dev, struct device_attribute *da,
char *buf)
{
u16 status=0;
status = psoc_read16(VERSION_OFFSET);
return sprintf(buf, "ver: %x.%x\n", (status & 0xFF00)>>8, (status & 0xFF) );
}
static ssize_t show_fan_led(struct device *dev, struct device_attribute *da,
char *buf)
{
int status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 bit = attr->index;
if(bit < 8) { status = psoc_read8(FAN_LED_OFFSET); }
#if FAN_NUM>4
if(bit >= 8) { status = psoc_read8(FAN_LED2_OFFSET); bit-=8; }
#endif
return sprintf(buf, "%d\n",
(status & (1<<bit))?1:0 );
}
static ssize_t set_fan_led(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
u8 bit = attr->index;
u8 led_state = 0;
u8 v = simple_strtol(buf, NULL, 10);
if(attr->index < 8) { led_state = psoc_read8(FAN_LED_OFFSET ); }
#if FAN_NUM>4
if(attr->index >= 8) { led_state = psoc_read8(FAN_LED2_OFFSET); bit-=8; }
#endif
if(v) led_state |= (1<<bit);
else led_state &= ~(1<<bit);
if(attr->index < 8) { psoc_ipmi_write(&led_state, FAN_LED_OFFSET, 1);}
#if FAN_NUM>4
if(attr->index >= 8) { psoc_ipmi_write(&led_state, FAN_LED2_OFFSET,1);}
#endif
return count;
}
static ssize_t show_value8(struct device *dev, struct device_attribute *da,
char *buf)
{
int status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index;
status = psoc_read8(offset);
return sprintf(buf, "0x%02X\n", status );
}
static long pmbus_reg2data_linear(int data, int linear16)
{
s16 exponent;
s32 mantissa;
long val;
if (linear16) { /* LINEAR16 */
exponent = -9;
mantissa = (u16) data;
} else { /* LINEAR11 */
exponent = ((s16)data) >> 11;
exponent = ((s16)( data & 0xF800) ) >> 11;
mantissa = ((s32)((data & 0x7ff) << 5)) >> 5;
}
//printk("data=%d, m=%d, e=%d\n", data, exponent, mantissa);
val = mantissa;
/* scale result to micro-units for power sensors */
val = val * 1000L;
if (exponent >= 0)
val <<= exponent;
else
val >>= -exponent;
return val;
}
static ssize_t show_psu_psoc(struct device *dev, struct device_attribute *da,
char *buf)
{
u16 status=0;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
u8 offset = attr->index + PSU_INFO_OFFSET;
status = psoc_read16(offset);
if((strstr(attr->dev_attr.attr.name, "vout")!=NULL)|(strstr(attr->dev_attr.attr.name, "in3")!=NULL)|(strstr(attr->dev_attr.attr.name, "in4")!=NULL)) {
offset=1;
}
else {
offset=0;
}
return sprintf(buf, "%ld \n", pmbus_reg2data_linear(status, offset ));
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0)
static ssize_t show_name(struct device *dev,
struct device_attribute *devattr, char *buf)
{
return sprintf(buf, "net_psoc\n");
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
#endif
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_thermal, 0, 0);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_thermal, 0, 1);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_thermal, 0, 2);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_thermal, 0, 3);
static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_thermal, 0, 4);
static SENSOR_DEVICE_ATTR(thermal_psu1, S_IRUGO, show_thermal, 0, 5);
static SENSOR_DEVICE_ATTR(thermal_psu2, S_IRUGO, show_thermal, 0, 6);
static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_thermal, 0, 5);
static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_thermal, 0, 6);
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 2 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 3 + PWM_OFFSET);
#if FAN_NUM > 4
static SENSOR_DEVICE_ATTR(pwm5, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0 + PWM2_OFFSET);
#endif
static SENSOR_DEVICE_ATTR(pwm_psu1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm_psu2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 5 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm6, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 4 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(pwm7, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 5 + PWM_OFFSET);
static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu_st, 0, 0);
static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu_st, 0, 1);
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, 0, 0*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_rpm, 0, 1*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_rpm, 0, 2*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_rpm, 0, 3*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_rpm, 0, 4*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_rpm, 0, 5*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_rpm, 0, 6*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_rpm, 0, 7*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(rpm_psu1, S_IRUGO, show_rpm, 0, 8*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(rpm_psu2, S_IRUGO, show_rpm, 0, 9*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan11_input, S_IRUGO, show_rpm, 0, 8*2 + RPM_OFFSET);
static SENSOR_DEVICE_ATTR(fan12_input, S_IRUGO, show_rpm, 0, 9*2 + RPM_OFFSET);
#if FAN_NUM > 4
static SENSOR_DEVICE_ATTR(fan9_input , S_IRUGO, show_rpm, 0,0*2 + RPM2_OFFSET);
static SENSOR_DEVICE_ATTR(fan10_input, S_IRUGO, show_rpm, 0,1*2 + RPM2_OFFSET);
#endif
static SENSOR_DEVICE_ATTR(switch_tmp, S_IWUSR|S_IRUGO, show_switch_tmp, set_switch_tmp, 0);
static SENSOR_DEVICE_ATTR(temp6_input, S_IWUSR|S_IRUGO, show_switch_tmp, set_switch_tmp, 0);
static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0);
static SENSOR_DEVICE_ATTR(version, S_IRUGO, show_version, 0, 0);
static SENSOR_DEVICE_ATTR(fan_led_grn1, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 0);
static SENSOR_DEVICE_ATTR(fan_led_grn2, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 1);
static SENSOR_DEVICE_ATTR(fan_led_grn3, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 2);
static SENSOR_DEVICE_ATTR(fan_led_grn4, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 3);
static SENSOR_DEVICE_ATTR(fan_led_red1, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 4);
static SENSOR_DEVICE_ATTR(fan_led_red2, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 5);
static SENSOR_DEVICE_ATTR(fan_led_red3, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 6);
static SENSOR_DEVICE_ATTR(fan_led_red4, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 7);
#if FAN_NUM>4
static SENSOR_DEVICE_ATTR(fan_led_grn5, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 8);
static SENSOR_DEVICE_ATTR(fan_led_red5, S_IWUSR|S_IRUGO, show_fan_led, set_fan_led, 12);
static SENSOR_DEVICE_ATTR(fan_gpi2, S_IRUGO, show_value8, 0, FAN_GPI2_OFFSET);
#endif
static SENSOR_DEVICE_ATTR(fan_gpi, S_IRUGO, show_value8, 0, FAN_GPI_OFFSET);
static SENSOR_DEVICE_ATTR(psoc_psu1_vin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_vin));
static SENSOR_DEVICE_ATTR(psoc_psu1_vout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_vout));
static SENSOR_DEVICE_ATTR(psoc_psu1_iin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_iin));
static SENSOR_DEVICE_ATTR(psoc_psu1_iout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_iout));
static SENSOR_DEVICE_ATTR(psoc_psu1_pin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_pin));
static SENSOR_DEVICE_ATTR(psoc_psu1_pout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_pout));
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_vin));
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_iin));
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_pin));
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_vout));
static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_iout));
static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu1_pout));
static SENSOR_DEVICE_ATTR(psoc_psu2_vin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_vin));
static SENSOR_DEVICE_ATTR(psoc_psu2_vout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_vout));
static SENSOR_DEVICE_ATTR(psoc_psu2_iin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_iin));
static SENSOR_DEVICE_ATTR(psoc_psu2_iout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_iout));
static SENSOR_DEVICE_ATTR(psoc_psu2_pin, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_pin));
static SENSOR_DEVICE_ATTR(psoc_psu2_pout, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_pout));
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_vin));
static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_iin));
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_pin));
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_vout));
static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_iout));
static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, show_psu_psoc, 0, PSOC_PSU_OFF(psu2_pout));
//IPMI
static SENSOR_DEVICE_ATTR(thermal2_psu1, S_IRUGO, show_ipmi_pmbus, 0, PSU1 | PMBus_Temp2);
static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_ipmi_pmbus, 0, PSU1 | PMBus_Temp2);
static SENSOR_DEVICE_ATTR(psoc_psu1_vendor, S_IRUGO, show_ipmi_pmbus, 0, PSU1 | PMBus_Vendor);
static SENSOR_DEVICE_ATTR(psoc_psu1_serial, S_IRUGO, show_ipmi_pmbus, 0, PSU1 | PMBus_Serial);
static SENSOR_DEVICE_ATTR(psoc_psu1_version, S_IRUGO, show_ipmi_pmbus, 0, PSU1 | PMBus_Version);
static SENSOR_DEVICE_ATTR(thermal2_psu2, S_IRUGO, show_ipmi_pmbus, 0, PSU2 | PMBus_Temp2);
static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_ipmi_pmbus, 0, PSU2 | PMBus_Temp2);
static SENSOR_DEVICE_ATTR(psoc_psu2_vendor, S_IRUGO, show_ipmi_pmbus, 0, PSU2 | PMBus_Vendor);
static SENSOR_DEVICE_ATTR(psoc_psu2_serial, S_IRUGO, show_ipmi_pmbus, 0, PSU2 | PMBus_Serial);
static SENSOR_DEVICE_ATTR(psoc_psu2_version, S_IRUGO, show_ipmi_pmbus, 0, PSU2 | PMBus_Version);
//CLEI
#if FAN_CLEI_SUPPORT
static SENSOR_DEVICE_ATTR(fan1_clei, S_IRUGO, show_clei, 0, FAN1_CLEI_INDEX );
static SENSOR_DEVICE_ATTR(fan2_clei, S_IRUGO, show_clei, 0, FAN2_CLEI_INDEX );
static SENSOR_DEVICE_ATTR(fan3_clei, S_IRUGO, show_clei, 0, FAN3_CLEI_INDEX );
static SENSOR_DEVICE_ATTR(fan4_clei, S_IRUGO, show_clei, 0, FAN4_CLEI_INDEX );
#if FAN_NUM > 4
static SENSOR_DEVICE_ATTR(fan5_clei, S_IRUGO, show_clei, 0, FAN5_CLEI_INDEX );
#endif
#endif
#if PSU_CLEI_SUPPORT
static SENSOR_DEVICE_ATTR(psu1_clei, S_IRUGO, show_clei, 0, PSU1_CLEI_INDEX );
static SENSOR_DEVICE_ATTR(psu2_clei, S_IRUGO, show_clei, 0, PSU2_CLEI_INDEX );
#endif
static struct attribute *psoc_attributes[] = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,0)
//name
&dev_attr_name.attr,
#endif
//thermal
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp5_input.dev_attr.attr,
&sensor_dev_attr_thermal_psu1.dev_attr.attr,
&sensor_dev_attr_thermal_psu2.dev_attr.attr,
&sensor_dev_attr_temp7_input.dev_attr.attr,
&sensor_dev_attr_temp8_input.dev_attr.attr,
//pwm
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
&sensor_dev_attr_pwm3.dev_attr.attr,
&sensor_dev_attr_pwm4.dev_attr.attr,
#if FAN_NUM > 4
&sensor_dev_attr_pwm5.dev_attr.attr,
#endif
&sensor_dev_attr_pwm_psu1.dev_attr.attr,
&sensor_dev_attr_pwm_psu2.dev_attr.attr,
&sensor_dev_attr_pwm6.dev_attr.attr,
&sensor_dev_attr_pwm7.dev_attr.attr,
//rpm
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
&sensor_dev_attr_fan3_input.dev_attr.attr,
&sensor_dev_attr_fan4_input.dev_attr.attr,
&sensor_dev_attr_fan5_input.dev_attr.attr,
&sensor_dev_attr_fan6_input.dev_attr.attr,
&sensor_dev_attr_fan7_input.dev_attr.attr,
&sensor_dev_attr_fan8_input.dev_attr.attr,
#if FAN_NUM > 4
&sensor_dev_attr_fan9_input.dev_attr.attr,
&sensor_dev_attr_fan10_input.dev_attr.attr,
#endif
&sensor_dev_attr_rpm_psu1.dev_attr.attr,
&sensor_dev_attr_rpm_psu2.dev_attr.attr,
&sensor_dev_attr_fan11_input.dev_attr.attr,
&sensor_dev_attr_fan12_input.dev_attr.attr,
//switch temperature
&sensor_dev_attr_switch_tmp.dev_attr.attr,
&sensor_dev_attr_temp6_input.dev_attr.attr,
//diag flag
&sensor_dev_attr_diag.dev_attr.attr,
//version
&sensor_dev_attr_version.dev_attr.attr,
//fan led
&sensor_dev_attr_fan_led_grn1.dev_attr.attr,
&sensor_dev_attr_fan_led_grn2.dev_attr.attr,
&sensor_dev_attr_fan_led_grn3.dev_attr.attr,
&sensor_dev_attr_fan_led_grn4.dev_attr.attr,
&sensor_dev_attr_fan_led_red1.dev_attr.attr,
&sensor_dev_attr_fan_led_red2.dev_attr.attr,
&sensor_dev_attr_fan_led_red3.dev_attr.attr,
&sensor_dev_attr_fan_led_red4.dev_attr.attr,
#if FAN_NUM >4
&sensor_dev_attr_fan_led_grn5.dev_attr.attr,
&sensor_dev_attr_fan_led_red5.dev_attr.attr,
&sensor_dev_attr_fan_gpi2.dev_attr.attr,
#endif
//fan GPI
&sensor_dev_attr_fan_gpi.dev_attr.attr,
&sensor_dev_attr_psu1.dev_attr.attr,
&sensor_dev_attr_psu2.dev_attr.attr,
//psu_psoc
&sensor_dev_attr_psoc_psu1_vin.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_vout.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_iin.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_iout.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_pin.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_pout.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_vin.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_vout.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_iin.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_iout.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_pin.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_pout.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_curr2_input.dev_attr.attr,
&sensor_dev_attr_power2_input.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_curr3_input.dev_attr.attr,
&sensor_dev_attr_power3_input.dev_attr.attr,
&sensor_dev_attr_in4_input.dev_attr.attr,
&sensor_dev_attr_curr4_input.dev_attr.attr,
&sensor_dev_attr_power4_input.dev_attr.attr,
//ipmi_i2c_command
&sensor_dev_attr_thermal2_psu1.dev_attr.attr,
&sensor_dev_attr_temp9_input.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_vendor.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_serial.dev_attr.attr,
&sensor_dev_attr_psoc_psu1_version.dev_attr.attr,
&sensor_dev_attr_thermal2_psu2.dev_attr.attr,
&sensor_dev_attr_temp10_input.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_vendor.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_serial.dev_attr.attr,
&sensor_dev_attr_psoc_psu2_version.dev_attr.attr,
//clei
#if FAN_CLEI_SUPPORT
&sensor_dev_attr_fan1_clei.dev_attr.attr,
&sensor_dev_attr_fan2_clei.dev_attr.attr,
&sensor_dev_attr_fan3_clei.dev_attr.attr,
&sensor_dev_attr_fan4_clei.dev_attr.attr,
#if FAN_NUM > 4
&sensor_dev_attr_fan5_clei.dev_attr.attr,
#endif
#endif
#if PSU_CLEI_SUPPORT
&sensor_dev_attr_psu1_clei.dev_attr.attr,
&sensor_dev_attr_psu2_clei.dev_attr.attr,
#endif
NULL
};
static const struct attribute_group psoc_group = {
.attrs = psoc_attributes,
};
//=================================
static void check_switch_temp(void)
{
static struct file *f;
#ifdef set_fs
mm_segment_t old_fs=get_fs();
set_fs(get_ds());
#endif
f = filp_open(SWITCH_TEMPERATURE_SOCK,O_RDONLY,0644);
if(IS_ERR(f)) {
return;
}
filp_close(f,NULL);
#ifdef set_fs
set_fs(old_fs);
#endif
}
static int psoc_polling_thread(void *p)
{
while (!kthread_should_stop())
{
check_switch_temp();
set_current_state(TASK_INTERRUPTIBLE);
if(kthread_should_stop())
break;
schedule_timeout(msecs_to_jiffies(PSOC_POLLING_PERIOD));
}
return 0;
}
static int __init net_psoc_init(void)
{
int ret;
hwmon_dev = hwmon_device_register_with_info(NULL, "net_psoc", NULL, NULL, NULL);
if (IS_ERR(hwmon_dev)) {
goto fail_hwmon_device_register;
}
device_kobj = kobject_create_and_add("device", &hwmon_dev->kobj);
if(!device_kobj) {
goto fail_hwmon_device_register;
}
ret = sysfs_create_group(device_kobj, &psoc_group);
if (ret) {
goto fail_create_group_hwmon;
}
ret = sysfs_create_group(&hwmon_dev->kobj, &psoc_group);
if (ret) {
goto fail_create_group_hwmon;
}
kthread_auto_update = kthread_run(psoc_polling_thread,NULL,"BMC_DRIVER");
if (IS_ERR(kthread_auto_update)) {
goto fail_create_group_hwmon;
}
return ret;
fail_create_group_hwmon:
hwmon_device_unregister(hwmon_dev);
fail_hwmon_device_register:
return -ENOMEM;
}
static void __exit net_psoc_exit(void)
{
kthread_stop(kthread_auto_update);
if(ipmi_mh_user!=NULL) {ipmi_destroy_user(ipmi_mh_user);}
sysfs_remove_group(device_kobj, &psoc_group);
if(hwmon_dev != NULL) hwmon_device_unregister(hwmon_dev);
}
MODULE_AUTHOR("Netberg <support@netbergtw.com>");
MODULE_DESCRIPTION("Netberg psoc driver");
MODULE_LICENSE("GPL");
module_init(net_psoc_init);
module_exit(net_psoc_exit);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
#ifndef NET_SWPS_H
#define NET_SWPS_H
#include "transceiver.h"
#include "io_expander.h"
#include "net_mux.h"
/* Module settings */
#define SWP_CLS_NAME "swps"
#define SWP_DEV_PORT "port"
#define SWP_DEV_MODCTL "module"
#define SWP_RESET_PWD "netberg"
#define SWP_POLLING_PERIOD (300) /* msec */
#define SWP_POLLING_ENABLE (1)
#define SWP_AUTOCONFIG_ENABLE (1)
/* Module information */
#define SWP_AUTHOR "Netberg <support@netbergtw.com>"
#define SWP_DESC "Netberg port and transceiver driver"
#define SWP_VERSION "4.3.4"
#define SWP_LICENSE "GPL"
/* Module status define */
#define SWP_STATE_NORMAL (0)
#define SWP_STATE_I2C_DIE (-91)
#define PLATFORM_TYPE_AUTO (100)
#define PLATFORM_TYPE_AURORA_610_GA (202)
#define PLATFORM_TYPE_AURORA_610 (203)
/* Current running platfrom */
#define PLATFORM_SETTINGS PLATFORM_TYPE_AURORA_610
/* Define platform flag and kernel version */
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_AURORA_610_GA)
#define SWPS_AURORA_610_GA (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_AURORA_610)
#define SWPS_AURORA_610 (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#endif
struct net_platform_s {
int id;
char name[64];
};
struct net_ioexp_layout_s {
int ioexp_id;
int ioexp_type;
struct ioexp_addr_s addr[4];
};
struct net_port_layout_s {
int port_id;
int chan_id;
int ioexp_id;
int ioexp_offset;
int transvr_type;
int chipset_type;
int lane_id[8];
};
/* ==========================================
* Netberg Platform Settings
* ==========================================
*/
struct net_platform_s platform_map[] = {
{PLATFORM_TYPE_AUTO, "Auto-Detect" },
{PLATFORM_TYPE_AURORA_610_GA, "Aurora_610_GA" },
{PLATFORM_TYPE_AURORA_610, "Aurora_610" },
};
/* ==========================================
* Aurora 610 GA Layout configuration
* ==========================================
*/
#ifdef SWPS_AURORA_610_GA
unsigned aurora_610_ga_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
struct net_ioexp_layout_s aurora_610_ga_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_AURORA_610_GA_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_AURORA_610_GA_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_AURORA_610_GA_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_AURORA_610_GA_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_AURORA_610_GA_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_AURORA_610_GA_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_AURORA_610_GA_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct net_port_layout_s aurora_610_ga_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BFT_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 1} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 2} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 3} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 4} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 5} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 6} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 7} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 8} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 9} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 10} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 11} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 12} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 21} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 22} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 23} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 24} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 33} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 34} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 35} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 36} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 37} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 38} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 39} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 40} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 41} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 42} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 43} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 44} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 49} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 50} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 51} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 52} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 53} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 54} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 55} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 56} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 65} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 66} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 67} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 68} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 69} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 70} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 71} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 72} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 81} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 82} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 83} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, { 84} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 97, 98, 99,100} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, { 85, 86, 87, 88} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {101,102,103,104} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {105,106,107,108} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {109,110,111,112} },
};
#endif
/* ==========================================
* Aurora 610 Layout configuration
* ==========================================
*/
#ifdef SWPS_AURORA_610
unsigned aurora_610_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
struct net_ioexp_layout_s aurora_610_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_AURORA_610_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_AURORA_610_1ABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_AURORA_610_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_AURORA_610_3ABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_AURORA_610_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_AURORA_610_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_AURORA_610_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct net_port_layout_s aurora_610_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BFT_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, CHIP_TYPE_LAVENDER, {-99} },
{48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
{55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, CHIP_TYPE_LAVENDER, {-99,-99,-99,-99} },
};
#endif
#endif /* NET_SWPS_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,809 @@
#ifndef TRANSCEIVER_H
#define TRANSCEIVER_H
#include <linux/types.h>
/* advanced features control */
#define TRANSVR_INFO_DUMP_ENABLE (1)
#define TRANSVR_INFO_CACHE_ENABLE (1)
#define TRANSVR_UEVENT_ENABLE (1)
/* Transceiver type define */
#define TRANSVR_TYPE_UNKNOW_1 (0x00)
#define TRANSVR_TYPE_UNKNOW_2 (0xff)
#define TRANSVR_TYPE_SFP (0x03) /* Define for SFP, SFP+, SFP28 */
#define TRANSVR_TYPE_QSFP (0x0c)
#define TRANSVR_TYPE_QSFP_PLUS (0x0d)
#define TRANSVR_TYPE_QSFP_28 (0x11)
#define TRANSVR_TYPE_UNPLUGGED (0xfa) /* Define for ERROR handle */
#define TRANSVR_TYPE_FAKE (0xfc) /* Define for ERROR handle */
#define TRANSVR_TYPE_INCONSISTENT (0xfd) /* Define for ERROR handle */
#define TRANSVR_TYPE_ERROR (0xfe) /* Define for ERROR handle */
/* Transceiver class for base info */
#define TRANSVR_CLASS_UNSPECIFIED (0)
#define TRANSVR_CLASS_ERROR (-26001)
#define TRANSVR_CLASS_1G (26001)
#define TRANSVR_CLASS_10G (26011)
#define TRANSVR_CLASS_25G (26021)
#define TRANSVR_CLASS_40G (26041)
#define TRANSVR_CLASS_100G (26101)
#define TRANSVR_CLASS_NO_SPERARABLE (26901)
#define TRANSVR_CLASS_EXTEND_COMP (26902)
/* Transceiver class for Optical 1G */
#define TRANSVR_CLASS_OPTICAL (27000)
#define TRANSVR_CLASS_OPTICAL_100 (27001)
#define TRANSVR_CLASS_OPTICAL_1G (27002)
#define TRANSVR_CLASS_OPTICAL_1G_AOC (27003)
#define TRANSVR_CLASS_OPTICAL_1G_SX (27004)
#define TRANSVR_CLASS_OPTICAL_1G_LX (27005)
#define TRANSVR_CLASS_OPTICAL_1G_EX (27006)
/* Transceiver class for Optical 10G */
#define TRANSVR_CLASS_OPTICAL_10G (27010)
#define TRANSVR_CLASS_OPTICAL_10G_S_AOC (27011)
#define TRANSVR_CLASS_OPTICAL_10G_S_SR (27012)
#define TRANSVR_CLASS_OPTICAL_10G_S_LR (27013)
#define TRANSVR_CLASS_OPTICAL_10G_S_ER (27014)
#define TRANSVR_CLASS_OPTICAL_10G_Q_AOC (27015)
#define TRANSVR_CLASS_OPTICAL_10G_Q_SR (27016)
#define TRANSVR_CLASS_OPTICAL_10G_Q_LR (27017)
#define TRANSVR_CLASS_OPTICAL_10G_Q_ER (27018)
/* Transceiver class for Optical 25G */
#define TRANSVR_CLASS_OPTICAL_25G (27020)
#define TRANSVR_CLASS_OPTICAL_25G_AOC (27021)
#define TRANSVR_CLASS_OPTICAL_25G_SR (27022)
#define TRANSVR_CLASS_OPTICAL_25G_LR (27023)
#define TRANSVR_CLASS_OPTICAL_25G_ER (27024)
/* Transceiver class for Optical 40G */
#define TRANSVR_CLASS_OPTICAL_40G (27040)
#define TRANSVR_CLASS_OPTICAL_40G_AOC (27041)
#define TRANSVR_CLASS_OPTICAL_40G_SR4 (27042)
#define TRANSVR_CLASS_OPTICAL_40G_LR4 (27043)
#define TRANSVR_CLASS_OPTICAL_40G_ER4 (27044)
/* Transceiver class for Optical 100G */
#define TRANSVR_CLASS_OPTICAL_100G (27100)
#define TRANSVR_CLASS_OPTICAL_100G_AOC (27101)
#define TRANSVR_CLASS_OPTICAL_100G_SR4 (27102)
#define TRANSVR_CLASS_OPTICAL_100G_LR4 (27103)
#define TRANSVR_CLASS_OPTICAL_100G_ER4 (27104)
#define TRANSVR_CLASS_OPTICAL_100G_PSM4 (27105)
/* Transceiver class for Copper */
#define TRANSVR_CLASS_COPPER (28000)
#define TRANSVR_CLASS_COPPER_L1_1G (28001)
#define TRANSVR_CLASS_COPPER_L1_10G (28011)
#define TRANSVR_CLASS_COPPER_L4_10G (28012)
#define TRANSVR_CLASS_COPPER_L1_25G (28021)
#define TRANSVR_CLASS_COPPER_L4_40G (28041)
#define TRANSVR_CLASS_COPPER_L4_100G (28101)
/* Transceiver class for Base-T */
#define TRANSVR_CLASS_BASE_T_1000 (29001)
#define TRANSVR_CLASS_BASE_T_1000_up (29002)
/* For uevent message */
#define TRANSVR_UEVENT_KEY_IF "IF_TYPE"
#define TRANSVR_UEVENT_KEY_SP "IF_SPEED"
#define TRANSVR_UEVENT_KEY_LANE "IF_LANE"
#define TRANSVR_UEVENT_UNKNOW "UNKNOW"
#define TRANSVR_IF_KR "KR"
#define TRANSVR_IF_KR4 "KR4"
#define TRANSVR_IF_SR "SR"
#define TRANSVR_IF_SR4 "SR4"
#define TRANSVR_IF_SFI "SFI"
#define TRANSVR_IF_IF_GMII "GMII"
#define TRANSVR_IF_IF_XGMII "XGMII"
#define TRANSVR_IF_SP_100 "100"
#define TRANSVR_IF_SP_1G "1000"
#define TRANSVR_IF_SP_10G "10000"
#define TRANSVR_IF_SP_25G "25000"
#define TRANSVR_IF_SP_40G "40000"
#define TRANSVR_IF_SP_100G "100000"
/* Transceiver mode define */
#define TRANSVR_MODE_DIRECT (21000)
#define TRANSVR_MODE_POLLING (21001)
/* Transceiver state define
* [Note]
* 1. State is used to represent the state of "Transceiver" and "Object".
* 2. State for different target has different means. The description as following:
*/
#define STATE_TRANSVR_CONNECTED (0) /* [Transvr]:Be plugged in. [Obj]:Link up, and work normally. */
#define STATE_TRANSVR_NEW (-100) /* [Transvr]:(Not used) [Obj]:Create */
#define STATE_TRANSVR_INIT (-101) /* [Transvr]:Be plugged in. [Obj]:Link up, and in initial process. */
#define STATE_TRANSVR_ISOLATED (-102) /* [Transvr]:Be plugged in. [Obj]:Isolate, and not provide service. */
#define STATE_TRANSVR_SWAPPED (-200) /* [Transvr]:Be plugged in. [Obj]:(Not used) */
#define STATE_TRANSVR_DISCONNECTED (-300) /* [Transvr]:Un-plugged. [Obj]:Link down, and not provide service. */
#define STATE_TRANSVR_UNEXCEPTED (-901) /* [Transvr]:Any [Obj]:Any, and not in expect case. */
/* Task state define */
#define STATE_T_TASK_WAIT (110)
#define STATE_T_TASK_DONE (0)
#define STATE_T_TASK_INIT (-110)
#define STATE_T_TASK_FAIL (-410)
/* Event for task handling */
#define EVENT_TRANSVR_TASK_WAIT (2101)
#define EVENT_TRANSVR_TASK_DONE (0)
#define EVENT_TRANSVR_TASK_FAIL (-2101)
/* Event for initial handling */
#define EVENT_TRANSVR_INIT_UP (2201)
#define EVENT_TRANSVR_INIT_DOWN (1)
#define EVENT_TRANSVR_INIT_REINIT (-2201)
#define EVENT_TRANSVR_INIT_FAIL (-2202)
/* Event for others */
#define EVENT_TRANSVR_RELOAD_FAIL (-2301)
#define EVENT_TRANSVR_EXCEP_INIT (-2401)
#define EVENT_TRANSVR_EXCEP_UP (-2402)
#define EVENT_TRANSVR_EXCEP_DOWN (-2403)
#define EVENT_TRANSVR_EXCEP_SWAP (-2404)
#define EVENT_TRANSVR_EXCEP_EXCEP (-2405)
#define EVENT_TRANSVR_EXCEP_ISOLATED (-2406)
#define EVENT_TRANSVR_I2C_CRASH (-2501)
/* Transceiver error code define */
#define ERR_TRANSVR_UNINIT (-201)
#define ERR_TRANSVR_UNPLUGGED (-202)
#define ERR_TRANSVR_ABNORMAL (-203)
#define ERR_TRANSVR_NOSTATE (-204)
#define ERR_TRANSVR_NOTSUPPORT (-205)
#define ERR_TRANSVR_BADINPUT (-206)
#define ERR_TRANSVR_UPDATE_FAIL (-207)
#define ERR_TRANSVR_RELOAD_FAIL (-208)
#define ERR_TRANSVR_INIT_FAIL (-209)
#define ERR_TRANSVR_UNDEFINED (-210)
#define ERR_TRANSVR_TASK_FAIL (-211)
#define ERR_TRANSVR_TASK_BUSY (-212)
#define ERR_TRANSVR_UEVENT_FAIL (-213)
#define ERR_TRANSVR_FUNC_DISABLE (-214)
#define ERR_TRANSVR_I2C_CRASH (-297)
#define ERR_TRNASVR_BE_ISOLATED (-298)
#define ERR_TRANSVR_UNEXCPT (-299)
/* For debug */
#define DEBUG_TRANSVR_INT_VAL (-99)
#define DEBUG_TRANSVR_HEX_VAL (0xfe)
#define DEBUG_TRANSVR_STR_VAL "ERROR"
/* For system internal */
#define VAL_TRANSVR_COMID_ARREESS (0x50)
#define VAL_TRANSVR_COMID_OFFSET (0x00)
#define VAL_TRANSVR_EXTPHY_ADDR_56 (0x56)
#define VAL_TRANSVR_8472_READY_ADDR (0x51)
#define VAL_TRANSVR_8472_READY_PAGE (-1)
#define VAL_TRANSVR_8472_READY_OFFSET (110)
#define VAL_TRANSVR_8472_READY_BIT (0)
#define VAL_TRANSVR_8472_READY_VALUE (0)
#define VAL_TRANSVR_8472_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_READY_ADDR (0x50)
#define VAL_TRANSVR_8436_READY_PAGE (-1)
#define VAL_TRANSVR_8436_READY_OFFSET (2)
#define VAL_TRANSVR_8436_READY_BIT (0)
#define VAL_TRANSVR_8436_READY_VALUE (0)
#define VAL_TRANSVR_8436_READY_ABNORMAL (0xff)
#define VAL_TRANSVR_8436_PWD_ADDR (0x50)
#define VAL_TRANSVR_8436_PWD_PAGE (-1)
#define VAL_TRANSVR_8436_PWD_OFFSET (123)
#define VAL_TRANSVR_PAGE_FREE (-99)
#define VAL_TRANSVR_PAGE_SELECT_OFFSET (127)
#define VAL_TRANSVR_PAGE_SELECT_DELAY (5)
#define VAL_TRANSVR_TASK_RETRY_FOREVER (-999)
#define VAL_TRANSVR_FUNCTION_DISABLE (-1)
#define STR_TRANSVR_SFP "SFP"
#define STR_TRANSVR_QSFP "QSFP"
#define STR_TRANSVR_QSFP_PLUS "QSFP+"
#define STR_TRANSVR_QSFP28 "QSFP28"
/* For transvr buf len */
#define LEN_TRANSVR_S_STR (16)
#define LEN_TRANSVR_M_STR (32)
#define LEN_TRANSVR_L_STR (64)
/* Optical wavelength */
#define VAL_OPTICAL_WAVELENGTH_SR (850)
#define VAL_OPTICAL_WAVELENGTH_LR (1310)
#define VAL_OPTICAL_WAVELENGTH_ER (1550)
/* chip type define */
#define CHIP_TYPE_MAGNOLIA (31001) /* Magnolia, Hudson32i, Spruce */
#define CHIP_TYPE_REDWOOD (31002) /* Redwood, Cypress, Sequoia */
#define CHIP_TYPE_MAPLE (31003) /* Maple */
#define CHIP_TYPE_LAVENDER (31011) /* Lavender */
/* Info from transceiver EEPROM */
struct eeprom_map_s {
int addr_br; int page_br; int offset_br; int length_br;
int addr_cdr; int page_cdr; int offset_cdr; int length_cdr;
int addr_comp_rev; int page_comp_rev; int offset_comp_rev; int length_comp_rev;
int addr_connector; int page_connector; int offset_connector; int length_connector;
int addr_diag_type; int page_diag_type; int offset_diag_type; int length_diag_type;
int addr_extbr; int page_extbr; int offset_extbr; int length_extbr;
int addr_ext_id; int page_ext_id; int offset_ext_id; int length_ext_id;
int addr_id; int page_id; int offset_id; int length_id;
int addr_len_sm; int page_len_sm; int offset_len_sm; int length_len_sm;
int addr_len_smf; int page_len_smf; int offset_len_smf; int length_len_smf;
int addr_len_om1; int page_len_om1; int offset_len_om1; int length_len_om1;
int addr_len_om2; int page_len_om2; int offset_len_om2; int length_len_om2;
int addr_len_om3; int page_len_om3; int offset_len_om3; int length_len_om3;
int addr_len_om4; int page_len_om4; int offset_len_om4; int length_len_om4;
int addr_option; int page_option; int offset_option; int length_option;
int addr_rate_id; int page_rate_id; int offset_rate_id; int length_rate_id;
int addr_rx_am; int page_rx_am; int offset_rx_am; int length_rx_am;
int addr_rx_em; int page_rx_em; int offset_rx_em; int length_rx_em;
int addr_rx_los; int page_rx_los; int offset_rx_los; int length_rx_los;
int addr_rx_power; int page_rx_power; int offset_rx_power; int length_rx_power;
int addr_soft_rs0; int page_soft_rs0; int offset_soft_rs0; int length_soft_rs0;
int addr_soft_rs1; int page_soft_rs1; int offset_soft_rs1; int length_soft_rs1;
int addr_temp; int page_temp; int offset_temp; int length_temp;
int addr_trancomp; int page_trancomp; int offset_trancomp; int length_trancomp;
int addr_trancomp_ext; int page_trancomp_ext; int offset_trancomp_ext; int length_trancomp_ext;
int addr_tx_bias; int page_tx_bias; int offset_tx_bias; int length_tx_bias;
int addr_tx_disable; int page_tx_disable; int offset_tx_disable; int length_tx_disable;
int addr_tx_eq; int page_tx_eq; int offset_tx_eq; int length_tx_eq;
int addr_tx_fault; int page_tx_fault; int offset_tx_fault; int length_tx_fault;
int addr_tx_power; int page_tx_power; int offset_tx_power; int length_tx_power;
int addr_vendor_name; int page_vendor_name; int offset_vendor_name; int length_vendor_name;
int addr_vendor_pn; int page_vendor_pn; int offset_vendor_pn; int length_vendor_pn;
int addr_vendor_rev; int page_vendor_rev; int offset_vendor_rev; int length_vendor_rev;
int addr_vendor_sn; int page_vendor_sn; int offset_vendor_sn; int length_vendor_sn;
int addr_voltage; int page_voltage; int offset_voltage; int length_voltage;
int addr_wavelength; int page_wavelength; int offset_wavelength; int length_wavelength;
};
struct transvr_worker_s;
/* Class of transceiver object */
struct transvr_obj_s {
/* ========== Object private property ==========
* [Prop]: id
* [Desc]: Type of serial transceiver.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh /QSFP28:11h
*/
uint8_t id;
/* [Prop]: connector
* [Desc]: Connector type.
* [Note]: SFP : A0h / 2
* QSFP: 00h / 130
*/
uint8_t connector;
/* [Prop]: transvr_comp
* [Desc]: Transceiver compliance code.
* [Note]: SFP: SFF-8472
* - Normal : A0h / offset 3-10
* - Extended: A0h / offset 36
* QSFP: SFF-8436 & SFF-8636
* - Normal : 00h / offset 131-138
* - Extended: 00h / offset 192
*/
uint8_t transvr_comp[8];
uint8_t transvr_comp_ext;
/* [Prop]: vendor_name
* [Desc]: SFP vendor name (ASCII 16 byte char).
* [Note]: ex:FINISAR CORP.
*/
char *vendor_name;
/* [Prop]: vendor_pn
* [Desc]: Part number provided by SFP vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_pn;
/* [Prop]: vendor_rev
* [Desc]: Revision level for part number provided by vendor (ASCII 4 byte char).
* [Note]:
*/
char *vendor_rev;
/* [Prop]: vendor_sn
* [Desc]: Serial number provided by vendor (ASCII 16 byte char).
* [Note]:
*/
char *vendor_sn;
/* [Prop]: Extended identifier
* [Desc]: SFP:
* => None
*
* QSFP:
* => This byte contained two information:
* (1) Power consumption class
* (2) CDR function present
* [Note]: Bit description as below:
* [SFP]
* None
*
* [QSFP]
* (1) Power consumption class:
* Class 1: 1.5W (Bit6-7 = 00:)
* Class 2: 2.0W (Bit6-7 = 01:)
* Class 3: 2.5W (Bit6-7 = 10:)
* Class 4: 3.5W (Bit6-7 = 11:)
* Class 5: 4.0W (Bit0-1 = 01:)
* Class 6: 4.5W (Bit0-1 = 10:)
* Class 7: 5.0W (Bit0-1 = 11:)
* (2) CDR function present:
* Bit2: 0 = No CDR in RX
* 1 = CDR present in RX
* Bit3: 0 = No CDR in TX
* 1 = CDR present in TX
*/
uint8_t ext_id;
/* [Prop]: br
* [Desc]: Nominal bit rate, units of 100 MBits/sec.
* [Note]: SFP:03h / QSFP:0Ch / QSPF+:0Dh
* has val: 0x67
* no val :
*/
uint8_t br;
/* [Prop]: extbr
* [Desc]: Extended br (00h/222)
* [Desc]: Nominal bit rate per channel, units of 250 Mbps.
* Complements. Byte 140. See Table 32A.
*/
uint8_t extbr;
/* [Prop]: len_sm
* [Desc]: Length (single mode)-(100's)m
* [Note]: This value specifies the link length that is supported by the transceiver
* while operating in compliance with the applicable standards using single mode
* fiber. The value is in units of 100 meters. A value of 255 means that the
* transceiver supports a link length greater than 25.4 km. A value of zero means
* that the transceiver does not support single mode fiber or that the length
* information must be determined from the transceiver technology.
*/
int len_sm;
/* [Prop]: len_smf
* [Desc]: Length (single mode)-km
* [Note]: Addition to EEPROM data from original GBIC definition. This value specifies
* the link length that is supported by the transceiver while operating in
* compliance with the applicable standards using single mode fiber. The value
* is in units of kilometers. A value of 255 means that the transceiver supports
* a link length greater than 254 km. A value of zero means that the transceiver
* does not support single mode fiber or that the length information must be
* determined from the transceiver technology.
*/
int len_smf;
/* [Prop]: len_om1
* [Desc]: Link length supported for 62.5 um OM1 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om1;
/* [Prop]: len_om2
* [Desc]: Link length supported for 50 um OM2 fiber, units of 10 m
* [Note]: The value is in units of 10 meters. A value of 255 means that the
* transceiver supports a link length greater than 2.54 km. A value of
* zero means that the transceiver does not support 50 micron multi-mode
* fiber or that the length information must be determined from the transceiver
* technology.
*/
int len_om2;
/* [Prop]: len_om3
* [Desc]: Length (50um, OM3)
* [Note]: This value specifies link length that is supported by the transceiver while
* operating in compliance with applicable standards using 50 micron multimode
* OM3 [2000 MHz*km] fiber. The value is in units of 10 meters. A value of 255
* means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber
* or that the length information must be determined from the transceiver technology.
*/
int len_om3;
/* [Prop]: len_om4
* [Desc]: Length (50um, OM4) and Length (Active Cable or Copper)
* [Note]: For optical links, this value specifies link length that is supported by the
* transceiver while operating in compliance with applicable standards using 50 micron
* multimode OM4 [4700 MHz*km] fiber. The value is in units of 10 meters. A value of
* 255 means that the transceiver supports a link length greater than 2.54 km. A value
* of zero means that the transceiver does not support 50 micron multimode fiber or that
* the length information must be determined from the transceiver codes specified in Table 5-3.
*
* For copper links, this value specifies minimum link length supported by the transceiver
* while operating in compliance with applicable standards using copper cable. For active
* cable, this value represents actual length. The value is in units of 1 meter. A value of 255
* means the transceiver supports a link length greater than 254 meters. A value of zero means
* the transceiver does not support copper or active cables or the length information must be
* determined from transceiver technology. Further information about cable design, equalization,
* and connectors is usually required to guarantee meeting a particular length requirement.
*/
int len_om4;
/* [Prop]: comp_rev
* [Desc]: SFF spec revision compliance
* [Note]: Indicates which revision of SFF SFF-8472 (SFP) / SFF-8636 (QSFP) the transceiver
* complies with. (unsigned integer)
*/
uint8_t comp_rev;
/* [Prop]: CDR
* [Desc]: For transceivers with CDR capability, setting the CDR to ON engages the internal
* retiming function. Setting the CDR to OFF enables an internal bypassing mode ,which
* directs traffic around the internal CDR. (Reference: SFF-8636)
* [Note]: value=0xff: ON.
* value=0x00: OFF.
*/
uint8_t cdr;
/* [Prop]: rate_id
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Addr: A0h / Offset: 13
* 2. Value description:
* 00h Unspecified
* 01h SFF-8079 (4/2/1G Rate_Select & AS0/AS1)
* 02h SFF-8431 (8/4/2G Rx Rate_Select only)
* 03h Unspecified *
* 04h SFF-8431 (8/4/2G Tx Rate_Select only)
* 05h Unspecified *
* 06h SFF-8431 (8/4/2G Independent Rx & Tx Rate_select)
* 07h Unspecified *
* 08h FC-PI-5 (16/8/4G Rx Rate_select only) High=16G only, Low=8G/4G
* 09h Unspecified *
* 0Ah FC-PI-5 (16/8/4G Independent Rx, Tx Rate_select) High=16G only,
* Low=8G/4G
* 0Bh Unspecified *
* 0Ch FC-PI-6 (32/16/8G Independent Rx, Tx Rate_Select)
* High=32G only, Low = 16G/8G
* 0Dh Unspecified *
* 0Eh 10/8G Rx and Tx Rate_Select controlling the operation or locking
* modes of the internal signal conditioner, retimer or CDR, according
* to the logic table defined in Table 10-2, High Bit Rate
* (10G) =9.95-11.3 Gb/s; Low Bit Rate (8G) = 8.5 Gb/s. In this mode,
* the default value of bit 110.3 (Soft Rate Select RS(0), Table 9-11)
* and of bit 118.3 (Soft Rate Select RS(1), Table 10-1) is 1.
* 0Fh Unspecified *
* 10h-FFh Unallocated
*/
int rate_id;
/* [Prop]: soft_rs0
* [Desc]: Soft Rate Select 0(RX).
* [Note]: 1. Writing '1' selects full bandwidth operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(0) or RS(0) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 110 / Bit: 3
*/
uint8_t soft_rs0;
/* [Prop]: soft_rs1
* [Desc]: Soft Rate Select 1(TX).
* [Note]: 1. Writing '1' selects full bandwidth TX operation.
* 2. This bit is "OR'd with the hard Rate_Select, AS(1) or RS(1) pin value.
* 3. Default at power up is logic zero/low
* 4. Addr: A2h / Offset: 118 / Bit: 3
*/
uint8_t soft_rs1;
/* [Prop]: diag_type
* [Desc]: DIAGNOSTIC MONITORING TYPE (A0h/92)
* [Note]: Description in SFF-8472 as below:
* Bit7: Reserved for legacy diagnostic implementations. Must be '0' for compliance
* with this document.
* Bit6: Digital diagnostic monitoring implemented (described in this document).
* Must be '1' for compliance with this document.
* Bit5 Internally calibrated
* Bit4 Externally calibrated
* Bit3 Received power measurement type.0 = OMA, 1 = average power
* Bit2 Address change required see section above, "addressing modes"
* Bit1-0 Unallocated
*/
uint8_t diag_type;
/* [Prop]: curr_temp
* [Desc]: Transceiver Current Temperature (A2h/96-97)
* [Note]: 1. Dependent on diag_type.
* 2. 96: High byte
* 3. 97: Low byte
* 4. This feature only for SFP
*/
uint8_t curr_temp[2];
/* [Prop]: curr_vol
* [Desc]: Transceiver Current Voltage (SFP:A2h/108-109; QSFP:00h/22-23)
* [Note]: 1. Dependent on diag_type.
* 2. 98: High byte
* 3. 99: Low byte
* 4. This feature only for SFP
* 5. Internally measured transceiver supply voltage. Represented
* as a 16 bit unsigned integer with the voltage defined as the
* full 16 bit value (0-65535) with LSB equal to 100 uVolt,
* yielding a total range of 0 to +6.55 Volts
*/
uint8_t curr_voltage[2];
/* [Prop]: curr_tx_bias
* [Desc]: Transceiver TX Bias Current (SFP:A2h/100-101; QSFP:00h/26-27)
* [Note]: 1. Dependent on diag_type.
* 2. 100: High byte
* 3. 101: Low byte
* 4. This feature only for SFP
* 5. Measured TX bias current in uA. Represented as a 16 bit unsigned
* integer with the current defined as the full 16 bit value (0-65535)
* with LSB equal to 2 uA, yielding a total range of 0 to 131 mA.
* Accuracy is vendor specific but must be better than 10% of the
* manufacturer's nominal value over specified operating temperature
* and voltage.
*/
uint8_t curr_tx_bias[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured TX output power in mW. Represented as a 16 bit unsigned
* integer with the power defined as the full 16 bit value (0-65535)
* with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW
* (~ -40 to +8.2 dBm). Data is assumed to be based on measurement of
* laser monitor photodiode current. It is factory calibrated to absolute
* units using the most representative fiber output type. Accuracy is
* vendor specific but must be better than 3dB over specified temperature
* and voltage. Data is not valid when the transmitter is disabled.
*/
uint8_t curr_tx_power[8];
/* [Prop]: curr_tx_power
* [Desc]: Transceiver TX Output Power (A2h/102-103)
* [Note]: 1. Dependent on diag_type.
* 2. 102: High byte
* 3. 103: Low byte
* 4. This feature only for SFP
* 5. Measured RX received optical power in mW. Value can represent either
* average received power or OMA depending upon how bit 3 of byte 92 (A0h)
* is set. Represented as a 16 bit unsigned integer with the power defined
* as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a
* total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm). Absolute accuracy is
* dependent upon the exact optical wavelength. For the vendor specified
* wavelength, accuracy shall be better than 3dB over specified temperature
* and voltage.
*/
uint8_t curr_rx_power[8];
/* [Prop]: wavelength
* [Desc]: Wavelength or Copper Cable Attenuation
* [Note]: (Following is info from SFF-8636)
* For optical free side devices, this parameter identifies the nominal
* transmitter output wavelength at room temperature. This parameter is a
* 16-bit hex value with Byte 186 as high order byte and Byte 187 as low
* order byte. The laser wavelength is equal to the 16-bit integer value
* divided by 20 in nm (units of 0.05 nm). This resolution should be adequate
* to cover all relevant wavelengths yet provide enough resolution for all
* expected DWDM applications. For accurate representation of controlled
* wavelength applications, this value should represent the center of the
* guaranteed wavelength range. If the free side device is identified as
* copper cable these registers will be used to define the cable attenuation.
* An indication of 0 dB attenuation refers to the case where the attenuation
* is not known or is unavailable.
* Byte 186 (00-FFh) is the copper cable attenuation at 2.5 GHz in units of 1 dB.
* Byte 187 (00-FFh) is the copper cable attenuation at 5.0 GHz in units of 1 dB.
*/
uint8_t wavelength[2];
/* [Prop]: Amplitude control
* [Desc]: Amplitude control
* [Note]: QSFP28 => SFF-8636 03H Byte-238/239
*/
uint8_t rx_am[2];
/* [Prop]: Emphasis control
* [Desc]: Emphasis control
* [Note]: SFP+/28 => SFF-8472 A2H Byte-115
* QSFP28 => SFF-8636 03H Byte-236/237
*/
uint8_t rx_em[2];
/* [Prop]: Soft Rx LOS
* [Desc]: Soft Rx LOS which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 3:
* - Bit 0: L-Rx1 LOS
* - Bit 1: L-Rx2 LOS
* - Bit 2: L-Rx3 LOS
* - Bit 3: L-Rx4 LOS
*/
uint8_t rx_los;
/* [Prop]: Soft Tx Disable
* [Desc]: Soft Tx Disable which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Disable
* - Bit 1: Tx2 Disable
* - Bit 2: Tx3 Disable
* - Bit 3: Tx4 Disable
*/
uint8_t tx_disable;
/* [Prop]: Soft Tx Fault
* [Desc]: Soft Tx Fault which provide by transceiver
* [Note]: (Following is info from SFF-8636)
* Byte 86:
* - Bit 0: Tx1 Fault
* - Bit 1: Tx2 Fault
* - Bit 2: Tx3 Fault
* - Bit 3: Tx4 Fault
*/
uint8_t tx_fault;
/* [Prop]: Transceiver EQUALIZATION
* [Desc]: Transceiver EQUALIZATION
* [Note]: SFP+/28 => SFF-8472 A2H Byte-114
* QSFP28 => SFF-8636 03H Byte-234/235
*/
uint8_t tx_eq[2];
/* [Prop]: OPTION VALUES
* [Desc]: The bits in the option field shall specify the options implemented in the transceiver.
* [Note]: SFP+/28 => SFF-8472 A0H Byte-64/65
* QSFP+/28 => SFF-8636 00H Byte-193/195
*/
uint8_t option[3];
/* [Prop]: External PHY offset
* [Desc]: It needs to be setup first if you want to access transceiver external phy.
* [Note]: This feature dependent on transceiver.
* Currently, only 1G-RJ45 transceiver supported it.
*/
uint8_t extphy_offset;
/* ========== Object private property ==========
*/
struct device *transvr_dev_p;
struct eeprom_map_s *eeprom_map_p;
struct i2c_client *i2c_client_p;
struct ioexp_obj_s *ioexp_obj_p;
struct transvr_worker_s *worker_p;
struct mutex lock;
char swp_name[32];
int auto_config;
int auto_tx_disable;
int chan_id;
int chipset_type;
int curr_page;
int info;
int ioexp_virt_offset;
int lane_id[8];
int layout;
int mode;
int retry;
int state;
int temp;
int type;
/* ========== Object public functions ==========
*/
int (*get_id)(struct transvr_obj_s *self);
int (*get_ext_id)(struct transvr_obj_s *self);
int (*get_connector)(struct transvr_obj_s *self);
int (*get_vendor_name)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_pn)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_rev)(struct transvr_obj_s *self, char *buf_p);
int (*get_vendor_sn)(struct transvr_obj_s *self, char *buf_p);
int (*get_power_cls)(struct transvr_obj_s *self);
int (*get_br)(struct transvr_obj_s *self);
int (*get_len_sm)(struct transvr_obj_s *self);
int (*get_len_smf)(struct transvr_obj_s *self);
int (*get_len_om1)(struct transvr_obj_s *self);
int (*get_len_om2)(struct transvr_obj_s *self);
int (*get_len_om3)(struct transvr_obj_s *self);
int (*get_len_om4)(struct transvr_obj_s *self);
int (*get_comp_rev)(struct transvr_obj_s *self);
int (*get_comp_eth_1)(struct transvr_obj_s *self);
int (*get_comp_eth_10)(struct transvr_obj_s *self);
int (*get_comp_eth_10_40)(struct transvr_obj_s *self);
int (*get_comp_extend)(struct transvr_obj_s *self);
int (*get_cdr)(struct transvr_obj_s *self);
int (*get_rate_id)(struct transvr_obj_s *self);
int (*get_soft_rs0)(struct transvr_obj_s *self);
int (*get_soft_rs1)(struct transvr_obj_s *self);
int (*get_info)(struct transvr_obj_s *self);
int (*get_if_type)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_speed)(struct transvr_obj_s *self, char *buf_p);
int (*get_if_lane)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_temp)(struct transvr_obj_s *self, char *buf_p);
int (*get_curr_vol)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_rx_los)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_soft_tx_fault)(struct transvr_obj_s *self, char *buf_p);
int (*get_auto_tx_disable)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_bias)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_power)(struct transvr_obj_s *self, char *buf_p);
int (*get_tx_eq)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_am)(struct transvr_obj_s *self, char *buf_p);
int (*get_rx_em)(struct transvr_obj_s *self, char *buf_p);
int (*get_wavelength)(struct transvr_obj_s *self, char *buf_p);
int (*get_extphy_offset)(struct transvr_obj_s *self, char *buf_p);
int (*get_extphy_reg)(struct transvr_obj_s *self, char *buf_p);
int (*set_cdr)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs0)(struct transvr_obj_s *self, int input_val);
int (*set_soft_rs1)(struct transvr_obj_s *self, int input_val);
int (*set_soft_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_auto_tx_disable)(struct transvr_obj_s *self, int input_val);
int (*set_tx_eq)(struct transvr_obj_s *self, int input_val);
int (*set_rx_am)(struct transvr_obj_s *self, int input_val);
int (*set_rx_em)(struct transvr_obj_s *self, int input_val);
int (*set_extphy_offset)(struct transvr_obj_s *self, int input_val);
int (*set_extphy_reg)(struct transvr_obj_s *self, int input_val);
/* ========== Object private functions ==========
*/
int (*init)(struct transvr_obj_s *self);
int (*clean)(struct transvr_obj_s *self);
int (*check)(struct transvr_obj_s *self);
int (*update_all)(struct transvr_obj_s *self, int show_err);
int (*fsm_4_direct)(struct transvr_obj_s* self, char *caller_name);
int (*fsm_4_polling)(struct transvr_obj_s* self, char *caller_name);
int (*send_uevent)(struct transvr_obj_s* self, enum kobject_action u_action);
int (*dump_all)(struct transvr_obj_s* self);
};
/* For AVL Mapping */
struct transvr_avl_s {
char vendor_name[32];
char vendor_pn[32];
int (*init)(struct transvr_obj_s *self);
};
/* Worker for long term task of transceiver */
struct transvr_worker_s {
/* Task Parameter */
struct transvr_obj_s *transvr_p;
struct transvr_worker_s *next_p;
struct transvr_worker_s *pre_p;
unsigned long trigger_time;
char func_name[64];
int retry;
int state;
/* Task private data */
void *p_data;
/* Call back function */
int (*main_task)(struct transvr_worker_s *task);
int (*post_task)(struct transvr_worker_s *task);
};
struct transvr_obj_s *
create_transvr_obj(char *swp_name,
int chan_id,
struct ioexp_obj_s *ioexp_obj_p,
int ioexp_virt_offset,
int transvr_type,
int chipset_type,
int run_mode);
void lock_transvr_obj(struct transvr_obj_s *self);
void unlock_transvr_obj(struct transvr_obj_s *self);
int isolate_transvr_obj(struct transvr_obj_s *self);
int resync_channel_tier_2(struct transvr_obj_s *self);
void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);
#endif /* TRANSCEIVER_H */

View File

@ -0,0 +1,17 @@
[Unit]
Documentation=man:systemd-sysv-generator(8)
SourcePath=/etc/init.d/sonic-platform-netberg-aurora-610
Description=LSB: Setup Netberg Aurora 610
[Service]
Restart=no
TimeoutSec=1min
ExecStart=/etc/init.d/sonic-platform-netberg-aurora-610 start
ExecStop=/etc/init.d/sonic-platform-netberg-aurora-610 stop
[Install]
Alias=sonic-platform-netberg-aurora-610.target
WantedBy=multi-user.target

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
import os
from setuptools import setup
os.listdir
setup(
name='sonic_platform',
version='1.0',
description='Netberg Aurora 610 sonic platform API',
packages=['sonic_platform'],
package_dir={'sonic_platform': 'sonic_platform'},
classifiers=[
'Development Status :: 3 - Beta',
'Environment :: Plugins',
'Intended Audience :: Developers',
'Intended Audience :: Information Technology',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 3.7',
'Topic :: Utilities',
],
)

View File

@ -0,0 +1,2 @@
__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp']
from . import platform

View File

@ -0,0 +1,247 @@
#!/usr/bin/env python
#
# Name: chassis.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import re
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.eeprom import Eeprom
from sonic_platform.fan_drawer import FanDrawer
from sonic_platform.psu import Psu
from sonic_platform.sfp import Sfp
from sonic_platform.qsfp import QSfp
from sonic_platform.thermal import Thermal
from sonic_platform.component import Component
from sonic_platform.watchdog import Watchdog
from sonic_platform.event_monitor import EventMonitor
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/reboot-cause/"
REBOOT_CAUSE_FILE = "reboot-cause.txt"
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
monitor = None
class Chassis(ChassisBase):
__num_of_fans = 4
__num_of_psus = 2
__num_of_sfps = 56
__start_of_qsfp = 48
__num_of_thermals = 15
__num_of_components = 4
def __init__(self):
ChassisBase.__init__(self)
# Initialize EEPROM
self._eeprom = Eeprom()
self._eeprom_data = self._eeprom.get_eeprom_data()
# Initialize FAN
for index in range(self.__num_of_fans):
fandrawer = FanDrawer(index)
self._fan_drawer_list.append(fandrawer)
self._fan_list.extend(fandrawer._fan_list)
# Initialize PSU
for index in range(self.__num_of_psus):
psu = Psu(index)
self._psu_list.append(psu)
# Initialize SFP
for index in range(self.__num_of_sfps):
if index < self.__start_of_qsfp:
sfp = Sfp(index)
else:
sfp = QSfp(index)
self._sfp_list.append(sfp)
# Initialize THERMAL
for index in range(self.__num_of_thermals):
thermal = Thermal(index)
self._thermal_list.append(thermal)
# Initialize COMPONENT
for index in range(self.__num_of_components):
component = Component(index)
self._component_list.append(component)
# Initialize WATCHDOG
self._watchdog = Watchdog()
def __read_txt_file(self, file_path):
try:
with open(file_path, 'r') as fd:
data = fd.read()
return data.strip()
except IOError:
pass
return None
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the chassis
Returns:
string: The name of the chassis
"""
return self._eeprom.modelstr()
def get_presence(self):
"""
Retrieves the presence of the chassis
Returns:
bool: True if chassis is present, False if not
"""
return True
def get_model(self):
"""
Retrieves the model number (or part number) of the chassis
Returns:
string: Model/part number of chassis
"""
return self._eeprom.part_number_str()
def get_serial(self):
"""
Retrieves the serial number of the chassis
Returns:
string: Serial number of chassis
"""
return self._eeprom.serial_number_str()
def get_status(self):
"""
Retrieves the operational status of the chassis
Returns:
bool: A boolean value, True if chassis is operating properly
False if not
"""
return True
##############################################
# Chassis methods
##############################################
def get_base_mac(self):
"""
Retrieves the base MAC address for the chassis
Returns:
A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX'
"""
return self._eeprom.base_mac_addr(self._eeprom_data)
def get_serial_number(self):
"""
Retrieves the hardware serial number for the chassis
Returns:
A string containing the hardware serial number for this chassis.
"""
return self._eeprom.serial_number_str(self._eeprom_data)
def get_system_eeprom_info(self):
"""
Retrieves the full content of system EEPROM information for the chassis
Returns:
A dictionary where keys are the type code defined in
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821',
'0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00',
'0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'}
"""
return self._eeprom.system_eeprom_info()
def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
Returns:
A tuple (string, string) where the first element is a string
containing the cause of the previous reboot. This string must be
one of the predefined strings in this class. If the first string
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
to pass a description of the reboot cause.
"""
description = 'None'
reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER
reboot_cause_path = PMON_REBOOT_CAUSE_PATH + REBOOT_CAUSE_FILE
prev_reboot_cause_path = PMON_REBOOT_CAUSE_PATH + PREV_REBOOT_CAUSE_FILE
sw_reboot_cause = self.__read_txt_file(reboot_cause_path) or "Unknown"
prev_sw_reboot_cause = self.__read_txt_file(
prev_reboot_cause_path) or "Unknown"
if sw_reboot_cause == "Unknown" and prev_sw_reboot_cause in ("Unknown", self.REBOOT_CAUSE_POWER_LOSS):
reboot_cause = self.REBOOT_CAUSE_POWER_LOSS
description = prev_sw_reboot_cause
elif sw_reboot_cause != "Unknown":
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
description = sw_reboot_cause
elif prev_reboot_cause_path != "Unknown":
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
description = prev_sw_reboot_cause
return (reboot_cause, description)
def get_change_event(self, timeout=0):
"""
Returns a nested dictionary containing all devices which have
experienced a change at chassis level
Args:
timeout: Timeout in milliseconds (optional). If timeout == 0,
this method will block until a change is detected.
Returns:
(bool, dict):
- True if call successful, False if not;
- A nested dictionary where key is a device type,
value is a dictionary with key:value pairs in the format of
{'device_id':'device_event'},
where device_id is the device ID for this device and
device_event,
status='1' represents device inserted,
status='0' represents device removed.
Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}}
indicates that fan 0 has been removed, fan 2
has been inserted and sfp 11 has been removed.
"""
global monitor
port_dict = {}
while True:
with EventMonitor(timeout) as monitor:
while True:
event = monitor.get_events()
if not bool(event):
return True, {'sfp': port_dict}
else:
if event['SUBSYSTEM'] == 'swps':
portname = event['DEVPATH'].split("/")[-1]
rc = re.match(r"port(?P<num>\d+)", portname)
if rc is not None:
if event['ACTION'] == "remove":
remove_num = int(rc.group("num"))
port_dict[remove_num] = "0"
elif event['ACTION'] == "add":
add_num = int(rc.group("num"))
port_dict[add_num] = "1"
return True, {'sfp': port_dict}
return False, {'sfp': port_dict}
else:
pass

View File

@ -0,0 +1,267 @@
#!/usr/bin/env python
try:
import os
import re
import logging
from subprocess import Popen, PIPE
from sonic_platform_base.component_base import ComponentBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
OS_SYSTEM_SUCCESS = 0
CPLD_INFO_PATH = "/sys/bus/i2c/devices/0-0077/info"
BIOS_VER_PATH = "/sys/class/dmi/id/bios_version"
BIOS_CS_PATH = "/sys/bus/i2c/devices/0-0077/bios_cs"
CPLD_INDEX = 0
BMC_INDEX = 1
MAIN_BIOS_INDEX = 2
BACKUP_BIOS_INDEX = 3
COMPONENT_NAME_LIST = [
"CPLD",
"BMC",
"Main BIOS",
"Backup BIOS",
]
COMPONENT_DESC_LIST = [
"Platform management and LED",
"Baseboard management controller",
"Main BIOS",
"Backup BIOS",
]
FW_INSTALL_CMD_LIST = [
"/usr/share/sonic/platform/plugins/cpld -b 1 -s 0x60 {}",
"/usr/share/sonic/platform/plugins/Yafuflash -cd {} -img-select 3 -non-interactive",
"/usr/share/sonic/platform/plugins/afulnx_64 {} /B /P /N /K",
"/usr/share/sonic/platform/plugins/afulnx_64 {} /B /P /N /K",
]
BIOS_ID_MAPPING_TABLE = {
0: MAIN_BIOS_INDEX,
1: BACKUP_BIOS_INDEX
}
class Component(ComponentBase):
def __get_attr_value(self, attr_path):
retval = 'ERR'
if not os.path.isfile(attr_path):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open file: %s", attr_path)
retval = retval.rstrip(' \t\n\r')
return retval
def __set_attr_value(self, attr_path, value):
try:
with open(attr_path, 'r+') as reg_file:
reg_file.write(value)
except IOError as e:
logging.error("Error: unable to open file: %s", str(e))
return False
return True
def __get_current_bios(self):
current_bios = self.__get_attr_value(BIOS_CS_PATH)
if current_bios != 'ERR':
# Get first char to convert to bios ID
current_bios = int(current_bios[:1])
else:
current_bios = None
return current_bios
def __get_cpld_version(self):
'''
The info output would be like:
The CPLD release date is 06/13/2019.
The PCB version is 5
The CPLD version is 1.1
'''
cpld_version = None
ret_str = None
path = None
target = "The CPLD version is "
if self.index == CPLD_INDEX:
path = CPLD_INFO_PATH
else:
logging.error("Unable support index %d", self.index)
if path is not None:
try:
with open(path, 'r') as file:
ret_str = file.read()
except Exception as error:
logging.error("Unable to open file %s", path)
if ret_str is not None:
start_idx = ret_str.find(target)
if start_idx > 0:
start_idx = start_idx+len(target)
offset = ret_str[start_idx:].find('\n')
if offset > 0:
end_idx = start_idx+offset
cpld_version = ret_str[start_idx:end_idx].strip('\n')
if cpld_version is None:
logging.error("Unable to parse cpld info %d", self.index)
return cpld_version
def __get_bmc_version(self):
bmc_version = "N/A"
output = Popen(["ipmitool", "mc", "info"], stdout=PIPE, encoding='utf8')
ret_str = output.communicate(timeout=5)[0]
ret_search = re.search("Firmware Revision\s+:\s(.*)\n", ret_str, re.M)
if ret_search:
bmc_version = ret_search.group(1)
return bmc_version
def __get_bios_version(self):
bios_version = None
current_bios_id = self.__get_current_bios()
if current_bios_id is not None:
if self.index == BIOS_ID_MAPPING_TABLE[current_bios_id]:
try:
with open(BIOS_VER_PATH, 'r') as file:
bios_version = file.read().strip('\n')
except Exception as error:
logging.error("Unable to open file %s", BIOS_VER_PATH)
else:
logging.error(
"Only support bios version of current running BIOS")
bios_version = "N/A"
return bios_version
def __install_cpld_firmware(self, image_path):
result = False
cmd = FW_INSTALL_CMD_LIST[self.index].format(image_path)
ret = os.system(cmd)
if ret == OS_SYSTEM_SUCCESS:
result = True
return result
def __install_bmc_firmware(self, image_path):
result = False
cmd = FW_INSTALL_CMD_LIST[self.index].format(image_path)
ret = os.system(cmd)
if ret == OS_SYSTEM_SUCCESS:
result = True
return result
def __install_bios_firmware(self, image_path):
result = False
temp_bios_id = None
current_bios_id = self.__get_current_bios()
if current_bios_id == 0:
temp_bios_id = 1
elif current_bios_id == 1:
temp_bios_id = 0
else:
#If current BIOS ID illegal, treat as None
logging.error("Cannot get correct bios id")
current_bios_id = None
if (current_bios_id is not None) and (temp_bios_id is not None):
ret = True
if self.index == BIOS_ID_MAPPING_TABLE[current_bios_id]:
pass
elif self.index == BIOS_ID_MAPPING_TABLE[temp_bios_id]:
ret = self.__set_attr_value(BIOS_CS_PATH, str(temp_bios_id))
else:
logging.error("Not support BIOS index %d", self.index)
if ret:
cmd = FW_INSTALL_CMD_LIST[self.index].format(image_path)
ret = os.system(cmd)
if ret == OS_SYSTEM_SUCCESS:
result = True
else:
logging.error("Bios Firmware upgrade fail")
else:
logging.error("Set BIOS ID fail")
if self.index == BIOS_ID_MAPPING_TABLE[temp_bios_id]:
# Write back current_bios no matter what
self.__set_attr_value(BIOS_CS_PATH, str(current_bios_id))
return result
__get_version_callback_list = {
CPLD_INDEX: __get_cpld_version,
BMC_INDEX: __get_bmc_version,
MAIN_BIOS_INDEX: __get_bios_version,
BACKUP_BIOS_INDEX: __get_bios_version,
}
__install_firmware_callback_list = {
CPLD_INDEX: __install_cpld_firmware,
BMC_INDEX: __install_bmc_firmware,
MAIN_BIOS_INDEX: __install_bios_firmware,
BACKUP_BIOS_INDEX: __install_bios_firmware,
}
def __init__(self, component_index):
self.index = component_index
def get_name(self):
"""
Retrieves the name of the component
Returns:
A string containing the name of the component
"""
return COMPONENT_NAME_LIST[self.index]
def get_description(self):
"""
Retrieves the description of the component
Returns:
A string containing the description of the component
"""
return COMPONENT_DESC_LIST[self.index]
def get_firmware_version(self):
"""
Retrieves the firmware version of the component
Returns:
A string containing the firmware version of the component
"""
return self.__get_version_callback_list[self.index](self)
def install_firmware(self, image_path):
"""
Installs firmware to the component
Args:
image_path: A string, path to firmware image
Returns:
A boolean, True if install was successful, False if not
"""
return self.__install_firmware_callback_list[self.index](self, image_path)

View File

@ -0,0 +1,114 @@
#!/usr/bin/env python
try:
import sys
import re
if sys.version_info.major == 3:
from io import StringIO
else:
from cStringIO import StringIO
# from sonic_platform_base.sonic_eeprom import eeprom_dts
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
EEPROM_DECODE_HEADLINES = 6
def __init__(self):
self._eeprom_path = "/sys/bus/i2c/devices/0-0053/eeprom"
super(Eeprom, self).__init__(self._eeprom_path, 0, '', True)
self._eeprom = self._load_eeprom()
def __parse_output(self, decode_output):
decode_output.replace('\0', '')
lines = decode_output.split('\n')
lines = lines[self.EEPROM_DECODE_HEADLINES:]
_eeprom_info_dict = dict()
for line in lines:
match = re.search(
r'(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line)
if match is not None:
idx = match.group(1)
value = match.group(3).rstrip('\0')
_eeprom_info_dict[idx] = value
return _eeprom_info_dict
def _load_eeprom(self):
original_stdout = sys.stdout
sys.stdout = StringIO()
err = self.read_eeprom_db()
if err:
pass
else:
decode_output = sys.stdout.getvalue()
sys.stdout = original_stdout
return self.__parse_output(decode_output)
status = self.check_status()
if status < 'ok':
return {}
data = self.read_eeprom()
if data is None:
return 0
self.decode_eeprom(data)
decode_output = sys.stdout.getvalue()
sys.stdout = original_stdout
is_valid = self.is_checksum_valid(data)
if not is_valid:
return {}
return self.__parse_output(decode_output)
def get_eeprom(self):
return self._eeprom
def serial_number_str(self):
"""
Returns the serial number
"""
return self._eeprom.get('0x23', "Undefined.")
def base_mac_addr(self, ee):
"""
Returns the base mac address found in the system EEPROM
"""
return self._eeprom.get('0x24', "Undefined.")
def modelstr(self):
"""
Returns the Model name
"""
return self._eeprom.get('0x28', "Undefined.")
def part_number_str(self):
"""
Returns the part number
"""
return self._eeprom.get('0x22', "Undefined.")
def revision_str(self):
"""
Returns the device revision
"""
return self._eeprom.get('0x26', "Undefined.")
def serial_str(self):
return self._eeprom.get('0x2F', "Undefined.")
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
def get_eeprom_data(self):
return self._eeprom

View File

@ -0,0 +1,95 @@
#
# event_monitor.py
# Description: module to minitor events
#
try:
import socket
from collections import OrderedDict
import os
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
NETLINK_KOBJECT_UEVENT = 15
class EventMonitor:
def __init__(self, timeout):
self.recieved_events = OrderedDict()
self.socket = socket.socket(
socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
self.timeout = timeout
def start(self):
self.socket.bind((os.getpid(), -1))
if self.timeout == 0:
self.socket.settimeout(None)
else:
self.socket.settimeout(self.timeout/1000.0)
def stop(self):
self.socket.close()
def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.stop()
def __iter__(self):
while True:
for item in self.next_events():
yield item
def next_events(self):
try:
data = self.socket.recv(16384)
event = {}
for item in data.split(b'\x00'):
if not item:
# check if we have an event and if we already received it
if event and event['SEQNUM'] not in self.recieved_events:
self.recieved_events[event['SEQNUM']] = None
if len(self.recieved_events) > 100:
self.recieved_events.popitem(last=False)
yield event
event = {}
else:
try:
k, v = item.split(b'=', 1)
event[k.decode('ascii')] = v.decode('ascii')
except ValueError:
pass
except socket.timeout:
yield event
def get_events(self):
event = {}
while True:
try:
data = self.socket.recv(16384)
for item in data.split(b'\x00'):
if not item:
# check if we have an event and if we already received it
# if no item and event empty, means received garbled
if bool(event):
if event['SEQNUM'] not in self.recieved_events:
self.recieved_events[event['SEQNUM']] = None
if len(self.recieved_events) > 100:
self.recieved_events.popitem(last=False)
return event
else:
event = {}
else:
try:
k, v = item.split(b'=', 1)
event[k] = v
except ValueError:
pass
except socket.timeout:
return event

View File

@ -0,0 +1,293 @@
#!/usr/bin/env python
#
# Name: fan.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import logging
import math
import os
from sonic_platform_base.fan_base import FanBase
from sonic_py_common.logger import Logger
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
MAX_SPEED_OF_FAN_FRONT = 23000
MAX_SPEED_OF_FAN_BACK = 20500
MAX_SPEED_OF_FAN_PSU = 18100
MAX_PWM_OF_FAN = 255
class FanConst:
FAN_PSU_START_INDEX = 4
FAN_SYS_FS = "/sys/devices/virtual/hwmon/hwmon1/"
logger = Logger('sonic-platform-fan')
class Fan(FanBase):
__name_of_fans = ['FAN1', 'FAN2', 'FAN3', 'FAN4', 'PSU1_FAN1', 'PSU2_FAN1']
__start_of_psu_fans = FanConst().FAN_PSU_START_INDEX
__fan_gpi_attr = FAN_SYS_FS + "fan_gpi"
def __init__(self, index):
self.__index = index
if self.__index >= self.__start_of_psu_fans:
self.__presence_attr = FAN_SYS_FS + \
"psu{}".format(self.__index - self.__start_of_psu_fans + 1)
self.__pwm_attr = FAN_SYS_FS + \
"pwm_psu{}".format(self.__index - self.__start_of_psu_fans + 1)
self.__rpm1_attr = FAN_SYS_FS + \
"rpm_psu{}".format(self.__index - self.__start_of_psu_fans + 1)
self.__rpm2_attr = FAN_SYS_FS + ""
else:
self.__rpm1_attr = FAN_SYS_FS + \
"fan{}_input".format(2*self.__index + 1)
self.__rpm2_attr = FAN_SYS_FS + \
"fan{}_input".format(2*self.__index + 2)
self.__pwm_attr = FAN_SYS_FS + "pwm{}".format(self.__index + 1)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if not os.path.isfile(attr_path):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open file: %s", attr_path)
retval = retval.rstrip(' \t\n\r')
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return self.__name_of_fans[self.__index]
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
if self.__index >= self.__start_of_psu_fans:
# check fan of psu presence if psu presence
attr_normal = "0 : normal"
attr_unpowered = "2 : unpowered"
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if attr_rv == attr_normal or attr_rv == attr_unpowered:
presence = True
else:
raise SyntaxError
else:
attr_path = self.__fan_gpi_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
# B[0-3] installed(0)/uninstalled(1)
if not(int(attr_rv, 16) >> self.__index) & 1:
presence = True
else:
raise SyntaxError
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
raise NotImplementedError
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
raise NotImplementedError
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
status = False
if self.__index >= self.__start_of_psu_fans:
# check fan of psu presence if psu presence
attr_normal = "0 : normal"
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if attr_rv == attr_normal:
status = True
else:
raise SyntaxError
else:
status = self.get_presence()
return status
##############################################
# FAN methods
##############################################
def get_direction(self):
"""
Retrieves the direction of fan
Returns:
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
depending on fan direction
"""
direction = 'N/A'
attr_path = self.__fan_gpi_attr
if self.__index >= self.__start_of_psu_fans:
raise NotImplementedError
else:
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
# B[4-7] FRtype(0)/RFtype(1)
if not((int(attr_rv, 16) >> self.__index) & 1):
if not((int(attr_rv, 16) >> (self.__index+4)) & 1):
direction = 'FAN_DIRECTION_EXHAUST'
else:
direction = 'FAN_DIRECTION_INTAKE'
else:
raise SyntaxError
return direction
def get_speed(self):
"""
Retrieves the speed of fan as a percentage of full speed
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
speed = 0
attr_path1 = self.__rpm1_attr
attr_path2 = self.__rpm2_attr
if self.get_presence() and attr_path1 is not None:
attr_rv1 = self.__get_attr_value(attr_path1)
attr_rv2 = self.__get_attr_value(attr_path2)
if attr_rv1 != 'ERR' and attr_rv2 != 'ERR':
fan1_input = int(attr_rv1)
speed = math.ceil(
float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT))
fan2_input = int(attr_rv2)
speed += math.ceil(float(fan2_input * 100 /
MAX_SPEED_OF_FAN_BACK))
speed /= 2
elif attr_rv1 != 'ERR':
fan1_input = int(attr_rv1)
if self.__index >= self.__start_of_psu_fans:
speed = math.ceil(
float(fan1_input * 100 / MAX_SPEED_OF_FAN_PSU))
else:
speed = math.ceil(
float(fan1_input * 100 / MAX_SPEED_OF_FAN_FRONT))
elif attr_rv2 != 'ERR':
fan2_input = int(attr_rv2)
speed += math.ceil(float(fan2_input * 100 /
MAX_SPEED_OF_FAN_BACK))
else:
raise SyntaxError
return speed
def get_target_speed(self):
"""
Retrieves the target (expected) speed of the fan
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
speed = 0
attr_path = self.__pwm_attr
if self.get_presence() and attr_path is not None:
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
pwm = int(attr_rv)
speed = math.ceil(float(pwm * 100 / MAX_PWM_OF_FAN))
else:
raise SyntaxError
return speed
def get_speed_tolerance(self):
"""
Retrieves the speed tolerance of the fan
Returns:
An integer, the percentage of variance from target speed which is
considered tolerable
"""
raise NotImplementedError
def set_speed(self, speed):
"""
Sets the fan speed
Args:
speed: An integer, the percentage of full fan speed to set fan to,
in the range 0 (off) to 100 (full speed)
Returns:
A boolean, True if speed is set successfully, False if not
"""
raise NotImplementedError
def set_status_led(self, color):
"""
Sets the state of the fan module status LED
Args:
color: A string representing the color with which to set the
fan module status LED
Returns:
bool: True if status LED state is set successfully, False if not
"""
raise NotImplementedError
def get_status_led(self):
"""
Gets the state of the fan status LED
Returns:
A string, one of the predefined STATUS_LED_COLOR_* strings above
"""
raise NotImplementedError

View File

@ -0,0 +1,22 @@
try:
from sonic_platform_base.fan_drawer_base import FanDrawerBase
from sonic_platform.fan import Fan
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class FanDrawer(FanDrawerBase):
""" Platform-specific Fan class"""
def __init__(self, fantray_index):
FanDrawerBase.__init__(self)
self.fantrayindex = fantray_index
self._fan_list.append(Fan(fantray_index))
def get_name(self):
"""
Retrieves the fan drawer name
Returns:
string: The name of the device
"""
return "FanTray{}".format(self.fantrayindex+1)

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
#
# Name: platform.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
from sonic_platform_base.platform_base import PlatformBase
from sonic_platform.chassis import Chassis
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Platform(PlatformBase):
def __init__(self):
PlatformBase.__init__(self)
self._chassis = Chassis()

View File

@ -0,0 +1,245 @@
#!/usr/bin/env python
#
# Name: psu.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
from sonic_platform_base.psu_base import PsuBase
from sonic_py_common.logger import Logger
from sonic_platform.fan import Fan, FanConst
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
VOLTAGE_UPPER_LIMIT = 14
VOLTAGE_LOWER_LIMIT = 10
PSU_SYS_FS = "/sys/devices/virtual/hwmon/hwmon1/device/"
logger = Logger('sonic-platform-psu')
class Psu(PsuBase):
__num_of_fans = 1
__name_of_psus = ['PSU1', 'PSU2']
def __init__(self, index):
self.__index = index
self.__psu_presence_attr = PSU_SYS_FS+"psu{}".format(self.__index + 1)
self.__psu_voltage_out_attr = PSU_SYS_FS + \
"psoc_psu{}_vout".format(self.__index + 1)
self.__psu_current_out_attr = PSU_SYS_FS + \
"psoc_psu{}_iout".format(self.__index + 1)
self.__psu_power_out_attr = PSU_SYS_FS + \
"psoc_psu{}_pout".format(self.__index + 1)
self.__psu_model_attr = PSU_SYS_FS + \
"psoc_psu{}_vendor".format(self.__index + 1)
self.__psu_serial_attr = PSU_SYS_FS + \
"psoc_psu{}_serial".format(self.__index + 1)
# Get the start index of fan list
self.__fan_psu_start_index = self.__index + FanConst().FAN_PSU_START_INDEX
# Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object
self._fan_list = []
# Initialize FAN
for x in range(self.__fan_psu_start_index, self.__fan_psu_start_index + self.__num_of_fans):
fan = Fan(x)
self._fan_list.append(fan)
def __get_attr_value(self, filepath):
retval = 'ERR'
try:
with open(filepath, 'r') as fd:
data = fd.readlines()
return data[0].rstrip('\r\n')
except FileNotFoundError:
logger.log_error(f"File {filepath} not found. Aborting")
except OSError as ex:
logger.log_error("Cannot open - {}: {}".format(filepath, repr(ex)))
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return self.__name_of_psus[self.__index]
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_normal = "0 : normal"
attr_unpowered = "2 : unpowered"
attr_path = self.__psu_presence_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if attr_rv in (attr_normal, attr_unpowered):
presence = True
else:
raise SyntaxError
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
model = 'Unknow'
attr_path = self.__psu_model_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if attr_rv != '':
model = attr_rv
else:
raise SyntaxError
return model
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
serial = 'Unknow'
attr_path = self.__psu_serial_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if attr_rv != '':
serial = attr_rv
else:
raise SyntaxError
return serial
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
attr_normal = "0 : normal"
attr_path = self.__psu_presence_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
return attr_rv == attr_normal
raise SyntaxError
##############################################
# PSU methods
##############################################
def get_voltage(self):
"""
Retrieves current PSU voltage output
Returns:
A float number, the output voltage in volts,
e.g. 12.1
"""
attr_path = self.__psu_voltage_out_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
voltage_out = float(attr_rv) / 1000
else:
raise SyntaxError
return voltage_out
def get_current(self):
"""
Retrieves present electric current supplied by PSU
Returns:
A float number, the electric current in amperes, e.g 15.4
"""
attr_path = self.__psu_current_out_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
current_out = float(attr_rv) / 1000
else:
raise SyntaxError
return current_out
def get_power(self):
"""
Retrieves current energy supplied by PSU
Returns:
A float number, the power in watts, e.g. 302.6
"""
attr_path = self.__psu_power_out_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
power_out = float(attr_rv) / 1000
else:
raise SyntaxError
return power_out
def get_powergood_status(self):
"""
Retrieves the powergood status of PSU
Returns:
A boolean, True if PSU has stablized its output voltages and passed all
its internal self-tests, False if not.
"""
powergood_status = False
voltage_out = self.get_voltage()
# Check the voltage out with 12V, plus or minus 20 percentage.
if VOLTAGE_LOWER_LIMIT <= voltage_out <= VOLTAGE_UPPER_LIMIT:
powergood_status = True
return powergood_status
def set_status_led(self, color):
"""
Sets the state of the PSU status LED
Args:
color: A string representing the color with which to set the
PSU status LED
Returns:
bool: True if status LED state is set successfully, False if not
"""
raise NotImplementedError
def get_status_led(self):
"""
Gets the state of the PSU status LED
Returns:
A string, one of the predefined STATUS_LED_COLOR_* strings above
"""
raise NotImplementedError

View File

@ -0,0 +1,924 @@
#!/usr/bin/env python
#
# Name: thermal.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
import logging
from ctypes import create_string_buffer
from sonic_platform_base.sfp_base import SfpBase
from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
INFO_OFFSET = 0
DOM_OFFSET = 256
XCVR_INTFACE_BULK_OFFSET = 0
XCVR_INTFACE_BULK_WIDTH_SFP = 21
XCVR_VENDOR_NAME_OFFSET = 20
XCVR_VENDOR_NAME_WIDTH = 16
XCVR_VENDOR_OUI_OFFSET = 37
XCVR_VENDOR_OUI_WIDTH = 3
XCVR_VENDOR_PN_OFFSET = 40
XCVR_VENDOR_PN_WIDTH = 16
XCVR_HW_REV_OFFSET = 56
XCVR_HW_REV_WIDTH_SFP = 4
XCVR_VENDOR_SN_OFFSET = 68
XCVR_VENDOR_SN_WIDTH = 16
XCVR_VENDOR_DATE_OFFSET = 84
XCVR_VENDOR_DATE_WIDTH = 8
XCVR_DOM_CAPABILITY_OFFSET = 92
XCVR_DOM_CAPABILITY_WIDTH = 1
# Offset for values in QSFP eeprom
SFP_TEMPE_OFFSET = 96
SFP_TEMPE_WIDTH = 2
SFP_VOLT_OFFSET = 98
SFP_VOLT_WIDTH = 2
SFP_CHANNL_MON_OFFSET = 100
SFP_CHANNL_MON_WIDTH = 6
SFP_MODULE_THRESHOLD_OFFSET = 0
SFP_MODULE_THRESHOLD_WIDTH = 40
SFP_CHANNL_THRESHOLD_OFFSET = 112
SFP_CHANNL_THRESHOLD_WIDTH = 2
SFP_STATUS_CONTROL_OFFSET = 110
SFP_STATUS_CONTROL_WIDTH = 1
SFP_TX_DISABLE_HARD_BIT = 7
SFP_TX_DISABLE_SOFT_BIT = 6
class Sfp(SfpBase):
__platform = "x86_64-netberg_aurora_610-r0"
__hwsku = "aurora-610"
__port_to_i2c_mapping = {
0: 10, 1: 11, 2: 12, 3: 13, 4: 14, 5: 15, 6: 16, 7: 17,
8: 18, 9: 19, 10: 20, 11: 21, 12: 22, 13: 23, 14: 24, 15: 25,
16: 26, 17: 27, 18: 28, 19: 29, 20: 30, 21: 31, 22: 32, 23: 33,
24: 34, 25: 35, 26: 36, 27: 37, 28: 38, 29: 39, 30: 40, 31: 41,
32: 42, 33: 43, 34: 44, 35: 45, 36: 46, 37: 47, 38: 48, 39: 49,
40: 50, 41: 51, 42: 52, 43: 53, 44: 54, 45: 55, 46: 56, 47: 57,
48: 59, 49: 58, 50: 61, 51: 60, 52: 63, 53: 62, 54: 65, 55: 64
}
def __init__(self, index):
self.__index = index
self.__port_end = len(self.__port_to_i2c_mapping) - 1
self.__presence_attr = None
self.__eeprom_path = None
if self.__index in range(0, self.__port_end + 1):
self.__presence_attr = "/sys/class/swps/port{}/present".format(
self.__index)
self.__eeprom_path = "/sys/bus/i2c/devices/{}-0050/eeprom".format(
self.__port_to_i2c_mapping[self.__index])
SfpBase.__init__(self)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if not os.path.isfile(attr_path):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except FileNotFoundError:
logging.error("File %s not found. Aborting", attr_path)
except OSError as ex:
logging.error("Cannot open - %s: %s", attr_path, repr(ex))
retval = retval.rstrip(' \t\n\r')
return retval
def __set_attr_value(self, attr_path, value):
try:
with open(attr_path, 'r+') as reg_file:
reg_file.write(value)
except IOError as e:
logging.error("Error: unable to open file: '%s'", str(e))
return False
return True
def __is_host(self):
return os.system("docker > /dev/null 2>&1") == 0
def __get_path_to_port_config_file(self):
host_platform_root_path = '/usr/share/sonic/device'
docker_hwsku_path = '/usr/share/sonic/hwsku'
host_platform_path = "/".join([host_platform_root_path,
self.__platform])
hwsku_path = "/".join([host_platform_path, self.__hwsku]
) if self.__is_host() else docker_hwsku_path
return "/".join([hwsku_path, "port_config.ini"])
def __read_eeprom_specific_bytes(self, offset, num_bytes):
eeprom_raw = []
for i in range(0, num_bytes):
eeprom_raw.append("0x00")
sysfs_eeprom_path = self.__eeprom_path
try:
with open(sysfs_eeprom_path, mode="rb", buffering=0) as sysfsfile_eeprom:
sysfsfile_eeprom.seek(offset)
raw = sysfsfile_eeprom.read(num_bytes)
raw_len = len(raw)
for n in range(0, raw_len):
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
except FileNotFoundError:
logging.error("File %s not found. Aborting", sysfs_eeprom_path)
return None
except OSError as ex:
logging.error("Cannot open - %s: %s", sysfs_eeprom_path, repr(ex))
return None
return eeprom_raw
def __write_eeprom_specific_bytes(self, offset, buffer):
sysfs_eeprom_path = self.__eeprom_path
try:
with open(sysfs_eeprom_path, "r+b") as sysfsfile_eeprom:
sysfsfile_eeprom.seek(offset)
sysfsfile_eeprom.write(buffer[0])
except IOError as e:
logging.error("Error: unable to open file: '%s'", str(e))
return False
return True
def __convert_string_to_num(self, value_str):
if "-inf" in value_str:
return 'N/A'
elif "Unknown" in value_str:
return 'N/A'
elif 'dBm' in value_str:
t_str = value_str.rstrip('dBm')
return float(t_str)
elif 'mA' in value_str:
t_str = value_str.rstrip('mA')
return float(t_str)
elif 'C' in value_str:
t_str = value_str.rstrip('C')
return float(t_str)
elif 'Volts' in value_str:
t_str = value_str.rstrip('Volts')
return float(t_str)
else:
return 'N/A'
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
name = None
sfputil_helper = SfpUtilHelper()
sfputil_helper.read_porttab_mappings(
self.__get_path_to_port_config_file())
name = sfputil_helper.logical[self.__index] or "Unknown"
return name
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
if int(attr_rv) == 0:
presence = True
else:
raise SyntaxError
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
model = "N/A"
offset = INFO_OFFSET
sfpi_obj = sff8472InterfaceId()
if not self.get_presence() or not sfpi_obj:
return model
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
model = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
return model
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
serial = "N/A"
offset = INFO_OFFSET
sfpi_obj = sff8472InterfaceId()
if not self.get_presence() or not sfpi_obj:
return serial
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
serial = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
return serial
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
status = False
tx_fault = self.get_tx_fault()
if self.get_presence() and (tx_fault is False):
status = True
return status
##############################################
# SFP methods
##############################################
def get_transceiver_info(self):
"""
Retrieves transceiver info of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
type |1*255VCHAR |type of SFP
vendor_rev |1*255VCHAR |vendor version of SFP
serial |1*255VCHAR |serial number of the SFP
manufacturer |1*255VCHAR |SFP vendor name
model |1*255VCHAR |SFP model name
connector |1*255VCHAR |connector information
encoding |1*255VCHAR |encoding information
ext_identifier |1*255VCHAR |extend identifier
ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance
cable_length |INT |cable length in m
mominal_bit_rate |INT |nominal bit rate by 100Mbs
specification_compliance |1*255VCHAR |specification compliance
vendor_date |1*255VCHAR |vendor date
vendor_oui |1*255VCHAR |vendor OUI
========================================================================
"""
transceiver_info_dict_keys = ['type', 'vendor_rev',
'serial', 'manufacturer',
'model', 'connector',
'encoding', 'ext_identifier',
'ext_rateselect_compliance', 'cable_type',
'cable_length', 'nominal_bit_rate',
'specification_compliance', 'vendor_date',
'vendor_oui']
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode',
'ESCONComplianceCodes', 'SONETComplianceCodes',
'EthernetComplianceCodes', 'FibreChannelLinkLength',
'FibreChannelTechnology', 'SFP+CableTechnology',
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
sfpi_obj = sff8472InterfaceId()
if not self.get_presence() or not sfpi_obj:
return {}
offset = INFO_OFFSET
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP)
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
sfp_interface_bulk_raw, 0)
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
sfp_vendor_name_raw, 0)
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP)
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
if sfp_vendor_oui_raw is not None:
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
sfp_vendor_oui_raw, 0)
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
(offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
sfp_vendor_date_raw, 0)
transceiver_info_dict = dict.fromkeys(
transceiver_info_dict_keys, 'N/A')
if sfp_interface_bulk_data:
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value']
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
transceiver_info_dict['nominal_bit_rate'] = str(
sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data'][
'Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
transceiver_info_dict['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data'][
'VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
transceiver_info_dict['cable_type'] = "Unknown"
transceiver_info_dict['cable_length'] = "Unknown"
for key in sfp_cable_length_tup:
if key in sfp_interface_bulk_data['data']:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = str(
sfp_interface_bulk_data['data'][key]['value'])
compliance_code_dict = dict()
for key in sfp_compliance_code_tup:
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
transceiver_info_dict['specification_compliance'] = str(
compliance_code_dict)
return transceiver_info_dict
def get_transceiver_bulk_status(self):
"""
Retrieves transceiver bulk status of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
| |to channel 3.
temperature |INT |module temperature in Celsius
voltage |INT |supply voltage in mV
tx<n>bias |INT |TX Bias Current in mA, n is the channel number,
| |for example, tx2bias stands for tx bias of channel 2.
rx<n>power |INT |received optical power in mW, n is the channel number,
| |for example, rx2power stands for rx power of channel 2.
tx<n>power |INT |TX output power in mW, n is the channel number,
| |for example, tx2power stands for tx power of channel 2.
========================================================================
"""
transceiver_dom_info_dict_keys = ['rx_los', 'tx_fault',
'reset_status', 'power_lpmode',
'tx_disable', 'tx_disable_channel',
'temperature', 'voltage',
'rx1power', 'rx2power',
'rx3power', 'rx4power',
'tx1bias', 'tx2bias',
'tx3bias', 'tx4bias',
'tx1power', 'tx2power',
'tx3power', 'tx4power']
sfpd_obj = sff8472Dom()
if not self.get_presence() or not sfpd_obj:
return {}
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
cal_type = sfpi_obj.get_calibration_type()
sfpd_obj._calibration_type = cal_type
offset = DOM_OFFSET
transceiver_dom_info_dict = dict.fromkeys(
transceiver_dom_info_dict_keys, 'N/A')
dom_temperature_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(
dom_temperature_raw, 0)
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
dom_voltage_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
dom_channel_monitor_raw, 0)
transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value']
transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value']
transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value']
for key in transceiver_dom_info_dict:
transceiver_dom_info_dict[key] = self.__convert_string_to_num(
transceiver_dom_info_dict[key])
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable()
transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel(
)
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
return transceiver_dom_info_dict
def get_transceiver_threshold_info(self):
"""
Retrieves transceiver threshold info of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
========================================================================
"""
transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning',
'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning',
'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning',
'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning',
'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
sfpd_obj = sff8472Dom()
if not self.get_presence() or not sfpd_obj:
return {}
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
cal_type = sfpi_obj.get_calibration_type()
sfpd_obj._calibration_type = cal_type
offset = DOM_OFFSET
transceiver_dom_threshold_info_dict = dict.fromkeys(
transceiver_dom_threshold_info_dict_keys, 'N/A')
dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
if dom_module_threshold_raw is not None:
dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(
dom_module_threshold_raw, 0)
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value']
transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value']
transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[
'data']['VoltageHighWarning']['value']
transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value']
transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value']
transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value']
transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value']
transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value']
transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value']
transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value']
transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value']
transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value']
transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value']
transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value']
transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value']
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
for key in transceiver_dom_threshold_info_dict:
transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(
transceiver_dom_threshold_info_dict[key])
return transceiver_dom_threshold_info_dict
def get_reset_status(self):
"""
Retrieves the reset status of SFP
Returns:
A Boolean, True if reset enabled, False if disabled
"""
# SFP doesn't support this feature
return False
def get_rx_los(self):
"""
Retrieves the RX LOS (lost-of-signal) status of SFP
Returns:
A Boolean, True if SFP has RX LOS, False if not.
Note : RX LOS status is latched until a call to get_rx_los or a reset.
"""
rx_los = False
status_control_raw = self.__read_eeprom_specific_bytes(
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
if status_control_raw:
data = int(status_control_raw[0], 16)
rx_los = (sffbase().test_bit(data, 1) != 0)
return rx_los
def get_tx_fault(self):
"""
Retrieves the TX fault status of SFP
Returns:
A Boolean, True if SFP has TX fault, False if not
Note : TX fault status is lached until a call to get_tx_fault or a reset.
"""
tx_fault = False
status_control_raw = self.__read_eeprom_specific_bytes(
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
if status_control_raw:
data = int(status_control_raw[0], 16)
tx_fault = (sffbase().test_bit(data, 2) != 0)
return tx_fault
def get_tx_disable(self):
"""
Retrieves the tx_disable status of this SFP
Returns:
A Boolean, True if tx_disable is enabled, False if disabled
"""
tx_disable = False
status_control_raw = self.__read_eeprom_specific_bytes(
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
if status_control_raw:
data = int(status_control_raw[0], 16)
tx_disable_hard = (sffbase().test_bit(
data, SFP_TX_DISABLE_HARD_BIT) != 0)
tx_disable_soft = (sffbase().test_bit(
data, SFP_TX_DISABLE_SOFT_BIT) != 0)
tx_disable = tx_disable_hard | tx_disable_soft
return tx_disable
def get_tx_disable_channel(self):
"""
Retrieves the TX disabled channels in this SFP
Returns:
A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent
TX channels which have been disabled in this SFP.
As an example, a returned value of 0x5 indicates that channel 0
and channel 2 have been disabled.
"""
# SFP doesn't support this feature
return 0
def get_lpmode(self):
"""
Retrieves the lpmode (low power mode) status of this SFP
Returns:
A Boolean, True if lpmode is enabled, False if disabled
"""
# SFP doesn't support this feature
return False
def get_power_override(self):
"""
Retrieves the power-override status of this SFP
Returns:
A Boolean, True if power-override is enabled, False if disabled
"""
# SFP doesn't support this feature
return False
def get_temperature(self):
"""
Retrieves the temperature of this SFP
Returns:
An integer number of current temperature in Celsius
"""
temp = "N/A"
sfpd_obj = sff8472Dom()
offset = DOM_OFFSET
if not self.get_presence() or not sfpd_obj:
return temp
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
cal_type = sfpi_obj.get_calibration_type()
sfpd_obj._calibration_type = cal_type
dom_temperature_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(
dom_temperature_raw, 0)
temp = self.__convert_string_to_num(
dom_temperature_data['data']['Temperature']['value'])
return temp
def get_voltage(self):
"""
Retrieves the supply voltage of this SFP
Returns:
An integer number of supply voltage in mV
"""
voltage = "N/A"
sfpd_obj = sff8472Dom()
offset = DOM_OFFSET
if not self.get_presence() or not sfpd_obj:
return voltage
eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
cal_type = sfpi_obj.get_calibration_type()
sfpd_obj._calibration_type = cal_type
dom_voltage_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
voltage = self.__convert_string_to_num(
dom_voltage_data['data']['Vcc']['value'])
return voltage
def get_tx_bias(self):
"""
Retrieves the TX bias current of this SFP
Returns:
A list of four integer numbers, representing TX bias in mA
for channel 0 to channel 4.
Ex. ['110.09', '111.12', '108.21', '112.09']
"""
tx_bias_list = []
tx_bias = "N/A"
sfpd_obj = sff8472Dom()
offset = DOM_OFFSET
if not self.get_presence() or not sfpd_obj:
return []
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
dom_channel_monitor_raw, 0)
tx_bias = self.__convert_string_to_num(
dom_voltage_data['data']['TXBias']['value'])
tx_bias_list.append(tx_bias)
tx_bias_list.append("N/A")
tx_bias_list.append("N/A")
tx_bias_list.append("N/A")
return tx_bias_list
def get_rx_power(self):
"""
Retrieves the received optical power for this SFP
Returns:
A list of four integer numbers, representing received optical
power in mW for channel 0 to channel 4.
Ex. ['1.77', '1.71', '1.68', '1.70']
"""
rx_power_list = []
rx_power = "N/A"
sfpd_obj = sff8472Dom()
offset = DOM_OFFSET
if not self.get_presence() or not sfpd_obj:
return []
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
dom_channel_monitor_raw, 0)
rx_power = self.__convert_string_to_num(
dom_voltage_data['data']['RXPower']['value'])
rx_power_list.append(rx_power)
rx_power_list.append("N/A")
rx_power_list.append("N/A")
rx_power_list.append("N/A")
return rx_power_list
def get_tx_power(self):
"""
Retrieves the TX power of this SFP
Returns:
A list of four integer numbers, representing TX power in mW
for channel 0 to channel 4.
Ex. ['1.86', '1.86', '1.86', '1.86']
"""
tx_power_list = []
tx_power = "N/A"
sfpd_obj = sff8472Dom()
offset = DOM_OFFSET
if not self.get_presence() or not sfpd_obj:
return []
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
(offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
dom_channel_monitor_raw, 0)
tx_power = self.__convert_string_to_num(
dom_voltage_data['data']['TXPower']['value'])
tx_power_list.append(tx_power)
tx_power_list.append("N/A")
tx_power_list.append("N/A")
tx_power_list.append("N/A")
return tx_power_list
def reset(self):
"""
Reset SFP and return all user module settings to their default srate.
Returns:
A boolean, True if successful, False if not
"""
# SFP doesn't support this feature
return False
def tx_disable(self, tx_disable):
"""
Disable SFP TX for all channels
Args:
tx_disable : A Boolean, True to enable tx_disable mode, False to disable
tx_disable mode.
Returns:
A boolean, True if tx_disable is set successfully, False if not
"""
status_control_raw = self.__read_eeprom_specific_bytes(
SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
if status_control_raw is not None:
tx_disable_mask = 1 << SFP_TX_DISABLE_SOFT_BIT
status_control = int(status_control_raw[0], 16)
if tx_disable:
tx_disable_ctl = status_control | tx_disable_mask
else:
tx_disable_ctl = status_control & (tx_disable_mask ^ 0xFF)
buffer = create_string_buffer(1)
buffer[0] = chr(tx_disable_ctl)
return self.__write_eeprom_specific_bytes(SFP_STATUS_CONTROL_OFFSET, buffer)
return False
def tx_disable_channel(self, channel, disable):
"""
Sets the tx_disable for specified SFP channels
Args:
channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3,
e.g. 0x5 for channel 0 and channel 2.
disable : A boolean, True to disable TX channels specified in channel,
False to enable
Returns:
A boolean, True if successful, False if not
"""
# SFP doesn't support this feature
return False
def set_lpmode(self, lpmode):
"""
Sets the lpmode (low power mode) of SFP
Args:
lpmode: A Boolean, True to enable lpmode, False to disable it
Note : lpmode can be overridden by set_power_override
Returns:
A boolean, True if lpmode is set successfully, False if not
"""
# SFP doesn't support this feature
return False
def set_power_override(self, power_override, power_set):
"""
Sets SFP power level using power_override and power_set
Args:
power_override :
A Boolean, True to override set_lpmode and use power_set
to control SFP power, False to disable SFP power control
through power_override/power_set and use set_lpmode
to control SFP power.
power_set :
Only valid when power_override is True.
A Boolean, True to set SFP to low power mode, False to set
SFP to high power mode.
Returns:
A boolean, True if power-override and power_set are set successfully,
False if not
"""
# SFP doesn't support this feature
return False

View File

@ -0,0 +1,229 @@
#!/usr/bin/env python
#
# Name: thermal.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
import logging
from sonic_platform_base.thermal_base import ThermalBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Thermal(ThermalBase):
__core_temp_path = "/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp{}_input"
__switch_thermal_path = "/sys/devices/virtual/hwmon/hwmon1/temp{}_input"
__max_temp_path = "/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp{}_max"
__name_of_thermal = [
"Core 0 Temperature",
"Core 1 Temperature",
"Core 2 Temperature",
"Core 3 Temperature",
"Core 4 Temperature",
"FrontSide Temperature",
"FanBoard Temperature",
"ASIC Temperature",
"Center Temperature",
"CPU Board Temperature",
"Switch die temperature",
"PSU1 Temperature1",
"PSU2 Temperature1",
"PSU1 Temperature2",
"PSU2 Temperature2"
]
__thermal_path_list = [
__core_temp_path.format(1),
__core_temp_path.format(2),
__core_temp_path.format(3),
__core_temp_path.format(4),
__core_temp_path.format(5),
__switch_thermal_path.format(1),
__switch_thermal_path.format(2),
__switch_thermal_path.format(3),
__switch_thermal_path.format(4),
__switch_thermal_path.format(5),
__switch_thermal_path.format(6),
__switch_thermal_path.format(7),
__switch_thermal_path.format(8),
__switch_thermal_path.format(9),
__switch_thermal_path.format(10)
]
__max_temp_path_list = [
__max_temp_path.format(1),
__max_temp_path.format(2),
__max_temp_path.format(3),
__max_temp_path.format(4),
__max_temp_path.format(5),
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
]
def __init__(self, index):
self.__index = index
self.__thermal_temp_attr = self.__thermal_path_list[self.__index]
self.__max_temp_attr = self.__max_temp_path_list[self.__index]
def __get_attr_value(self, attr_path):
retval = 'ERR'
if not os.path.isfile(attr_path):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except FileNotFoundError:
logging.error("File %s not found. Aborting", attr_path)
except (OSError, IOError) as ex:
logging.error("Cannot open - %s: %s", attr_path, repr(ex))
retval = retval.rstrip(' \t\n\r')
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return self.__name_of_thermal[self.__index]
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
attr_path = self.__thermal_temp_attr
return os.path.isfile(attr_path)
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
raise NotImplementedError
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
raise NotImplementedError
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
status = False
if self.get_presence():
status = True
return status
##############################################
# THERMAL methods
##############################################
def get_temperature(self):
"""
Retrieves current temperature reading from thermal
Returns:
A float number of current temperature in Celsius up to nearest thousandth
of one degree Celsius, e.g. 30.125
"""
attr_path = self.__thermal_temp_attr
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
temperature = float(attr_rv) / 1000
else:
raise SyntaxError
return temperature
def get_high_threshold(self):
"""
Retrieves the high threshold temperature of thermal
Returns:
A float number, the high threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
attr_path = self.__max_temp_attr
if attr_path == '':
raise NotImplementedError
else:
attr_rv = self.__get_attr_value(attr_path)
if attr_rv != 'ERR':
high_threshold = float(attr_rv) / 1000
else:
raise SyntaxError
return high_threshold
def get_low_threshold(self):
"""
Retrieves the low threshold temperature of thermal
Returns:
A float number, the low threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
raise NotImplementedError
def set_high_threshold(self, temperature):
"""
Sets the high threshold temperature of thermal
Args :
temperature: A float number up to nearest thousandth of one degree Celsius,
e.g. 30.125
Returns:
A boolean, True if threshold is set successfully, False if not
"""
raise NotImplementedError
def set_low_threshold(self, temperature):
"""
Sets the low threshold temperature of thermal
Args :
temperature: A float number up to nearest thousandth of one degree Celsius,
e.g. 30.125
Returns:
A boolean, True if threshold is set successfully, False if not
"""
raise NotImplementedError

View File

@ -0,0 +1,251 @@
#!/usr/bin/env python
#############################################################################
#
# Module contains an implementation of SONiC Platform Base API and
# provides the Watchdog information
#
#############################################################################
import fcntl
import os
import array
try:
from sonic_platform_base.watchdog_base import WatchdogBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
""" ioctl constants """
IO_WRITE = 0x40000000
IO_READ = 0x80000000
IO_READ_WRITE = 0xC0000000
IO_SIZE_INT = 0x00040000
IO_SIZE_40 = 0x00280000
IO_TYPE_WATCHDOG = ord('W') << 8
WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG
WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG
WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG
""" Watchdog ioctl commands """
WDIOC_GETSUPPORT = 0 | WDR_40
WDIOC_GETSTATUS = 1 | WDR_INT
WDIOC_GETBOOTSTATUS = 2 | WDR_INT
WDIOC_GETTEMP = 3 | WDR_INT
WDIOC_SETOPTIONS = 4 | WDR_INT
WDIOC_KEEPALIVE = 5 | WDR_INT
WDIOC_SETTIMEOUT = 6 | WDWR_INT
WDIOC_GETTIMEOUT = 7 | WDR_INT
WDIOC_SETPRETIMEOUT = 8 | WDWR_INT
WDIOC_GETPRETIMEOUT = 9 | WDR_INT
WDIOC_GETTIMELEFT = 10 | WDR_INT
""" Watchdog status constants """
WDIOS_DISABLECARD = 0x0001
WDIOS_ENABLECARD = 0x0002
WDT_COMMON_ERROR = -1
WD_MAIN_IDENTITY = "iTCO_wdt"
WDT_SYSFS_PATH = "/sys/class/watchdog/"
class Watchdog(WatchdogBase):
def __init__(self):
self.watchdog = None
self.armed = False
def _is_wd_main(self, dev):
"""
Checks watchdog identity
"""
identity = self._read_file(
"{}/{}/identity".format(WDT_SYSFS_PATH, dev))
return identity == WD_MAIN_IDENTITY
def _get_wdt(self):
"""
Retrieves watchdog device
"""
wdt_main_dev_list = [dev for dev in os.listdir(
"/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)]
if not wdt_main_dev_list:
return None
wdt_main_dev_name = wdt_main_dev_list[0]
watchdog_device_path = "/dev/{}".format(wdt_main_dev_name)
try:
watchdog = os.open(watchdog_device_path, os.O_RDWR)
except (FileNotFoundError, IOError, OSError):
watchdog = None
except SystemExit:
pass
return watchdog, wdt_main_dev_name
def _read_file(self, file_path):
"""
Read text file
"""
try:
with open(file_path, "r") as fd:
txt = fd.read()
except IOError:
return WDT_COMMON_ERROR
return txt.strip()
def _enable(self):
"""
Turn on the watchdog timer
"""
req = array.array('h', [WDIOS_ENABLECARD])
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
def _disable(self):
"""
Turn off the watchdog timer
"""
if self.watchdog is None:
return WDT_COMMON_ERROR
req = array.array('h', [WDIOS_DISABLECARD])
fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
def _keepalive(self):
"""
Keep alive watchdog timer
"""
fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
def _settimeout(self, seconds):
"""
Set watchdog timer timeout
@param seconds - timeout in seconds
@return is the actual set timeout
"""
req = array.array('I', [seconds])
fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True)
return int(req[0])
def _gettimeout(self, timeout_path):
"""
Get watchdog timeout
@return watchdog timeout
"""
if self.watchdog is None:
return WDT_COMMON_ERROR
req = array.array('I', [0])
fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
return int(req[0])
def _gettimeleft(self):
"""
Get time left before watchdog timer expires
@return time left in seconds
"""
req = array.array('I', [0])
fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True)
return int(req[0])
def _set_arm(self):
self.watchdog, self.wdt_main_dev_name = self._get_wdt()
self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name
self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name
self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name
# Set default value
self._disable()
self.timeout = self._gettimeout(self.timeout_path)
#################################################################
def arm(self, seconds):
"""
Arm the hardware watchdog with a timeout of <seconds> seconds.
If the watchdog is currently armed, calling this function will
simply reset the timer to the provided value. If the underlying
hardware does not support the value provided in <seconds>, this
method should arm the watchdog with the *next greater* available
value.
Returns:
An integer specifying the *actual* number of seconds the watchdog
was armed with. On failure returns -1.
"""
if self.watchdog is None:
self._set_arm()
ret = WDT_COMMON_ERROR
if seconds < 0 or self.watchdog is None:
return ret
try:
if self.timeout != seconds:
self.timeout = self._settimeout(seconds)
if self.armed:
self._keepalive()
else:
self._enable()
self.armed = True
ret = self.timeout
except IOError as e:
pass
return ret
def disarm(self):
"""
Disarm the hardware watchdog
Returns:
A boolean, True if watchdog is disarmed successfully, False if not
"""
disarmed = False
if self.watchdog is None:
return disarmed
if self.is_armed():
try:
self._disable()
self.armed = False
disarmed = True
except IOError:
pass
return disarmed
def is_armed(self):
"""
Retrieves the armed state of the hardware watchdog.
Returns:
A boolean, True if watchdog is armed, False if not
"""
return self.armed
def get_remaining_time(self):
"""
If the watchdog is armed, retrieve the number of seconds remaining on
the watchdog timer
Returns:
An integer specifying the number of seconds remaining on thei
watchdog timer. If the watchdog is not armed, returns -1.
"""
timeleft = WDT_COMMON_ERROR
if self.watchdog is None:
return WDT_COMMON_ERROR
if self.armed:
try:
timeleft = self._gettimeleft()
except IOError:
pass
return timeleft
def __del__(self):
"""
Close watchdog
"""
if self.watchdog is not None:
os.close(self.watchdog)

View File

@ -0,0 +1,101 @@
#!/bin/bash
normal='0 : normal'
unpowered='2 : unpowered'
fault='4 : fault'
notinstalled='7 : not installed'
FAN_UNPLUG_NUM=0
FAN_LED_RED='fan_led_red'
NUM=1
FAN_NUM=5
FIRST_READ=0
SECOND_READ=0
PSOC_PATH="/tmp/psoc"
CPLD_ADDR="/sys/bus/i2c/devices/i2c-0/0-0077"
ROUTE="/sys/class/hwmon/"
#PSU_STAUS='000'
#switch is ready , transfer control of cpld to cpu
echo 1 > $CPLD_ADDR/ctl
while true
do
#monitor how many fan modules are unplugged
#first check
FAN_UNPLUG_NUM=0
FAN_ARR=$(cat $PSOC_PATH/$FAN_LED_RED?)
while read -r line; do
fan_led_red_check=$(echo "$line")
if [ $fan_led_red_check -eq 1 ]
then
let FAN_UNPLUG_NUM=FAN_UNPLUG_NUM+1
fi
done <<< "$FAN_ARR"
FIRST_READ=$FAN_UNPLUG_NUM
#second check
FAN_UNPLUG_NUM=0
FAN_ARR=$(cat $PSOC_PATH/$FAN_LED_RED?)
while read -r line; do
fan_led_red_check=$(echo "$line")
if [ $fan_led_red_check -eq 1 ]
then
let FAN_UNPLUG_NUM=FAN_UNPLUG_NUM+1
fi
done <<< "$FAN_ARR"
SECOND_READ=$FAN_UNPLUG_NUM
if [ $FIRST_READ -ne $SECOND_READ ]
then
#echo "not equl:$FIRST_READ != $SECOND_READ"
continue
fi
if [ $FAN_UNPLUG_NUM -ge 2 ]
then
#echo "solid red"
echo 7 > $CPLD_ADDR/red_led
echo 0 > $CPLD_ADDR/grn_led
sleep 1
continue
elif [ $FAN_UNPLUG_NUM -eq 1 ]
then
#solid orange
echo 7 > $CPLD_ADDR/red_led
echo 7 > $CPLD_ADDR/grn_led
sleep 1
continue
fi
#echo "normal"
psu0var=$(cat $CPLD_ADDR/psu0) # bottom PSU
psu1var=$(cat $CPLD_ADDR/psu1) # top PSU
if [ "$psu0var" = "$normal" ] &&
[ "$psu1var" = "$normal" ] # PSU normal operatio
then
#solid green
echo 7 > $CPLD_ADDR/grn_led
echo 0 > $CPLD_ADDR/red_led
#echo "solid green"
else
if [ "$psu0var" = "$unpowered" ] ||
[ "$psu1var" = "$unpowered" ]
then
#echo solid orange
echo 7 > $CPLD_ADDR/grn_led
echo 7 > $CPLD_ADDR/red_led
fi
fi
sleep 1
done

View File

@ -0,0 +1,14 @@
#!/bin/bash
# Install Netberg Aurora python package
DEVICE="/usr/share/sonic/device"
PLATFORM=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
if [ -e $DEVICE/$PLATFORM/sonic_platform-1.0-py3-none-any.whl ]; then
pip install $DEVICE/$PLATFORM/sonic_platform-1.0-py3-none-any.whl
fi
depmod -a
systemctl enable sonic-platform-netberg-aurora-610
systemctl start sonic-platform-netberg-aurora-610

View File

@ -0,0 +1,12 @@
platform-driver (1.1.0) unstable; urgency=low
* Add support for Aurora 610
-- developer <support@netbergtw.com> Fri, 26 May 2017 11:00:00 +0800
platform-driver (1.0.0) unstable; urgency=low
* Initial commit
-- developer <support@netbergtw.com> Wed, 05 Oct 2016 16:30:45 +0800

View File

@ -0,0 +1 @@
10

View File

@ -0,0 +1,11 @@
Source: platform-driver
Section: unknown
Priority: optional
Maintainer: Netberg <support@netbergtw.com>
Build-Depends: debhelper (>= 9)
Standards-Version: 1.0.0
Package: sonic-platform-netberg-aurora-610
Architecture: amd64
Description: This package contains Aurora 610 platform driver utility for SONiC project.

View File

@ -0,0 +1,47 @@
#!/usr/bin/make -f
export INSTALL_MOD_DIR:=extra
PYTHON3 ?= python3
PACKAGE_PRE_NAME := sonic-platform-netberg
KVERSION ?= $(shell uname -r)
KERNEL_SRC := /lib/modules/$(KVERSION)
MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= aurora-610
MODULE_DIR := modules
UTILS_DIR := utils
SERVICE_DIR := service
CONF_DIR := conf
%:
dh $@ --with systemd
override_dh_auto_build:
(for mod in $(MODULE_DIRS); do \
make modules -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
cd $(MOD_SRC_DIR)/$${mod}; \
$(PYTHON3) setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \
cd $(MOD_SRC_DIR); \
done)
override_dh_auto_install:
(for mod in $(MODULE_DIRS); do \
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} \
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko \
debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} lib/systemd/system; \
cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service \
debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \
cd $(MOD_SRC_DIR)/$${mod}; \
python3 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \
cd $(MOD_SRC_DIR); \
done)
override_dh_clean:
dh_clean
(for mod in $(MODULE_DIRS); do \
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \
done)

View File

@ -0,0 +1,212 @@
#!/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 Netberg Aurora 610 board.
### END INIT INFO
case "$1" in
start)
echo "Setting up board... " >> /dev/kmsg
INIT_ERROR="FALSE"
depmod -a
# Insert modules by order
rmmod lpc_ich
rmmod gpio_ich
modprobe gpio_ich gpiobase=0
modprobe lpc_ich
modprobe i2c-gpio
modprobe i2c-mux-pca954x
modprobe i2c-dev
modprobe net_platform
modprobe net_psoc
modprobe net_cpld
modprobe optoe
# wait net_platform init complete
# wait hwmon0 (coretemp) load complete to make sure psoc and cpld
PLATFORM_WAITING_COUNT=0
while [ $PLATFORM_WAITING_COUNT -le 10 ]
do
if [ -d /sys/bus/i2c/devices/i2c-0/ ] &&
[ -d /sys/bus/i2c/devices/i2c-2/ ] &&
[ -d /sys/bus/i2c/devices/i2c-3/ ] &&
[ -d /sys/bus/i2c/devices/i2c-4/ ] &&
[ -d /sys/bus/i2c/devices/i2c-5/ ] &&
[ -d /sys/bus/i2c/devices/i2c-6/ ] &&
[ -d /sys/bus/i2c/devices/i2c-7/ ] &&
[ -d /sys/bus/i2c/devices/i2c-8/ ] &&
[ -d /sys/class/hwmon/hwmon0/ ]
then
break
else
#200ms for each step
sleep 0.2
let "PLATFORM_WAITING_COUNT++"
fi
done
if [ -d "/sys/bus/i2c/devices/i2c-0/" ]
then
echo net_cpld 0x77 > /sys/bus/i2c/devices/i2c-0/new_device
else
echo "i2c-0 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
# IPMI support
modprobe ipmi_devintf
# Attach 48 instances of EEPROM driver SFP ports on IO module
#eeprom can dump data using below command
if [ -d "/sys/bus/i2c/devices/i2c-2/" ]
then
for ((i=10;i<=17;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-2/i2c-$i/new_device
done
else
echo "i2c-2 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ -d "/sys/bus/i2c/devices/i2c-3/" ]
then
for ((i=18;i<=25;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-3/i2c-$i/new_device
done
else
echo "i2c-3 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ -d "/sys/bus/i2c/devices/i2c-4/" ]
then
for ((i=26;i<=33;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-4/i2c-$i/new_device
done
else
echo "i2c-4 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ -d "/sys/bus/i2c/devices/i2c-5/" ]
then
for ((i=34;i<=41;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-5/i2c-$i/new_device
done
else
echo "i2c-5 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ -d "/sys/bus/i2c/devices/i2c-6/" ]
then
for ((i=42;i<=49;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-6/i2c-$i/new_device
done
else
echo "i2c-6 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ -d "/sys/bus/i2c/devices/i2c-7/" ]
then
for ((i=50;i<=57;i++));
do
echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-7/i2c-$i/new_device
done
else
echo "i2c-7 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
# Attach 6 instances of EEPROM driver QSFP ports on IO module
#eeprom can dump data using below command
if [ -d "/sys/bus/i2c/devices/i2c-8/" ]
then
for ((i=58;i<=65;i++));
do
echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-8/i2c-$i/new_device
done
else
echo "i2c-8 error" >> /dev/kmsg
INIT_ERROR="TRUE"
fi
if [ $INIT_ERROR != "TRUE" ]
then
case "$(cat /proc/cmdline)" in
*fast-reboot*)
modprobe swps io_no_init=1
;;
# warm-reboot will be set to fastfast in barefoot
*fastfast*)
modprobe swps io_no_init=1
;;
*)
modprobe swps
;;
esac
modprobe at24
echo 24c64 0x53 > /sys/bus/i2c/devices/i2c-0/new_device
else
echo " AS: nba610 init fail" >> /dev/kmsg
fi
# Setting ARP garbage collection threshold values
echo "Setting IPv4 Neighbor GC threshold values."
sysctl -w net.ipv4.neigh.default.gc_thresh1=16384
sysctl -w net.ipv4.neigh.default.gc_thresh2=32768
sysctl -w net.ipv4.neigh.default.gc_thresh3=32768
echo "done."
;;
stop)
exit 0
# remove modules by order
rmmod at24
rmmod swps
# rmmod optoe
rmmod net_cpld
rmmod net_psoc
rmmod net_platform
rmmod i2c-dev
rmmod i2c-mux-pca954x
rmmod i2c-gpio
rmmod lpc_ich
rmmod gpio_ich
echo "done."
;;
force-reload|restart)
echo "Not supported"
;;
*)
echo "Usage: /etc/init.d/sonic-platform-netberg-aurora-610.init {start|stop}"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,6 @@
aurora-610/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-netberg_aurora_610-r0
aurora-610/utils/healthstatus.sh usr/bin/
aurora-610/utils/netberg_nba610_platform.sh usr/bin/
aurora-610/utils/Yafuflash usr/share/sonic/platform/plugins
aurora-610/utils/afulnx_64 usr/share/sonic/platform/plugins
aurora-610/utils/cpld usr/share/sonic/platform/plugins

View File

@ -0,0 +1 @@
/usr/bin/netberg_nba610_platform.sh