[Inventec][D6356] Update driver and Add new platform API implementation (#3521)

* Update driver and Add new platform API implementation for Inventec D6356
* Update Platform API (SFP)
* Update Platform API (QSFP)
* Update Platform API (FAN, THERMAL)
Signed-off-by: David Xiao <xiao.david@inventec.com>
This commit is contained in:
David Xiao 2019-10-09 16:16:05 -07:00 committed by Joe LeVeque
parent 41e855c211
commit 110bff9b47
44 changed files with 8077 additions and 602 deletions

View File

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

View File

@ -0,0 +1,50 @@
{%- set default_cable = '40m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
{% for port_idx in range(0,47) %}
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
{% endfor %}
{% for port_idx in range(12,19) %}
{% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
{% endfor %}
{%- endmacro %}
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
"size": "10443264",
"type": "ingress",
"mode": "dynamic",
"xoff": "7335744"
},
"egress_lossy_pool": {
"size": "8877440",
"type": "egress",
"mode": "dynamic"
},
"egress_lossless_pool": {
"size": "15982720",
"type": "egress",
"mode": "static"
}
},
"BUFFER_PROFILE": {
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"1518",
"static_th":"3995680"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossy_pool]",
"size":"1518",
"dynamic_th":"3"
}
},
{%- endmacro %}

View File

@ -0,0 +1,50 @@
{%- set default_cable = '40m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
{% for port_idx in range(0,47) %}
{% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %}
{% endfor %}
{% for port_idx in range(12,19) %}
{% if PORT.append("Ethernet%d" % (port_idx*4)) %}{% endif %}
{% endfor %}
{%- endmacro %}
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
"size": "10443264",
"type": "ingress",
"mode": "dynamic",
"xoff": "7335744"
},
"egress_lossy_pool": {
"size": "8877440",
"type": "egress",
"mode": "dynamic"
},
"egress_lossless_pool": {
"size": "15982720",
"type": "egress",
"mode": "static"
}
},
"BUFFER_PROFILE": {
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
"dynamic_th":"3"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"1518",
"static_th":"3995680"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossy_pool]",
"size":"1518",
"dynamic_th":"3"
}
},
{%- endmacro %}

View File

@ -0,0 +1,17 @@
# PG lossless profiles.
# speed cable size xon xoff threshold xon_offset
10000 5m 1248 2288 35776 -4 2288
25000 5m 1248 2288 53248 -4 2288
40000 5m 1248 2288 66560 -4 2288
50000 5m 1248 2288 79872 -4 2288
100000 5m 1248 2288 165568 -4 2288
10000 40m 1248 2288 37024 -4 2288
25000 40m 1248 2288 56160 -4 2288
40000 40m 1248 2288 71552 -4 2288
50000 40m 1248 2288 85696 -4 2288
100000 40m 1248 2288 177632 -4 2288
10000 300m 1248 2288 46176 -4 2288
25000 300m 1248 2288 79040 -4 2288
40000 300m 1248 2288 108160 -4 2288
50000 300m 1248 2288 131456 -4 2288
100000 300m 1248 2288 268736 -4 2288

View File

@ -1,57 +1,57 @@
# name lanes alias index
Ethernet0 1 Ethernet0 0
Ethernet1 2 Ethernet1 1
Ethernet2 3 Ethernet2 2
Ethernet3 4 Ethernet3 3
Ethernet4 5 Ethernet4 4
Ethernet5 6 Ethernet5 5
Ethernet6 7 Ethernet6 6
Ethernet7 8 Ethernet7 7
Ethernet8 13 Ethernet8 8
Ethernet9 14 Ethernet9 9
Ethernet10 15 Ethernet10 10
Ethernet11 16 Ethernet11 11
Ethernet12 21 Ethernet12 12
Ethernet13 22 Ethernet13 13
Ethernet14 23 Ethernet14 14
Ethernet15 24 Ethernet15 15
Ethernet16 29 Ethernet16 16
Ethernet17 30 Ethernet17 17
Ethernet18 31 Ethernet18 18
Ethernet19 32 Ethernet19 19
Ethernet20 33 Ethernet20 20
Ethernet21 34 Ethernet21 21
Ethernet22 35 Ethernet22 22
Ethernet23 36 Ethernet23 23
Ethernet24 41 Ethernet24 24
Ethernet25 42 Ethernet25 25
Ethernet26 43 Ethernet26 26
Ethernet27 44 Ethernet27 27
Ethernet28 49 Ethernet28 28
Ethernet29 50 Ethernet29 29
Ethernet30 51 Ethernet30 30
Ethernet31 52 Ethernet31 31
Ethernet32 57 Ethernet32 32
Ethernet33 58 Ethernet33 33
Ethernet34 59 Ethernet34 34
Ethernet35 60 Ethernet35 35
Ethernet36 61 Ethernet36 36
Ethernet37 62 Ethernet37 37
Ethernet38 63 Ethernet38 38
Ethernet39 64 Ethernet39 39
Ethernet40 65 Ethernet40 40
Ethernet41 66 Ethernet41 41
Ethernet42 67 Ethernet42 42
Ethernet43 68 Ethernet43 43
Ethernet44 69 Ethernet44 44
Ethernet45 70 Ethernet45 45
Ethernet46 71 Ethernet46 46
Ethernet47 72 Ethernet47 47
Ethernet48 85,86,87,88 Ethernet48 48
Ethernet52 77,78,79,80 Ethernet52 49
Ethernet56 93,94,95,96 Ethernet56 50
Ethernet60 97,98,99,100 Ethernet60 51
Ethernet64 113,114,115,116 Ethernet64 52
Ethernet68 105,106,107,108 Ethernet68 53
Ethernet72 121,122,123,124 Ethernet72 54
Ethernet76 125,126,127,128 Ethernet76 55
# name lanes alias index speed
Ethernet0 1 Ethernet0 0 25000
Ethernet1 2 Ethernet1 1 25000
Ethernet2 3 Ethernet2 2 25000
Ethernet3 4 Ethernet3 3 25000
Ethernet4 5 Ethernet4 4 25000
Ethernet5 6 Ethernet5 5 25000
Ethernet6 7 Ethernet6 6 25000
Ethernet7 8 Ethernet7 7 25000
Ethernet8 13 Ethernet8 8 25000
Ethernet9 14 Ethernet9 9 25000
Ethernet10 15 Ethernet10 10 25000
Ethernet11 16 Ethernet11 11 25000
Ethernet12 21 Ethernet12 12 25000
Ethernet13 22 Ethernet13 13 25000
Ethernet14 23 Ethernet14 14 25000
Ethernet15 24 Ethernet15 15 25000
Ethernet16 29 Ethernet16 16 25000
Ethernet17 30 Ethernet17 17 25000
Ethernet18 31 Ethernet18 18 25000
Ethernet19 32 Ethernet19 19 25000
Ethernet20 33 Ethernet20 20 25000
Ethernet21 34 Ethernet21 21 25000
Ethernet22 35 Ethernet22 22 25000
Ethernet23 36 Ethernet23 23 25000
Ethernet24 41 Ethernet24 24 25000
Ethernet25 42 Ethernet25 25 25000
Ethernet26 43 Ethernet26 26 25000
Ethernet27 44 Ethernet27 27 25000
Ethernet28 49 Ethernet28 28 25000
Ethernet29 50 Ethernet29 29 25000
Ethernet30 51 Ethernet30 30 25000
Ethernet31 52 Ethernet31 31 25000
Ethernet32 57 Ethernet32 32 25000
Ethernet33 58 Ethernet33 33 25000
Ethernet34 59 Ethernet34 34 25000
Ethernet35 60 Ethernet35 35 25000
Ethernet36 61 Ethernet36 36 25000
Ethernet37 62 Ethernet37 37 25000
Ethernet38 63 Ethernet38 38 25000
Ethernet39 64 Ethernet39 39 25000
Ethernet40 65 Ethernet40 40 25000
Ethernet41 66 Ethernet41 41 25000
Ethernet42 67 Ethernet42 42 25000
Ethernet43 68 Ethernet43 43 25000
Ethernet44 69 Ethernet44 44 25000
Ethernet45 70 Ethernet45 45 25000
Ethernet46 71 Ethernet46 46 25000
Ethernet47 72 Ethernet47 47 25000
Ethernet48 85,86,87,88 Ethernet48 48 100000
Ethernet52 77,78,79,80 Ethernet52 49 100000
Ethernet56 93,94,95,96 Ethernet56 50 100000
Ethernet60 97,98,99,100 Ethernet60 51 100000
Ethernet64 113,114,115,116 Ethernet64 52 100000
Ethernet68 105,106,107,108 Ethernet68 53 100000
Ethernet72 121,122,123,124 Ethernet72 54 100000
Ethernet76 125,126,127,128 Ethernet76 55 100000

View File

@ -0,0 +1,155 @@
{
"TC_TO_PRIORITY_GROUP_MAP": {
"AZURE": {
"0": "0",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7"
}
},
"MAP_PFC_PRIORITY_TO_QUEUE": {
"AZURE": {
"0": "0",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7"
}
},
"TC_TO_QUEUE_MAP": {
"AZURE": {
"0": "0",
"1": "1",
"2": "2",
"3": "3",
"4": "4",
"5": "5",
"6": "6",
"7": "7"
}
},
"DSCP_TO_TC_MAP": {
"AZURE": {
"0":"0",
"1":"0",
"2":"0",
"3":"3",
"4":"4",
"5":"0",
"6":"0",
"7":"0",
"8":"1",
"9":"0",
"10":"0",
"11":"0",
"12":"0",
"13":"0",
"14":"0",
"15":"0",
"16":"0",
"17":"0",
"18":"0",
"19":"0",
"20":"0",
"21":"0",
"22":"0",
"23":"0",
"24":"0",
"25":"0",
"26":"0",
"27":"0",
"28":"0",
"29":"0",
"30":"0",
"31":"0",
"32":"0",
"33":"0",
"34":"0",
"35":"0",
"36":"0",
"37":"0",
"38":"0",
"39":"0",
"40":"0",
"41":"0",
"42":"0",
"43":"0",
"44":"0",
"45":"0",
"46":"0",
"47":"0",
"48":"0",
"49":"0",
"50":"0",
"51":"0",
"52":"0",
"53":"0",
"54":"0",
"55":"0",
"56":"0",
"57":"0",
"58":"0",
"59":"0",
"60":"0",
"61":"0",
"62":"0",
"63":"0"
}
},
"SCHEDULER": {
"scheduler.0" : {
"type":"DWRR",
"weight": "25"
},
"scheduler.1" : {
"type":"DWRR",
"weight": "30"
},
"scheduler.2" : {
"type":"DWRR",
"weight": "20"
}
},
"PORT_QOS_MAP": {
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76": {
"dscp_to_tc_map" : "[DSCP_TO_TC_MAP|AZURE]",
"tc_to_queue_map" : "[TC_TO_QUEUE_MAP|AZURE]",
"tc_to_pg_map" : "[TC_TO_PRIORITY_GROUP_MAP|AZURE]",
"pfc_to_queue_map": "[MAP_PFC_PRIORITY_TO_QUEUE|AZURE]",
"pfc_enable": "3,4"
}
},
"WRED_PROFILE": {
"AZURE_LOSSLESS" : {
"wred_green_enable":"true",
"wred_yellow_enable":"true",
"wred_red_enable":"true",
"ecn":"ecn_all",
"red_max_threshold":"312000",
"red_min_threshold":"104000",
"yellow_max_threshold":"312000",
"yellow_min_threshold":"104000",
"green_max_threshold": "312000",
"green_min_threshold": "104000"
}
},
"QUEUE": {
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|3-4" : {
"scheduler" : "[SCHEDULER|scheduler.0]",
"wred_profile" : "[WRED_PROFILE|AZURE_LOSSLESS]"
},
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|0" : {
"scheduler" : "[SCHEDULER|scheduler.1]"
},
"Ethernet0,Ethernet1,Ethernet2,Ethernet3,Ethernet4,Ethernet5,Ethernet6,Ethernet7,Ethernet8,Ethernet9,Ethernet10,Ethernet11,Ethernet12,Ethernet13,Ethernet14,Ethernet15,Ethernet16,Ethernet17,Ethernet18,Ethernet19,Ethernet20,Ethernet21,Ethernet22,Ethernet23,Ethernet24,Ethernet25,Ethernet26,Ethernet27,Ethernet28,Ethernet29,Ethernet30,Ethernet31,Ethernet32,Ethernet33,Ethernet34,Ethernet35,Ethernet36,Ethernet37,Ethernet38,Ethernet39,Ethernet40,Ethernet41,Ethernet42,Ethernet43,Ethernet44,Ethernet45,Ethernet46,Ethernet47,Ethernet48,Ethernet52,Ethernet56,Ethernet60,Ethernet64,Ethernet68,Ethernet72,Ethernet76|1" : {
"scheduler" : "[SCHEDULER|scheduler.2]"
}
}
}

View File

@ -2,8 +2,10 @@
ptp_ts_pll_fref=50000000
ptp_bs_fref_0=50000000
ptp_bs_fref_1=50000000
ifp_inports_support_enable=1
### end fix
stable_size=0x5500000
core_clock_frequency=1525
dpp_clock_ratio=2:3
@ -12,7 +14,7 @@ oversubscribe_mode=1
pbmp_xport_xe=0x488787878808787fdfe1e1e1fe1e1e1fe
portmap_65=130:10
#portmap_65=130:10
### Pipeline0, halfpipe 0 (12x25G + 2x100G)
portmap_1=1:25
@ -60,11 +62,11 @@ portmap_64=64:25
### Pipeline 1
### First management port
portmap_66=129:10:m
#portmap_66=129:10:m
### Second management port
portmap_130=128:10:m
#portmap_130=128:10:m
### Loopback port
portmap_131=131:10
#portmap_131=131:10
### Pipeline 1, halfpipe 0 (12x25G + 2x100G)
portmap_67=65:25
@ -92,6 +94,11 @@ fpem_mem_entries=16384
l2xmsg_mode=1
pdma_descriptor_prefetch_enable=1
port_flex_enable=1
#dport part
dport_map_port_79=87
dport_map_port_87=79
@ -281,118 +288,125 @@ phy_chain_tx_polarity_flip_physical{132.0}=0x0
phy_chain_rx_polarity_flip_physical{132.0}=0x0
# EQ/IDriver
serdes_preemphasis_1=0x13460B
serdes_preemphasis_2=0x13460B
serdes_preemphasis_3=0x14450B
serdes_preemphasis_4=0x13460B
serdes_preemphasis_5=0x11480B
serdes_preemphasis_6=0x13470A
serdes_preemphasis_7=0x14460A
serdes_preemphasis_8=0x11490A
serdes_preemphasis_13=0x10490B
serdes_preemphasis_14=0x104A0A
serdes_preemphasis_15=0x0F4B0A
serdes_preemphasis_16=0x0F4B0A
serdes_preemphasis_21=0x0D4D0A
serdes_preemphasis_22=0x0D4D0A
serdes_preemphasis_23=0x0D4D0A
serdes_preemphasis_24=0x0D4D0A
serdes_preemphasis_29=0x0B4F0A
serdes_preemphasis_30=0x0D4E09
serdes_preemphasis_31=0x0B4F0A
serdes_preemphasis_32=0x0C4F09
serdes_preemphasis_33=0x0B4F0A
serdes_preemphasis_34=0x0A5109
serdes_preemphasis_35=0x09510A
serdes_preemphasis_36=0x0B5009
serdes_preemphasis_41=0x09510A
serdes_preemphasis_42=0x0B5009
serdes_preemphasis_43=0x09510A
serdes_preemphasis_44=0x0A5109
serdes_preemphasis_49=0x0A500A
serdes_preemphasis_50=0x0B4F0A
serdes_preemphasis_51=0x09510A
serdes_preemphasis_52=0x0E4C0A
serdes_preemphasis_57=0x0D4D0A
serdes_preemphasis_58=0x0E4D09
serdes_preemphasis_59=0x0C4E0A
serdes_preemphasis_60=0x0E4D09
serdes_preemphasis_61=0x0B4F0A
serdes_preemphasis_62=0x0D4E09
serdes_preemphasis_63=0x0D4D0A
serdes_preemphasis_64=0x0D4D0A
serdes_preemphasis_67=0x0B4F0A
serdes_preemphasis_68=0x0C4E0A
serdes_preemphasis_69=0x0B4F0A
serdes_preemphasis_70=0x0B4F0A
serdes_preemphasis_71=0x0B4F0A
serdes_preemphasis_72=0x0F4B0A
serdes_preemphasis_73=0x0E4C0A
serdes_preemphasis_74=0x0F4B0A
serdes_preemphasis_87=0x0E4C0A
serdes_preemphasis_79=0x0F4B0A
serdes_preemphasis_95=0x0F4B0A
serdes_preemphasis_99=0x0F4B0A
serdes_preemphasis_115=0x13470A
serdes_preemphasis_107=0x12480A
serdes_preemphasis_123=0x154609
serdes_preemphasis_127=0x13470A
# 25G
serdes_preemphasis_1=0x0F4B0A
serdes_preemphasis_2=0x104A0A
serdes_preemphasis_3=0x0E4C0A
serdes_preemphasis_4=0x0E4C0A
serdes_preemphasis_5=0x0D4D0A
serdes_preemphasis_6=0x0D4D0A
serdes_preemphasis_7=0x0D4D0A
serdes_preemphasis_8=0x0D4D0A
serdes_preemphasis_13=0x0C4E0A
serdes_preemphasis_14=0x0D4D0A
serdes_preemphasis_15=0x0B4F0A
serdes_preemphasis_16=0x0C4E0A
serdes_preemphasis_21=0x0A500A
serdes_preemphasis_22=0x0A500A
serdes_preemphasis_23=0x09510A
serdes_preemphasis_24=0x09510A
serdes_preemphasis_29=0x08520A
serdes_preemphasis_30=0x08520A
serdes_preemphasis_31=0x07530A
serdes_preemphasis_32=0x07530A
serdes_preemphasis_33=0x06540A
serdes_preemphasis_34=0x07530A
serdes_preemphasis_35=0x05550A
serdes_preemphasis_36=0x06540A
serdes_preemphasis_41=0x05550A
serdes_preemphasis_42=0x06540A
serdes_preemphasis_43=0x05550A
serdes_preemphasis_44=0x05550A
serdes_preemphasis_49=0x04560A
serdes_preemphasis_50=0x05550A
serdes_preemphasis_51=0x05550A
serdes_preemphasis_52=0x06540A
serdes_preemphasis_57=0x06540A
serdes_preemphasis_58=0x07530A
serdes_preemphasis_59=0x06540A
serdes_preemphasis_60=0x07530A
serdes_preemphasis_61=0x06540A
serdes_preemphasis_62=0x08520A
serdes_preemphasis_63=0x08520A
serdes_preemphasis_64=0x09510A
serdes_preemphasis_67=0x06540A
serdes_preemphasis_68=0x06540A
serdes_preemphasis_69=0x06540A
serdes_preemphasis_70=0x08520A
serdes_preemphasis_71=0x09510A
serdes_preemphasis_72=0x09510A
serdes_preemphasis_73=0x09510A
serdes_preemphasis_74=0x0A500A
serdes_preemphasis_lane0_87=0x07530A
serdes_preemphasis_lane1_87=0x05550A
serdes_preemphasis_lane2_87=0x07530A
serdes_preemphasis_lane3_87=0x05550A
serdes_preemphasis_79=0x05550A
serdes_preemphasis_95=0x07530A
serdes_preemphasis_lane0_99=0x085309
serdes_preemphasis_lane1_99=0x0B4F0A
serdes_preemphasis_lane2_99=0x085309
serdes_preemphasis_lane3_99=0x0B4F0A
serdes_preemphasis_115=0x0B4F0A
serdes_preemphasis_107=0x0B4F0A
serdes_preemphasis_123=0x0B4F0A
serdes_preemphasis_127=0x0D4E09
# 10G
# interface type
serdes_if_type_1=13
serdes_if_type_2=13
serdes_if_type_3=13
serdes_if_type_4=13
serdes_if_type_5=13
serdes_if_type_6=13
serdes_if_type_7=13
serdes_if_type_8=13
serdes_if_type_13=13
serdes_if_type_14=13
serdes_if_type_15=13
serdes_if_type_16=13
serdes_if_type_21=13
serdes_if_type_22=13
serdes_if_type_23=13
serdes_if_type_24=13
serdes_if_type_29=13
serdes_if_type_30=13
serdes_if_type_31=13
serdes_if_type_32=13
serdes_if_type_33=13
serdes_if_type_34=13
serdes_if_type_35=13
serdes_if_type_36=13
serdes_if_type_41=13
serdes_if_type_42=13
serdes_if_type_43=13
serdes_if_type_44=13
serdes_if_type_49=13
serdes_if_type_50=13
serdes_if_type_51=13
serdes_if_type_52=13
serdes_if_type_57=13
serdes_if_type_58=13
serdes_if_type_59=13
serdes_if_type_60=13
serdes_if_type_61=13
serdes_if_type_62=13
serdes_if_type_63=13
serdes_if_type_64=13
serdes_if_type_67=13
serdes_if_type_68=13
serdes_if_type_69=13
serdes_if_type_70=13
serdes_if_type_71=13
serdes_if_type_72=13
serdes_if_type_73=13
serdes_if_type_74=13
serdes_if_type_87=14
serdes_if_type_79=14
serdes_if_type_95=14
serdes_if_type_99=14
serdes_if_type_115=14
serdes_if_type_107=14
serdes_if_type_123=14
serdes_if_type_127=14
serdes_if_type_1=16
serdes_if_type_2=16
serdes_if_type_3=16
serdes_if_type_4=16
serdes_if_type_5=16
serdes_if_type_6=16
serdes_if_type_7=16
serdes_if_type_8=16
serdes_if_type_13=16
serdes_if_type_14=16
serdes_if_type_15=16
serdes_if_type_16=16
serdes_if_type_21=16
serdes_if_type_22=16
serdes_if_type_23=16
serdes_if_type_24=16
serdes_if_type_29=16
serdes_if_type_30=16
serdes_if_type_31=16
serdes_if_type_32=16
serdes_if_type_33=16
serdes_if_type_34=16
serdes_if_type_35=16
serdes_if_type_36=16
serdes_if_type_41=16
serdes_if_type_42=16
serdes_if_type_43=16
serdes_if_type_44=16
serdes_if_type_49=16
serdes_if_type_50=16
serdes_if_type_51=16
serdes_if_type_52=16
serdes_if_type_57=16
serdes_if_type_58=16
serdes_if_type_59=16
serdes_if_type_60=16
serdes_if_type_61=16
serdes_if_type_62=16
serdes_if_type_63=16
serdes_if_type_64=16
serdes_if_type_67=16
serdes_if_type_68=16
serdes_if_type_69=16
serdes_if_type_70=16
serdes_if_type_71=16
serdes_if_type_72=16
serdes_if_type_73=16
serdes_if_type_74=16
serdes_if_type_87=28
serdes_if_type_79=28
serdes_if_type_95=28
serdes_if_type_99=28
serdes_if_type_115=28
serdes_if_type_107=28
serdes_if_type_123=28
serdes_if_type_127=28

View File

@ -1,5 +1,5 @@
led auto off
led stop
#led auto off
#led stop
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
led auto on

View File

@ -15,7 +15,7 @@ except ImportError as e:
class PsuUtil(PsuBase):
"""Platform-specific PSUutil class"""
PSU_DIR = "/sys/class/hwmon/hwmon1"
PSU_DIR = "/sys/class/hwmon/hwmon2/device/"
def __init__(self):
PsuBase.__init__(self)
@ -53,9 +53,12 @@ class PsuUtil(PsuBase):
faulty
"""
status = 0
attr_file = 'psoc_psu'+ str(index) + '_iout'
attr_path = self.PSU_DIR +'/' + attr_file
if index == 1 :
attr_path = "/sys/class/hwmon/hwmon7/in1_input"
else :
attr_path = "/sys/class/hwmon/hwmon8/in1_input"
attr_value = self.get_attr_value(attr_path)
if (attr_value != 'ERR'):
# Check for PSU status
@ -75,10 +78,11 @@ class PsuUtil(PsuBase):
ind = index
attr_file ='psu'+ str(ind)
attr_path = self.PSU_DIR +'/' + attr_file
normal_attr_value = '0 : normal'
normal_attr_value = '1:normal'
attr_value = self.get_attr_value(attr_path)
if (attr_value != 'ERR'):
# Check for PSU presence
if (attr_value == normal_attr_value):
status = 1
return status

View File

@ -3,12 +3,78 @@
# Platform-specific SFP transceiver interface for SONiC
#
#
# INV_FIX-4037
# (1) Support get_transceiver_change_event.
# Create the SWPSEventMonitor class to handle any kobject event from the SWPS driver.
# (2) Integrated with the optoe driver
# Due to installing the optoe driver to create the i2c topology,
# it needs to overwrite the followings functions which are declared in the sfputilbase.py.
# First, it needs to impore some SFP-related class object
#
try:
import time
import socket, re,os
from collections import OrderedDict
from sonic_sfp.sfputilbase import SfpUtilBase
from sonic_sfp.sff8472 import sff8472Dom
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
SFP_TEMPE_OFFSET = 96
SFP_TEMPE_WIDTH = 2
SFP_VLOT_OFFSET = 98
SFP_VOLT_WIDTH = 2
SFP_CHANNL_MON_OFFSET = 100
SFP_CHANNL_MON_WIDTH = 6
NETLINK_KOBJECT_UEVENT = 15
monitor = None
class SWPSEventMonitor(object):
def __init__(self):
self.recieved_events = OrderedDict()
self.socket = socket.socket(
socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
def start(self):
self.socket.bind((os.getpid(), -1))
def stop(self):
self.socket.close()
def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_value, traceback):
self.stop()
def __iter__(self):
global monitor
while True:
for item in monitor.next_events():
yield item
def next_events(self):
data = self.socket.recv(16384)
event = {}
for item in data.split(b'\x00'):
if not item:
# check if we have an event and if we already received it
if event and event['SEQNUM'] not in self.recieved_events:
self.recieved_events[event['SEQNUM']] = None
if (len(self.recieved_events) > 100):
self.recieved_events.popitem(last=False)
yield event
event = {}
else:
try:
k, v = item.split(b'=', 1)
event[k.decode('ascii')] = v.decode('ascii')
except ValueError:
pass
class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""
@ -210,8 +276,104 @@ class SfpUtil(SfpUtilBase):
return True
#
# INV_FIX-4037
# (1) Support get_transceiver_change_event.
# Modify get_transceiver_change_event() to listen the SWPS kobject event.
# (2) Integrated with the optoe driver
# Due to installing the optoe driver to create the i2c topology,
# it needs to overwrite the followings functions which are declared in the sfputilbase.py.
# It modified the get_eeprom_dom_raw() and get_transceiver_dom_info_dict().
#
def get_transceiver_change_event(self):
"""
TODO: This function need to be implemented
"""
raise NotImplementedError
global monitor
port_dict = {}
with SWPSEventMonitor() as monitor:
for event in monitor:
if event['SUBSYSTEM'] == 'swps':
#print('SWPS event. From %s, ACTION %s, IF_TYPE %s, IF_LANE %s' % (event['DEVPATH'], event['ACTION'], event['IF_TYPE'], event['IF_LANE']))
portname = event['DEVPATH'].split("/")[-1]
rc = re.match(r"port(?P<num>\d+)",portname)
if rc is not None:
if event['ACTION'] == "remove":
remove_num = int(rc.group("num"))
port_dict[remove_num] = "0"
#port_dict[rc.group("num")] = "0"
if event['ACTION'] == "add":
add_num = int(rc.group("num"))
port_dict[add_num] = "1"
#port_dict[rc.group("num")] = "1"
return True, port_dict
return False, {}
def get_eeprom_dom_raw(self, port_num):
if port_num in self.qsfp_ports:
# QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw
return None
else:
# Read dom eeprom at addr 0x51
return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256)
def get_transceiver_dom_info_dict(self, port_num):
if port_num in self.qsfp_ports:
return SfpUtilBase.get_transceiver_dom_info_dict(self, port_num)
else:
transceiver_dom_info_dict = {}
offset = 256
file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR)
if not self._sfp_eeprom_present(file_path, 0):
return None
try:
sysfsfile_eeprom = open(file_path, "rb")
except IOError:
print("Error: reading sysfs file %s" % file_path)
return None
sfpd_obj = sff8472Dom(None, 1)
if sfpd_obj is None:
return None
dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
else:
return None
dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VLOT_OFFSET), SFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
else:
return None
dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
else:
return None
try:
sysfsfile_eeprom.close()
except IOError:
print("Error: closing sysfs file %s" % file_path)
return None
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value']
transceiver_dom_info_dict['rx2power'] = 'N/A'
transceiver_dom_info_dict['rx3power'] = 'N/A'
transceiver_dom_info_dict['rx4power'] = 'N/A'
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value']
transceiver_dom_info_dict['tx2bias'] = 'N/A'
transceiver_dom_info_dict['tx3bias'] = 'N/A'
transceiver_dom_info_dict['tx4bias'] = 'N/A'
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value']
transceiver_dom_info_dict['tx2power'] = 'N/A'
transceiver_dom_info_dict['tx3power'] = 'N/A'
transceiver_dom_info_dict['tx4power'] = 'N/A'
return transceiver_dom_info_dict

View File

@ -2,6 +2,9 @@
chip "ucd90160-*"
ignore temp1
chip "pch_haswell-*"
label temp1 "PCH Temperature"
chip "tmp75-i2c-*-0048"
label temp1 "CPU Board Temperature"
@ -31,7 +34,7 @@ chip "inv_cpld-i2c-*-77"
label pwm4 "FanModule4 PWM (0-255)"
label pwm5 "FanModule5 PWM (0-255)"
chip "pmbus-i2c-*-005a"
chip "pmbus-i2c-*-005b"
ignore power3
ignore curr3
label fan1 "PSU1 Fan RPM"
@ -46,7 +49,7 @@ chip "pmbus-i2c-*-005a"
label power2 "PSU1 Output Power"
label pwm1 "PSU1 PWM (0-100)"
chip "pmbus-i2c-*-005b"
chip "pmbus-i2c-*-005a"
ignore power3
ignore curr3
label fan1 "PSU2 Fan RPM"

View File

@ -1,3 +1,7 @@
obj-m += ucd9000.o
obj-m += i2c-mux-pca9541.o
obj-m += gpio-ich.o
obj-m += lpc_ich.o
obj-m += inv_cpld.o
obj-m += inv_platform.o
obj-m += inv_eeprom.o

View File

@ -0,0 +1,513 @@
/*
* Intel ICH6-10, Series 5 and 6, Atom C2000 (Avoton/Rangeley) GPIO driver
*
* Copyright (C) 2010 Extreme Engineering Solutions.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mfd/lpc_ich.h>
#define DRV_NAME "gpio_ich"
/*
* GPIO register offsets in GPIO I/O space.
* Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and
* LVLx registers. Logic in the read/write functions takes a register and
* an absolute bit number and determines the proper register offset and bit
* number in that register. For example, to read the value of GPIO bit 50
* the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)],
* bit 18 (50%32).
*/
enum GPIO_REG {
GPIO_USE_SEL = 0,
GPIO_IO_SEL,
GPIO_LVL,
GPO_BLINK
};
static const u8 ichx_regs[4][3] = {
{0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */
{0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */
{0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
{0x18, 0x18, 0x18}, /* BLINK offset */
};
static const u8 ichx_reglen[3] = {
0x30, 0x10, 0x10,
};
static const u8 avoton_regs[4][3] = {
{0x00, 0x80, 0x00},
{0x04, 0x84, 0x00},
{0x08, 0x88, 0x00},
};
static const u8 avoton_reglen[3] = {
0x10, 0x10, 0x00,
};
#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start)
#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
struct ichx_desc {
/* Max GPIO pins the chipset can have */
uint ngpio;
/* chipset registers */
const u8 (*regs)[3];
const u8 *reglen;
/* GPO_BLINK is available on this chipset */
bool have_blink;
/* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
bool uses_gpe0;
/* USE_SEL is bogus on some chipsets, eg 3100 */
u32 use_sel_ignore[3];
/* Some chipsets have quirks, let these use their own request/get */
int (*request)(struct gpio_chip *chip, unsigned offset);
int (*get)(struct gpio_chip *chip, unsigned offset);
/*
* Some chipsets don't let reading output values on GPIO_LVL register
* this option allows driver caching written output values
*/
bool use_outlvl_cache;
};
static struct {
spinlock_t lock;
struct platform_device *dev;
struct gpio_chip chip;
struct resource *gpio_base; /* GPIO IO base */
struct resource *pm_base; /* Power Mangagment IO base */
struct ichx_desc *desc; /* Pointer to chipset-specific description */
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
u8 use_gpio; /* Which GPIO groups are usable */
int outlvl_cache[3]; /* cached output values */
} ichx_priv;
static int modparam_gpiobase = -1; /* dynamic */
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, "
"which is the default.");
static int ichx_write_bit(int reg, unsigned nr, int val, int verify)
{
unsigned long flags;
u32 data, tmp;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
int ret = 0;
spin_lock_irqsave(&ichx_priv.lock, flags);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr];
else
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (val)
data |= 1 << bit;
else
data &= ~(1 << bit);
ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
ichx_priv.outlvl_cache[reg_nr] = data;
tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (verify && data != tmp)
ret = -EPERM;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return ret;
}
static int ichx_read_bit(int reg, unsigned nr)
{
unsigned long flags;
u32 data;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
spin_lock_irqsave(&ichx_priv.lock, flags);
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr] | data;
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return data & (1 << bit) ? 1 : 0;
}
static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
{
return !!(ichx_priv.use_gpio & (1 << (nr / 32)));
}
static int ichx_gpio_get_direction(struct gpio_chip *gpio, unsigned nr)
{
return ichx_read_bit(GPIO_IO_SEL, nr) ? GPIOF_DIR_IN : GPIOF_DIR_OUT;
}
static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
{
/*
* Try setting pin as an input and verify it worked since many pins
* are output-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
int val)
{
/* Disable blink hardware which is available for GPIOs from 0 to 31. */
if (nr < 32 && ichx_priv.desc->have_blink)
ichx_write_bit(GPO_BLINK, nr, 0, 0);
/* Set GPIO output value. */
ichx_write_bit(GPIO_LVL, nr, val, 0);
/*
* Try setting pin as an output and verify it worked since many pins
* are input-only.
*/
if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1))
return -EINVAL;
return 0;
}
static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
{
return ichx_read_bit(GPIO_LVL, nr);
}
static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
{
unsigned long flags;
u32 data;
/*
* GPI 0 - 15 need to be read from the power management registers on
* a ICH6/3100 bridge.
*/
if (nr < 16) {
if (!ichx_priv.pm_base)
return -ENXIO;
spin_lock_irqsave(&ichx_priv.lock, flags);
/* GPI 0 - 15 are latched, write 1 to clear*/
ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base);
data = ICHX_READ(0, ichx_priv.pm_base);
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return (data >> 16) & (1 << nr) ? 1 : 0;
} else {
return ichx_gpio_get(chip, nr);
}
}
static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr)
{
if (!ichx_gpio_check_available(chip, nr))
return -ENXIO;
/*
* Note we assume the BIOS properly set a bridge's USE value. Some
* chips (eg Intel 3100) have bogus USE values though, so first see if
* the chipset's USE value can be trusted for this specific bit.
* If it can't be trusted, assume that the pin can be used as a GPIO.
*/
if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f)))
return 0;
return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV;
}
static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr)
{
/*
* Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100
* bridge as they are controlled by USE register bits 0 and 1. See
* "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for
* additional info.
*/
if (nr == 16 || nr == 17)
nr -= 16;
return ichx_gpio_request(chip, nr);
}
static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val)
{
ichx_write_bit(GPIO_LVL, nr, val, 0);
}
static void ichx_gpiolib_setup(struct gpio_chip *chip)
{
chip->owner = THIS_MODULE;
chip->label = DRV_NAME;
chip->parent = &ichx_priv.dev->dev;
/* Allow chip-specific overrides of request()/get() */
chip->request = ichx_priv.desc->request ?
ichx_priv.desc->request : ichx_gpio_request;
chip->get = ichx_priv.desc->get ?
ichx_priv.desc->get : ichx_gpio_get;
chip->set = ichx_gpio_set;
chip->get_direction = ichx_gpio_get_direction;
chip->direction_input = ichx_gpio_direction_input;
chip->direction_output = ichx_gpio_direction_output;
chip->base = modparam_gpiobase;
chip->ngpio = ichx_priv.desc->ngpio;
chip->can_sleep = false;
chip->dbg_show = NULL;
}
/* ICH6-based, 631xesb-based */
static struct ichx_desc ich6_desc = {
/* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 3100 */
static struct ichx_desc i3100_desc = {
/*
* Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on
* the Intel 3100. See "Table 712. GPIO Summary Table" of 3100
* Datasheet for more info.
*/
.use_sel_ignore = {0x00130000, 0x00010000, 0x0},
/* The 3100 needs fixups for GPIO 0 - 17 */
.request = ich6_gpio_request,
.get = ich6_gpio_get,
/* GPIO 0-15 are read in the GPE0_STS PM register */
.uses_gpe0 = true,
.ngpio = 50,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH7 and ICH8-based */
static struct ichx_desc ich7_desc = {
.ngpio = 50,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH9-based */
static struct ichx_desc ich9_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* ICH10-based - Consumer/corporate versions have different amount of GPIO */
static struct ichx_desc ich10_cons_desc = {
.ngpio = 61,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
static struct ichx_desc ich10_corp_desc = {
.ngpio = 72,
.have_blink = true,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Intel 5 series, 6 series, 3400 series, and C200 series */
static struct ichx_desc intel5_desc = {
.ngpio = 76,
.regs = ichx_regs,
.reglen = ichx_reglen,
};
/* Avoton */
static struct ichx_desc avoton_desc = {
/* Avoton has only 59 GPIOs, but we assume the first set of register
* (Core) has 32 instead of 31 to keep gpio-ich compliance
*/
.ngpio = 60,
.regs = avoton_regs,
.reglen = avoton_reglen,
.use_outlvl_cache = true,
};
static int ichx_gpio_request_regions(struct device *dev,
struct resource *res_base, const char *name, u8 use_gpio)
{
int i;
if (!res_base || !res_base->start || !res_base->end)
return -ENODEV;
for (i = 0; i < ARRAY_SIZE(ichx_priv.desc->regs[0]); i++) {
if (!(use_gpio & (1 << i)))
continue;
if (!devm_request_region(dev,
res_base->start + ichx_priv.desc->regs[0][i],
ichx_priv.desc->reglen[i], name))
return -EBUSY;
}
return 0;
}
static int ichx_gpio_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_pm;
int err;
struct lpc_ich_info *ich_info = dev_get_platdata(&pdev->dev);
if (!ich_info)
return -ENODEV;
ichx_priv.dev = pdev;
switch (ich_info->gpio_version) {
case ICH_I3100_GPIO:
ichx_priv.desc = &i3100_desc;
break;
case ICH_V5_GPIO:
ichx_priv.desc = &intel5_desc;
break;
case ICH_V6_GPIO:
ichx_priv.desc = &ich6_desc;
break;
case ICH_V7_GPIO:
ichx_priv.desc = &ich7_desc;
break;
case ICH_V9_GPIO:
ichx_priv.desc = &ich9_desc;
break;
case ICH_V10CORP_GPIO:
ichx_priv.desc = &ich10_corp_desc;
break;
case ICH_V10CONS_GPIO:
ichx_priv.desc = &ich10_cons_desc;
break;
case AVOTON_GPIO:
ichx_priv.desc = &avoton_desc;
break;
default:
return -ENODEV;
}
spin_lock_init(&ichx_priv.lock);
res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
ichx_priv.use_gpio = ich_info->use_gpio;
err = ichx_gpio_request_regions(&pdev->dev, res_base, pdev->name,
ichx_priv.use_gpio);
if (err)
return err;
ichx_priv.gpio_base = res_base;
/*
* If necessary, determine the I/O address of ACPI/power management
* registers which are needed to read the the GPE0 register for GPI pins
* 0 - 15 on some chipsets.
*/
if (!ichx_priv.desc->uses_gpe0)
goto init;
res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0);
if (!res_pm) {
pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n");
goto init;
}
if (!devm_request_region(&pdev->dev, res_pm->start,
resource_size(res_pm), pdev->name)) {
pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n");
goto init;
}
ichx_priv.pm_base = res_pm;
init:
ichx_gpiolib_setup(&ichx_priv.chip);
err = gpiochip_add_data(&ichx_priv.chip, NULL);
if (err) {
pr_err("Failed to register GPIOs\n");
return err;
}
pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base,
ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME);
return 0;
}
static int ichx_gpio_remove(struct platform_device *pdev)
{
gpiochip_remove(&ichx_priv.chip);
return 0;
}
static struct platform_driver ichx_gpio_driver = {
.driver = {
.name = DRV_NAME,
},
.probe = ichx_gpio_probe,
.remove = ichx_gpio_remove,
};
module_platform_driver(ichx_gpio_driver);
MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>");
MODULE_DESCRIPTION("GPIO interface for Intel ICH series");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:"DRV_NAME);

View File

@ -0,0 +1,573 @@
/*
* I2C multiplexer driver for PCA9541 bus master selector
*
* Copyright (c) 2010 Ericsson AB.
*
* Author: Guenter Roeck <linux@roeck-us.net>
*
* Derived from:
* pca954x.c
*
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
/*
* The PCA9541 is a bus master selector. It supports two I2C masters connected
* to a single slave bus.
*
* Before each bus transaction, a master has to acquire bus ownership. After the
* transaction is complete, bus ownership has to be released. This fits well
* into the I2C multiplexer framework, which provides select and release
* functions for this purpose. For this reason, this driver is modeled as
* single-channel I2C bus multiplexer.
*
* This driver assumes that the two bus masters are controlled by two different
* hosts. If a single host controls both masters, platform code has to ensure
* that only one of the masters is instantiated at any given time.
*/
#define PCA9541_CONTROL 0x01
#define PCA9541_ISTAT 0x02
#define PCA9541_CTL_MYBUS (1 << 0)
#define PCA9541_CTL_NMYBUS (1 << 1)
#define PCA9541_CTL_BUSON (1 << 2)
#define PCA9541_CTL_NBUSON (1 << 3)
#define PCA9541_CTL_BUSINIT (1 << 4)
#define PCA9541_CTL_TESTON (1 << 6)
#define PCA9541_CTL_NTESTON (1 << 7)
#define PCA9541_ISTAT_INTIN (1 << 0)
#define PCA9541_ISTAT_BUSINIT (1 << 1)
#define PCA9541_ISTAT_BUSOK (1 << 2)
#define PCA9541_ISTAT_BUSLOST (1 << 3)
#define PCA9541_ISTAT_MYTEST (1 << 6)
#define PCA9541_ISTAT_NMYTEST (1 << 7)
#define PCA9641_ID 0x00
#define PCA9641_ID_MAGIC 0x38
#define PCA9641_CONTROL 0x01
#define PCA9641_STATUS 0x02
#define PCA9641_TIME 0x03
#define PCA9641_CTL_LOCK_REQ BIT(0)
#define PCA9641_CTL_LOCK_GRANT BIT(1)
#define PCA9641_CTL_BUS_CONNECT BIT(2)
#define PCA9641_CTL_BUS_INIT BIT(3)
#define PCA9641_CTL_SMBUS_SWRST BIT(4)
#define PCA9641_CTL_IDLE_TIMER_DIS BIT(5)
#define PCA9641_CTL_SMBUS_DIS BIT(6)
#define PCA9641_CTL_PRIORITY BIT(7)
#define PCA9641_STS_OTHER_LOCK BIT(0)
#define PCA9641_STS_BUS_INIT_FAIL BIT(1)
#define PCA9641_STS_BUS_HUNG BIT(2)
#define PCA9641_STS_MBOX_EMPTY BIT(3)
#define PCA9641_STS_MBOX_FULL BIT(4)
#define PCA9641_STS_TEST_INT BIT(5)
#define PCA9641_STS_SCL_IO BIT(6)
#define PCA9641_STS_SDA_IO BIT(7)
#define PCA9641_RES_TIME 0x03
#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON)
#define BUSOFF(x, y) (!((x) & PCA9641_CTL_LOCK_GRANT) && \
!((y) & PCA9641_STS_OTHER_LOCK))
#define other_lock(x) ((x) & PCA9641_STS_OTHER_LOCK)
#define lock_grant(x) ((x) & PCA9641_CTL_LOCK_GRANT)
/* arbitration timeouts, in jiffies */
#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */
#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */
/* arbitration retry delays, in us */
#define SELECT_DELAY_SHORT 50
#define SELECT_DELAY_LONG 1000
struct pca9541 {
struct i2c_client *client;
unsigned long select_timeout;
unsigned long arb_timeout;
};
static const struct i2c_device_id pca9541_id[] = {
{"pca9541", 0},
{"pca9641", 1},
{}
};
MODULE_DEVICE_TABLE(i2c, pca9541_id);
#ifdef CONFIG_OF
static const struct of_device_id pca9541_of_match[] = {
{ .compatible = "nxp,pca9541" },
{ .compatible = "nxp,pca9641" },
{}
};
#endif
/*
* Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
* as they will try to lock the adapter a second time.
*/
static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
{
struct i2c_adapter *adap = client->adapter;
int ret;
if (adap->algo->master_xfer) {
struct i2c_msg msg;
char buf[2];
msg.addr = client->addr;
msg.flags = 0;
msg.len = 2;
buf[0] = command;
buf[1] = val;
msg.buf = buf;
ret = __i2c_transfer(adap, &msg, 1);
} else {
union i2c_smbus_data data;
data.byte = val;
ret = adap->algo->smbus_xfer(adap, client->addr,
client->flags,
I2C_SMBUS_WRITE,
command,
I2C_SMBUS_BYTE_DATA, &data);
}
return ret;
}
/*
* Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer()
* as they will try to lock adapter a second time.
*/
static int pca9541_reg_read(struct i2c_client *client, u8 command)
{
struct i2c_adapter *adap = client->adapter;
int ret;
u8 val;
if (adap->algo->master_xfer) {
struct i2c_msg msg[2] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = &command
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = 1,
.buf = &val
}
};
ret = __i2c_transfer(adap, msg, 2);
if (ret == 2)
ret = val;
else if (ret >= 0)
ret = -EIO;
} else {
union i2c_smbus_data data;
ret = adap->algo->smbus_xfer(adap, client->addr,
client->flags,
I2C_SMBUS_READ,
command,
I2C_SMBUS_BYTE_DATA, &data);
if (!ret)
ret = data.byte;
}
return ret;
}
/*
* Arbitration management functions
*/
/* Release bus. Also reset NTESTON and BUSINIT if it was set. */
static void pca9541_release_bus(struct i2c_client *client)
{
int reg;
reg = pca9541_reg_read(client, PCA9541_CONTROL);
if (reg >= 0 && !busoff(reg) && mybus(reg))
pca9541_reg_write(client, PCA9541_CONTROL,
(reg & PCA9541_CTL_NBUSON) >> 1);
}
/*
* Arbitration is defined as a two-step process. A bus master can only activate
* the slave bus if it owns it; otherwise it has to request ownership first.
* This multi-step process ensures that access contention is resolved
* gracefully.
*
* Bus Ownership Other master Action
* state requested access
* ----------------------------------------------------
* off - yes wait for arbitration timeout or
* for other master to drop request
* off no no take ownership
* off yes no turn on bus
* on yes - done
* on no - wait for arbitration timeout or
* for other master to release bus
*
* The main contention point occurs if the slave bus is off and both masters
* request ownership at the same time. In this case, one master will turn on
* the slave bus, believing that it owns it. The other master will request
* bus ownership. Result is that the bus is turned on, and master which did
* _not_ own the slave bus before ends up owning it.
*/
/* Control commands per PCA9541 datasheet */
static const u8 pca9541_control[16] = {
4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
};
/*
* Channel arbitration
*
* Return values:
* <0: error
* 0 : bus not acquired
* 1 : bus acquired
*/
static int pca9541_arbitrate(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca9541 *data = i2c_mux_priv(muxc);
int reg;
reg = pca9541_reg_read(client, PCA9541_CONTROL);
if (reg < 0)
return reg;
if (busoff(reg)) {
int istat;
/*
* Bus is off. Request ownership or turn it on unless
* other master requested ownership.
*/
istat = pca9541_reg_read(client, PCA9541_ISTAT);
if (!(istat & PCA9541_ISTAT_NMYTEST)
|| time_is_before_eq_jiffies(data->arb_timeout)) {
/*
* Other master did not request ownership,
* or arbitration timeout expired. Take the bus.
*/
pca9541_reg_write(client,
PCA9541_CONTROL,
pca9541_control[reg & 0x0f]
| PCA9541_CTL_NTESTON);
data->select_timeout = SELECT_DELAY_SHORT;
} else {
/*
* Other master requested ownership.
* Set extra long timeout to give it time to acquire it.
*/
data->select_timeout = SELECT_DELAY_LONG * 2;
}
} else if (mybus(reg)) {
/*
* Bus is on, and we own it. We are done with acquisition.
* Reset NTESTON and BUSINIT, then return success.
*/
if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
pca9541_reg_write(client,
PCA9541_CONTROL,
reg & ~(PCA9541_CTL_NTESTON
| PCA9541_CTL_BUSINIT));
return 1;
} else {
/*
* Other master owns the bus.
* If arbitration timeout has expired, force ownership.
* Otherwise request it.
*/
data->select_timeout = SELECT_DELAY_LONG;
if (time_is_before_eq_jiffies(data->arb_timeout)) {
/* Time is up, take the bus and reset it. */
pca9541_reg_write(client,
PCA9541_CONTROL,
pca9541_control[reg & 0x0f]
| PCA9541_CTL_BUSINIT
| PCA9541_CTL_NTESTON);
} else {
/* Request bus ownership if needed */
if (!(reg & PCA9541_CTL_NTESTON))
pca9541_reg_write(client,
PCA9541_CONTROL,
reg | PCA9541_CTL_NTESTON);
}
}
return 0;
}
static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
int ret;
unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */
data->arb_timeout = jiffies + ARB_TIMEOUT;
/* force bus ownership after this time */
do {
ret = pca9541_arbitrate(client);
if (ret)
return ret < 0 ? ret : 0;
if (data->select_timeout == SELECT_DELAY_SHORT)
udelay(data->select_timeout);
else
msleep(data->select_timeout / 1000);
} while (time_is_after_eq_jiffies(timeout));
return -ETIMEDOUT;
}
static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
pca9541_release_bus(client);
return 0;
}
/*
* Arbitration management functions
*/
static void pca9641_release_bus(struct i2c_client *client)
{
pca9541_reg_write(client, PCA9641_CONTROL, 0);
}
/*
* Channel arbitration
*
* Return values:
* <0: error
* 0 : bus not acquired
* 1 : bus acquired
*/
static int pca9641_arbitrate(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
struct pca9541 *data = i2c_mux_priv(muxc);
int reg_ctl, reg_sts;
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
if (reg_ctl < 0)
return reg_ctl;
reg_sts = pca9541_reg_read(client, PCA9641_STATUS);
if (BUSOFF(reg_ctl, reg_sts)) {
/*
* Bus is off. Request ownership or turn it on unless
* other master requested ownership.
*/
reg_ctl |= PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
reg_ctl = pca9541_reg_read(client, PCA9641_CONTROL);
if (lock_grant(reg_ctl)) {
/*
* Other master did not request ownership,
* or arbitration timeout expired. Take the bus.
*/
reg_ctl |= PCA9641_CTL_BUS_CONNECT
| PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
data->select_timeout = SELECT_DELAY_SHORT;
return 1;
} else {
/*
* Other master requested ownership.
* Set extra long timeout to give it time to acquire it.
*/
data->select_timeout = SELECT_DELAY_LONG * 2;
}
} else if (lock_grant(reg_ctl)) {
/*
* Bus is on, and we own it. We are done with acquisition.
*/
reg_ctl |= PCA9641_CTL_BUS_CONNECT | PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
return 1;
} else if (other_lock(reg_sts)) {
/*
* Other master owns the bus.
* If arbitration timeout has expired, force ownership.
* Otherwise request it.
*/
data->select_timeout = SELECT_DELAY_LONG;
reg_ctl |= PCA9641_CTL_LOCK_REQ;
pca9541_reg_write(client, PCA9641_CONTROL, reg_ctl);
}
return 0;
}
static int pca9641_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
int ret;
unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */
data->arb_timeout = jiffies + ARB_TIMEOUT;
/* force bus ownership after this time */
do {
ret = pca9641_arbitrate(client);
if (ret)
return ret < 0 ? ret : 0;
if (data->select_timeout == SELECT_DELAY_SHORT)
udelay(data->select_timeout);
else
msleep(data->select_timeout / 1000);
} while (time_is_after_eq_jiffies(timeout));
return -ETIMEDOUT;
}
static int pca9641_release_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca9541 *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
pca9641_release_bus(client);
return 0;
}
static int pca9641_detect_id(struct i2c_client *client)
{
int reg;
reg = pca9541_reg_read(client, PCA9641_ID);
if (reg == PCA9641_ID_MAGIC)
return 1;
else
return 0;
}
/*
* I2C init/probing/exit functions
*/
static int pca9541_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = client->adapter;
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
struct i2c_mux_core *muxc;
struct pca9541 *data;
int force;
int ret;
int detect_id;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
detect_id = pca9641_detect_id(client);
/*
* I2C accesses are unprotected here.
* We have to lock the adapter before releasing the bus.
*/
if (detect_id == 0) {
i2c_lock_adapter(adap);
pca9541_release_bus(client);
i2c_unlock_adapter(adap);
} else {
i2c_lock_adapter(adap);
pca9641_release_bus(client);
i2c_unlock_adapter(adap);
}
/* Create mux adapter */
force = 0;
if (pdata)
force = pdata->modes[0].adap_id;
if (detect_id == 0) {
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
I2C_MUX_ARBITRATOR,
pca9541_select_chan, pca9541_release_chan);
} else {
muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
I2C_MUX_ARBITRATOR,
pca9641_select_chan, pca9641_release_chan);
}
if (!muxc)
return -ENOMEM;
data = i2c_mux_priv(muxc);
data->client = client;
i2c_set_clientdata(client, muxc);
ret = i2c_mux_add_adapter(muxc, force, 0, 0);
if (ret) {
dev_err(&client->dev, "failed to register master selector\n");
return ret;
}
dev_info(&client->dev, "registered master selector for I2C %s\n",
client->name);
return 0;
}
static int pca9541_remove(struct i2c_client *client)
{
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
i2c_mux_del_adapters(muxc);
return 0;
}
static struct i2c_driver pca9541_driver = {
.driver = {
.name = "pca9541",
.of_match_table = of_match_ptr(pca9541_of_match),
},
.probe = pca9541_probe,
.remove = pca9541_remove,
.id_table = pca9541_id,
};
module_i2c_driver(pca9541_driver);
MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
MODULE_LICENSE("GPL v2");

View File

@ -30,6 +30,7 @@
#define CPLD_INFO_OFFSET 0x00
#define CPLD_BIOSCS_OFFSET 0x04
#define CPLD_CTL_OFFSET 0x0C
#define CPLD_SYSLED_OFFSET 0x0E
#define CPLD_LED_OFFSET 0x2E
#define CPLD_INT_OFFSET 0x30
#define CPLD_INTMASK_OFFSET 0x31
@ -58,6 +59,7 @@ struct cpld_data {
struct device *hwmon_dev;
struct mutex update_lock;
u8 diag;
struct task_struct *tsk;
};
/*-----------------------------------------------------------------------*/
@ -97,6 +99,7 @@ static ssize_t cpld_i2c_write(struct i2c_client *client, char *buf, unsigned off
#define CMD_GETDATA 0x31
#define CMD_SETDATA 0x32
#define IPMI_DIAGFLAG_OFFSET 0x00
#define IPMI_SWITCHTEMP_OFFSET 0x02
struct ipmi_result{
char result[MAX_IPMI_RECV_LENGTH];
@ -203,6 +206,30 @@ int start_ipmi_command(char NetFn, char cmd,char *data,int data_length, char* re
}
EXPORT_SYMBOL(start_ipmi_command);
static int cpld_thread(void *p)
{
#ifndef XORP
struct i2c_client *client = p;
u8 byte[9];
uint8_t result[MAX_IPMI_RECV_LENGTH];
int result_len=0;
//Handle LED control by the driver
byte[0]=0x01;
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
//Disable BMC Watchdog
byte[0]=0x04;
byte[1]=0x00;
byte[2]=0x00;
byte[3]=0x00;
byte[4]=0x2C;
byte[5]=0x01;
start_ipmi_command(0x06, 0x24, byte, 6, result, &result_len);
#endif
return 0;
}
/*-----------------------------------------------------------------------*/
/* sysfs attributes for hwmon */
static ssize_t show_info(struct device *dev, struct device_attribute *da,
@ -231,7 +258,7 @@ static ssize_t show_info(struct device *dev, struct device_attribute *da,
sprintf (buf, "%s\nThe CPLD2 release date is %02d/%02d/%d.\n", buf,
byte[2] & 0xf, (byte[3] & 0x1f), 2014+(byte[2] >> 4)); /* mm/dd/yyyy*/
sprintf (buf, "%sThe CPLD version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
sprintf (buf, "%sThe CPLD2 version is %d.%d\n", buf, byte[1]>>4, byte[1]&0xf);
}
return strlen(buf);
@ -251,7 +278,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
u8 byte[2] = {0,0};
mutex_lock(&data->update_lock);
len = cpld_i2c_read(client, byte, CPLD_POWERSTATUS_OFFSET, 2);
len = cpld_i2c_read(client2, byte, CPLD_POWERSTATUS_OFFSET, 2);
mutex_unlock(&data->update_lock);
if (len==0) return 0;
@ -265,8 +292,7 @@ static ssize_t show_powerstatus(struct device *dev, struct device_attribute *da,
sprintf (buf, "%sPGD_P0V8_A: %s\n", buf,powerstatus_str[(byte[1]>>7) & 0x01]);
sprintf (buf, "%sPGD_P0V89_ROV: %s\n", buf, powerstatus_str[(byte[1]>>6) & 0x01]);
sprintf (buf, "%sSW_PWR_READY: %s\n", buf, powerstatus_str[(byte[1]>>3) & 0x01]);
sprintf (buf, "%sCORE_PWRGD_TO_CPLD: %s\n", buf, powerstatus_str[(byte[1]>>2) & 0x01]);
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>1) & 0x01]);
sprintf (buf, "%sCPU_STBY_PWROK: %s\n", buf, powerstatus_str[(byte[1]>>0) & 0x01]);
return strlen(buf);
}
@ -302,44 +328,27 @@ static ssize_t set_diag(struct device *dev,
return count;
}
static char* resetbutton_str[] = {
"No press", //0
"Reserved", //1
"Press and hold <5s", //2
"Press and hold >5s", //3
};
static ssize_t show_resetbuttonstatus(struct device *dev, struct device_attribute *da,
static ssize_t show_thermal(struct device *dev, struct device_attribute *da,
char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
ssize_t len = 0;
u8 byte = 0;
mutex_lock(&data->update_lock);
len = cpld_i2c_read(client, &byte, CPLD_RESETBUTTONSTATUS_OFFSET, 1);
mutex_unlock(&data->update_lock);
if (len==0) return 0;
byte &=0x03;
return sprintf (buf, "0x%02X:%s\n", byte,resetbutton_str[byte]);
uint8_t ipmisend[]= { IPMI_SWITCHTEMP_OFFSET, 1};
uint8_t result[MAX_IPMI_RECV_LENGTH];
int result_len=0;
start_ipmi_command(NETFN_OEM, CMD_GETDATA,ipmisend, 2, result, &result_len);
return sprintf(buf, "%d\n", result[0] * 1000 );
}
static char* interrupt_str[] = {
"CPU_SEN_ALERT_N", //0
"EXT_USB_OC_N", //1
"PS2_ALERT_N", //2
"PS1_ALERT_N", //3
"", //2
"", //3
"PLD_SEN5_ALERT_N", //4
"PLD_SEN4_ALERT_N", //5
"PLD_SEN3_ALERT_N", //6
"UCD90160_TEMP_INT_N", //7
"RSTBTN_INT_N", //8
"WDT_IRQ_N", //9
"RSTBTN_5s_INT_N", //10
"Reserved" //11
"WDT_IRQ_N", //9
};
static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
@ -359,15 +368,12 @@ static ssize_t show_interrupt(struct device *dev, struct device_attribute *da,
if(byte[0]==0xff && byte[2]==0x07) sprintf (buf, "%sNone",buf);
if(!(byte[0]&0x01)) sprintf (buf, "%s%s ",buf,interrupt_str[0]);
if(!(byte[0]&0x02)) sprintf (buf, "%s%s ",buf,interrupt_str[1]);
if(!(byte[0]&0x04)) sprintf (buf, "%s%s ",buf,interrupt_str[2]);
if(!(byte[0]&0x08)) sprintf (buf, "%s%s ",buf,interrupt_str[3]);
if(!(byte[0]&0x10)) sprintf (buf, "%s%s ",buf,interrupt_str[4]);
if(!(byte[0]&0x20)) sprintf (buf, "%s%s ",buf,interrupt_str[5]);
if(!(byte[0]&0x40)) sprintf (buf, "%s%s ",buf,interrupt_str[6]);
if(!(byte[0]&0x80)) sprintf (buf, "%s%s ",buf,interrupt_str[7]);
if(!(byte[2]&0x01)) sprintf (buf, "%s%s%s ",buf,interrupt_str[8] ,(byte[3]&0x01)?"(Blocked)":"");
if(!(byte[2]&0x02)) sprintf (buf, "%s%s%s ",buf,interrupt_str[9] ,(byte[3]&0x02)?"(Blocked)":"");
if(!(byte[2]&0x04)) sprintf (buf, "%s%s%s ",buf,interrupt_str[10],(byte[3]&0x04)?"(Blocked)":"");
return sprintf (buf, "%s\n", buf);
}
@ -414,10 +420,10 @@ static ssize_t set_bios_cs(struct device *dev,
}
static char* led_str[] = {
"OFF", //000
"ON", //001
"1 Hz", //010
"2 Hz", //011
"OFF", //00
"Green/Blue", //01
"Yellow/Orange", //10
"Red", //11
};
static ssize_t show_led(struct device *dev, struct device_attribute *da,
@ -437,7 +443,7 @@ static ssize_t show_led(struct device *dev, struct device_attribute *da,
byte = (byte >> shift) & 0x3;
return sprintf (buf, "%d: %s\n", byte, led_str[byte]);
return sprintf (buf, "%d:%s\n", byte, led_str[byte]);
}
static ssize_t set_led(struct device *dev, struct device_attribute *da,
@ -462,6 +468,61 @@ static ssize_t set_led(struct device *dev, struct device_attribute *da,
return count;
}
static char* sysled_str[] = {
"OFF", //000
"0.5 Hz", //001
"1 Hz", //010
"2 Hz", //011
"4 Hz", //100
"NA", //101
"NA", //110
"ON", //111
};
static ssize_t show_sysled(struct device *dev, struct device_attribute *da,
char *buf)
{
u32 status;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 byte;
int shift = (attr->index == 0)?3:0;
mutex_lock(&data->update_lock);
status = cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1);
mutex_unlock(&data->update_lock);
byte = (byte >> shift) & 0x7;
status = sprintf (buf, "%d:%s\n", byte, sysled_str[byte]);
return strlen(buf);
}
static ssize_t set_sysled(struct device *dev,
struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct cpld_data *data = i2c_get_clientdata(client);
u8 temp = simple_strtol(buf, NULL, 16);
u8 byte;
int shift = (attr->index == 0)?3:0;
temp &= 0x7;
mutex_lock(&data->update_lock);
cpld_i2c_read(client, &byte, CPLD_SYSLED_OFFSET, 1);
byte &= ~(0x7<<shift);
byte |= (temp<<shift);
cpld_i2c_write(client, &byte, CPLD_SYSLED_OFFSET, 1);
mutex_unlock(&data->update_lock);
return count;
}
static char* psu_str[] = {
"unpowered", //00
"normal", //01
@ -714,12 +775,15 @@ static ssize_t show_watchdog_counter(struct device *dev, struct device_attribute
static SENSOR_DEVICE_ATTR(info, S_IRUGO, show_info, 0, 0);
static SENSOR_DEVICE_ATTR(diag, S_IWUSR|S_IRUGO, show_diag, set_diag, 0);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_thermal, 0, 0);
static SENSOR_DEVICE_ATTR(interrupt, S_IRUGO, show_interrupt, 0, 0);
static SENSOR_DEVICE_ATTR(stacking_led, S_IWUSR|S_IRUGO, show_led, set_led, 0);
static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2);
static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4);
static SENSOR_DEVICE_ATTR(service_led, S_IWUSR|S_IRUGO, show_led, set_led, 6);
static SENSOR_DEVICE_ATTR(fan_led, S_IWUSR|S_IRUGO, show_led, set_led, 2);
static SENSOR_DEVICE_ATTR(power_led, S_IWUSR|S_IRUGO, show_led, set_led, 4);
static SENSOR_DEVICE_ATTR(location_led, S_IWUSR|S_IRUGO, show_led, set_led, 6);
static SENSOR_DEVICE_ATTR(grn_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 0);
static SENSOR_DEVICE_ATTR(red_led, S_IWUSR|S_IRUGO, show_sysled, set_sysled, 1);
static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 0);
static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR|S_IRUGO, show_pwm, set_pwm, 1);
@ -761,7 +825,6 @@ static SENSOR_DEVICE_ATTR(fan10_input,S_IRUGO, show_rpm, 0, 9);
static SENSOR_DEVICE_ATTR(psu1, S_IRUGO, show_psu, 0, 0);
static SENSOR_DEVICE_ATTR(psu2, S_IRUGO, show_psu, 0, 1);
static SENSOR_DEVICE_ATTR(power_status, S_IRUGO, show_powerstatus, 0, 0);
static SENSOR_DEVICE_ATTR(resetbutton_status, S_IRUGO, show_resetbuttonstatus, 0, 0);
static SENSOR_DEVICE_ATTR(watchdog_feed, S_IWUSR, 0, set_watchdog_feed, 0);
static SENSOR_DEVICE_ATTR(watchdog_enable, S_IWUSR|S_IRUGO, show_watchdog_enable, set_watchdog_enable, 0);
@ -773,18 +836,20 @@ static SENSOR_DEVICE_ATTR(bios_cs, S_IWUSR|S_IRUGO, show_bios_cs, set_b
static struct attribute *cpld_attributes[] = {
&sensor_dev_attr_info.dev_attr.attr,
&sensor_dev_attr_diag.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_stacking_led.dev_attr.attr,
&sensor_dev_attr_fan_led.dev_attr.attr,
&sensor_dev_attr_power_led.dev_attr.attr,
&sensor_dev_attr_service_led.dev_attr.attr,
&sensor_dev_attr_location_led.dev_attr.attr,
&sensor_dev_attr_grn_led.dev_attr.attr,
&sensor_dev_attr_red_led.dev_attr.attr,
&sensor_dev_attr_interrupt.dev_attr.attr,
&sensor_dev_attr_psu1.dev_attr.attr,
&sensor_dev_attr_psu2.dev_attr.attr,
&sensor_dev_attr_power_status.dev_attr.attr,
&sensor_dev_attr_resetbutton_status.dev_attr.attr,
&sensor_dev_attr_pwm1.dev_attr.attr,
&sensor_dev_attr_pwm2.dev_attr.attr,
@ -839,7 +904,6 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct cpld_data *data;
int status;
u8 byte[5];
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
@ -879,11 +943,7 @@ cpld_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
}
//Handle LED control by the driver
byte[0]=0x01;
cpld_i2c_write(client, byte, CPLD_CTL_OFFSET, 1);
cpld_i2c_write(client2, byte, CPLD_CTL_OFFSET, 1);
data->tsk = kthread_run(cpld_thread,client,"%s",dev_name(data->hwmon_dev));
dev_info(&client->dev, "%s: sensor '%s'\n",
dev_name(data->hwmon_dev), client->name);
@ -908,6 +968,7 @@ static int cpld_remove(struct i2c_client *client)
i2c_unregister_device(client2);
i2c_set_clientdata(client2, NULL);
}
kfree(data);
return 0;
}

View File

@ -1,22 +1,55 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <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 "inv_mux.h"
static struct mux_obj_s *mux_head_p = NULL;
/* For build single module using (Ex: ONL platform) */
#include <linux/module.h>
//#include <linux/inventec/d5254/io_expander.h>
//#include <linux/inventec/d5254/inv_mux.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,
@ -93,6 +126,78 @@ normal_gpio_pull_low(struct mux_obj_s *self){
}
int
cpld_rst_all_4_pull_low(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto setlow_cpld_rst_all_4_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_cpld_rst_all_4_pull_low;
setlow_cpld_rst_all_4_c0_a77_70_74_rst_all:
err = _setup_i2c_value(self, 0x70, 0x0);
if (err < 0) {
emsg = "setup 0x70 fail";
goto err_cpld_rst_all_4_pull_low;
}
err = _setup_i2c_value(self, 0x74, 0x01);
if (err < 0) {
emsg = "setup 0x74 fail";
goto err_cpld_rst_all_4_pull_low;
}
return 0;
err_cpld_rst_all_4_pull_low:
SWPS_INFO("%s: %s <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)
@ -108,16 +213,47 @@ pca9548_reset_mux_all(struct mux_obj_s *self){
SWPS_ERR("%s: _pull_low fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
mdelay(MUX_RST_WAIT_MS_PCA9548);
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: _pull_high fail!\n", __func__);
return -1;
}
mdelay(MUX_RST_WAIT_MS);
mdelay(MUX_RST_WAIT_MS_PCA9548);
return 0;
}
int
cpld_reset_mux_all(struct mux_obj_s *self){
char *emsg = "ERR";
int err = ERR_MUX_UNEXCPT;
switch(self->gpio_num) {
case MUX_RST_CPLD_C0_A77_70_74_RST_ALL:
goto reset_cpld_rst_all_4_c0_a77_70_74_rst_all;
default:
break;
}
emsg = "Undefined case";
goto err_cpld_reset_mux_all;
reset_cpld_rst_all_4_c0_a77_70_74_rst_all:
if (self->_pull_low(self) < 0) {
emsg = "_pull_low fail";
goto err_cpld_reset_mux_all;
}
mdelay(MUX_RST_WAIT_MS_CPLD);
return 0;
err_cpld_reset_mux_all:
SWPS_INFO("%s: %s <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__);
@ -127,6 +263,11 @@ common_reset_mux_all(struct mux_obj_s *self){
int
init_gpio_4_force(struct mux_obj_s *self){
if (self->_pull_high(self) < 0) {
SWPS_ERR("%s: setup default fail!\n", __func__);
return -1;
}
return 0;
}
@ -134,20 +275,95 @@ init_gpio_4_force(struct mux_obj_s *self){
int
init_gpio_4_normal(struct mux_obj_s *self){
int err = 0;
int err = 0;
char *emsg = "ERR";
if (!gpio_is_valid(self->gpio_num)) {
SWPS_ERR("%s: GIPO:%d isn't valid\n", __func__, self->gpio_num);
return -1;
emsg = "GPIO invalid";
goto err_init_gpio_4_normal;
}
err = gpio_request(self->gpio_num, MUX_GPIO_LABEL);
if (err < 0) {
SWPS_ERR("%s: gpio_request fail <err>:%d <gpio>:%d\n",
__func__, err, self->gpio_num);
return -1;
emsg = "gpio_request fail";
goto err_init_gpio_4_normal;
}
err = self->_pull_high(self);
if (err < 0) {
emsg = "setup default fail";
goto err_init_gpio_4_normal;
}
SWPS_DEBUG("%s: gpio_request:%d ok.\n", __func__, self->gpio_num);
return 0;
err_init_gpio_4_normal:
SWPS_ERR("%s: %s <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;
}
@ -163,6 +379,7 @@ _setup_muxctl_cb(struct mux_obj_s *self,
self->_pull_low = rangeley_force_pull_low;
self->_pull_high = rangeley_force_pull_high;
self->_init = init_gpio_4_force;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Rangeley force mode");
@ -173,25 +390,38 @@ _setup_muxctl_cb(struct mux_obj_s *self,
self->_pull_low = hedera_force_pull_low;
self->_pull_high = hedera_force_pull_high;
self->_init = init_gpio_4_force;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Hedera force mode");
goto ok_setup_muxctl_cb;
case MUX_RST_GPIO_48_PAC9548:
case MUX_RST_GPIO_69_PAC9548:
case MUX_RST_GPIO_48_PCA9548:
case MUX_RST_GPIO_69_PCA9548:
case MUX_RST_GPIO_249_PCA9548:
case MUX_RST_GPIO_500_PAC9548:
case MUX_RST_GPIO_500_PCA9548:
case MUX_RST_GPIO_505_PCA9548:
self->gpio_num = gpio;
self->_pull_low = normal_gpio_pull_low;
self->_pull_high = normal_gpio_pull_high;
self->_init = init_gpio_4_normal;
self->_clean = clean_gpio_4_common;
self->reset = pca9548_reset_mux_all;
memset(mod_dsc, 0, 32);
snprintf(mod_dsc, 31, "Normal mode <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;
}
@ -207,23 +437,28 @@ ok_setup_muxctl_cb:
/* ========== MUX public functions ==========
*/
void
clean_mux_gpio(void){
clean_mux_objs(void){
if (!mux_head_p) {
struct mux_obj_s *curr_p = mux_head_p;
struct mux_obj_s *next_p = NULL;
if (!curr_p) {
SWPS_DEBUG("%s: mux_head_p is NULL\n", __func__);
return;
}
if (gpio_is_valid(mux_head_p->gpio_num)) {
gpio_free(mux_head_p->gpio_num);
while (curr_p) {
next_p = curr_p->next;
curr_p->_clean(curr_p);
kfree(curr_p);
curr_p = next_p;
}
kfree(mux_head_p);
mux_head_p = NULL;
SWPS_DEBUG("%s: done.\n", __func__);
}
EXPORT_SYMBOL(clean_mux_objs);
int
reset_mux_gpio(void){
reset_mux_objs(void){
if (!mux_head_p) {
SWPS_ERR("%s: MUX ctl object doesn't exist!\n", __func__);
@ -235,46 +470,77 @@ reset_mux_gpio(void){
}
return 0;
}
EXPORT_SYMBOL(reset_mux_objs);
struct mux_obj_s *
_create_mux_obj(unsigned gpio){
char *emsg = "ERR";
struct mux_obj_s *obj_p = NULL;
obj_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
if (!obj_p) {
emsg = "kzalloc fail!";
goto err_create_mux_obj_1;
}
if (_setup_muxctl_cb(obj_p, gpio) < 0){
emsg = "_setup_muxctl_cb fail!";
goto err_create_mux_obj_2;
}
if (obj_p->_init(obj_p) < 0) {
emsg = "_init() fail!";
goto err_create_mux_obj_2;
}
SWPS_DEBUG("%s: created MUX object <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_gpio(unsigned gpio){
init_mux_objs(unsigned gpio){
struct mux_obj_s *curr_p = NULL;
char *emsg = "ERR";
/* Create MUX control object */
if (mux_head_p) {
SWPS_DEBUG("%s: mux_head_p is not NULL!\n", __func__);
clean_mux_gpio();
clean_mux_objs();
}
/* Currently, it is using single muxctl architecture.
* In the future, it may use the multi-muxctl if HW add new features.
* (Ex: Port power-status control)
* In the future, it may use the multi-muxctl.
* (Ex: Gulmohar's advance I2C control / Peony's reset single mux)
*/
mux_head_p = kzalloc(sizeof(struct mux_obj_s), GFP_KERNEL);
if (!mux_head_p) {
SWPS_ERR("%s: kzalloc fail!\n", __func__);
return -1;
}
/* Initial MUX controller */
if (_setup_muxctl_cb(mux_head_p, gpio) < 0){
SWPS_ERR("%s: _setup_muxctl_cb fail!\n", __func__);
return -1;
}
if (mux_head_p->_init(mux_head_p) < 0) {
SWPS_ERR("%s: init() fail\n", __func__);
goto err_init_mux_gpio;
}
/* Setup default value */
if (mux_head_p->_pull_high(mux_head_p) < 0) {
SWPS_ERR("%s: setup default fail!\n", __func__);
goto err_init_mux_gpio;
curr_p = _create_mux_obj(gpio);
if (!curr_p) {
emsg = "_create_mux_obj fail";
goto err_init_mux_objs;
}
curr_p->next = NULL;
mux_head_p = curr_p;
SWPS_DEBUG("%s: all done. <type>:%d\n", __func__, gpio);
return 0;
err_init_mux_gpio:
clean_mux_gpio();
err_init_mux_objs:
clean_mux_objs();
SWPS_ERR("%s: %s\n", __func__, emsg);
return -1;
}
EXPORT_SYMBOL(init_mux_objs);
/* For single ko module
* => You need to declare MODULE_LICENSE If you want to build single module along.
* => Ex: For ONL platform
*/
MODULE_LICENSE("GPL");

View File

@ -1,47 +1,51 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef INV_MUX_H
#define INV_MUX_H
#include <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_PAC9548 (48)
#define MUX_RST_GPIO_69_PAC9548 (69)
#define MUX_RST_GPIO_249_PCA9548 (249)
#define MUX_RST_GPIO_500_PAC9548 (500)
#define MUX_RST_GPIO_505_PCA9548 (505)
#define MUX_RST_GPIO_FORCE (30100)
#define MUX_RST_GPIO_FORCE_RANGELEY (30101)
#define MUX_RST_GPIO_FORCE_HEDERA (30102)
#define MUX_RST_GPIO_48_PCA9548 (48)
#define MUX_RST_GPIO_69_PCA9548 (69)
#define MUX_RST_GPIO_249_PCA9548 (249)
#define MUX_RST_GPIO_500_PCA9548 (500)
#define MUX_RST_GPIO_505_PCA9548 (505)
#define MUX_RST_CPLD_C0_A77_70_74_RST_ALL (30201)
/* MUX relate value define */
#define MUX_RST_WAIT_MS (1)
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
#define MUX_RST_WAIT_MS_PCA9548 (1)
#define MUX_RST_WAIT_MS_CPLD (10)
#define MUX_RST_MEM_ADDR_RANGELEY (0) // TBD
#define MUX_RST_MEM_ADDR_HEDERA (0x548)
/* MUX error code define */
#define ERR_MUX_UNEXCPT (-399)
struct mux_obj_s {
struct i2c_client *i2c_client_p;
struct mux_obj_s *next;
unsigned gpio_num;
int (*_pull_high)(struct mux_obj_s *self);
int (*_pull_low)(struct mux_obj_s *self);
int (*_init)(struct mux_obj_s *self);
int (*_clean)(struct mux_obj_s *self);
int (*reset)(struct mux_obj_s *self);
};
void clean_mux_gpio(void);
int reset_mux_gpio(void);
int init_mux_gpio(unsigned gpio);
void clean_mux_objs(void);
int reset_mux_objs(void);
int init_mux_objs(unsigned gpio);
#endif /* INV_MUX_H */

View File

@ -137,49 +137,49 @@ static struct pca954x_platform_data mux_data_0_6 = {
};
static struct i2c_board_info i2c_device_info0[] __initdata = {
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
{"pca9641", 0, 0x76, &pca9641_data_1, 0, 0}, //PCA9641-1
{"pca9641", 0, 0x73, &pca9641_data_3, 0, 0}, //PCA9641-3
{"pca9641", 0, 0x09, &pca9641_data_4, 0, 0}, //PCA9641-4
};
static struct i2c_board_info i2c_device_info1[] __initdata = {
{"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2
{"pca9641", 0, 0x0A, &pca9641_data_2, 0, 0}, //PCA9641-2
};
static struct i2c_board_info i2c_device_info2[] __initdata = {
{"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD
{"inv_cpld", 0, 0x77, 0, 0, 0}, //CPLD
};
static struct i2c_board_info i2c_device_info3[] __initdata = {
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
{"tmp75", 0, 0x48, 0, 0, 0}, //CPU Board Temp
{"tmp75", 0, 0x4A, 0, 0, 0}, //Temp
{"tmp75", 0, 0x4D, 0, 0, 0}, //Temp
{"tmp75", 0, 0x4E, 0, 0, 0}, //Temp
};
static struct i2c_board_info i2c_device_info4[] __initdata = {
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU1
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU2
{"pmbus", 0, 0x5B, 0, 0, 0}, //PSU1
{"pmbus", 0, 0x5A, 0, 0, 0}, //PSU2
};
static struct i2c_board_info i2c_device_info5[] __initdata = {
{"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root
{"pca9548", 0, 0x70, &mux_data_0, 0, 0}, //mux root
};
static struct i2c_board_info i2c_device_info6[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_0, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_0, 0, 0},
};
static struct i2c_board_info i2c_device_info7[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_1, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_1, 0, 0},
};
static struct i2c_board_info i2c_device_info8[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_2, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_2, 0, 0},
};
static struct i2c_board_info i2c_device_info9[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_3, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_3, 0, 0},
};
static struct i2c_board_info i2c_device_info10[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_4, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_4, 0, 0},
};
static struct i2c_board_info i2c_device_info11[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_5, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_5, 0, 0},
};
static struct i2c_board_info i2c_device_info12[] __initdata = {
{"pca9548", 0, 0x72, &mux_data_0_6, 0, 0},
{"pca9548", 0, 0x72, &mux_data_0_6, 0, 0},
};
@ -196,19 +196,23 @@ static struct inv_i2c_board_info i2cdev_list[] = {
{bus_id(9), ARRAY_SIZE(i2c_device_info9), i2c_device_info9 }, //mux CH3
{bus_id(10),ARRAY_SIZE(i2c_device_info10), i2c_device_info10}, //mux CH4
{bus_id(11),ARRAY_SIZE(i2c_device_info11), i2c_device_info11}, //mux CH5
{bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6
{bus_id(12),ARRAY_SIZE(i2c_device_info12), i2c_device_info12}, //mux CH6
};
#define INV_PLATFORM_CLIENT_MAX_NUM 50 /*A big enough number for sum of i2cdev_list[i].size */
static int client_list_index = 0;
static struct i2c_client *client_list[INV_PLATFORM_CLIENT_MAX_NUM] = {0};
/////////////////////////////////////////////////////////////////////////////////////////
static struct platform_device *device_i2c_gpio0;
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
.scl_pin = 58, //494,
.sda_pin = 75, //511,
.udelay = 5, //5:100kHz
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
static struct i2c_gpio_platform_data i2c_gpio_platdata0 = {
.scl_pin = 58, //494,
.sda_pin = 75, //511,
.udelay = 5, //5:100kHz
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
.scl_is_output_only = 0
};
static int __init inv_platform_init(void)
@ -220,7 +224,7 @@ static int __init inv_platform_init(void)
//printk("%s \n", __func__);
//use i2c-gpio
//use i2c-gpio
//register i2c gpio
//config gpio58,75 to gpio function 58=32+3*8+2 75=32*2+8*1+3 gpio69=32*2+8*0+5
outl( inl(0x533) | (1<<2), 0x533); //i2c-gpio sdl (GPIO58)
@ -229,7 +233,7 @@ static int __init inv_platform_init(void)
outl( inl(0x500) | (1<<7), 0x500); //SYS_RDY_N (GPIO7)
outl( inl(0x501) | (1<<7), 0x501); //BMC_HEART_BEAT (GPIO15)
outl( inl(0x503) | (1<<2)|(1<<3), 0x503); //PSOC_HEART_BEAT(26),CPLD_HEART_BEAT(27)
device_i2c_gpio0 = platform_device_alloc("i2c-gpio", 1);
if (!device_i2c_gpio0) {
printk(KERN_ERR "i2c-gpio: platform_device_alloc fail\n");
@ -243,7 +247,8 @@ static int __init inv_platform_init(void)
if (ret) {
printk(KERN_ERR "i2c-gpio: platform_device_add fail %d\n", ret);
}
msleep(10);
msleep(10);
for(i=0; i<ARRAY_SIZE(i2cdev_list); i++) {
adap = i2c_get_adapter( i2cdev_list[i].ch );
if (adap == NULL) {
@ -254,17 +259,33 @@ static int __init inv_platform_init(void)
for(j=0; j<i2cdev_list[i].size; j++) {
for(k=0; k<300; k++) {
e = i2c_new_device(adap, &i2cdev_list[i].board_info[j] );
if(e == NULL) msleep(10); else break;
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);
}
}
}
return ret;
printk("inv_platform_init done\n");
return ret;
}
static void __exit inv_platform_exit(void)
{
device_i2c_gpio0->dev.platform_data = NULL;
platform_device_unregister(device_i2c_gpio0);
int i;
for(i=client_list_index-1; i>=0; i--) {
i2c_unregister_device(client_list[i]);
}
device_i2c_gpio0->dev.platform_data = NULL;
platform_device_unregister(device_i2c_gpio0);
printk("inv_platform_exit done\n");
}
module_init(inv_platform_init);
@ -273,3 +294,4 @@ module_exit(inv_platform_exit);
MODULE_AUTHOR("Inventec");
MODULE_DESCRIPTION("Platform devices");
MODULE_LICENSE("GPL");

View File

@ -1,9 +1,3 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@ -15,12 +9,14 @@
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
#include "inv_swps.h"
static int ctl_major;
static int port_major;
static int ioexp_total;
static int port_total;
static int block_polling;
static int auto_config;
static int flag_i2c_reset;
static int flag_mod_state;
@ -29,7 +25,8 @@ static struct class *swp_class_p = NULL;
static struct inv_platform_s *platform_p = NULL;
static struct inv_ioexp_layout_s *ioexp_layout = NULL;
static struct inv_port_layout_s *port_layout = NULL;
int io_no_init = 0;
module_param(io_no_init, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
static void swp_polling_worker(struct work_struct *work);
static DECLARE_DELAYED_WORK(swp_polling, swp_polling_worker);
@ -140,6 +137,47 @@ _get_transvr_obj(char *dev_name) {
}
static int
_is_i2c_target_exist(int chan, int addr) {
/* retval: Exist = 1 / Not exist = 0 / Error < 0
*/
struct i2c_adapter *adap = NULL;
struct i2c_client *client = NULL;
int retval = -1;
int err = -1;
int d_offs = 0;
adap = i2c_get_adapter(chan);
if (!adap) {
SWPS_DEBUG("%s: can't get adapter\n", __func__);
retval = 0;
goto out_is_i2c_target_exist_1;
}
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
SWPS_ERR("%s: kzalloc fail\n", __func__);
retval = -1;
goto out_is_i2c_target_exist_2;
}
client->adapter = adap;
client->addr = addr;
err = i2c_smbus_read_byte_data(client, d_offs);
if (err < 0) {
retval = 0;
} else {
retval = 1;
}
i2c_put_adapter(adap);
kfree(client);
return retval;
out_is_i2c_target_exist_2:
i2c_put_adapter(adap);
out_is_i2c_target_exist_1:
return retval;
}
static void
unlock_tobj_all(void) {
@ -254,6 +292,22 @@ show_attr_auto_config(struct device *dev_p,
}
static ssize_t
show_attr_block_poll(struct device *dev_p,
struct device_attribute *attr_p,
char *buf_p){
return snprintf(buf_p, 8, "%d\n", block_polling);
}
static ssize_t
show_attr_io_no_init(struct device *dev_p,
struct device_attribute *attr_p,
char *buf_p){
return snprintf(buf_p, 8, "%d\n", io_no_init);
}
static int
_check_reset_pwd(const char *buf_p,
size_t count) {
@ -360,6 +414,53 @@ store_attr_auto_config(struct device *dev_p,
}
static ssize_t
store_attr_block_poll( struct device *dev_p,
struct device_attribute *attr_p,
const char *buf_p,
size_t count){
int input_val = sscanf_2_int(buf_p);
if (input_val < 0){
return -EBFONT;
}
if ((input_val != 0) && (input_val != 1)) {
return -EBFONT;
}
if(input_val != block_polling){
block_polling = input_val;
if(block_polling){
cancel_delayed_work_sync(&swp_polling);
}
else{
schedule_delayed_work(&swp_polling, _get_polling_period());
}
}
return count;
}
static ssize_t
store_attr_io_no_init( struct device *dev_p,
struct device_attribute *attr_p,
const char *buf_p,
size_t count){
int input_val = sscanf_2_int(buf_p);
if ((input_val != 0) && (input_val != 1)) {
return -EBFONT;
}
if(input_val != io_no_init){
io_no_init = input_val;
}
return count;
}
/* ========== Show functions: For transceiver attribute ==========
*/
static ssize_t
@ -1604,6 +1705,9 @@ static DEVICE_ATTR(status, S_IRUGO, show_attr_status,
static DEVICE_ATTR(reset_i2c, S_IWUSR, NULL, store_attr_reset_i2c);
static DEVICE_ATTR(reset_swps, S_IWUSR, NULL, store_attr_reset_swps);
static DEVICE_ATTR(auto_config, S_IRUGO|S_IWUSR, show_attr_auto_config, store_attr_auto_config);
static DEVICE_ATTR(block_poll, S_IRUGO|S_IWUSR, show_attr_block_poll, store_attr_block_poll);
static DEVICE_ATTR(io_no_init, S_IRUGO|S_IWUSR, show_attr_io_no_init, store_attr_io_no_init);
/* ========== Transceiver attribute: from eeprom ==========
*/
@ -1666,12 +1770,12 @@ static DEVICE_ATTR(hard_rs1, S_IRUGO|S_IWUSR, show_attr_hard_rs1,
/* ========== Functions for module handling ==========
*/
static void
clean_port_obj(void){
clean_port_objs(void){
dev_t dev_num;
char dev_name[32];
struct device *device_p;
struct transvr_obj_s *transvr_obj_p;
struct transvr_obj_s *tobj_p;
int minor_curr, port_id;
for (minor_curr=0; minor_curr<port_total; minor_curr++){
@ -1682,15 +1786,18 @@ clean_port_obj(void){
if (!device_p){
continue;
}
transvr_obj_p = dev_get_drvdata(device_p);
if (transvr_obj_p){
kfree(transvr_obj_p->i2c_client_p);
kfree(transvr_obj_p->vendor_name);
kfree(transvr_obj_p->vendor_pn);
kfree(transvr_obj_p->vendor_rev);
kfree(transvr_obj_p->vendor_sn);
kfree(transvr_obj_p->worker_p);
kfree(transvr_obj_p);
tobj_p = dev_get_drvdata(device_p);
if (tobj_p){
if (tobj_p->i2c_client_p) {
i2c_put_adapter(tobj_p->i2c_client_p->adapter);
kfree(tobj_p->i2c_client_p);
}
kfree(tobj_p->vendor_name);
kfree(tobj_p->vendor_pn);
kfree(tobj_p->vendor_rev);
kfree(tobj_p->vendor_sn);
kfree(tobj_p->worker_p);
kfree(tobj_p);
}
dev_num = MKDEV(port_major, minor_curr);
device_unregister(device_p);
@ -1713,6 +1820,9 @@ clean_swps_common(void){
device_destroy(swp_class_p, dev_num);
}
cancel_delayed_work_sync(&swp_polling);
if (platform_p) {
kfree(platform_p);
}
SWPS_DEBUG("%s: done.\n", __func__);
}
@ -1720,8 +1830,10 @@ clean_swps_common(void){
static int
get_platform_type(void){
int i;
int pf_total = ARRAY_SIZE(platform_map);
int i, tmp;
int auto_chan = -1;
int auto_addr = -1;
int pf_total = ARRAY_SIZE(platform_map);
char log_msg[64] = "ERROR";
platform_p = kzalloc(sizeof(struct inv_platform_s), GFP_KERNEL);
@ -1749,6 +1861,30 @@ get_platform_type(void){
platform_p->name);
goto err_get_platform_type_2;
case PLATFORM_TYPE_PEONY_AUTO:
#ifdef SWPS_PEONY_SFP
auto_chan = peony_sfp_ioexp_layout[0].addr[0].chan_id;
auto_addr = peony_sfp_ioexp_layout[0].addr[0].chip_addr;
#endif
tmp = _is_i2c_target_exist(auto_chan, auto_addr);
switch (tmp) {
case 0: /* Copper SKU */
SWPS_INFO("Auto-detected <platform>:Peony <SKU>:Copper\n");
platform_p->id = PLATFORM_TYPE_PEONY_COPPER_GA;
goto map_platform_name;
case 1: /* SFP SKU */
SWPS_INFO("Auto-detected <platform>:Peony <SKU>:SFP\n");
platform_p->id = PLATFORM_TYPE_PEONY_SFP_GA;
goto map_platform_name;
default:
break;
}
snprintf(log_msg, sizeof(log_msg),
"Auto detect Peony SKU fail! <err>:%d", tmp);
goto err_get_platform_type_2;
case PLATFORM_TYPE_MAGNOLIA:
case PLATFORM_TYPE_MAGNOLIA_FNC:
case PLATFORM_TYPE_REDWOOD:
@ -1763,22 +1899,14 @@ get_platform_type(void){
case PLATFORM_TYPE_LAVENDER_GA:
case PLATFORM_TYPE_LAVENDER_ONL:
case PLATFORM_TYPE_COTTONWOOD_RANGELEY:
case PLATFORM_TYPE_MAPLE:
case PLATFORM_TYPE_MAPLE_GA:
case PLATFORM_TYPE_MAPLE_B:
case PLATFORM_TYPE_GULMOHAR_GA:
case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA:
case PLATFORM_TYPE_PEONY_SFP_GA:
case PLATFORM_TYPE_PEONY_COPPER_GA:
platform_p->id = PLATFORM_SETTINGS;
for (i=0; i<pf_total; i++) {
if (PLATFORM_SETTINGS == platform_map[i].id) {
snprintf(platform_p->name, (sizeof(platform_p->name) - 1),
"%s", platform_map[i].name);
snprintf(log_msg, sizeof(log_msg),
"User setup platform: %d (%s)",
platform_p->id, platform_p->name);
goto ok_get_platform_type_1;
}
}
snprintf(log_msg, sizeof(log_msg),
"Internal error, can not map id:%d",
PLATFORM_SETTINGS);
goto err_get_platform_type_2;
goto map_platform_name;
default:
break;
@ -1787,6 +1915,22 @@ get_platform_type(void){
"PLATFORM_SETTINGS:%d undefined", PLATFORM_SETTINGS);
goto err_get_platform_type_2;
map_platform_name:
for (i=0; i<pf_total; i++) {
if (platform_p->id == platform_map[i].id) {
snprintf(platform_p->name, (sizeof(platform_p->name) - 1),
"%s", platform_map[i].name);
snprintf(log_msg, sizeof(log_msg),
"User setup platform: %d (%s)",
platform_p->id, platform_p->name);
goto ok_get_platform_type_1;
}
}
snprintf(log_msg, sizeof(log_msg),
"Internal error, can not map id:%d",
platform_p->id );
goto err_get_platform_type_2;
ok_get_platform_type_1:
SWPS_DEBUG("%s: %s, <conf>:%d\n", __func__, log_msg, PLATFORM_SETTINGS);
return 0;
@ -1913,15 +2057,61 @@ get_layout_info(void){
port_total = ARRAY_SIZE(cottonwood_rangeley_port_layout);
break;
#endif
#ifdef SWPS_MAPLE
case PLATFORM_TYPE_MAPLE:
gpio_rest_mux = maple_gpio_rest_mux;
ioexp_layout = maple_ioexp_layout;
port_layout = maple_port_layout;
ioexp_total = ARRAY_SIZE(maple_ioexp_layout);
port_total = ARRAY_SIZE(maple_port_layout);
#ifdef SWPS_MAPLE_GA
case PLATFORM_TYPE_MAPLE_GA:
gpio_rest_mux = maple_ga_gpio_rest_mux;
ioexp_layout = maple_ga_ioexp_layout;
port_layout = maple_ga_port_layout;
ioexp_total = ARRAY_SIZE(maple_ga_ioexp_layout);
port_total = ARRAY_SIZE(maple_ga_port_layout);
break;
#endif
#ifdef SWPS_MAPLE_B
case PLATFORM_TYPE_MAPLE_B:
gpio_rest_mux = maple_b_gpio_rest_mux;
ioexp_layout = maple_b_ioexp_layout;
port_layout = maple_b_port_layout;
ioexp_total = ARRAY_SIZE(maple_b_ioexp_layout);
port_total = ARRAY_SIZE(maple_b_port_layout);
break;
#endif
#ifdef SWPS_GULMOHAR
case PLATFORM_TYPE_GULMOHAR_GA:
gpio_rest_mux = gulmohar_gpio_rest_mux;
ioexp_layout = gulmohar_ioexp_layout;
port_layout = gulmohar_port_layout;
ioexp_total = ARRAY_SIZE(gulmohar_ioexp_layout);
port_total = ARRAY_SIZE(gulmohar_port_layout);
break;
#endif
#ifdef SWPS_GULMOHAR_2T_EVT1
case PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA:
gpio_rest_mux = gulmohar_2t_evt1_gpio_rest_mux;
ioexp_layout = gulmohar_2t_evt1_ioexp_layout;
port_layout = gulmohar_2t_evt1_port_layout;
ioexp_total = ARRAY_SIZE(gulmohar_2t_evt1_ioexp_layout);
port_total = ARRAY_SIZE(gulmohar_2t_evt1_port_layout);
break;
#endif
#ifdef SWPS_PEONY_SFP
case PLATFORM_TYPE_PEONY_SFP_GA:
gpio_rest_mux = peony_sfp_gpio_rest_mux;
ioexp_layout = peony_sfp_ioexp_layout;
port_layout = peony_sfp_port_layout;
ioexp_total = ARRAY_SIZE(peony_sfp_ioexp_layout);
port_total = ARRAY_SIZE(peony_sfp_port_layout);
break;
#endif
#ifdef SWPS_PEONY_COPPER
case PLATFORM_TYPE_PEONY_COPPER_GA:
gpio_rest_mux = peony_copper_gpio_rest_mux;
ioexp_layout = peony_copper_ioexp_layout;
port_layout = peony_copper_port_layout;
ioexp_total = ARRAY_SIZE(peony_copper_ioexp_layout);
port_total = ARRAY_SIZE(peony_copper_port_layout);
break;
#endif
default:
SWPS_ERR(" Invalid platform: %d (%s)\n",
platform_p->id, platform_p->name);
@ -1952,11 +2142,18 @@ __detect_issues_port(int minor_num) {
}
if (resync_channel_tier_2(tobj_p) < 0) {
if (check_channel_tier_1() < 0) {
alarm_msg_2_user(tobj_p, i2c_emsg);
return -2;;
goto get_target_issues_port;
}
}
/* Re-check again for i2c-gpio special case */
if (check_channel_tier_1() < 0) {
goto get_target_issues_port;
}
return 0;
get_target_issues_port:
alarm_msg_2_user(tobj_p, i2c_emsg);
return -2;
}
@ -2015,11 +2212,11 @@ _isolate_issues_port(int minor_num) {
static int
_reset_i2c_topology_tier_1(void) {
if (reset_mux_gpio() < 0) {
if (reset_mux_objs() < 0) {
SWPS_ERR("%s: reset MUX GPIO fail!\n", __func__);
return -1;
}
SWPS_DEBUG("%s: reset_mux_gpio OK.\n", __func__);
SWPS_DEBUG("%s: reset_mux_objs OK.\n", __func__);
if (resync_channel_tier_1() < 0) {
SWPS_ERR("%s: resync tier-1 channel fail!\n", __func__);
return -1;
@ -2596,6 +2793,15 @@ register_modctl_attr(struct device *device_p){
err_msg = "dev_attr_auto_config";
goto err_reg_modctl_attr;
}
if (device_create_file(device_p, &dev_attr_block_poll) < 0) {
err_msg = "dev_attr_block_poll";
goto err_reg_modctl_attr;
}
if (device_create_file(device_p, &dev_attr_io_no_init) < 0) {
err_msg = "dev_attr_io_no_init";
goto err_reg_modctl_attr;
}
return 0;
err_reg_modctl_attr:
@ -2619,13 +2825,19 @@ register_ioexp_attr(struct device *device_p,
goto err_reg_ioexp_attr;
}
break;
case IOEXP_TYPE_CYPRESS_NABC:
case IOEXP_TYPE_MAPLE_NABC:
case IOEXP_TYPE_GULMOHAR_NABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
if (register_ioexp_attr_sfp_2(device_p) < 0){
err_msg = "register_ioexp_attr_sfp_2 fail";
goto err_reg_ioexp_attr;
}
break;
case IOEXP_TYPE_MAGINOLIA_7AB:
case IOEXP_TYPE_SPRUCE_7AB:
case IOEXP_TYPE_CYPRESS_7ABC:
@ -2638,6 +2850,9 @@ register_ioexp_attr(struct device *device_p,
case IOEXP_TYPE_SEQUOIA_NABC:
case IOEXP_TYPE_LAVENDER_P65:
case IOEXP_TYPE_MAPLE_0ABC:
case IOEXP_TYPE_GULMOHAR_7ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
if (register_ioexp_attr_qsfp_1(device_p) < 0){
err_msg = "register_ioexp_attr_qsfp_1 fail";
goto err_reg_ioexp_attr;
@ -2732,7 +2947,7 @@ register_swp_module(void){
SWPS_WARN("Allocate CTL MAJOR failure! \n");
goto err_register_swp_module_1;
}
if (alloc_chrdev_region(&port_devt, 0, dev_total, SWP_CLS_NAME) < 0){
if (alloc_chrdev_region(&port_devt, 0, port_total, SWP_CLS_NAME) < 0){
SWPS_WARN("Allocate PORT MAJOR failure! \n");
goto err_register_swp_module_2;
}
@ -2863,13 +3078,13 @@ create_port_objs(void) {
/* Success */
ok_count++;
}
SWPS_INFO("%s: initialed %d port-dev",__func__, ok_count);
SWPS_INFO("%s: initialed %d port-dev\n",__func__, ok_count);
return 0;
err_initport_reg_device:
kfree(transvr_obj_p);
err_initport_create_tranobj:
clean_port_obj();
clean_port_objs();
SWPS_ERR("%s: %s", __func__, err_msg);
SWPS_ERR("Dump: <port_id>:%d <chan_id>:%d <ioexp_id>:%d <voffset>:%d <tvr_type>:%d <run_mod>:%d\n",
port_id, chan_id, ioexp_id, ioexp_virt_offset, transvr_type, run_mod);
@ -2942,6 +3157,7 @@ init_swps_common(void){
char *err_msg = "ERR";
block_polling = 0;
auto_config = 0;
if ((SWP_AUTOCONFIG_ENABLE) && (SWP_POLLING_ENABLE)){
auto_config = 1;
@ -2985,7 +3201,7 @@ swp_module_init(void){
if (create_port_objs() < 0){
goto err_init_portobj;
}
if (init_mux_gpio(gpio_rest_mux) < 0){
if (init_mux_objs(gpio_rest_mux) < 0){
goto err_init_mux;
}
if (init_dev_topology() < 0){
@ -2999,13 +3215,12 @@ swp_module_init(void){
err_init_topology:
clean_mux_gpio();
clean_mux_objs();
err_init_mux:
clean_port_obj();
clean_port_objs();
err_init_portobj:
clean_ioexp_objs();
err_init_ioexp:
class_unregister(swp_class_p);
class_destroy(swp_class_p);
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
@ -3019,10 +3234,9 @@ static void __exit
swp_module_exit(void){
clean_swps_common();
clean_port_obj();
clean_port_objs();
clean_ioexp_objs();
clean_mux_gpio();
class_unregister(swp_class_p);
clean_mux_objs();
class_destroy(swp_class_p);
unregister_chrdev_region(MKDEV(ctl_major, 0), 1);
unregister_chrdev_region(MKDEV(port_major, 0), port_total);
@ -3035,6 +3249,7 @@ MODULE_AUTHOR(SWP_AUTHOR);
MODULE_DESCRIPTION(SWP_DESC);
MODULE_VERSION(SWP_VERSION);
MODULE_LICENSE(SWP_LICENSE);
MODULE_SOFTDEP("pre: inv_platform");
module_init(swp_module_init);
module_exit(swp_module_exit);
@ -3047,3 +3262,5 @@ module_exit(swp_module_exit);

View File

@ -1,10 +1,3 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef INV_SWPS_H
#define INV_SWPS_H
@ -24,7 +17,7 @@
/* Module information */
#define SWP_AUTHOR "Neil <liao.neil@inventec.com>"
#define SWP_DESC "Inventec port and transceiver driver"
#define SWP_VERSION "4.2.9"
#define SWP_VERSION "C1-4.3.5"
#define SWP_LICENSE "GPL"
/* Module status define */
@ -52,9 +45,15 @@
#define PLATFORM_TYPE_LAVENDER_GA (181)
#define PLATFORM_TYPE_LAVENDER_ONL (182)
#define PLATFORM_TYPE_COTTONWOOD_RANGELEY (191)
#define PLATFORM_TYPE_MAPLE (201)
#define PLATFORM_TYPE_MAPLE_GA (201)
#define PLATFORM_TYPE_GULMOHAR_GA (202)
#define PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA (203)
#define PLATFORM_TYPE_PEONY_SFP_GA (204)
#define PLATFORM_TYPE_PEONY_COPPER_GA (205)
#define PLATFORM_TYPE_PEONY_AUTO (206)
#define PLATFORM_TYPE_MAPLE_B (207)
/* Current running platfrom */
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE
#define PLATFORM_SETTINGS PLATFORM_TYPE_MAPLE_B
/* Define platform flag and kernel version */
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_MAGNOLIA)
@ -99,12 +98,30 @@
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_COTTONWOOD_RANGELEY)
#define SWPS_COTTONWOOD_RANGELEY (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE)
#define SWPS_MAPLE (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_GA)
#define SWPS_MAPLE_GA (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_MAPLE_B)
#define SWPS_MAPLE_B (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_GA)
#define SWPS_GULMOHAR (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA)
#define SWPS_GULMOHAR_2T_EVT1 (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_SFP_GA)
#define SWPS_PEONY_SFP (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_COPPER_GA)
#define SWPS_PEONY_COPPER (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_PEONY_AUTO)
#define SWPS_PEONY_SFP (1)
#define SWPS_PEONY_COPPER (1)
#define SWPS_KERN_VER_AF_3_10 (1)
#endif
struct inv_platform_s {
int id;
char name[64];
@ -147,7 +164,13 @@ struct inv_platform_s platform_map[] = {
{PLATFORM_TYPE_LAVENDER_GA, "Lavender_GA" },
{PLATFORM_TYPE_LAVENDER_ONL, "Lavender_ONL" },
{PLATFORM_TYPE_COTTONWOOD_RANGELEY, "Cottonwood_RANGELEY" },
{PLATFORM_TYPE_MAPLE, "Maple" },
{PLATFORM_TYPE_MAPLE_GA, "Maple_GA" },
{PLATFORM_TYPE_MAPLE_B, "Maple_B" },
{PLATFORM_TYPE_GULMOHAR_GA, "Gulmohar_GA" },
{PLATFORM_TYPE_GULMOHAR_2T_EVT1_GA, "Gulmohar_2T_EVT1_GA" },
{PLATFORM_TYPE_PEONY_SFP_GA, "Peony_SFP_GA" },
{PLATFORM_TYPE_PEONY_COPPER_GA, "Peony_Copper_GA" },
{PLATFORM_TYPE_PEONY_AUTO, "Peony_Auto_Detect" },
};
@ -156,7 +179,7 @@ struct inv_platform_s platform_map[] = {
* ==========================================
*/
#ifdef SWPS_MAGNOLIA
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
unsigned magnolia_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
struct inv_ioexp_layout_s magnolia_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -248,7 +271,7 @@ struct inv_port_layout_s magnolia_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_REDWOOD
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
unsigned redwood_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
struct inv_ioexp_layout_s redwood_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -313,7 +336,7 @@ struct inv_port_layout_s redwood_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_HUDSON32I_GA
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
unsigned hudsin32iga_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
struct inv_ioexp_layout_s hudson32iga_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -378,7 +401,7 @@ struct inv_port_layout_s hudson32iga_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_SPRUCE
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
unsigned spruce_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
struct inv_ioexp_layout_s spruce_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -404,33 +427,33 @@ struct inv_port_layout_s spruce_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_CYPRESS_GA1
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
unsigned cypress_ga1_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
struct inv_ioexp_layout_s cypress_ga1_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
@ -507,29 +530,29 @@ unsigned cypress_ga2_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_ga2_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
@ -606,29 +629,29 @@ unsigned cypress_b_gpio_rest_mux = MUX_RST_GPIO_FORCE_HEDERA;
struct inv_ioexp_layout_s cypress_b_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_CYPRESS_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{0, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_CYPRESS_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_CYPRESS_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_CYPRESS_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_CYPRESS_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_CYPRESS_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_CYPRESS_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xc0}, {0xff, 0xc0}, }, /* addr[1] = I/O Expander 7 B */
@ -701,7 +724,7 @@ struct inv_port_layout_s cypress_b_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_REDWOOD_FSL
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PAC9548;
unsigned redwood_fsl_gpio_rest_mux = MUX_RST_GPIO_48_PCA9548;
struct inv_ioexp_layout_s redwood_fsl_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -801,7 +824,7 @@ struct inv_port_layout_s tahoe_port_layout[] = {
* ==========================================
*/
#ifdef SWPS_SEQUOIA
unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
unsigned sequoia_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
struct inv_ioexp_layout_s sequoia_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -917,7 +940,7 @@ struct inv_port_layout_s sequoia_port_layout[] = {
#if (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_GA)
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
#elif (PLATFORM_SETTINGS == PLATFORM_TYPE_LAVENDER_ONL)
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PAC9548;
unsigned lavender_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
#endif
#ifdef SWPS_LAVENDER
@ -1035,7 +1058,7 @@ struct inv_port_layout_s lavender_port_layout[] = {
* ===========================================================
*/
#ifdef SWPS_COTTONWOOD_RANGELEY
unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PAC9548;
unsigned cottonwood_rangeley_gpio_rest_mux = MUX_RST_GPIO_500_PCA9548;
struct inv_ioexp_layout_s cottonwood_rangeley_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
@ -1055,13 +1078,13 @@ struct inv_port_layout_s cottonwood_rangeley_port_layout[] = {
#endif
/* ===========================================================
* Maple Layout configuration
* Maple Layout configuration (Old)
* ===========================================================
*/
#ifdef SWPS_MAPLE
unsigned maple_gpio_rest_mux = 249;
#ifdef SWPS_MAPLE_GA
unsigned maple_ga_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
struct inv_ioexp_layout_s maple_ioexp_layout[] = {
struct inv_ioexp_layout_s maple_ga_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_MAPLE_0ABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */
@ -1093,7 +1116,7 @@ struct inv_ioexp_layout_s maple_ioexp_layout[] = {
},
};
struct inv_port_layout_s maple_port_layout[] = {
struct inv_port_layout_s maple_ga_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 18, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
{ 1, 19, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
@ -1154,6 +1177,438 @@ struct inv_port_layout_s maple_port_layout[] = {
};
#endif
/* ===========================================================
* Maple Layout configuration (B version)
* ===========================================================
*/
#ifdef SWPS_MAPLE_B
unsigned maple_b_gpio_rest_mux = MUX_RST_GPIO_69_PCA9548;
struct inv_ioexp_layout_s maple_b_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_MAPLE_0ABC, { { 6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0x00, 0x00}, }, /* addr[0] = I/O Expander 0 A */
{ 6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0xff}, }, /* addr[1] = I/O Expander 0 B */
{ 6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0x00, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
},
{1, IOEXP_TYPE_MAPLE_NABC, { { 7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{ 7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{ 7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_MAPLE_NABC, { { 8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{ 8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{ 8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_MAPLE_NABC, { { 9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{ 9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{ 9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_MAPLE_NABC, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_MAPLE_NABC, { {11, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{11, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{11, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_MAPLE_NABC, { {12, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{12, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{12, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
};
struct inv_port_layout_s maple_b_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 1, 23, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
{ 0, 22, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
{ 3, 25, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} },
{ 2, 24, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} },
{ 5, 27, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} },
{ 4, 26, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} },
{ 7, 29, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} },
{ 6, 28, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} },
{ 9, 31, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} },
{ 8, 30, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} },
{11, 33, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} },
{10, 32, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} },
{13, 35, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} },
{12, 34, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} },
{15, 37, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} },
{14, 36, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} },
{17, 39, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} },
{16, 38, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} },
{19, 41, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} },
{18, 40, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} },
{21, 43, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} },
{20, 42, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} },
{23, 45, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} },
{22, 44, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} },
{25, 47, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 42} },
{24, 46, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 41} },
{27, 49, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 44} },
{26, 48, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 43} },
{29, 51, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 50} },
{28, 50, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 49} },
{31, 53, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 52} },
{30, 52, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 51} },
{33, 55, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 58} },
{32, 54, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 57} },
{35, 57, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 60} },
{34, 56, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 59} },
{37, 59, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 62} },
{36, 58, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 61} },
{39, 61, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 64} },
{38, 60, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 63} },
{41, 63, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} },
{40, 62, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} },
{43, 65, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} },
{42, 64, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} },
{45, 67, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} },
{44, 66, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} },
{47, 69, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} },
{46, 68, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} },
{49, 15, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
{48, 14, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
{51, 17, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 97, 98, 99,100} },
{50, 16, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
{53, 19, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {105,106,107,108} },
{52, 18, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {113,114,115,116} },
{55, 21, 0, 7, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {125,126,127,128} },
{54, 20, 0, 6, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, {121,122,123,124} },
};
#endif
/* ==========================================
* Gulmohar Layout configuration
* ==========================================
*/
#ifdef SWPS_GULMOHAR
unsigned gulmohar_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
struct inv_ioexp_layout_s gulmohar_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_GULMOHAR_NABC, { {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_GULMOHAR_NABC, { {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_GULMOHAR_NABC, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_GULMOHAR_NABC, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_GULMOHAR_NABC, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_GULMOHAR_NABC, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_GULMOHAR_7ABC, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s gulmohar_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 1} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 2} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 3} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 4} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 5} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 6} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 7} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 8} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 9} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 10} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 11} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 12} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 21} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 22} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 23} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 24} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 33} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 34} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 35} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 36} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 37} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 38} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 39} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 40} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 41} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 42} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 43} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 44} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 49} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 50} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 51} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 52} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 53} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 54} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 55} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 56} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 65} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 66} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 67} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 68} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 69} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 70} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 71} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 72} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 81} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 82} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 83} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, { 84} },
{48, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 97, 98, 99,100} },
{49, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, { 85, 86, 87, 88} },
{50, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {101,102,103,104} },
{51, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {105,106,107,108} },
{52, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} },
{53, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {109,110,111,112} },
};
#endif
/* ==========================================
* Gulmohar_2T EVT1 Layout configuration
* ==========================================
*/
#ifdef SWPS_GULMOHAR_2T_EVT1
unsigned gulmohar_2t_evt1_gpio_rest_mux = MUX_RST_GPIO_505_PCA9548;
struct inv_ioexp_layout_s gulmohar_2t_evt1_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {2, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{2, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{2, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{1, IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC,{ {3, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{3, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[1] = I/O Expander N B */
{3, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC,{ {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xf3, 0xf3}, {0xf3, 0xf3}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC,{ {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xdd, 0xdd}, {0xdd, 0xdd}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC,{ {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[0] = I/O Expander 7 A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xda}, {0x18, 0xe3}, }, /* addr[1] = I/O Expander 7 B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xd6, 0xff}, {0x18, 0xff}, }, }, /* addr[2] = I/O Expander 7 C */
},
};
struct inv_port_layout_s gulmohar_2t_evt1_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 10, 0, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 1, 11, 0, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 2, 12, 0, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 3, 13, 0, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 4, 14, 0, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 5, 15, 0, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 6, 16, 0, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 7, 17, 0, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 8, 18, 1, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{ 9, 19, 1, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{10, 20, 1, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{11, 21, 1, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{12, 22, 1, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{13, 23, 1, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{14, 24, 1, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{15, 25, 1, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{16, 26, 2, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{17, 27, 2, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{18, 28, 2, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{19, 29, 2, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{20, 30, 2, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{21, 31, 2, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{22, 32, 2, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{23, 33, 2, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{24, 34, 3, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{25, 35, 3, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{26, 36, 3, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{27, 37, 3, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{28, 38, 3, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{29, 39, 3, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{30, 40, 3, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{31, 41, 3, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{32, 42, 4, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{33, 43, 4, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{34, 44, 4, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{35, 45, 4, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{36, 46, 4, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{37, 47, 4, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{38, 48, 4, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{39, 49, 4, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{40, 50, 5, 0, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{41, 51, 5, 1, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{42, 52, 5, 2, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{43, 53, 5, 3, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{44, 54, 5, 4, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{45, 55, 5, 5, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{46, 56, 5, 6, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{47, 57, 5, 7, TRANSVR_TYPE_SFP, BF_CHIP_TYPE_TOFINO, {-99} },
{48, 59, 6, 1, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{49, 58, 6, 0, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{50, 61, 6, 3, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{51, 60, 6, 2, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{52, 63, 6, 5, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{53, 62, 6, 4, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{54, 65, 6, 7, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
{55, 64, 6, 6, TRANSVR_TYPE_QSFP_28, BF_CHIP_TYPE_TOFINO, {-99,-99,-99,-99} },
};
#endif
/* ===========================================================
* Peony-SFP Layout configuration
* ===========================================================
*/
#ifdef SWPS_PEONY_SFP
unsigned peony_sfp_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL;
struct inv_ioexp_layout_s peony_sfp_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {4, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */
{4, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */
{4, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
},
{1, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {5, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{5, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{5, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{2, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {6, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{6, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{6, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{3, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {7, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{7, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{7, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{4, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {8, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{8, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{8, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{5, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {9, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{9, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{9, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
{6, IOEXP_TYPE_SFP_8P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[0] = I/O Expander N A */
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xf0}, {0xff, 0xf0}, }, /* addr[1] = I/O Expander N B */
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0x00, 0x00}, }, }, /* addr[2] = I/O Expander N C */
},
};
struct inv_port_layout_s peony_sfp_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{ 0, 20, 1, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 1} },
{ 1, 21, 1, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 2} },
{ 2, 22, 1, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 3} },
{ 3, 23, 1, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 4} },
{ 4, 24, 1, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 5} },
{ 5, 25, 1, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 6} },
{ 6, 26, 1, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 7} },
{ 7, 27, 1, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 8} },
{ 8, 28, 2, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 13} },
{ 9, 29, 2, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 14} },
{10, 30, 2, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 15} },
{11, 31, 2, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 16} },
{12, 32, 2, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 21} },
{13, 33, 2, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 22} },
{14, 34, 2, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 23} },
{15, 35, 2, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 24} },
{16, 36, 3, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 29} },
{17, 37, 3, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 30} },
{18, 38, 3, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 31} },
{19, 39, 3, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 32} },
{20, 40, 3, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 33} },
{21, 41, 3, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 34} },
{22, 42, 3, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 35} },
{23, 43, 3, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 36} },
{24, 44, 4, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 65} },
{25, 45, 4, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 66} },
{26, 46, 4, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 67} },
{27, 47, 4, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 68} },
{28, 48, 4, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 69} },
{29, 49, 4, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 70} },
{30, 50, 4, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 71} },
{31, 51, 4, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 72} },
{32, 52, 5, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 97} },
{33, 53, 5, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 98} },
{34, 54, 5, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, { 99} },
{35, 55, 5, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {100} },
{36, 56, 5, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {105} },
{37, 57, 5, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {106} },
{38, 58, 5, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {107} },
{39, 59, 5, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {108} },
{40, 60, 6, 0, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {113} },
{41, 61, 6, 1, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {114} },
{42, 62, 6, 2, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {115} },
{43, 63, 6, 3, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {116} },
{44, 64, 6, 4, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {121} },
{45, 65, 6, 5, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {122} },
{46, 66, 6, 6, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {123} },
{47, 67, 6, 7, TRANSVR_TYPE_SFP, BCM_CHIP_TYPE_TRIDENT_3, {124} },
{48, 12, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} },
{49, 13, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} },
{50, 14, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} },
{51, 15, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
{52, 16, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
{53, 17, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
};
#endif
/* ===========================================================
* Peony-Copper Layout configuration
* ===========================================================
*/
#ifdef SWPS_PEONY_COPPER
unsigned peony_copper_gpio_rest_mux = MUX_RST_CPLD_C0_A77_70_74_RST_ALL;
struct inv_ioexp_layout_s peony_copper_ioexp_layout[] = {
/* IOEXP_ID / IOEXP_TYPE / { Chan_ID, Chip_addr, Read_offset, Write_offset, config_offset, data_default, conf_default } */
{0, IOEXP_TYPE_QSFP_6P_LAYOUT_1, { {10, 0x20, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xc0, 0xc0}, }, /* addr[0] = I/O Expander 0 A */
{10, 0x21, {0, 1}, {2, 3}, {6, 7}, {0xff, 0xff}, {0xc0, 0xff}, }, /* addr[1] = I/O Expander 0 B */
{10, 0x22, {0, 1}, {2, 3}, {6, 7}, {0xc0, 0xff}, {0xff, 0xff}, }, }, /* addr[2] = I/O Expander 0 C */
},
};
struct inv_port_layout_s peony_copper_port_layout[] = {
/* Port_ID / Chan_ID / IOEXP_ID / IOEXP_VIRT_OFFSET / TRANSCEIVER_TYPE / BCM_CHIP_TYPE / LANE_ID */
{48, 4, 0, 0, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 49, 50, 51, 52} },
{49, 5, 0, 1, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 57, 58, 59, 60} },
{50, 6, 0, 2, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 61, 62, 63, 64} },
{51, 7, 0, 3, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 77, 78, 79, 80} },
{52, 8, 0, 4, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 85, 86, 87, 88} },
{53, 9, 0, 5, TRANSVR_TYPE_QSFP_28, BCM_CHIP_TYPE_TRIDENT_3, { 93, 94, 95, 96} },
};
#endif
#endif /* INV_SWPS_H */
@ -1162,3 +1617,5 @@ struct inv_port_layout_s maple_port_layout[] = {

View File

@ -2,9 +2,14 @@
#include <linux/i2c.h>
#include "io_expander.h"
/* For build single module using (Ex: ONL platform) */
#include <linux/module.h>
//#include <linux/inventec/d5254/io_expander.h>
static struct ioexp_obj_s *ioexp_head_p = NULL;
static struct ioexp_obj_s *ioexp_tail_p = NULL;
extern int io_no_init;
/* ========== Register IOEXP layout ==========
*/
@ -571,6 +576,7 @@ struct ioexp_map_s cpld_map_cottonwood = {
},
};
struct ioexp_map_s ioexp_map_maple_0abc = {
.chip_amount = 3,
@ -614,6 +620,7 @@ struct ioexp_map_s ioexp_map_maple_0abc = {
},
};
struct ioexp_map_s ioexp_map_maple_nabc = {
.chip_amount = 3,
@ -675,6 +682,440 @@ struct ioexp_map_s ioexp_map_maple_nabc = {
},
};
struct ioexp_map_s ioexp_map_gulmohar_nabc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
{0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
{1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
{1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
},
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
{0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
{1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
},
.map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
{1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
},
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
},
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
},
};
struct ioexp_map_s ioexp_map_gulmohar_7abc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */
{2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
},
.map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
{0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
{0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
{0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
{0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
{0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
},
.map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
{1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
{1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
{1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
{1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
{1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
},
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
{0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
{0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
{0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
{0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
{0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
},
};
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_nabc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
{0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
{0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
{0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
{1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
{1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
{1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
{1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
},
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
{0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
{0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
{1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
{1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
},
.map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
{0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
{1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
{1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
},
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
},
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
},
};
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_1abc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 2}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 0, 6}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{0, 1, 6}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{1, 1, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{1, 1, 5}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_tx_disable = { {0, 0, 1}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
{0, 0, 5}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
{0, 1, 1}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
{0, 1, 5}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
{1, 0, 2}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
{1, 0, 3}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
},
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
{0, 0, 4}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
{0, 1, 4}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
{1, 1, 1}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
},
.map_rxlos = { {0, 0, 3}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
{0, 1, 3}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
{1, 0, 6}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
},
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
},
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
},
};
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_3abc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 1, 4}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{0, 1, 5}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 0, 2}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 0, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{1, 1, 2}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{1, 1, 6}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_tx_disable = { {0, 0, 2}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
{0, 0, 3}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
{1, 0, 1}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
{1, 0, 5}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
{1, 1, 1}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
{1, 1, 5}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
},
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
{0, 1, 0}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
{0, 1, 1}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
{1, 0, 4}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
{1, 1, 0}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
{1, 1, 4}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
},
.map_rxlos = { {0, 0, 6}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
{0, 0, 7}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
{1, 0, 3}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
{1, 0, 7}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
{1, 1, 3}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
},
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
},
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
},
};
struct ioexp_map_s ioexp_map_gulmohar_2t_evt1_7abc = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 1, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{1, 0, 4}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 1, 1}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 1, 6}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{2, 0, 4}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{2, 1, 1}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_reset = { {0, 0, 1}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
{0, 0, 6}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
{0, 1, 3}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
{1, 0, 1}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
{1, 0, 6}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
{1, 1, 3}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
{2, 0, 1}, /* map_reset[6] = QRESET_QSFP_N_P(X+6) */
{2, 0, 6}, /* map_reset[7] = QRESET_QSFP_N_P(X+7) */
},
.map_lpmod = { {0, 0, 2}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
{0, 0, 7}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
{0, 1, 4}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
{1, 0, 2}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
{1, 0, 7}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
{1, 1, 4}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
{2, 0, 2}, /* map_lpmod[6] = LPMODE_QSFP_P(X+6) */
{2, 0, 7}, /* map_lpmod[7] = LPMODE_QSFP_P(X+7) */
},
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
{0, 0, 5}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
{0, 1, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
{1, 0, 0}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
{1, 0, 5}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
{1, 1, 2}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
{2, 0, 0}, /* map_modsel[6] = MODSEL_QSFP_N_P(X+6) */
{2, 0, 5}, /* map_modsel[7] = MODSEL_QSFP_N_P(X+7) */
},
};
/* PortType: SFP / 8 port
* Platform: Cypress, Peony_SFP
*/
struct ioexp_map_s ioexp_map_sfp_8p_layout_1 = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {0, 0, 4}, /* map_present[0] = MOD_ABS_PORT(X) */
{0, 0, 5}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{0, 0, 6}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{0, 0, 7}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{1, 0, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{1, 0, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
{1, 0, 6}, /* map_present[6] = MOD_ABS_PORT(X+6) */
{1, 0, 7}, /* map_present[7] = MOD_ABS_PORT(X+7) */
},
.map_tx_disable = { {0, 1, 0}, /* map_tx_disable[0] = TXDISABLE_SFP+_P(X) */
{0, 1, 1}, /* map_tx_disable[1] = TXDISABLE_SFP+_P(X+1) */
{0, 1, 2}, /* map_tx_disable[2] = TXDISABLE_SFP+_P(X+2) */
{0, 1, 3}, /* map_tx_disable[3] = TXDISABLE_SFP+_P(X+3) */
{1, 1, 0}, /* map_tx_disable[4] = TXDISABLE_SFP+_P(X+4) */
{1, 1, 1}, /* map_tx_disable[5] = TXDISABLE_SFP+_P(X+5) */
{1, 1, 2}, /* map_tx_disable[6] = TXDISABLE_SFP+_P(X+6) */
{1, 1, 3}, /* map_tx_disable[7] = TXDISABLE_SFP+_P(X+7) */
},
.map_tx_fault = { {0, 0, 0}, /* map_tx_fault[0] = TXFAULT_SFP+_P(X) */
{0, 0, 1}, /* map_tx_fault[1] = TXFAULT_SFP+_P(X+1) */
{0, 0, 2}, /* map_tx_fault[2] = TXFAULT_SFP+_P(X+2) */
{0, 0, 3}, /* map_tx_fault[3] = TXFAULT_SFP+_P(X+3) */
{1, 0, 0}, /* map_tx_fault[4] = TXFAULT_SFP+_P(X+4) */
{1, 0, 1}, /* map_tx_fault[5] = TXFAULT_SFP+_P(X+5) */
{1, 0, 2}, /* map_tx_fault[6] = TXFAULT_SFP+_P(X+6) */
{1, 0, 3}, /* map_tx_fault[7] = TXFAULT_SFP+_P(X+7) */
},
.map_rxlos = { {0, 1, 4}, /* map_rxlos[0] = OPRXLOS_PORT(X) */
{0, 1, 5}, /* map_rxlos[1] = OPRXLOS_PORT(X+1) */
{0, 1, 6}, /* map_rxlos[2] = OPRXLOS_PORT(X+2) */
{0, 1, 7}, /* map_rxlos[3] = OPRXLOS_PORT(X+3) */
{1, 1, 4}, /* map_rxlos[4] = OPRXLOS_PORT(X+4) */
{1, 1, 5}, /* map_rxlos[5] = OPRXLOS_PORT(X+5) */
{1, 1, 6}, /* map_rxlos[6] = OPRXLOS_PORT(X+6) */
{1, 1, 7}, /* map_rxlos[7] = OPRXLOS_PORT(X+7) */
},
.map_hard_rs0 = { {2, 0, 0}, /* map_hard_rs0[0] = RS0_SFP28_P(X) */
{2, 0, 2}, /* map_hard_rs0[1] = RS0_SFP28_P(X+1) */
{2, 0, 4}, /* map_hard_rs0[2] = RS0_SFP28_P(X+2) */
{2, 0, 6}, /* map_hard_rs0[3] = RS0_SFP28_P(X+3) */
{2, 1, 0}, /* map_hard_rs0[4] = RS0_SFP28_P(X+4) */
{2, 1, 2}, /* map_hard_rs0[5] = RS0_SFP28_P(X+5) */
{2, 1, 4}, /* map_hard_rs0[6] = RS0_SFP28_P(X+6) */
{2, 1, 6}, /* map_hard_rs0[7] = RS0_SFP28_P(X+7) */
},
.map_hard_rs1 = { {2, 0, 1}, /* map_hard_rs1[0] = RS1_SFP28_P(X) */
{2, 0, 3}, /* map_hard_rs1[1] = RS1_SFP28_P(X+1) */
{2, 0, 5}, /* map_hard_rs1[2] = RS1_SFP28_P(X+2) */
{2, 0, 7}, /* map_hard_rs1[3] = RS1_SFP28_P(X+3) */
{2, 1, 1}, /* map_hard_rs1[4] = RS1_SFP28_P(X+4) */
{2, 1, 3}, /* map_hard_rs1[5] = RS1_SFP28_P(X+5) */
{2, 1, 5}, /* map_hard_rs1[6] = RS1_SFP28_P(X+6) */
{2, 1, 7}, /* map_hard_rs1[7] = RS1_SFP28_P(X+7) */
},
};
/* PortType: QSFP / 6 port
* Platform: Gulmohar, Peony_SFP, Peony_Copper
*/
struct ioexp_map_s ioexp_map_6p_qsfp_type_1 = {
.chip_amount = 3,
.data_width = 2,
.map_present = { {2, 1, 0}, /* map_present[0] = MOD_ABS_PORT(X) */
{2, 1, 1}, /* map_present[1] = MOD_ABS_PORT(X+1) */
{2, 1, 2}, /* map_present[2] = MOD_ABS_PORT(X+2) */
{2, 1, 3}, /* map_present[3] = MOD_ABS_PORT(X+3) */
{2, 1, 4}, /* map_present[4] = MOD_ABS_PORT(X+4) */
{2, 1, 5}, /* map_present[5] = MOD_ABS_PORT(X+5) */
},
.map_reset = { {0, 1, 0}, /* map_reset[0] = QRESET_QSFP_N_P(X) */
{0, 1, 1}, /* map_reset[1] = QRESET_QSFP_N_P(X+1) */
{0, 1, 2}, /* map_reset[2] = QRESET_QSFP_N_P(X+2) */
{0, 1, 3}, /* map_reset[3] = QRESET_QSFP_N_P(X+3) */
{0, 1, 4}, /* map_reset[4] = QRESET_QSFP_N_P(X+4) */
{0, 1, 5}, /* map_reset[5] = QRESET_QSFP_N_P(X+5) */
},
.map_lpmod = { {1, 0, 0}, /* map_lpmod[0] = LPMODE_QSFP_P(X) */
{1, 0, 1}, /* map_lpmod[1] = LPMODE_QSFP_P(X+1) */
{1, 0, 2}, /* map_lpmod[2] = LPMODE_QSFP_P(X+2) */
{1, 0, 3}, /* map_lpmod[3] = LPMODE_QSFP_P(X+3) */
{1, 0, 4}, /* map_lpmod[4] = LPMODE_QSFP_P(X+4) */
{1, 0, 5}, /* map_lpmod[5] = LPMODE_QSFP_P(X+5) */
},
.map_modsel = { {0, 0, 0}, /* map_modsel[0] = MODSEL_QSFP_N_P(X) */
{0, 0, 1}, /* map_modsel[1] = MODSEL_QSFP_N_P(X+1) */
{0, 0, 2}, /* map_modsel[2] = MODSEL_QSFP_N_P(X+2) */
{0, 0, 3}, /* map_modsel[3] = MODSEL_QSFP_N_P(X+3) */
{0, 0, 4}, /* map_modsel[4] = MODSEL_QSFP_N_P(X+4) */
{0, 0, 5}, /* map_modsel[5] = MODSEL_QSFP_N_P(X+5) */
},
};
/* ========== Private functions ==========
*/
int check_channel_tier_1(void);
@ -1125,32 +1566,35 @@ common_ioexp_init(struct ioexp_obj_s *self) {
if (self->mode == IOEXP_MODE_DIRECT) {
goto update_common_ioexp_init;
}
/* Setup default value to each physical IO Expander */
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
/* Get address mapping */
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
if (!addr_p){
SWPS_ERR("%s: IOEXP config incorrect! <chip_id>:%d \n",
__func__, chip_id);
return -1;
}
/* Setup default value */
for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){
/* [Desc] Skip the setup default value behavior
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
*/
if(addr_p->write_offset[offset] < 0){
SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]);
continue;
if (!io_no_init) { /*normal init*/
/* Setup default value to each physical IO Expander */
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
/* Get address mapping */
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
if (!addr_p){
SWPS_ERR("%s: IOEXP config incorrect! <chip_id>:%d \n",
__func__, chip_id);
return -1;
}
err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id),
addr_p->write_offset[offset],
addr_p->data_default[offset]);
if (err_code < 0){
SWPS_ERR("%s: set default fail! <error>:%d \n",
__func__, err_code);
return ERR_IOEXP_UNEXCPT;
/* Setup default value */
for (offset=0; offset<(self->ioexp_map_p->data_width); offset++){
/* [Desc] Skip the setup default value behavior
[Note] Setup default value = -1 if you don't want to write the value to IOEXP or CPLD
*/
if(addr_p->write_offset[offset] < 0){
SWPS_DEBUG("skip a write_offset <%d>\n", addr_p->conf_offset[offset]);
continue;
}
err_code = i2c_smbus_write_byte_data(_get_i2c_client(self, chip_id),
addr_p->write_offset[offset],
addr_p->data_default[offset]);
if (err_code < 0){
SWPS_ERR("%s: set default fail! <error>:%d \n",
__func__, err_code);
return ERR_IOEXP_UNEXCPT;
}
}
}
}
@ -1171,24 +1615,56 @@ update_common_ioexp_init:
int
_is_channel_ready(struct ioexp_obj_s *self){
int buf = 0;
int chip_id = 0; /* Use first chip which be registered */
int data_id = 0; /* Use first byte which be registered */
struct ioexp_addr_s *ioexp_addr = NULL;
int chip_id = 0;
int byte_id = 0;
int getval = ERR_IOEXP_UNEXCPT;
int chkval = ERR_IOEXP_UNEXCPT;
char *emsg = "ERR";
struct ioexp_addr_s *addr_p = NULL;
ioexp_addr = &(self->ioexp_map_p->map_addr[chip_id]);
if (!ioexp_addr){
SWPS_ERR("%s: config incorrect!\n", __func__);
return ERR_IOEXP_UNEXCPT;
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++) {
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
if (!addr_p){
emsg = "IOEXP config incorrect";
goto err_is_channel_ready;
}
for (byte_id=0; byte_id<(self->ioexp_map_p->data_width); byte_id++) {
if (addr_p->conf_offset[byte_id] < 0) {
continue;
}
if ((addr_p->conf_default[byte_id]) != 0) {
goto go_is_channel_ready;
}
}
if (chip_id == ((self->ioexp_map_p->chip_amount) - 1)) {
SWPS_DEBUG("%s: no non-zero config", __func__);
break;
}
}
buf = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id),
ioexp_addr->read_offset[data_id]);
if (buf >= 0){
chip_id = 0;
byte_id = 0;
go_is_channel_ready:
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
chkval = addr_p->conf_default[byte_id];
getval = i2c_smbus_read_byte_data(_get_i2c_client(self, chip_id),
addr_p->conf_offset[byte_id]);
SWPS_DEBUG("%s: target info <ioexp>:%d <chip>:%d <byte>:%d <chkv>:%d <getv>:%d\n",
__func__, self->ioexp_id, chip_id, byte_id, chkval, getval);
if ((getval >= 0) && (getval == chkval)) {
return 1;
}
return 0;
err_is_channel_ready:
SWPS_ERR("%s: %s <ioexp>:%d <chip>:%d <byte>:%d <chkv>:%d <getv>:%d\n",
__func__, emsg, self->ioexp_id, chip_id, byte_id, chkval, getval);
return ERR_IOEXP_UNEXCPT;
}
int
_ioexp_init_handler(struct ioexp_obj_s *self){
@ -1395,8 +1871,6 @@ get_ioexp_map(int ioexp_type){
return &ioexp_map_hudson32iga_p01p08_p17p24;
case IOEXP_TYPE_HUDSON32IGA_P09P16:
return &ioexp_map_hudson32iga_p09p16_p25p32;
case IOEXP_TYPE_CYPRESS_NABC:
return &ioexp_map_cypress_nabc;
case IOEXP_TYPE_CYPRESS_7ABC:
return &ioexp_map_cypress_7abc;
case IOEXP_TYPE_TAHOE_5A:
@ -1413,6 +1887,22 @@ get_ioexp_map(int ioexp_type){
return &ioexp_map_maple_0abc;
case IOEXP_TYPE_MAPLE_NABC:
return &ioexp_map_maple_nabc;
case IOEXP_TYPE_GULMOHAR_NABC:
return &ioexp_map_gulmohar_nabc;
case IOEXP_TYPE_GULMOHAR_7ABC:
return &ioexp_map_gulmohar_7abc;
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
return &ioexp_map_gulmohar_2t_evt1_nabc;
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
return &ioexp_map_gulmohar_2t_evt1_1abc;
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
return &ioexp_map_gulmohar_2t_evt1_3abc;
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
return &ioexp_map_gulmohar_2t_evt1_7abc;
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
return &ioexp_map_sfp_8p_layout_1;
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
return &ioexp_map_6p_qsfp_type_1;
default:
return NULL;
}
@ -1497,8 +1987,13 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
self->set_hard_rs0 = ioexp_set_not_support;
self->set_hard_rs1 = ioexp_set_not_support;
return 0;
case IOEXP_TYPE_CYPRESS_NABC:
case IOEXP_TYPE_MAPLE_NABC:
case IOEXP_TYPE_GULMOHAR_NABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
self->get_present = common_get_present;
self->get_tx_fault = common_get_tx_fault;
self->get_rxlos = common_get_rxlos;
@ -1515,6 +2010,7 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
self->set_hard_rs0 = common_set_hard_rs0;
self->set_hard_rs1 = common_set_hard_rs1;
return 0;
case IOEXP_TYPE_MAGINOLIA_7AB:
case IOEXP_TYPE_SPRUCE_7AB:
case IOEXP_TYPE_REDWOOD_P01P08:
@ -1527,6 +2023,9 @@ setup_ioexp_public_cb(struct ioexp_obj_s *self,
case IOEXP_TYPE_SEQUOIA_NABC:
case IOEXP_TYPE_LAVENDER_P65:
case IOEXP_TYPE_MAPLE_0ABC:
case IOEXP_TYPE_GULMOHAR_7ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
self->get_present = common_get_present;
self->get_tx_fault = ioexp_get_not_support;
self->get_rxlos = ioexp_get_not_support;
@ -1565,7 +2064,6 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self,
case IOEXP_TYPE_REDWOOD_P09P16:
case IOEXP_TYPE_HUDSON32IGA_P01P08:
case IOEXP_TYPE_HUDSON32IGA_P09P16:
case IOEXP_TYPE_CYPRESS_NABC:
case IOEXP_TYPE_CYPRESS_7ABC:
case IOEXP_TYPE_TAHOE_5A:
case IOEXP_TYPE_TAHOE_6ABC:
@ -1574,6 +2072,14 @@ setup_ioexp_private_cb(struct ioexp_obj_s *self,
case CPLD_TYPE_COTTONWOOD:
case IOEXP_TYPE_MAPLE_NABC:
case IOEXP_TYPE_MAPLE_0ABC:
case IOEXP_TYPE_GULMOHAR_NABC:
case IOEXP_TYPE_GULMOHAR_7ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC:
case IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC:
case IOEXP_TYPE_SFP_8P_LAYOUT_1:
case IOEXP_TYPE_QSFP_6P_LAYOUT_1:
self->init = common_ioexp_init;
self->check = common_ioexp_check;
self->update_all = common_ioexp_update_all;
@ -1600,11 +2106,6 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
struct ioexp_i2c_s *i2c_curr_p = NULL;
int chan_id = self->ioexp_map_p->map_addr[chip_id].chan_id;
adap = i2c_get_adapter(chan_id);
if(!adap){
err_msg = "Can not get adap!";
goto err_ioexp_setup_i2c_1;
}
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client){
err_msg = "Can not kzalloc client!";
@ -1615,6 +2116,11 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
err_msg = "Can not kzalloc i2c_obj_p!";
goto err_ioexp_setup_i2c_2;
}
adap = i2c_get_adapter(chan_id);
if(!adap){
err_msg = "Can not get adap!";
goto err_ioexp_setup_i2c_3;
}
client->adapter = adap;
client->addr = self->ioexp_map_p->map_addr[chip_id].chip_addr;
i2c_obj_p->i2c_client_p = client;
@ -1631,6 +2137,8 @@ setup_i2c_client_one(struct ioexp_obj_s *self,
}
return 0;
err_ioexp_setup_i2c_3:
kfree(i2c_obj_p);
err_ioexp_setup_i2c_2:
kfree(client);
err_ioexp_setup_i2c_1:
@ -1661,6 +2169,11 @@ setup_ioexp_config(struct ioexp_obj_s *self) {
int chip_id, offset, err_code;
struct ioexp_addr_s *addr_p;
if (io_no_init) {
SWPS_INFO("io_no_init:%d \n", io_no_init);
return 0;
}
for (chip_id=0; chip_id<(self->ioexp_map_p->chip_amount); chip_id++){
addr_p = &(self->ioexp_map_p->map_addr[chip_id]);
@ -1743,7 +2256,10 @@ err_create_ioexp_setup_i2c_fail:
i2c_next_p = result_p->i2c_head_p;
while (i2c_curr_p){
i2c_next_p = i2c_curr_p->next;
kfree(i2c_curr_p->i2c_client_p);
if (i2c_curr_p->i2c_client_p) {
i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter);
kfree(i2c_curr_p->i2c_client_p);
}
kfree(i2c_curr_p);
i2c_curr_p = i2c_next_p;
}
@ -1778,6 +2294,7 @@ create_ioexp_obj(int ioexp_id,
ioexp_tail_p = ioexp_p;
return 0;
}
EXPORT_SYMBOL(create_ioexp_obj);
static int
@ -1818,7 +2335,6 @@ init_ioexp_objs(void){
* -1: Detect topology error
* -2: SWPS internal error
*/
struct ioexp_obj_s *curr_p = ioexp_head_p;
if (!curr_p) {
@ -1835,6 +2351,7 @@ init_ioexp_objs(void){
SWPS_DEBUG("%s: done.\n", __func__);
return 0;
}
EXPORT_SYMBOL(init_ioexp_objs);
void
@ -1861,7 +2378,10 @@ clean_ioexp_objs(void){
i2c_curr_p = ioexp_curr_p->i2c_head_p;
while (i2c_curr_p) {
i2c_next_p = i2c_curr_p->next;
kfree(i2c_curr_p->i2c_client_p);
if (i2c_curr_p->i2c_client_p) {
i2c_put_adapter(i2c_curr_p->i2c_client_p->adapter);
kfree(i2c_curr_p->i2c_client_p);
}
kfree(i2c_curr_p);
i2c_curr_p = i2c_next_p;
}
@ -1871,6 +2391,7 @@ clean_ioexp_objs(void){
ioexp_tail_p = NULL;
SWPS_DEBUG("%s: done.\n", __func__);
}
EXPORT_SYMBOL(clean_ioexp_objs);
int
@ -1888,6 +2409,7 @@ check_ioexp_objs(void){
}
return 0;
}
EXPORT_SYMBOL(check_ioexp_objs);
struct ioexp_obj_s *
@ -1905,6 +2427,7 @@ get_ioexp_obj(int ioexp_id){
}
return result_p;
}
EXPORT_SYMBOL(get_ioexp_obj);
void
@ -1917,7 +2440,7 @@ unlock_ioexp_all(void) {
ioexp_curr_p = ioexp_curr_p->next;
}
}
EXPORT_SYMBOL(unlock_ioexp_all);
int
lock_ioexp_all(void) {
@ -1930,6 +2453,7 @@ lock_ioexp_all(void) {
}
return 0;
}
EXPORT_SYMBOL(lock_ioexp_all);
int
@ -1941,6 +2465,7 @@ check_channel_tier_1(void) {
}
return 0;
}
EXPORT_SYMBOL(check_channel_tier_1);
static int
@ -2037,10 +2562,11 @@ err_resync_ioexp_status_1:
SWPS_ERR("%s: %s\n", __func__, emsg);
return -1;
}
EXPORT_SYMBOL(resync_channel_tier_1);
/* For build single module using (Ex: ONL platform) */
MODULE_LICENSE("GPL");

View File

@ -1,10 +1,3 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef IO_EXPANDER_H
#define IO_EXPANDER_H
@ -12,24 +5,31 @@
/* IOEXP type define (SFP series) */
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
#define IOEXP_TYPE_CYPRESS_NABC (10103)
#define IOEXP_TYPE_MAPLE_NABC (10104)
#define IOEXP_TYPE_MAGINOLIA_NAB (10101)
#define IOEXP_TYPE_MAGINOLIA_4AB (10102)
#define IOEXP_TYPE_MAPLE_NABC (10104)
#define IOEXP_TYPE_GULMOHAR_NABC (10105)
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_NABC (10106)
#define IOEXP_TYPE_SFP_8P_LAYOUT_1 (10107)
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_1ABC (10108)
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_3ABC (10109)
/* IOEXP type define (QSFP series) */
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
#define IOEXP_TYPE_SPRUCE_7AB (10206)
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
#define IOEXP_TYPE_TAHOE_5A (10208)
#define IOEXP_TYPE_TAHOE_6ABC (10209)
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
#define IOEXP_TYPE_LAVENDER_P65 (10211)
#define IOEXP_TYPE_MAPLE_0ABC (10212)
#define IOEXP_TYPE_MAGINOLIA_7AB (10201)
#define IOEXP_TYPE_REDWOOD_P01P08 (10202)
#define IOEXP_TYPE_REDWOOD_P09P16 (10203)
#define IOEXP_TYPE_HUDSON32IGA_P01P08 (10204)
#define IOEXP_TYPE_HUDSON32IGA_P09P16 (10205)
#define IOEXP_TYPE_SPRUCE_7AB (10206)
#define IOEXP_TYPE_CYPRESS_7ABC (10207)
#define IOEXP_TYPE_TAHOE_5A (10208)
#define IOEXP_TYPE_TAHOE_6ABC (10209)
#define IOEXP_TYPE_SEQUOIA_NABC (10210)
#define IOEXP_TYPE_LAVENDER_P65 (10211)
#define IOEXP_TYPE_MAPLE_0ABC (10212)
#define IOEXP_TYPE_GULMOHAR_7ABC (10213)
#define IOEXP_TYPE_GULMOHAR_2T_EVT1_7ABC (10214)
#define IOEXP_TYPE_QSFP_6P_LAYOUT_1 (10215)
/* CPLD type define */
#define CPLD_TYPE_COTTONWOOD (10301)
@ -87,8 +87,8 @@ struct ioexp_bitmap_s {
};
struct ioexp_map_s {
int chip_amount; /* Number of chips that IOEXP object content */
int data_width; /* Number of (Read/Write/Config) bytes */
int chip_amount; /* Number of chips that IOEXP object content */
int data_width; /* Number of (Read/Write/Config) bytes */
struct ioexp_addr_s *map_addr; /* Chip address info */
struct ioexp_bitmap_s map_present[10]; /* IOEXP for SFP / QSFP */
struct ioexp_bitmap_s map_tx_disable[10]; /* IOEXP for SFP */
@ -185,3 +185,5 @@ int resync_channel_tier_1(void);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,425 @@
/*
* pmbus.h - Common defines and structures for PMBus devices
*
* Copyright (c) 2010, 2011 Ericsson AB.
* Copyright (c) 2012 Guenter Roeck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef PMBUS_H
#define PMBUS_H
#include <linux/bitops.h>
#include <linux/regulator/driver.h>
/*
* Registers
*/
enum pmbus_regs {
PMBUS_PAGE = 0x00,
PMBUS_OPERATION = 0x01,
PMBUS_ON_OFF_CONFIG = 0x02,
PMBUS_CLEAR_FAULTS = 0x03,
PMBUS_PHASE = 0x04,
PMBUS_CAPABILITY = 0x19,
PMBUS_QUERY = 0x1A,
PMBUS_VOUT_MODE = 0x20,
PMBUS_VOUT_COMMAND = 0x21,
PMBUS_VOUT_TRIM = 0x22,
PMBUS_VOUT_CAL_OFFSET = 0x23,
PMBUS_VOUT_MAX = 0x24,
PMBUS_VOUT_MARGIN_HIGH = 0x25,
PMBUS_VOUT_MARGIN_LOW = 0x26,
PMBUS_VOUT_TRANSITION_RATE = 0x27,
PMBUS_VOUT_DROOP = 0x28,
PMBUS_VOUT_SCALE_LOOP = 0x29,
PMBUS_VOUT_SCALE_MONITOR = 0x2A,
PMBUS_COEFFICIENTS = 0x30,
PMBUS_POUT_MAX = 0x31,
PMBUS_FAN_CONFIG_12 = 0x3A,
PMBUS_FAN_COMMAND_1 = 0x3B,
PMBUS_FAN_COMMAND_2 = 0x3C,
PMBUS_FAN_CONFIG_34 = 0x3D,
PMBUS_FAN_COMMAND_3 = 0x3E,
PMBUS_FAN_COMMAND_4 = 0x3F,
PMBUS_VOUT_OV_FAULT_LIMIT = 0x40,
PMBUS_VOUT_OV_FAULT_RESPONSE = 0x41,
PMBUS_VOUT_OV_WARN_LIMIT = 0x42,
PMBUS_VOUT_UV_WARN_LIMIT = 0x43,
PMBUS_VOUT_UV_FAULT_LIMIT = 0x44,
PMBUS_VOUT_UV_FAULT_RESPONSE = 0x45,
PMBUS_IOUT_OC_FAULT_LIMIT = 0x46,
PMBUS_IOUT_OC_FAULT_RESPONSE = 0x47,
PMBUS_IOUT_OC_LV_FAULT_LIMIT = 0x48,
PMBUS_IOUT_OC_LV_FAULT_RESPONSE = 0x49,
PMBUS_IOUT_OC_WARN_LIMIT = 0x4A,
PMBUS_IOUT_UC_FAULT_LIMIT = 0x4B,
PMBUS_IOUT_UC_FAULT_RESPONSE = 0x4C,
PMBUS_OT_FAULT_LIMIT = 0x4F,
PMBUS_OT_FAULT_RESPONSE = 0x50,
PMBUS_OT_WARN_LIMIT = 0x51,
PMBUS_UT_WARN_LIMIT = 0x52,
PMBUS_UT_FAULT_LIMIT = 0x53,
PMBUS_UT_FAULT_RESPONSE = 0x54,
PMBUS_VIN_OV_FAULT_LIMIT = 0x55,
PMBUS_VIN_OV_FAULT_RESPONSE = 0x56,
PMBUS_VIN_OV_WARN_LIMIT = 0x57,
PMBUS_VIN_UV_WARN_LIMIT = 0x58,
PMBUS_VIN_UV_FAULT_LIMIT = 0x59,
PMBUS_IIN_OC_FAULT_LIMIT = 0x5B,
PMBUS_IIN_OC_WARN_LIMIT = 0x5D,
PMBUS_POUT_OP_FAULT_LIMIT = 0x68,
PMBUS_POUT_OP_WARN_LIMIT = 0x6A,
PMBUS_PIN_OP_WARN_LIMIT = 0x6B,
PMBUS_STATUS_BYTE = 0x78,
PMBUS_STATUS_WORD = 0x79,
PMBUS_STATUS_VOUT = 0x7A,
PMBUS_STATUS_IOUT = 0x7B,
PMBUS_STATUS_INPUT = 0x7C,
PMBUS_STATUS_TEMPERATURE = 0x7D,
PMBUS_STATUS_CML = 0x7E,
PMBUS_STATUS_OTHER = 0x7F,
PMBUS_STATUS_MFR_SPECIFIC = 0x80,
PMBUS_STATUS_FAN_12 = 0x81,
PMBUS_STATUS_FAN_34 = 0x82,
PMBUS_READ_VIN = 0x88,
PMBUS_READ_IIN = 0x89,
PMBUS_READ_VCAP = 0x8A,
PMBUS_READ_VOUT = 0x8B,
PMBUS_READ_IOUT = 0x8C,
PMBUS_READ_TEMPERATURE_1 = 0x8D,
PMBUS_READ_TEMPERATURE_2 = 0x8E,
PMBUS_READ_TEMPERATURE_3 = 0x8F,
PMBUS_READ_FAN_SPEED_1 = 0x90,
PMBUS_READ_FAN_SPEED_2 = 0x91,
PMBUS_READ_FAN_SPEED_3 = 0x92,
PMBUS_READ_FAN_SPEED_4 = 0x93,
PMBUS_READ_DUTY_CYCLE = 0x94,
PMBUS_READ_FREQUENCY = 0x95,
PMBUS_READ_POUT = 0x96,
PMBUS_READ_PIN = 0x97,
PMBUS_REVISION = 0x98,
PMBUS_MFR_ID = 0x99,
PMBUS_MFR_MODEL = 0x9A,
PMBUS_MFR_REVISION = 0x9B,
PMBUS_MFR_LOCATION = 0x9C,
PMBUS_MFR_DATE = 0x9D,
PMBUS_MFR_SERIAL = 0x9E,
/*
* Virtual registers.
* Useful to support attributes which are not supported by standard PMBus
* registers but exist as manufacturer specific registers on individual chips.
* Must be mapped to real registers in device specific code.
*
* Semantics:
* Virtual registers are all word size.
* READ registers are read-only; writes are either ignored or return an error.
* RESET registers are read/write. Reading reset registers returns zero
* (used for detection), writing any value causes the associated history to be
* reset.
* Virtual registers have to be handled in device specific driver code. Chip
* driver code returns non-negative register values if a virtual register is
* supported, or a negative error code if not. The chip driver may return
* -ENODATA or any other error code in this case, though an error code other
* than -ENODATA is handled more efficiently and thus preferred. Either case,
* the calling PMBus core code will abort if the chip driver returns an error
* code when reading or writing virtual registers.
*/
PMBUS_VIRT_BASE = 0x100,
PMBUS_VIRT_READ_TEMP_AVG,
PMBUS_VIRT_READ_TEMP_MIN,
PMBUS_VIRT_READ_TEMP_MAX,
PMBUS_VIRT_RESET_TEMP_HISTORY,
PMBUS_VIRT_READ_VIN_AVG,
PMBUS_VIRT_READ_VIN_MIN,
PMBUS_VIRT_READ_VIN_MAX,
PMBUS_VIRT_RESET_VIN_HISTORY,
PMBUS_VIRT_READ_IIN_AVG,
PMBUS_VIRT_READ_IIN_MIN,
PMBUS_VIRT_READ_IIN_MAX,
PMBUS_VIRT_RESET_IIN_HISTORY,
PMBUS_VIRT_READ_PIN_AVG,
PMBUS_VIRT_READ_PIN_MIN,
PMBUS_VIRT_READ_PIN_MAX,
PMBUS_VIRT_RESET_PIN_HISTORY,
PMBUS_VIRT_READ_POUT_AVG,
PMBUS_VIRT_READ_POUT_MIN,
PMBUS_VIRT_READ_POUT_MAX,
PMBUS_VIRT_RESET_POUT_HISTORY,
PMBUS_VIRT_READ_VOUT_AVG,
PMBUS_VIRT_READ_VOUT_MIN,
PMBUS_VIRT_READ_VOUT_MAX,
PMBUS_VIRT_RESET_VOUT_HISTORY,
PMBUS_VIRT_READ_IOUT_AVG,
PMBUS_VIRT_READ_IOUT_MIN,
PMBUS_VIRT_READ_IOUT_MAX,
PMBUS_VIRT_RESET_IOUT_HISTORY,
PMBUS_VIRT_READ_TEMP2_AVG,
PMBUS_VIRT_READ_TEMP2_MIN,
PMBUS_VIRT_READ_TEMP2_MAX,
PMBUS_VIRT_RESET_TEMP2_HISTORY,
PMBUS_VIRT_READ_VMON,
PMBUS_VIRT_VMON_UV_WARN_LIMIT,
PMBUS_VIRT_VMON_OV_WARN_LIMIT,
PMBUS_VIRT_VMON_UV_FAULT_LIMIT,
PMBUS_VIRT_VMON_OV_FAULT_LIMIT,
PMBUS_VIRT_STATUS_VMON,
};
/*
* OPERATION
*/
#define PB_OPERATION_CONTROL_ON BIT(7)
/*
* CAPABILITY
*/
#define PB_CAPABILITY_SMBALERT BIT(4)
#define PB_CAPABILITY_ERROR_CHECK BIT(7)
/*
* VOUT_MODE
*/
#define PB_VOUT_MODE_MODE_MASK 0xe0
#define PB_VOUT_MODE_PARAM_MASK 0x1f
#define PB_VOUT_MODE_LINEAR 0x00
#define PB_VOUT_MODE_VID 0x20
#define PB_VOUT_MODE_DIRECT 0x40
/*
* Fan configuration
*/
#define PB_FAN_2_PULSE_MASK (BIT(0) | BIT(1))
#define PB_FAN_2_RPM BIT(2)
#define PB_FAN_2_INSTALLED BIT(3)
#define PB_FAN_1_PULSE_MASK (BIT(4) | BIT(5))
#define PB_FAN_1_RPM BIT(6)
#define PB_FAN_1_INSTALLED BIT(7)
/*
* STATUS_BYTE, STATUS_WORD (lower)
*/
#define PB_STATUS_NONE_ABOVE BIT(0)
#define PB_STATUS_CML BIT(1)
#define PB_STATUS_TEMPERATURE BIT(2)
#define PB_STATUS_VIN_UV BIT(3)
#define PB_STATUS_IOUT_OC BIT(4)
#define PB_STATUS_VOUT_OV BIT(5)
#define PB_STATUS_OFF BIT(6)
#define PB_STATUS_BUSY BIT(7)
/*
* STATUS_WORD (upper)
*/
#define PB_STATUS_UNKNOWN BIT(8)
#define PB_STATUS_OTHER BIT(9)
#define PB_STATUS_FANS BIT(10)
#define PB_STATUS_POWER_GOOD_N BIT(11)
#define PB_STATUS_WORD_MFR BIT(12)
#define PB_STATUS_INPUT BIT(13)
#define PB_STATUS_IOUT_POUT BIT(14)
#define PB_STATUS_VOUT BIT(15)
/*
* STATUS_IOUT
*/
#define PB_POUT_OP_WARNING BIT(0)
#define PB_POUT_OP_FAULT BIT(1)
#define PB_POWER_LIMITING BIT(2)
#define PB_CURRENT_SHARE_FAULT BIT(3)
#define PB_IOUT_UC_FAULT BIT(4)
#define PB_IOUT_OC_WARNING BIT(5)
#define PB_IOUT_OC_LV_FAULT BIT(6)
#define PB_IOUT_OC_FAULT BIT(7)
/*
* STATUS_VOUT, STATUS_INPUT
*/
#define PB_VOLTAGE_UV_FAULT BIT(4)
#define PB_VOLTAGE_UV_WARNING BIT(5)
#define PB_VOLTAGE_OV_WARNING BIT(6)
#define PB_VOLTAGE_OV_FAULT BIT(7)
/*
* STATUS_INPUT
*/
#define PB_PIN_OP_WARNING BIT(0)
#define PB_IIN_OC_WARNING BIT(1)
#define PB_IIN_OC_FAULT BIT(2)
/*
* STATUS_TEMPERATURE
*/
#define PB_TEMP_UT_FAULT BIT(4)
#define PB_TEMP_UT_WARNING BIT(5)
#define PB_TEMP_OT_WARNING BIT(6)
#define PB_TEMP_OT_FAULT BIT(7)
/*
* STATUS_FAN
*/
#define PB_FAN_AIRFLOW_WARNING BIT(0)
#define PB_FAN_AIRFLOW_FAULT BIT(1)
#define PB_FAN_FAN2_SPEED_OVERRIDE BIT(2)
#define PB_FAN_FAN1_SPEED_OVERRIDE BIT(3)
#define PB_FAN_FAN2_WARNING BIT(4)
#define PB_FAN_FAN1_WARNING BIT(5)
#define PB_FAN_FAN2_FAULT BIT(6)
#define PB_FAN_FAN1_FAULT BIT(7)
/*
* CML_FAULT_STATUS
*/
#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0)
#define PB_CML_FAULT_OTHER_COMM BIT(1)
#define PB_CML_FAULT_PROCESSOR BIT(3)
#define PB_CML_FAULT_MEMORY BIT(4)
#define PB_CML_FAULT_PACKET_ERROR BIT(5)
#define PB_CML_FAULT_INVALID_DATA BIT(6)
#define PB_CML_FAULT_INVALID_COMMAND BIT(7)
enum pmbus_sensor_classes {
PSC_VOLTAGE_IN = 0,
PSC_VOLTAGE_OUT,
PSC_CURRENT_IN,
PSC_CURRENT_OUT,
PSC_POWER,
PSC_TEMPERATURE,
PSC_FAN,
PSC_NUM_CLASSES /* Number of power sensor classes */
};
#define PMBUS_PAGES 32 /* Per PMBus specification */
/* Functionality bit mask */
#define PMBUS_HAVE_VIN BIT(0)
#define PMBUS_HAVE_VCAP BIT(1)
#define PMBUS_HAVE_VOUT BIT(2)
#define PMBUS_HAVE_IIN BIT(3)
#define PMBUS_HAVE_IOUT BIT(4)
#define PMBUS_HAVE_PIN BIT(5)
#define PMBUS_HAVE_POUT BIT(6)
#define PMBUS_HAVE_FAN12 BIT(7)
#define PMBUS_HAVE_FAN34 BIT(8)
#define PMBUS_HAVE_TEMP BIT(9)
#define PMBUS_HAVE_TEMP2 BIT(10)
#define PMBUS_HAVE_TEMP3 BIT(11)
#define PMBUS_HAVE_STATUS_VOUT BIT(12)
#define PMBUS_HAVE_STATUS_IOUT BIT(13)
#define PMBUS_HAVE_STATUS_INPUT BIT(14)
#define PMBUS_HAVE_STATUS_TEMP BIT(15)
#define PMBUS_HAVE_STATUS_FAN12 BIT(16)
#define PMBUS_HAVE_STATUS_FAN34 BIT(17)
#define PMBUS_HAVE_VMON BIT(18)
#define PMBUS_HAVE_STATUS_VMON BIT(19)
enum pmbus_data_format { linear = 0, direct, vid };
enum vrm_version { vr11 = 0, vr12, vr13 };
struct pmbus_driver_info {
int pages; /* Total number of pages */
enum pmbus_data_format format[PSC_NUM_CLASSES];
enum vrm_version vrm_version;
/*
* Support one set of coefficients for each sensor type
* Used for chips providing data in direct mode.
*/
int m[PSC_NUM_CLASSES]; /* mantissa for direct data format */
int b[PSC_NUM_CLASSES]; /* offset */
int R[PSC_NUM_CLASSES]; /* exponent */
u32 func[PMBUS_PAGES]; /* Functionality, per page */
/*
* The following functions map manufacturing specific register values
* to PMBus standard register values. Specify only if mapping is
* necessary.
* Functions return the register value (read) or zero (write) if
* successful. A return value of -ENODATA indicates that there is no
* manufacturer specific register, but that a standard PMBus register
* may exist. Any other negative return value indicates that the
* register does not exist, and that no attempt should be made to read
* the standard register.
*/
int (*read_byte_data)(struct i2c_client *client, int page, int reg);
int (*read_word_data)(struct i2c_client *client, int page, int reg);
int (*write_word_data)(struct i2c_client *client, int page, int reg,
u16 word);
int (*write_byte)(struct i2c_client *client, int page, u8 value);
/*
* The identify function determines supported PMBus functionality.
* This function is only necessary if a chip driver supports multiple
* chips, and the chip functionality is not pre-determined.
*/
int (*identify)(struct i2c_client *client,
struct pmbus_driver_info *info);
/* Regulator functionality, if supported by this chip driver. */
int num_regulators;
const struct regulator_desc *reg_desc;
};
/* Regulator ops */
extern const struct regulator_ops pmbus_regulator_ops;
/* Macro for filling in array of struct regulator_desc */
#define PMBUS_REGULATOR(_name, _id) \
[_id] = { \
.name = (_name # _id), \
.id = (_id), \
.of_match = of_match_ptr(_name # _id), \
.regulators_node = of_match_ptr("regulators"), \
.ops = &pmbus_regulator_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
/* Function declarations */
void pmbus_clear_cache(struct i2c_client *client);
int pmbus_set_page(struct i2c_client *client, u8 page);
int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg);
int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word);
int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg);
int pmbus_write_byte(struct i2c_client *client, int page, u8 value);
int pmbus_write_byte_data(struct i2c_client *client, int page, u8 reg,
u8 value);
int pmbus_update_byte_data(struct i2c_client *client, int page, u8 reg,
u8 mask, u8 value);
void pmbus_clear_faults(struct i2c_client *client);
bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg);
bool pmbus_check_word_register(struct i2c_client *client, int page, int reg);
int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
struct pmbus_driver_info *info);
int pmbus_do_remove(struct i2c_client *client);
const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client
*client);
#endif /* PMBUS_H */

View File

@ -1,10 +1,3 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/kobject.h>
@ -12,7 +5,12 @@
#include "io_expander.h"
#include "transceiver.h"
/* For build single module using (Ex: ONL platform) */
#include <linux/module.h>
//#include <linux/inventec/d5254/io_expander.h>
//#include <linux/inventec/d5254/transceiver.h>
extern int io_no_init;
/* ========== Register EEPROM address mapping ==========
*/
struct eeprom_map_s eeprom_map_sfp = {
@ -152,7 +150,7 @@ alarm_msg_2_user(struct transvr_obj_s *self,
SWPS_ERR("%s on %s.\n", emsg, self->swp_name);
}
EXPORT_SYMBOL(alarm_msg_2_user);
/* ========== Private functions ==========
*/
@ -181,6 +179,7 @@ lock_transvr_obj(struct transvr_obj_s *self) {
mutex_lock(&self->lock);
self->curr_page = VAL_TRANSVR_PAGE_FREE;
}
EXPORT_SYMBOL(lock_transvr_obj);
void
@ -189,6 +188,7 @@ unlock_transvr_obj(struct transvr_obj_s *self) {
self->curr_page = VAL_TRANSVR_PAGE_FREE;
mutex_unlock(&self->lock);
}
EXPORT_SYMBOL(unlock_transvr_obj);
static int
@ -4833,6 +4833,11 @@ _taskfunc_qsfp_setup_power_mod(struct transvr_obj_s *self,
int curr_val = DEBUG_TRANSVR_INT_VAL;
int err_val = DEBUG_TRANSVR_INT_VAL;
char *err_msg = DEBUG_TRANSVR_STR_VAL;
if (io_no_init) {
SWPS_INFO("%s no_io_init\n",__func__);
return EVENT_TRANSVR_TASK_DONE;
}
curr_val = self->ioexp_obj_p->get_lpmod(self->ioexp_obj_p,
self->ioexp_virt_offset);
@ -8259,6 +8264,7 @@ err_create_transvr_fail:
__func__, err_msg, chan_id, ioexp_virt_offset, transvr_type);
return NULL;
}
EXPORT_SYMBOL(create_transvr_obj);
static int
@ -8290,11 +8296,17 @@ _reload_transvr_obj(struct transvr_obj_s *self,
if (setup_transvr_private_cb(self, new_type) < 0){
goto err_private_reload_func_3;
}
if(old_i2c_p){
i2c_put_adapter(old_i2c_p->adapter);
}
kfree(old_i2c_p);
return 0;
err_private_reload_func_3:
SWPS_INFO("%s: init() fail!\n", __func__);
if(old_i2c_p){
i2c_put_adapter(old_i2c_p->adapter);
}
kfree(old_i2c_p);
self->state = STATE_TRANSVR_UNEXCEPTED;
self->type = TRANSVR_TYPE_ERROR;
@ -8341,6 +8353,7 @@ isolate_transvr_obj(struct transvr_obj_s *self) {
SWPS_INFO("%s: %s be isolated\n", __func__, self->swp_name);
return 0;
}
EXPORT_SYMBOL(isolate_transvr_obj);
int
@ -8359,6 +8372,10 @@ resync_channel_tier_2(struct transvr_obj_s *self) {
}
return 0;
}
EXPORT_SYMBOL(resync_channel_tier_2);
/* For build single module using (Ex: ONL platform) */
MODULE_LICENSE("GPL");
/* -----------------------------------------
@ -8387,3 +8404,5 @@ resync_channel_tier_2(struct transvr_obj_s *self) {

View File

@ -1,10 +1,3 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef TRANSCEIVER_H
#define TRANSCEIVER_H
@ -813,3 +806,4 @@ void alarm_msg_2_user(struct transvr_obj_s *self, char *emsg);

View File

@ -0,0 +1,247 @@
/*
* Hardware monitoring driver for UCD90xxx Sequencer and System Health
* Controller series
*
* Copyright (C) 2011 Ericsson AB.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c/pmbus.h>
#include "pmbus.h"
enum chips { ucd9000, ucd90120, ucd90124, ucd90160, ucd9090, ucd90910 };
#define UCD9000_MONITOR_CONFIG 0xd5
#define UCD9000_NUM_PAGES 0xd6
#define UCD9000_FAN_CONFIG_INDEX 0xe7
#define UCD9000_FAN_CONFIG 0xe8
#define UCD9000_DEVICE_ID 0xfd
#define UCD9000_MON_TYPE(x) (((x) >> 5) & 0x07)
#define UCD9000_MON_PAGE(x) ((x) & 0x0f)
#define UCD9000_MON_VOLTAGE 1
#define UCD9000_MON_TEMPERATURE 2
#define UCD9000_MON_CURRENT 3
#define UCD9000_MON_VOLTAGE_HW 4
#define UCD9000_NUM_FAN 4
struct ucd9000_data {
u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
struct pmbus_driver_info info;
};
#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
{
int fan_config = 0;
struct ucd9000_data *data
= to_ucd9000_data(pmbus_get_driver_info(client));
if (data->fan_data[fan][3] & 1)
fan_config |= PB_FAN_2_INSTALLED; /* Use lower bit position */
/* Pulses/revolution */
fan_config |= (data->fan_data[fan][3] & 0x06) >> 1;
return fan_config;
}
static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg)
{
int ret = 0;
int fan_config;
switch (reg) {
case PMBUS_FAN_CONFIG_12:
if (page > 0)
return -ENXIO;
ret = ucd9000_get_fan_config(client, 0);
if (ret < 0)
return ret;
fan_config = ret << 4;
ret = ucd9000_get_fan_config(client, 1);
if (ret < 0)
return ret;
fan_config |= ret;
ret = fan_config;
break;
case PMBUS_FAN_CONFIG_34:
if (page > 0)
return -ENXIO;
ret = ucd9000_get_fan_config(client, 2);
if (ret < 0)
return ret;
fan_config = ret << 4;
ret = ucd9000_get_fan_config(client, 3);
if (ret < 0)
return ret;
fan_config |= ret;
ret = fan_config;
break;
default:
ret = -ENODATA;
break;
}
return ret;
}
static const struct i2c_device_id ucd9000_id[] = {
{"ucd9000", ucd9000},
{"ucd90120", ucd90120},
{"ucd90124", ucd90124},
{"ucd90160", ucd90160},
{"ucd9090", ucd9090},
{"ucd90910", ucd90910},
{}
};
MODULE_DEVICE_TABLE(i2c, ucd9000_id);
static int ucd9000_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
struct ucd9000_data *data;
struct pmbus_driver_info *info;
const struct i2c_device_id *mid;
int i, ret;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA))
return -ENODEV;
ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID,
block_buffer);
if (ret < 0) {
dev_err(&client->dev, "Failed to read device ID\n");
return ret;
}
block_buffer[ret] = '\0';
dev_info(&client->dev, "Device ID %s\n", block_buffer);
for (mid = ucd9000_id; mid->name[0]; mid++) {
if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
break;
}
if (!mid->name[0]) {
dev_err(&client->dev, "Unsupported device\n");
return -ENODEV;
}
if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data)
dev_notice(&client->dev,
"Device mismatch: Configured %s, detected %s\n",
id->name, mid->name);
data = devm_kzalloc(&client->dev, sizeof(struct ucd9000_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
info = &data->info;
ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES);
if (ret < 0) {
dev_err(&client->dev,
"Failed to read number of active pages\n");
return ret;
}
info->pages = ret;
if (!info->pages) {
dev_err(&client->dev, "No pages configured\n");
return -ENODEV;
}
/* The internal temperature sensor is always active */
info->func[0] = PMBUS_HAVE_TEMP;
/* Everything else is configurable */
ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG,
block_buffer);
if (ret <= 0) {
dev_err(&client->dev, "Failed to read configuration data\n");
return -ENODEV;
}
for (i = 0; i < ret; i++) {
int page = UCD9000_MON_PAGE(block_buffer[i]);
if (page >= info->pages)
continue;
switch (UCD9000_MON_TYPE(block_buffer[i])) {
case UCD9000_MON_VOLTAGE:
case UCD9000_MON_VOLTAGE_HW:
info->func[page] |= PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT;
break;
case UCD9000_MON_TEMPERATURE:
info->func[page] |= PMBUS_HAVE_TEMP2
| PMBUS_HAVE_STATUS_TEMP;
break;
case UCD9000_MON_CURRENT:
info->func[page] |= PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT;
break;
default:
break;
}
}
/* Fan configuration */
if (mid->driver_data == ucd90124) {
for (i = 0; i < UCD9000_NUM_FAN; i++) {
i2c_smbus_write_byte_data(client,
UCD9000_FAN_CONFIG_INDEX, i);
ret = i2c_smbus_read_block_data(client,
UCD9000_FAN_CONFIG,
data->fan_data[i]);
if (ret < 0)
return ret;
}
i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0);
info->read_byte_data = ucd9000_read_byte_data;
info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
| PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
}
return pmbus_do_probe(client, mid, info);
}
/* This is the driver that will be inserted */
static struct i2c_driver ucd9000_driver = {
.driver = {
.name = "ucd9000",
},
.probe = ucd9000_probe,
.remove = pmbus_do_remove,
.id_table = ucd9000_id,
};
module_i2c_driver(ucd9000_driver);
MODULE_AUTHOR("Guenter Roeck");
MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,15 @@
#!/usr/bin/env python
import os
import sys
from setuptools import setup
os.listdir
setup(
name='sonic_platform',
version='1.0',
description='Module to initialize Ivnetec D6356 platforms',
packages=['sonic_platform'],
)

View File

@ -0,0 +1,3 @@
__all__ = ["platform", "chassis"]
from sonic_platform import *

View File

@ -0,0 +1,149 @@
#!/usr/bin/env python
#
# Name: chassis.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.eeprom import Eeprom
from sonic_platform.fan import Fan
from sonic_platform.psu import Psu
from sonic_platform.sfp import Sfp
from sonic_platform.qsfp import QSfp
from sonic_platform.thermal import Thermal
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Chassis(ChassisBase):
def __init__(self):
ChassisBase.__init__(self)
self.__num_of_fans = 8
self.__num_of_psus = 2
self.__num_of_sfps = 56
self.__start_of_qsfp = 48
self.__num_of_thermals = 5
# Initialize EEPROM
self._eeprom = Eeprom()
# Initialize FAN
for index in range(1, self.__num_of_fans + 1):
fan = Fan(index, False, 0)
self._fan_list.append(fan)
# Initialize PSU
for index in range(1, self.__num_of_psus + 1):
psu = Psu(index)
self._psu_list.append(psu)
# Initialize SFP
for index in range(0, self.__num_of_sfps):
if index < self.__start_of_qsfp:
sfp = Sfp(index)
else:
sfp = QSfp(index)
self._sfp_list.append(sfp)
# Initialize THERMAL
for index in range(0, self.__num_of_thermals):
thermal = Thermal(index)
self._thermal_list.append(thermal)
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the chassis
Returns:
string: The name of the chassis
"""
return self._eeprom.modelstr()
def get_presence(self):
"""
Retrieves the presence of the chassis
Returns:
bool: True if chassis is present, False if not
"""
return True
def get_model(self):
"""
Retrieves the model number (or part number) of the chassis
Returns:
string: Model/part number of chassis
"""
return self._eeprom.part_number_str()
def get_serial(self):
"""
Retrieves the serial number of the chassis
Returns:
string: Serial number of chassis
"""
return self._eeprom.serial_number_str()
def get_status(self):
"""
Retrieves the operational status of the chassis
Returns:
bool: A boolean value, True if chassis is operating properly
False if not
"""
return True
##############################################
# Chassis methods
##############################################
def get_base_mac(self):
"""
Retrieves the base MAC address for the chassis
Returns:
A string containing the MAC address in the format
'XX:XX:XX:XX:XX:XX'
"""
return self._eeprom.base_mac_address()
def get_serial_number(self):
"""
Retrieves the hardware serial number for the chassis
Returns:
A string containing the hardware serial number for this chassis.
"""
return self._eeprom.serial_number_str()
def get_system_eeprom_info(self):
"""
Retrieves the full content of system EEPROM information for the chassis
Returns:
A dictionary where keys are the type code defined in
OCP ONIE TlvInfo EEPROM format and values are their corresponding
values.
Ex. { '0x21':'AG9064', '0x22':'V1.0', '0x23':'AG9064-0109867821',
'0x24':'001c0f000fcd0a', '0x25':'02/03/2018 16:22:00',
'0x26':'01', '0x27':'REV01', '0x28':'AG9064-C2358-16G'}
"""
return self._eeprom.system_eeprom_info()
def get_reboot_cause(self):
"""
Retrieves the cause of the previous reboot
Returns:
A tuple (string, string) where the first element is a string
containing the cause of the previous reboot. This string must be
one of the predefined strings in this class. If the first string
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
to pass a description of the reboot cause.
"""
raise NotImplementedError

View File

@ -0,0 +1,110 @@
#!/usr/bin/env python
#
# Name: eeprom.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
from sonic_eeprom import eeprom_tlvinfo
import binascii
except ImportError, e:
raise ImportError(str(e) + "- required module not found")
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
def __init__(self):
self.__eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0055/eeprom"
super(Eeprom, self).__init__(self.__eeprom_path, 0, '', True)
self.__eeprom_tlv_dict = dict()
try:
self.__eeprom_data = self.read_eeprom()
except:
self.__eeprom_data = "N/A"
raise RuntimeError("Eeprom is not Programmed")
else:
eeprom = self.__eeprom_data
if not self.is_valid_tlvinfo_header(eeprom):
return
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
tlv_index = self._TLV_INFO_HDR_LEN
tlv_end = self._TLV_INFO_HDR_LEN + total_length
while (tlv_index + 2) < len(eeprom) and tlv_index < tlv_end:
if not self.is_valid_tlv(eeprom[tlv_index:]):
break
tlv = eeprom[tlv_index:tlv_index + 2
+ ord(eeprom[tlv_index + 1])]
code = "0x%02X" % (ord(tlv[0]))
if ord(tlv[0]) == self._TLV_CODE_VENDOR_EXT:
value = str((ord(tlv[2]) << 24) | (ord(tlv[3]) << 16) |
(ord(tlv[4]) << 8) | ord(tlv[5]))
value += str(tlv[6:6 + ord(tlv[1])])
else:
name, value = self.decoder(None, tlv)
self.__eeprom_tlv_dict[code] = value
if ord(eeprom[tlv_index]) == self._TLV_CODE_CRC_32:
break
tlv_index += ord(eeprom[tlv_index+1]) + 2
def serial_number_str(self):
(is_valid, results) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_SERIAL_NUMBER)
if not is_valid:
return "N/A"
return results[2]
def base_mac_address(self):
(is_valid, t) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_MAC_BASE)
if not is_valid or t[1] != 6:
return super(eeprom_tlvinfo.TlvInfoDecoder, self).switchaddrstr(self.__eeprom_data)
return ":".join([binascii.b2a_hex(T) for T in t[2]])
def modelstr(self):
(is_valid, results) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_PRODUCT_NAME)
if not is_valid:
return "N/A"
return results[2]
def part_number_str(self):
(is_valid, results) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_PART_NUMBER)
if not is_valid:
return "N/A"
return results[2]
def serial_tag_str(self):
(is_valid, results) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_SERVICE_TAG)
if not is_valid:
return "N/A"
return results[2]
def revision_str(self):
(is_valid, results) = self.get_tlv_field(
self.__eeprom_data, self._TLV_CODE_DEVICE_VERSION)
if not is_valid:
return "N/A"
return results[2]
def system_eeprom_info(self):
"""
Returns a dictionary, where keys are the type code defined in
ONIE EEPROM format and values are their corresponding values
found in the system EEPROM.
"""
return self.__eeprom_tlv_dict

View File

@ -0,0 +1,204 @@
#!/usr/bin/env python
#
# Name: fan.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import math
import os
from sonic_platform_base.fan_base import FanBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Fan(FanBase):
def __init__(self, index, is_psu_fan=False, psu_index=0):
self.__index = index
self.__is_psu_fan = is_psu_fan
if self.__is_psu_fan:
self.__psu_index = psu_index
self.__presence_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index)
self.__speed_rpm_attr = "/sys/class/hwmon/hwmon{}/fan{}_input".format((self.__psu_index + 6), self.__index)
self.__pwm_attr = None
else:
self.__presence_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index)
self.__speed_rpm_attr = "/sys/class/hwmon/hwmon2/device/fan{}_input".format(self.__index)
self.__pwm_attr = "/sys/class/hwmon/hwmon2/device/pwm{}".format((self.__index + 1)/2)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if (not os.path.isfile(attr_path)):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open ", attr_path, " file !")
retval = retval.rstrip(' \t\n\r')
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
if self.__is_psu_fan:
return "PSU{}-FAN{}".format(self.__psu_index, self.__index)
else:
return "FAN{}".format(self.__index)
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) != 0):
presence = True
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return "N/A"
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return "N/A"
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
return self.get_presence()
##############################################
# FAN methods
##############################################
def get_direction(self):
"""
Retrieves the direction of fan
Returns:
A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST
depending on fan direction
"""
raise NotImplementedError
def get_speed(self):
"""
Retrieves the speed of fan as a percentage of full speed
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
speed = 0
if self.__is_psu_fan:
attr_path = self.__speed_rpm_attr
else:
attr_path = self.__pwm_attr
if self.get_presence() and None != attr_path:
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if self.__is_psu_fan:
fan_speed_rpm = int(attr_rv)
speed = math.ceil(float(fan_speed_rpm) * 100 / 11000)
else:
pwm = int(attr_rv)
speed = math.ceil(float(pwm * 100 / 255))
return speed
def get_target_speed(self):
"""
Retrieves the target (expected) speed of the fan
Returns:
An integer, the percentage of full fan speed, in the range 0 (off)
to 100 (full speed)
"""
raise NotImplementedError
def get_speed_tolerance(self):
"""
Retrieves the speed tolerance of the fan
Returns:
An integer, the percentage of variance from target speed which is
considered tolerable
"""
raise NotImplementedError
def set_speed(self, speed):
"""
Sets the fan speed
Args:
speed: An integer, the percentage of full fan speed to set fan to,
in the range 0 (off) to 100 (full speed)
Returns:
A boolean, True if speed is set successfully, False if not
"""
raise NotImplementedError
def set_status_led(self, color):
"""
Sets the state of the fan module status LED
Args:
color: A string representing the color with which to set the
fan module status LED
Returns:
bool: True if status LED state is set successfully, False if not
"""
raise NotImplementedError
def get_status_led(self):
"""
Gets the state of the fan status LED
Returns:
A string, one of the predefined STATUS_LED_COLOR_* strings above
"""
if self.get_status() and self.get_speed() > 0:
return self.STATUS_LED_COLOR_GREEN
else:
return self.STATUS_LED_COLOR_OFF

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,202 @@
#!/usr/bin/env python
#
# Name: psu.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
from sonic_platform_base.psu_base import PsuBase
from sonic_platform.fan import Fan
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Psu(PsuBase):
def __init__(self, index):
self.__num_of_fans = 1
self.__index = index
self.__psu_presence_attr = "/sys/class/hwmon/hwmon2/device/psu{}".format(self.__index)
self.__psu_power_in_attr = "/sys/class/hwmon/hwmon{}/power1_input".format(self.__index + 6)
self.__psu_power_out_attr = "/sys/class/hwmon/hwmon{}/power2_input".format(self.__index + 6)
self.__psu_voltage_out_attr = "/sys/class/hwmon/hwmon{}/in2_input".format(self.__index + 6)
self.__psu_current_out_attr = "/sys/class/hwmon/hwmon{}/curr2_input".format(self.__index + 6)
# Overriding _fan_list class variable defined in PsuBase, to make it unique per Psu object
self._fan_list = []
# Initialize FAN
for x in range(1, self.__num_of_fans + 1):
fan = Fan(x, True, self.__index)
self._fan_list.append(fan)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if (not os.path.isfile(attr_path)):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open ", attr_path, " file !")
retval = retval.rstrip(' \t\n\r')
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return "PSU{}".format(self.__index)
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_normal = "1:normal"
attr_path = self.__psu_presence_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (attr_rv == attr_normal):
presence = True
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return "N/A"
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return "N/A"
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
status = False
attr_path = self.__psu_power_in_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) != 0):
status = True
return status
##############################################
# PSU methods
##############################################
def get_voltage(self):
"""
Retrieves current PSU voltage output
Returns:
A float number, the output voltage in volts,
e.g. 12.1
"""
voltage_out = 0.0
attr_path = self.__psu_voltage_out_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
voltage_out = float(attr_rv) / 1000
return voltage_out
def get_current(self):
"""
Retrieves present electric current supplied by PSU
Returns:
A float number, the electric current in amperes, e.g 15.4
"""
current_out = 0.0
attr_path = self.__psu_current_out_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
current_out = float(attr_rv) / 1000
return current_out
def get_power(self):
"""
Retrieves current energy supplied by PSU
Returns:
A float number, the power in watts, e.g. 302.6
"""
power_out = 0.0
attr_path = self.__psu_power_out_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
power_out = float(attr_rv) / 1000000
return power_out
def get_powergood_status(self):
"""
Retrieves the powergood status of PSU
Returns:
A boolean, True if PSU has stablized its output voltages and passed all
its internal self-tests, False if not.
"""
return self.get_status()
def set_status_led(self, color):
"""
Sets the state of the PSU status LED
Args:
color: A string representing the color with which to set the
PSU status LED
Returns:
bool: True if status LED state is set successfully, False if not
"""
raise NotImplementedError
def get_status_led(self):
"""
Gets the state of the PSU status LED
Returns:
A string, one of the predefined STATUS_LED_COLOR_* strings above
"""
if self.get_powergood_status():
return self.STATUS_LED_COLOR_GREEN
else:
return self.STATUS_LED_COLOR_OFF

View File

@ -0,0 +1,925 @@
#!/usr/bin/env python
#
# Name: qsfp.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
import sys
import time
from sonic_platform_base.sfp_base import SfpBase
from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
INFO_OFFSET = 128
DOM_OFFSET = 0
XCVR_INTFACE_BULK_OFFSET = 0
XCVR_INTFACE_BULK_WIDTH_QSFP = 20
XCVR_HW_REV_WIDTH_QSFP = 2
XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
XCVR_VENDOR_NAME_OFFSET = 20
XCVR_VENDOR_NAME_WIDTH = 16
XCVR_VENDOR_OUI_OFFSET = 37
XCVR_VENDOR_OUI_WIDTH = 3
XCVR_VENDOR_PN_OFFSET = 40
XCVR_VENDOR_PN_WIDTH = 16
XCVR_HW_REV_OFFSET = 56
XCVR_HW_REV_WIDTH_OSFP = 2
XCVR_VENDOR_SN_OFFSET = 68
XCVR_VENDOR_SN_WIDTH = 16
XCVR_VENDOR_DATE_OFFSET = 84
XCVR_VENDOR_DATE_WIDTH = 8
XCVR_DOM_CAPABILITY_OFFSET = 92
XCVR_DOM_CAPABILITY_WIDTH = 1
# Offset for values in QSFP eeprom
QSFP_DOM_REV_OFFSET = 1
QSFP_DOM_REV_WIDTH = 1
QSFP_TEMPE_OFFSET = 22
QSFP_TEMPE_WIDTH = 2
QSFP_VOLT_OFFSET = 26
QSFP_VOLT_WIDTH = 2
QSFP_CHANNL_MON_OFFSET = 34
QSFP_CHANNL_MON_WIDTH = 16
QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
QSFP_CONTROL_OFFSET = 86
QSFP_CONTROL_WIDTH = 8
QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
QSFP_POWEROVERRIDE_OFFSET = 93
QSFP_POWEROVERRIDE_WIDTH = 1
QSFP_MODULE_THRESHOLD_OFFSET = 128
QSFP_MODULE_THRESHOLD_WIDTH = 24
QSFP_CHANNEL_THRESHOLD_OFFSET = 176
QSFP_CHANNEL_THRESHOLD_WIDTH = 16
class QSfp(SfpBase):
def __init__(self, index):
self.__index = index
self.__platform = "x86_64-inventec_d6356-r0"
self.__hwsku = "INVENTEC-D6356"
self.__port_to_i2c_mapping = {
0:22, 1:23, 2:24, 3:25, 4:26, 5:27, 6:28, 7:29,
8:30, 9:31, 10:32, 11:33, 12:34, 13:35, 14:36, 15:37,
16:38, 17:39, 18:40, 19:41, 20:42, 21:43, 22:44, 23:45,
24:46, 25:47, 26:48, 27:49, 28:50, 29:51, 30:52, 31:53,
32:54, 33:55, 34:56, 35:57, 36:58, 37:59, 38:60, 39:61,
40:62, 41:63, 42:64, 43:65, 44:66, 45:67, 46:68, 47:69,
48:14, 49:15, 50:16, 51:17, 52:18, 53:19, 54:20, 55:21
}
self.__port_end = len(self.__port_to_i2c_mapping) - 1;
self.__presence_attr = None
self.__eeprom_path = None
if self.__index in range(0, self.__port_end + 1):
self.__presence_attr = "/sys/class/swps/port{}/present".format(self.__index)
self.__lpmode_attr = "/sys/class/swps/port{}/lpmod".format(self.__index)
self.__reset_attr = "/sys/class/swps/port{}/reset".format(self.__index)
self.__eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom".format(self.__port_to_i2c_mapping[self.__index])
#print(self.__eeprom_path)
SfpBase.__init__(self)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if (not os.path.isfile(attr_path)):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open ", attr_path, " file !")
retval = retval.rstrip(' \t\n\r')
return retval
def __is_host(self):
return os.system("docker > /dev/null 2>&1") == 0
def __get_path_to_port_config_file(self):
host_platform_root_path = '/usr/share/sonic/device'
docker_hwsku_path = '/usr/share/sonic/hwsku'
host_platform_path = "/".join([host_platform_root_path, self.__platform])
hwsku_path = "/".join([host_platform_path, self.__hwsku]) if self.__is_host() else docker_hwsku_path
return "/".join([hwsku_path, "port_config.ini"])
def __read_eeprom_specific_bytes(self, offset, num_bytes):
sysfsfile_eeprom = None
eeprom_raw = []
for i in range(0, num_bytes):
eeprom_raw.append("0x00")
sysfs_eeprom_path = self.__eeprom_path
try:
sysfsfile_eeprom = open(sysfs_eeprom_path, mode="rb", buffering=0)
sysfsfile_eeprom.seek(offset)
raw = sysfsfile_eeprom.read(num_bytes)
raw_len = len(raw)
for n in range(0, raw_len):
eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
except:
pass
finally:
if sysfsfile_eeprom:
sysfsfile_eeprom.close()
return eeprom_raw
def __convert_string_to_num(self, value_str):
if "-inf" in value_str:
return 'N/A'
elif "Unknown" in value_str:
return 'N/A'
elif 'dBm' in value_str:
t_str = value_str.rstrip('dBm')
return float(t_str)
elif 'mA' in value_str:
t_str = value_str.rstrip('mA')
return float(t_str)
elif 'C' in value_str:
t_str = value_str.rstrip('C')
return float(t_str)
elif 'Volts' in value_str:
t_str = value_str.rstrip('Volts')
return float(t_str)
else:
return 'N/A'
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
name = None
sfputil_helper = SfpUtilHelper()
sfputil_helper.read_porttab_mappings(self.__get_path_to_port_config_file())
name = sfputil_helper.logical[self.__index] or "Unknown"
return name
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) == 0):
presence = True
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
transceiver_info_dict = self.get_transceiver_info()
return transceiver_info_dict.get("modelname", "N/A")
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
transceiver_info_dict = self.get_transceiver_info()
return transceiver_info_dict.get("serialnum", "N/A")
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
return self.get_presence() and not self.get_reset_status()
##############################################
# SFP methods
##############################################
def get_transceiver_info(self):
"""
Retrieves transceiver info of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
type |1*255VCHAR |type of SFP
hardwarerev |1*255VCHAR |hardware version of SFP
serialnum |1*255VCHAR |serial number of the SFP
manufacturename |1*255VCHAR |SFP vendor name
modelname |1*255VCHAR |SFP model name
Connector |1*255VCHAR |connector information
encoding |1*255VCHAR |encoding information
ext_identifier |1*255VCHAR |extend identifier
ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance
cable_length |INT |cable length in m
mominal_bit_rate |INT |nominal bit rate by 100Mbs
specification_compliance |1*255VCHAR |specification compliance
vendor_date |1*255VCHAR |vendor date
vendor_oui |1*255VCHAR |vendor OUI
========================================================================
"""
transceiver_info_dict_keys = ['type', 'hardwarerev',
'serialnum', 'manufacturename',
'modelname', 'Connector',
'encoding', 'ext_identifier',
'ext_rateselect_compliance', 'cable_type',
'cable_length', 'nominal_bit_rate',
'specification_compliance', 'vendor_date',
'vendor_oui']
qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)')
qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
'Fibre Channel link length/Transmitter Technology', 'Fibre Channel transmission media',
'Fibre Channel Speed')
sfpi_obj = sff8436InterfaceId()
if not self.get_presence() or not sfpi_obj:
return {}
offset = INFO_OFFSET
sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes((offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_QSFP)
sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(sfp_interface_bulk_raw, 0)
sfp_vendor_name_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
sfp_vendor_name_data = sfpi_obj.parse_vendor_name(sfp_vendor_name_raw, 0)
sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(sfp_vendor_pn_raw, 0)
sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes((offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_QSFP)
sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(sfp_vendor_rev_raw, 0)
sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(sfp_vendor_sn_raw, 0)
sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
if sfp_vendor_oui_raw is not None:
sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(sfp_vendor_oui_raw, 0)
sfp_vendor_date_raw = self.__read_eeprom_specific_bytes((offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
sfp_vendor_date_data = sfpi_obj.parse_vendor_date(sfp_vendor_date_raw, 0)
transceiver_info_dict = dict.fromkeys(transceiver_info_dict_keys, 'N/A')
if sfp_interface_bulk_data:
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
transceiver_info_dict['Connector'] = sfp_interface_bulk_data['data']['Connector']['value']
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
transceiver_info_dict['nominal_bit_rate'] = str(sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
transceiver_info_dict['manufacturename'] = sfp_vendor_name_data['data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
transceiver_info_dict['modelname'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
transceiver_info_dict['hardwarerev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
transceiver_info_dict['serialnum'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
transceiver_info_dict['vendor_date'] = sfp_vendor_date_data['data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
transceiver_info_dict['cable_type'] = "Unknown"
transceiver_info_dict['cable_length'] = "Unknown"
for key in qsfp_cable_length_tup:
if key in sfp_interface_bulk_data['data']:
transceiver_info_dict['cable_type'] = key
transceiver_info_dict['cable_length'] = str(sfp_interface_bulk_data['data'][key]['value'])
compliance_code_dict = dict()
for key in qsfp_compliance_code_tup:
if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
transceiver_info_dict['specification_compliance'] = str(compliance_code_dict)
return transceiver_info_dict
def get_transceiver_bulk_status(self):
"""
Retrieves transceiver bulk status of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not.
tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not.
reset_status |BOOLEAN |reset status, True if SFP in reset, False if not.
lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not.
tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not.
tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0
| |to channel 3.
temperature |INT |module temperature in Celsius
voltage |INT |supply voltage in mV
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 = sff8436Dom()
sfpi_obj = sff8436InterfaceId()
if not self.get_presence() or not sfpi_obj or not sfpd_obj:
return {}
transceiver_dom_info_dict = dict.fromkeys(transceiver_dom_info_dict_keys, 'N/A')
offset = DOM_OFFSET
offset_xcvr = INFO_OFFSET
# QSFP capability byte parse, through this byte can know whether it support tx_power or not.
# TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
# need to add more code for determining the capability and version compliance
# in SFF-8636 dom capability definitions evolving with the versions.
qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes((offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
if qsfp_dom_capability_raw is not None:
qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0)
else:
return None
dom_temperature_raw = self.__read_eeprom_specific_bytes((offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH)
if dom_temperature_raw is not None:
dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0)
transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
dom_voltage_raw = self.__read_eeprom_specific_bytes((offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH)
if dom_voltage_raw is not None:
dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
qsfp_dom_rev_raw = self.__read_eeprom_specific_bytes((offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH)
if qsfp_dom_rev_raw is not None:
qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0)
qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value']
# The tx_power monitoring is only available on QSFP which compliant with SFF-8636
# and claimed that it support tx_power with one indicator bit.
dom_channel_monitor_data = {}
dom_channel_monitor_raw = None
qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value']
if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')):
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0)
else:
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH)
if dom_channel_monitor_raw is not None:
dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0)
transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value']
transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value']
transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value']
transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value']
if dom_channel_monitor_raw:
transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value']
transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value']
transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value']
transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value']
transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value']
transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value']
transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value']
transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value']
for key in transceiver_dom_info_dict:
transceiver_dom_info_dict[key] = self.__convert_string_to_num(transceiver_dom_info_dict[key])
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
transceiver_dom_info_dict['reset_status'] = self.get_reset_status()
transceiver_dom_info_dict['tx_disable'] = self.get_tx_disable()
transceiver_dom_info_dict['tx_disable_channel'] = self.get_tx_disable_channel()
transceiver_dom_info_dict['lp_mode'] = self.get_lpmode()
return transceiver_dom_info_dict
def get_transceiver_threshold_info(self):
"""
Retrieves transceiver threshold info of this SFP
Returns:
A dict which contains following keys/values :
========================================================================
keys |Value Format |Information
---------------------------|---------------|----------------------------
temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius.
templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius.
temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius.
templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius.
vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV.
vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV.
vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV.
vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV.
rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm.
rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm.
rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm.
rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm.
txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm.
txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm.
txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm.
txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm.
txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA.
txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA.
txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA.
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
========================================================================
"""
transceiver_dom_threshold_info_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning',
'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning',
'rxpowerhighalarm', 'rxpowerhighwarning', 'rxpowerlowalarm', 'rxpowerlowwarning',
'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning',
'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
sfpd_obj = sff8436Dom()
if not self.get_presence() or not sfpd_obj:
return {}
transceiver_dom_threshold_dict = dict.fromkeys(transceiver_dom_threshold_info_dict_keys, 'N/A')
offset = DOM_OFFSET
dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH)
if dom_module_threshold_raw:
module_threshold_values = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0)
module_threshold_data = module_threshold_values.get('data')
if module_threshold_data:
transceiver_dom_threshold_dict['temphighalarm'] = module_threshold_data['TempHighAlarm']['value']
transceiver_dom_threshold_dict['templowalarm'] = module_threshold_data['TempLowAlarm']['value']
transceiver_dom_threshold_dict['temphighwarning'] = module_threshold_data['TempHighWarning']['value']
transceiver_dom_threshold_dict['templowwarning'] = module_threshold_data['TempLowWarning']['value']
transceiver_dom_threshold_dict['vcchighalarm'] = module_threshold_data['VccHighAlarm']['value']
transceiver_dom_threshold_dict['vcclowalarm'] = module_threshold_data['VccLowAlarm']['value']
transceiver_dom_threshold_dict['vcchighwarning'] = module_threshold_data['VccHighWarning']['value']
transceiver_dom_threshold_dict['vcclowwarning'] = module_threshold_data['VccLowWarning']['value']
dom_channel_thres_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNEL_THRESHOLD_OFFSET), QSFP_CHANNEL_THRESHOLD_WIDTH)
channel_threshold_values = sfpd_obj.parse_channel_threshold_values(dom_channel_thres_raw, 0)
channel_threshold_data = channel_threshold_values.get('data')
if channel_threshold_data:
transceiver_dom_threshold_dict['rxpowerhighalarm'] = channel_threshold_data['RxPowerHighAlarm']['value']
transceiver_dom_threshold_dict['rxpowerlowalarm'] = channel_threshold_data['RxPowerLowAlarm']['value']
transceiver_dom_threshold_dict['rxpowerhighwarning'] = channel_threshold_data['RxPowerHighWarning']['value']
transceiver_dom_threshold_dict['rxpowerlowwarning'] = channel_threshold_data['RxPowerLowWarning']['value']
transceiver_dom_threshold_dict['txpowerhighalarm'] = "0.0dBm"
transceiver_dom_threshold_dict['txpowerlowalarm'] = "0.0dBm"
transceiver_dom_threshold_dict['txpowerhighwarning'] = "0.0dBm"
transceiver_dom_threshold_dict['txpowerlowwarning'] = "0.0dBm"
transceiver_dom_threshold_dict['txbiashighalarm'] = channel_threshold_data['TxBiasHighAlarm']['value']
transceiver_dom_threshold_dict['txbiaslowalarm'] = channel_threshold_data['TxBiasLowAlarm']['value']
transceiver_dom_threshold_dict['txbiashighwarning'] = channel_threshold_data['TxBiasHighWarning']['value']
transceiver_dom_threshold_dict['txbiaslowwarning'] = channel_threshold_data['TxBiasLowWarning']['value']
for key in transceiver_dom_threshold_dict:
transceiver_dom_threshold_dict[key] = self.__convert_string_to_num(transceiver_dom_threshold_dict[key])
return transceiver_dom_threshold_dict
def get_reset_status(self):
"""
Retrieves the reset status of SFP
Returns:
A Boolean, True if reset enabled, False if disabled
"""
reset_status = False
attr_path = self.__reset_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) == 0):
reset_status = True
return reset_status
def get_rx_los(self):
"""
Retrieves the RX LOS (lost-of-signal) status of SFP
Returns:
A Boolean, True if SFP has RX LOS, False if not.
Note : RX LOS status is latched until a call to get_rx_los or a reset.
"""
rx_los = False
rx_los_list = []
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_RX_LOS_STATUS_OFFSET, QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
if dom_channel_monitor_raw is not None:
rx_los_data = int(dom_channel_monitor_raw[0], 16)
rx_los_list.append(rx_los_data & 0x01 != 0)
rx_los_list.append(rx_los_data & 0x02 != 0)
rx_los_list.append(rx_los_data & 0x04 != 0)
rx_los_list.append(rx_los_data & 0x08 != 0)
rx_los = rx_los_list[0] and rx_los_list[1] and rx_los_list[2] and rx_los_list[3]
return rx_los
def get_tx_fault(self):
"""
Retrieves the TX fault status of SFP
Returns:
A Boolean, True if SFP has TX fault, False if not
Note : TX fault status is lached until a call to get_tx_fault or a reset.
"""
tx_fault = False
tx_fault_list = []
dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(QSFP_CHANNL_TX_FAULT_STATUS_OFFSET, QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
if dom_channel_monitor_raw is not None:
tx_fault_data = int(dom_channel_monitor_raw[0], 16)
tx_fault_list.append(tx_fault_data & 0x01 != 0)
tx_fault_list.append(tx_fault_data & 0x02 != 0)
tx_fault_list.append(tx_fault_data & 0x04 != 0)
tx_fault_list.append(tx_fault_data & 0x08 != 0)
tx_fault = tx_fault_list[0] and tx_fault_list[1] and tx_fault_list[2] and tx_fault_list[3]
return tx_fault
def get_tx_disable(self):
"""
Retrieves the tx_disable status of this SFP
Returns:
A Boolean, True if tx_disable is enabled, False if disabled
"""
tx_disable = False
tx_disable_list = []
sfpd_obj = sff8436Dom()
if sfpd_obj is None:
return tx_disable
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
if dom_control_raw is not None:
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value'])
tx_disable = tx_disable_list[0] and tx_disable_list[1] and tx_disable_list[2] and tx_disable_list[3]
return tx_disable
def get_tx_disable_channel(self):
"""
Retrieves the TX disabled channels in this SFP
Returns:
A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent
TX channels which have been disabled in this SFP.
As an example, a returned value of 0x5 indicates that channel 0
and channel 2 have been disabled.
"""
tx_disable_channel = 0
tx_disable_list = []
sfpd_obj = sff8436Dom()
if sfpd_obj is None:
return tx_disable_channel
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
if dom_control_raw is not None:
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
tx_disable_list.append('On' == dom_control_data['data']['TX1Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX2Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX3Disable']['value'])
tx_disable_list.append('On' == dom_control_data['data']['TX4Disable']['value'])
for i in range(len(tx_disable_list)):
if tx_disable_list[i]:
tx_disable_channel |= 1 << i
return tx_disable_channel
def get_lpmode(self):
"""
Retrieves the lpmode (low power mode) status of this SFP
Returns:
A Boolean, True if lpmode is enabled, False if disabled
"""
lpmode = False
attr_path = self.__lpmode_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) == 1):
lpmode = True
return lpmode
def get_power_override(self):
"""
Retrieves the power-override status of this SFP
Returns:
A Boolean, True if power-override is enabled, False if disabled
"""
power_override = False
sfpd_obj = sff8436Dom()
if sfpd_obj is None:
return power_override
dom_control_raw = self.__read_eeprom_specific_bytes(QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH)
if dom_control_raw is not None:
dom_control_data = sfpd_obj.parse_control_bytes(dom_control_raw, 0)
power_override = ('On' == dom_control_data['data']['PowerOverride']['value'])
return power_override
def get_temperature(self):
"""
Retrieves the temperature of this SFP
Returns:
An integer number of current temperature in Celsius
"""
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
return transceiver_dom_info_dict.get("temperature", "N/A")
def get_voltage(self):
"""
Retrieves the supply voltage of this SFP
Returns:
An integer number of supply voltage in mV
"""
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
return transceiver_dom_info_dict.get("voltage", "N/A")
def get_tx_bias(self):
"""
Retrieves the TX bias current of this SFP
Returns:
A list of four integer numbers, representing TX bias in mA
for channel 0 to channel 4.
Ex. ['110.09', '111.12', '108.21', '112.09']
"""
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
tx1_bs = transceiver_dom_info_dict.get("tx1bias", "N/A")
tx2_bs = transceiver_dom_info_dict.get("tx2bias", "N/A")
tx3_bs = transceiver_dom_info_dict.get("tx3bias", "N/A")
tx4_bs = transceiver_dom_info_dict.get("tx4bias", "N/A")
return [tx1_bs, tx2_bs, tx3_bs, tx4_bs] if transceiver_dom_info_dict else []
def get_rx_power(self):
"""
Retrieves the received optical power for this SFP
Returns:
A list of four integer numbers, representing received optical
power in mW for channel 0 to channel 4.
Ex. ['1.77', '1.71', '1.68', '1.70']
"""
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
rx1_pw = transceiver_dom_info_dict.get("rx1power", "N/A")
rx2_pw = transceiver_dom_info_dict.get("rx2power", "N/A")
rx3_pw = transceiver_dom_info_dict.get("rx3power", "N/A")
rx4_pw = transceiver_dom_info_dict.get("rx4power", "N/A")
return [rx1_pw, rx2_pw, rx3_pw, rx4_pw] if transceiver_dom_info_dict else []
def get_tx_power(self):
"""
Retrieves the TX power of this SFP
Returns:
A list of four integer numbers, representing TX power in mW
for channel 0 to channel 4.
Ex. ['1.86', '1.86', '1.86', '1.86']
"""
transceiver_dom_info_dict = self.get_transceiver_bulk_status()
tx1_pw = transceiver_dom_info_dict.get("tx1power", "N/A")
tx2_pw = transceiver_dom_info_dict.get("tx2power", "N/A")
tx3_pw = transceiver_dom_info_dict.get("tx3power", "N/A")
tx4_pw = transceiver_dom_info_dict.get("tx4power", "N/A")
return [tx1_pw, tx2_pw, tx3_pw, tx4_pw]
def reset(self):
"""
Reset SFP and return all user module settings to their default srate.
Returns:
A boolean, True if successful, False if not
"""
try:
reg_file = open(self.__reset_attr, "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
reg_value = 0
reg_file.write(hex(reg_value))
reg_file.close()
# Sleep 2 second to allow it to settle
time.sleep(2)
try:
reg_file = open(self.__reset_attr, "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
reg_value = 1
reg_file.write(hex(reg_value))
reg_file.close()
return True
def tx_disable(self, tx_disable):
"""
Disable SFP TX for all channels
Args:
tx_disable : A Boolean, True to enable tx_disable mode, False to disable
tx_disable mode.
Returns:
A boolean, True if tx_disable is set successfully, False if not
"""
sysfs_eeprom_path = self.__eeprom_path
sysfsfile_eeprom = None
try:
tx_disable_ctl = 0xf if tx_disable else 0x0
buffer = create_string_buffer(1)
buffer[0] = chr(tx_disable_ctl)
# Write to eeprom
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
sysfsfile_eeprom.write(buffer[0])
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if sysfsfile_eeprom is not None:
sysfsfile_eeprom.close()
time.sleep(0.01)
return True
def tx_disable_channel(self, channel, disable):
"""
Sets the tx_disable for specified SFP channels
Args:
channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3,
e.g. 0x5 for channel 0 and channel 2.
disable : A boolean, True to disable TX channels specified in channel,
False to enable
Returns:
A boolean, True if successful, False if not
"""
sysfs_eeprom_path = self.__eeprom_path
sysfsfile_eeprom = None
try:
channel_state = self.get_tx_disable_channel()
tx_enable_mask = [0xe, 0xd, 0xb, 0x7]
tx_disable_mask = [0x1, 0x3, 0x7, 0xf]
tx_disable_ctl = channel_state | tx_disable_mask[channel] if disable else channel_state & tx_enable_mask[channel]
buffer = create_string_buffer(1)
buffer[0] = chr(tx_disable_ctl)
# Write to eeprom
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET)
sysfsfile_eeprom.write(buffer[0])
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if sysfsfile_eeprom is not None:
sysfsfile_eeprom.close()
time.sleep(0.01)
return True
def set_lpmode(self, lpmode):
"""
Sets the lpmode (low power mode) of SFP
Args:
lpmode: A Boolean, True to enable lpmode, False to disable it
Note : lpmode can be overridden by set_power_override
Returns:
A boolean, True if lpmode is set successfully, False if not
"""
try:
reg_file = open(self.__lpmode_attr, "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
reg_value = int(reg_file.readline().rstrip())
if lpmode is True:
reg_value = 1
else:
reg_value = 0
reg_file.write(hex(reg_value))
reg_file.close()
return True
def set_power_override(self, power_override, power_set):
"""
Sets SFP power level using power_override and power_set
Args:
power_override :
A Boolean, True to override set_lpmode and use power_set
to control SFP power, False to disable SFP power control
through power_override/power_set and use set_lpmode
to control SFP power.
power_set :
Only valid when power_override is True.
A Boolean, True to set SFP to low power mode, False to set
SFP to high power mode.
Returns:
A boolean, True if power-override and power_set are set successfully,
False if not
"""
sysfs_eeprom_path = self.__eeprom_path
sysfsfile_eeprom = None
try:
power_override_bit = 0
if power_override:
power_override_bit |= 1 << 0
power_set_bit = 0
if power_set:
power_set_bit |= 1 << 1
buffer = create_string_buffer(1)
buffer[0] = chr(power_override_bit | power_set_bit)
# Write to eeprom
sysfsfile_eeprom = open(sysfs_eeprom_path, "r+b")
sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET)
sysfsfile_eeprom.write(buffer[0])
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
finally:
if sysfsfile_eeprom is not None:
sysfsfile_eeprom.close()
time.sleep(0.01)
return True

View File

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

View File

@ -0,0 +1,170 @@
#!/usr/bin/env python
#
# Name: thermal.py, version: 1.0
#
# Description: Module contains the definitions of SONiC platform APIs
#
try:
import os
from sonic_platform_base.thermal_base import ThermalBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
class Thermal(ThermalBase):
def __init__(self, index):
self.__index = index
#thermal name list
self.__thermal_name_list = [ "PCH Temperature Sensor",
"CPU Board Temperature Sensor",
"FrontSide Temperature Sensor",
"NearASIC Temperature Sensor",
"RearSide Temperature Sensor" ]
offset = 0
if 0 != self.__index:
offset = 2
self.__presence_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset)
self.__temperature_attr = "/sys/class/hwmon/hwmon{}/temp1_input".format(self.__index + offset)
def __get_attr_value(self, attr_path):
retval = 'ERR'
if (not os.path.isfile(attr_path)):
return retval
try:
with open(attr_path, 'r') as fd:
retval = fd.read()
except Exception as error:
logging.error("Unable to open ", attr_path, " file !")
retval = retval.rstrip(' \t\n\r')
return retval
##############################################
# Device methods
##############################################
def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
return self.__thermal_name_list[self.__index] or "Unknown"
def get_presence(self):
"""
Retrieves the presence of the device
Returns:
bool: True if device is present, False if not
"""
presence = False
attr_path = self.__presence_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
if (int(attr_rv) != 0):
presence = True
return presence
def get_model(self):
"""
Retrieves the model number (or part number) of the device
Returns:
string: Model/part number of device
"""
return "N/A"
def get_serial(self):
"""
Retrieves the serial number of the device
Returns:
string: Serial number of device
"""
return "N/A"
def get_status(self):
"""
Retrieves the operational status of the device
Returns:
A boolean value, True if device is operating properly, False if not
"""
return self.get_presence()
##############################################
# THERMAL methods
##############################################
def get_temperature(self):
"""
Retrieves current temperature reading from thermal
Returns:
A float number of current temperature in Celsius up to nearest thousandth
of one degree Celsius, e.g. 30.125
"""
temperature = 0.0
attr_path = self.__temperature_attr
attr_rv = self.__get_attr_value(attr_path)
if (attr_rv != 'ERR'):
temperature = float(attr_rv) / 1000
return temperature
def get_high_threshold(self):
"""
Retrieves the high threshold temperature of thermal
Returns:
A float number, the high threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
raise NotImplementedError
def get_low_threshold(self):
"""
Retrieves the low threshold temperature of thermal
Returns:
A float number, the low threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
raise NotImplementedError
def set_high_threshold(self, temperature):
"""
Sets the high threshold temperature of thermal
Args :
temperature: A float number up to nearest thousandth of one degree Celsius,
e.g. 30.125
Returns:
A boolean, True if threshold is set successfully, False if not
"""
raise NotImplementedError
def set_low_threshold(self, temperature):
"""
Sets the low threshold temperature of thermal
Args :
temperature: A float number up to nearest thousandth of one degree Celsius,
e.g. 30.125
Returns:
A boolean, True if threshold is set successfully, False if not
"""
raise NotImplementedError

View File

@ -126,7 +126,7 @@ drivers =[
'inv_eeprom',
'inv_cpld',
'inv_platform',
'monitor',
#'monitor',
'swps']
@ -141,7 +141,7 @@ def system_install():
status, output = exec_cmd("rmmod lpc_ich ", 1)
#insert extra module
status, output = exec_cmd("insmod /lib/modules/3.16.0-5-amd64/extra/gpio-ich.ko gpiobase=0",1)
status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1)
#install drivers
for i in range(0,len(drivers)):
@ -159,52 +159,49 @@ def system_install():
print output
if FORCE == 0:
return status
#swps map to i2c-bus
#
# INV_FIX-4037
# It replaces the original sff8436 driver with the optoe driver
#
#optoe map to i2c-bus
for i in range(14,22):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-6/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(22,30):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-7/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(30,38):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-8/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(38,46):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-9/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(46,54):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-10/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(54,62):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-11/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
return status
for i in range(62,70):
status, output =exec_cmd("echo sff8436 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo sff8436 0x51 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
status, output =exec_cmd("echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-1/i2c-5/i2c-12/i2c-"+str(i)+"/new_device", 1)
if status:
print output
if FORCE == 0:
@ -243,7 +240,7 @@ def uninstall():
def device_found():
ret1, log = exec_cmd("ls "+i2c_prefix+"*0072", 0)
ret2, log = exec_cmd("ls "+i2c_prefix+"i2c-5", 0)
return not(ret1 or ret2)
return not(ret1 or ret2)
if __name__ == "__main__":
main()

View File

@ -27,7 +27,7 @@ Description: kernel modules for platform devices such as fan, led
Package: platform-modules-d6356
Architecture: amd64
Depends: linux-image-4.9.0-8-2-amd64
Depends: linux-image-4.9.0-9-2-amd64
Description: kernel modules for platform devices such as fan, led
Package: platform-modules-d7264q28b

View File

@ -1 +1,3 @@
d6356/utils/inventec_d6356_util.py /usr/local/bin
d6356/utils/inventec_d6356_util.py usr/local/bin
d6356/utils/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-inventec_d6356-r0
systemd/platform-modules-d6356.service lib/systemd/system

View File

@ -17,11 +17,17 @@ MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= d7032q28b d7054q28b d6254qs d6556 d6356 d7264q28b
%:
dh $@ --with=systemd
dh $@ --with python2,systemd
override_dh_auto_build:
(for mod in $(MODULE_DIRS); do \
make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \
if [ $$mod = "d6356" ]; then \
cd $(MOD_SRC_DIR)/$${mod}; \
python2 setup.py build; \
python2 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/utils; \
cd $(MOD_SRC_DIR); \
fi \
done)
override_dh_auto_install:
@ -30,11 +36,13 @@ override_dh_auto_install:
$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
cp $(MOD_SRC_DIR)/$${mod}/modules/*.ko \
debian/platform-modules-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \
dh_installdirs -pplatform-modules-$${mod} usr/local/bin; \
cp $(MOD_SRC_DIR)/$${mod}/utils/* \
debian/platform-modules-$${mod}/usr/local/bin; \
if [ $$mod = "d6356" ]; then \
cd $(MOD_SRC_DIR)/$${mod}; \
python2 setup.py install --root=$(MOD_SRC_DIR)/debian/platform-modules-$${mod} --install-layout=deb; \
cd $(MOD_SRC_DIR); \
fi \
done)
override_dh_usrlocal:
override_dh_pysupport:

View File

@ -0,0 +1,13 @@
[Unit]
Description=Inventec d6356 Platform modules
After=local-fs.target
Before=pmon.service
[Service]
Type=oneshot
ExecStart=-/etc/init.d/platform-modules-d6356 start
ExecStop=-/etc/init.d/platform-modules-d6356 stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target