two platforms supporting S3IP SYSFS (TCS8400, TCS9400) (#12386)

Why I did it
Add two platform that support s3IP framework

How I did it
Add two platforms supporting S3IP SYSFS (TCS8400, TCS9400)

How to verify it
Manual test
This commit is contained in:
tianshangfei
2022-12-18 16:16:53 +08:00
committed by GitHub
parent bb09ebe977
commit b65e06f998
333 changed files with 103583 additions and 1 deletions

View File

@@ -0,0 +1,574 @@
#
# BCM56880 128x100g port configuration.
#
# configuration yaml file
# device:
# <unit>:
# <table>:
# ?
# <key_fld_1>: <value>
# <key_fld_2>: <value>
# ...
# <key_fld_n>: <value>
# :
# <data_fld_1>: <value>
# <data_fld_2>: <value>
# ...
# <data_fld_n>: <value>
#
# $Copyright: (c) 2019 Broadcom.
# Broadcom Proprietary and Confidential. All rights reserved.$
#
---
bcm_device:
0:
global:
bcm_tunnel_term_compatible_mode: 1
# Multicast group allocated by brcm-sai, setting "vlan_flooding_l2mc_num_reserved=0"
vlan_flooding_l2mc_num_reserved: 0
shared_block_mask_section: uc_bc
sai_tunnel_support: 1
l3_alpm_template: 1
l3_alpm2_bnk_threshold: 100
uft_mode: 1
l3_enable: 1
l2_hitbit_enable: 1
pktio_mode: 1
skip_protocol_default_entries: 1
ifa_enable: 1
...
---
bcm_device:
0:
port:
"*":
encap_mode: IEEE
dport_map_enable: 1
11:
dport_map_port: 1
13:
dport_map_port: 2
20:
dport_map_port: 3
22:
dport_map_port: 4
24:
dport_map_port: 5
26:
dport_map_port: 6
28:
dport_map_port: 7
30:
dport_map_port: 8
3:
dport_map_port: 9
5:
dport_map_port: 10
7:
dport_map_port: 11
9:
dport_map_port: 12
40:
dport_map_port: 13
42:
dport_map_port: 14
44:
dport_map_port: 15
46:
dport_map_port: 16
48:
dport_map_port: 17
50:
dport_map_port: 18
64:
dport_map_port: 19
66:
dport_map_port: 20
68:
dport_map_port: 21
70:
dport_map_port: 22
72:
dport_map_port: 23
74:
dport_map_port: 24
1:
dport_map_port: 25
15:
dport_map_port: 26
32:
dport_map_port: 27
34:
dport_map_port: 28
52:
dport_map_port: 29
54:
dport_map_port: 30
60:
dport_map_port: 31
62:
dport_map_port: 32
...
---
device:
0:
DEVICE_CONFIG:
# CORE CLOCK FREQUENCY
CORE_CLK_FREQ: CLK_1350MHZ
# PP CLOCK FREQUENCY
PP_CLK_FREQ: CLK_1350MHZ
...
---
device:
0:
PC_PM_CORE:
?
PC_PM_ID: 1
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x73510624
RX_LANE_MAP: 0x46270513
TX_POLARITY_FLIP: 0xa
RX_POLARITY_FLIP: 0x17
?
PC_PM_ID: 2
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x52317046
RX_LANE_MAP: 0x31247056
TX_POLARITY_FLIP: 0x90
RX_POLARITY_FLIP: 0x47
?
PC_PM_ID: 3
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x23104567
RX_LANE_MAP: 0x64752310
TX_POLARITY_FLIP: 0x29
RX_POLARITY_FLIP: 0x5a
?
PC_PM_ID: 4
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x23104567
RX_LANE_MAP: 0x64752310
TX_POLARITY_FLIP: 0x29
RX_POLARITY_FLIP: 0x5a
?
PC_PM_ID: 5
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x25047361
RX_LANE_MAP: 0x10452736
TX_POLARITY_FLIP: 0xf5
RX_POLARITY_FLIP: 0xc0
?
PC_PM_ID: 6
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x45763210
RX_LANE_MAP: 0x13026457
TX_POLARITY_FLIP: 0xa
RX_POLARITY_FLIP: 0xf9
?
PC_PM_ID: 7
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x45763210
RX_LANE_MAP: 0x13026457
TX_POLARITY_FLIP: 0xa
RX_POLARITY_FLIP: 0xf9
?
PC_PM_ID: 8
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x45673210
RX_LANE_MAP: 0x13026457
TX_POLARITY_FLIP: 0x4a
RX_POLARITY_FLIP: 0xf3
?
PC_PM_ID: 9
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x02476531
RX_LANE_MAP: 0x05261734
TX_POLARITY_FLIP: 0xdf
RX_POLARITY_FLIP: 0x84
?
PC_PM_ID: 10
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x37065241
RX_LANE_MAP: 0x04175263
TX_POLARITY_FLIP: 0x36
RX_POLARITY_FLIP: 0x39
?
PC_PM_ID: 11
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x54762301
RX_LANE_MAP: 0x13025467
TX_POLARITY_FLIP: 0x70
RX_POLARITY_FLIP: 0x6f
?
PC_PM_ID: 12
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x73125046
RX_LANE_MAP: 0x21437056
TX_POLARITY_FLIP: 0x78
RX_POLARITY_FLIP: 0x5c
?
PC_PM_ID: 13
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x32104567
RX_LANE_MAP: 0x64572310
TX_POLARITY_FLIP: 0xd6
RX_POLARITY_FLIP: 0xad
?
PC_PM_ID: 14
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x03172465
RX_LANE_MAP: 0x45173620
TX_POLARITY_FLIP: 0xed
RX_POLARITY_FLIP: 0x36
?
PC_PM_ID: 15
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x36175042
RX_LANE_MAP: 0x04176253
TX_POLARITY_FLIP: 0x10
RX_POLARITY_FLIP: 0xfa
?
PC_PM_ID: 16
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x74615203
RX_LANE_MAP: 0x51704236
TX_POLARITY_FLIP: 0x5f
RX_POLARITY_FLIP: 0x56
?
PC_PM_ID: 17
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x26374051
RX_LANE_MAP: 0x37046251
TX_POLARITY_FLIP: 0xaa
RX_POLARITY_FLIP: 0x21
?
PC_PM_ID: 18
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x45672310
RX_LANE_MAP: 0x32105476
TX_POLARITY_FLIP: 0x15
RX_POLARITY_FLIP: 0x92
?
PC_PM_ID: 19
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x70465321
RX_LANE_MAP: 0x63107542
TX_POLARITY_FLIP: 0xe6
RX_POLARITY_FLIP: 0xf2
?
PC_PM_ID: 20
CORE_INDEX: 0
:
TX_LANE_MAP_AUTO: 0
RX_LANE_MAP_AUTO: 0
TX_POLARITY_FLIP_AUTO: 0
RX_POLARITY_FLIP_AUTO: 0
TX_LANE_MAP: 0x23015476
RX_LANE_MAP: 0x64752301
TX_POLARITY_FLIP: 0x50
RX_POLARITY_FLIP: 0x6c
...
---
device:
0:
PC_PORT_PHYS_MAP:
?
# CPU port
PORT_ID: 0
:
PC_PHYS_PORT_ID: 0
?
PORT_ID: 1
:
PC_PHYS_PORT_ID: 1
?
PORT_ID: 3
:
PC_PHYS_PORT_ID: 9
?
PORT_ID: 5
:
PC_PHYS_PORT_ID: 13
?
PORT_ID: 7
:
PC_PHYS_PORT_ID: 17
?
PORT_ID: 9
:
PC_PHYS_PORT_ID: 21
?
PORT_ID: 11
:
PC_PHYS_PORT_ID: 25
?
PORT_ID: 13
:
PC_PHYS_PORT_ID: 29
?
PORT_ID: 15
:
PC_PHYS_PORT_ID: 33
?
PORT_ID: 20
:
PC_PHYS_PORT_ID: 41
?
PORT_ID: 22
:
PC_PHYS_PORT_ID: 45
?
PORT_ID: 24
:
PC_PHYS_PORT_ID: 49
?
PORT_ID: 26
:
PC_PHYS_PORT_ID: 53
?
PORT_ID: 28
:
PC_PHYS_PORT_ID: 57
?
PORT_ID: 30
:
PC_PHYS_PORT_ID: 61
?
PORT_ID: 32
:
PC_PHYS_PORT_ID: 65
?
PORT_ID: 34
:
PC_PHYS_PORT_ID: 73
?
PORT_ID: 40
:
PC_PHYS_PORT_ID: 81
?
PORT_ID: 42
:
PC_PHYS_PORT_ID: 85
?
PORT_ID: 44
:
PC_PHYS_PORT_ID: 89
?
PORT_ID: 46
:
PC_PHYS_PORT_ID: 93
?
PORT_ID: 48
:
PC_PHYS_PORT_ID: 97
?
PORT_ID: 50
:
PC_PHYS_PORT_ID: 101
?
PORT_ID: 52
:
PC_PHYS_PORT_ID: 105
?
PORT_ID: 54
:
PC_PHYS_PORT_ID: 113
?
PORT_ID: 60
:
PC_PHYS_PORT_ID: 121
?
PORT_ID: 62
:
PC_PHYS_PORT_ID: 129
?
PORT_ID: 64
:
PC_PHYS_PORT_ID: 137
?
PORT_ID: 66
:
PC_PHYS_PORT_ID: 141
?
PORT_ID: 68
:
PC_PHYS_PORT_ID: 145
?
PORT_ID: 70
:
PC_PHYS_PORT_ID: 149
?
PORT_ID: 72
:
PC_PHYS_PORT_ID: 153
?
PORT_ID: 74
:
PC_PHYS_PORT_ID: 157
...
---
device:
0:
PC_PORT:
?
PORT_ID: 0
:
ENABLE: 0
SPEED: 10000
NUM_LANES: 1
?
PORT_ID: [3, 5, 7, 9, 11, 13,
20, 22, 24, 26, 28, 30,
40, 42, 44, 46, 48, 50,
64, 66, 68, 70, 72, 74]
:
ENABLE: 0
SPEED: 200000
FEC_MODE: PC_FEC_RS544_2XN
NUM_LANES: 4
LINK_TRAINING: 0
MAX_FRAME_SIZE: 9416
?
PORT_ID: [1, 15, 32, 34, 52, 54, 60, 62]
:
ENABLE: 0
SPEED: 400000
FEC_MODE: PC_FEC_RS544_2XN
NUM_LANES: 8
LINK_TRAINING: 0
MAX_FRAME_SIZE: 9416
...
---
device:
0:
TM_SCHEDULER_CONFIG:
NUM_MC_Q: NUM_MC_Q_4
...
---
device:
0:
FP_CONFIG:
FP_ING_OPERMODE: GLOBAL_PIPE_AWARE
...
---
device:
0:
PORT_PROPERTY:
?
PORT_ID: 19
:
PORT_TYPE: 1
PORT_PARSER: 5
EGR_PORT_PROPERTY: 2
?
PORT_ID: 59
:
PORT_TYPE: 1
PORT_PARSER: 5
EGR_PORT_PROPERTY: 2
...

View File

@@ -0,0 +1,33 @@
# name lanes alias index speed
Ethernet1 25,26,27,28 Eth200GE0/1 1 200000
Ethernet2 29,30,31,32 Eth200GE0/2 2 200000
Ethernet3 41,42,43,44 Eth200GE0/3 3 200000
Ethernet4 45,46,47,48 Eth200GE0/4 4 200000
Ethernet5 49,50,51,52 Eth200GE0/5 5 200000
Ethernet6 53,54,55,56 Eth200GE0/6 6 200000
Ethernet7 57,58,59,60 Eth200GE0/7 7 200000
Ethernet8 61,62,63,64 Eth200GE0/8 8 200000
Ethernet9 9,10,11,12 Eth200GE0/9 9 200000
Ethernet10 13,14,15,16 Eth200GE0/10 10 200000
Ethernet11 17,18,19,20 Eth200GE0/11 11 200000
Ethernet12 21,22,23,24 Eth200GE0/12 12 200000
Ethernet13 81,82,83,84 Eth200GE0/13 13 200000
Ethernet14 85,86,87,88 Eth200GE0/14 14 200000
Ethernet15 89,90,91,92 Eth200GE0/15 15 200000
Ethernet16 93,94,95,96 Eth200GE0/16 16 200000
Ethernet17 97,98,99,100 Eth200GE0/17 17 200000
Ethernet18 101,102,103,104 Eth200GE0/18 18 200000
Ethernet19 137,138,139,140 Eth200GE0/19 19 200000
Ethernet20 141,142,143,144 Eth200GE0/20 20 200000
Ethernet21 145,146,147,148 Eth200GE0/21 21 200000
Ethernet22 149,150,151,152 Eth200GE0/22 22 200000
Ethernet23 153,154,155,156 Eth200GE0/23 23 200000
Ethernet24 157,158,159,160 Eth200GE0/24 24 200000
Ethernet25 1,2,3,4,5,6,7,8 Eth400GE0/25 25 400000
Ethernet26 33,34,35,36,37,38,39,40 Eth400GE0/26 26 400000
Ethernet27 65,66,67,68,69,70,71,72 Eth400GE0/27 27 400000
Ethernet28 73,74,75,76,77,78,79,80 Eth400GE0/28 28 400000
Ethernet29 105,106,107,108,109,110,111,112 Eth400GE0/29 29 400000
Ethernet30 113,114,115,116,117,118,119,120 Eth400GE0/30 30 400000
Ethernet31 121,122,123,124,125,126,127,128 Eth400GE0/31 31 400000
Ethernet32 129,130,131,132,133,134,135,136 Eth400GE0/32 32 400000

View File

@@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/TCS8400-24CC8CD.yml

View File

@@ -0,0 +1,268 @@
{
"DEVICE_METADATA": {
"localhost": {
"hwsku": "TCS8400-24CC8CD",
"platform": "x86_64-tencent_tcs8400-r0",
"mac": "58:69:6c:f1:23:12",
"hostname": "sonic"
}
},
"PORT": {
"Ethernet1": {
"lanes": "25,26,27,28",
"alias": "Eth200GE0/1",
"index": "1",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet2": {
"lanes": "29,30,31,32",
"alias": "Eth200GE0/2",
"index": "2",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet3": {
"lanes": "41,42,43,44",
"alias": "Eth200GE0/3",
"index": "3",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet4": {
"lanes": "45,46,47,48",
"alias": "Eth200GE0/4",
"index": "4",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet5": {
"lanes": "49,50,51,52",
"alias": "Eth200GE0/5",
"index": "5",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet6": {
"lanes": "53,54,55,56",
"alias": "Eth200GE0/6",
"index": "6",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet7": {
"lanes": "57,58,59,60",
"alias": "Eth200GE0/7",
"index": "7",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet8": {
"lanes": "61,62,63,64",
"alias": "Eth200GE0/8",
"index": "8",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet9": {
"lanes": "9,10,11,12",
"alias": "Eth200GE0/9",
"index": "9",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet10": {
"lanes": "13,14,15,16",
"alias": "Eth200GE0/10",
"index": "10",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet11": {
"lanes": "17,18,19,20",
"alias": "Eth200GE0/11",
"index": "11",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet12": {
"lanes": "21,22,23,24",
"alias": "Eth200GE0/12",
"index": "12",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet13": {
"lanes": "81,82,83,84",
"alias": "Eth200GE0/13",
"index": "13",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet14": {
"lanes": "85,86,87,88",
"alias": "Eth200GE0/14",
"index": "14",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet15": {
"lanes": "89,90,91,92",
"alias": "Eth200GE0/15",
"index": "15",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet16": {
"lanes": "93,94,95,96",
"alias": "Eth200GE0/16",
"index": "16",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet17": {
"lanes": "97,98,99,100",
"alias": "Eth200GE0/17",
"index": "17",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet18": {
"lanes": "101,102,103,104",
"alias": "Eth200GE0/18",
"index": "18",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet19": {
"lanes": "137,138,139,140",
"alias": "Eth200GE0/19",
"index": "19",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet20": {
"lanes": "141,142,143,144",
"alias": "Eth200GE0/20",
"index": "20",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet21": {
"lanes": "145,146,147,148",
"alias": "Eth200GE0/21",
"index": "21",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet22": {
"lanes": "149,150,151,152",
"alias": "Eth200GE0/22",
"index": "22",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet23": {
"lanes": "153,154,155,156",
"alias": "Eth200GE0/23",
"index": "23",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet24": {
"lanes": "157,158,159,160",
"alias": "Eth200GE0/24",
"index": "24",
"speed": "200000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet25": {
"lanes": "1,2,3,4,5,6,7,8",
"alias": "Eth400GE0/25",
"index": "25",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet26": {
"lanes": "33,34,35,36,37,38,39,40",
"alias": "Eth400GE0/26",
"index": "26",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet27": {
"lanes": "65,66,67,68,69,70,71,72",
"alias": "Eth400GE0/27",
"index": "27",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet28": {
"lanes": "73,74,75,76,77,78,79,80",
"alias": "Eth400GE0/28",
"index": "28",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet29": {
"lanes": "105,106,107,108,109,110,111,112",
"alias": "Eth400GE0/29",
"index": "29",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet30": {
"lanes": "113,114,115,116,117,118,119,120",
"alias": "Eth400GE0/30",
"index": "30",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet31": {
"lanes": "121,122,123,124,125,126,127,128",
"alias": "Eth400GE0/31",
"index": "31",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
},
"Ethernet32": {
"lanes": "129,130,131,132,133,134,135,136",
"alias": "Eth400GE0/32",
"index": "32",
"speed": "400000",
"admin_status": "up",
"mtu": "9100"
}
}
}

View File

@@ -0,0 +1,85 @@
cint_reset();
int cint_field_group_create(int unit, bcm_field_group_t grp)
{
int rv;
bcm_field_qset_t qset;
bcm_field_aset_t aset;
BCM_FIELD_QSET_INIT(qset);
BCM_FIELD_QSET_ADD(qset,bcmFieldQualifyDstMac);
BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageIngress);
BCM_FIELD_ASET_INIT(aset);
BCM_FIELD_ASET_ADD(aset, bcmFieldActionCopyToCpu);
rv = bcm_field_group_create_mode_id(unit, qset, 103, bcmFieldGroupModeAuto, grp);
if (rv != BCM_E_NONE) {
printf("bcm_field_group_create_mode_id failed, rv = %d\r\n", rv);
return -1;
}
printf("cint_field_group_create success!!!, rv = %d\r\n", rv);
bcm_field_group_dump(unit,grp);
return 0;
}
int cint_field_entry_create1(int unit, bcm_field_group_t grp,bcm_field_entry_t entry)
{
int rv;
bcm_mac_t dst_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bcm_mac_t mac_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
rv = bcm_field_entry_create_id(unit, grp, entry);
if (rv != BCM_E_NONE) {
printf("bcm_field_entry_create_id failed, rv = %d\r\n", rv);
return -1;
}
rv =bcm_field_qualify_DstMac(unit, entry, dst_mac, mac_mask);
if (rv != BCM_E_NONE) {
printf("bcm_field_qualify_DstMac failed,ret = %d\r\n", rv);
bcm_field_entry_destroy(unit, entry);
return -1;
}
rv = bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 1, 0);
if (rv != BCM_E_NONE) {
printf("bcm_field_action_add failed, rv = %d \r\n", rv);
bcm_field_entry_destroy(unit, entry);
return -1;
}
rv = bcm_field_action_add(unit, entry, bcmFieldActionDrop, 1, 0);
if (rv != BCM_E_NONE) {
printf("bcm_field_action_add failed, rv = %d \r\n", rv);
bcm_field_entry_destroy(unit, entry);
return -1;
}
rv = bcm_field_entry_install(unit, entry);
if (rv != BCM_E_NONE) {
printf("bcm_field_entry_install failed,ret = %d\r\n", rv);
bcm_field_entry_destroy(unit, entry);
return -1;
}
printf("********************* BEGIN ****************************\r\n");
bcm_field_entry_dump(unit, entry);
printf("*********************** END ****************************\r\n");
return 0;
}
cint_field_group_create(0,5);
cint_field_entry_create1(0,5,2048);
//bcm_field_entry_destroy(0, 2048);
//bcm_field_group_destroy(0, 5);

Binary file not shown.

View File

@@ -0,0 +1 @@
TCS8400-24CC8CD t1

View File

@@ -0,0 +1,349 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
### type 1 result/1000
type 2 result/100
type 3 read bit
### property need check must add int front
-->
<catalog>
<fans>
<fan id="fan1" >
<property name="present" location="/sys/rg_plat/fan/fan1/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan1/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan1/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/35-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan1/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan1/motor1/speed"/>
</fan>
<fan id="fan2" >
<property name="present" location="/sys/rg_plat/fan/fan2/present" type="4" decode="fanpresent" default="1" />
<property name="status" location="/sys/rg_plat/fan/fan2/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan2/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/34-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan2/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan2/motor1/speed"/>
</fan>
<fan id="fan3" >
<property name="present" location="/sys/rg_plat/fan/fan3/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan3/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan3/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/33-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan3/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan3/motor1/speed"/>
</fan>
<fan id="fan4" >
<property name="present" location="/sys/rg_plat/fan/fan4/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan4/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan4/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/32-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan4/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan4/motor1/speed"/>
</fan>
<fan id="fan5" >
<property name="present" location="/sys/rg_plat/fan/fan5/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan5/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan5/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/31-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan5/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan5/motor1/speed"/>
</fan>
<fan id="fan6" >
<property name="present" location="/sys/rg_plat/fan/fan6/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan6/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan6/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/30-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan6/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan6/motor1/speed"/>
</fan>
</fans>
<temps>
<temp id="air_inlet_TL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_input" type="1" addend="-3"/>
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_inlet_BL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_outlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_outlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_hotlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_PACKAGE0" >
<property name="temp1_input" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="MAC_PACKAGE1" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
</temps>
<psus>
<psu id="psu1" >
<property name="present" location="/sys/rg_plat/psu/psu1/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu1/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/41-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/41-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/41-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/41-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/41-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/41-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/41-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/41-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/41-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu2" >
<property name="present" location="/sys/rg_plat/psu/psu2/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu2/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/42-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/42-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/42-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/42-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/42-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/42-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/42-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/42-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/42-0058/hwmon/*/power2_input" type="5"/>
</psu>
</psus>
<dcdcs>
<dcdc id="VDD5V_CLK_MCU" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.345" />
<property name="dcdc_min" gettype="config" value="4.840" />
</dcdc>
<dcdc id="VDD3.3_CLK" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.560" />
<property name="dcdc_min" gettype="config" value="3.220" />
</dcdc>
<dcdc id="VDD1.0V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.049" />
<property name="dcdc_min" gettype="config" value="0.950" />
</dcdc>
<dcdc id="VDD1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.903" />
<property name="dcdc_min" gettype="config" value="1.720" />
</dcdc>
<dcdc id="MAC_BOARD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.499" />
<property name="dcdc_min" gettype="config" value="3.170" />
</dcdc>
<dcdc id="VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.272" />
<property name="dcdc_min" gettype="config" value="1.150" />
</dcdc>
<dcdc id="VDD_CORE" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.950" />
<property name="dcdc_min" gettype="config" value="0.670" />
</dcdc>
<dcdc id="ANALOG0.75V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.800" />
<property name="dcdc_min" gettype="config" value="0.700" />
</dcdc>
<dcdc id="MAC_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.259" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="VDDO1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.937" />
<property name="dcdc_min" gettype="config" value="1.750" />
</dcdc>
<dcdc id="MAC_ANA1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in11_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.276" />
<property name="dcdc_min" gettype="config" value="1.150" />
</dcdc>
<dcdc id="MAC_ANA1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in12_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.910" />
<property name="dcdc_min" gettype="config" value="1.730" />
</dcdc>
<dcdc id="QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in13_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.595" />
<property name="dcdc_min" gettype="config" value="3.250" />
</dcdc>
<dcdc id="QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in14_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.601" />
<property name="dcdc_min" gettype="config" value="3.260" />
</dcdc>
<dcdc id="QSFPDD_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in15_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.565" />
<property name="dcdc_min" gettype="config" value="3.230" />
</dcdc>
<dcdc id="QSFPDD_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in16_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.564" />
<property name="dcdc_min" gettype="config" value="3.220" />
</dcdc>
<dcdc id="VDD5.0V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.429" />
<property name="dcdc_min" gettype="config" value="4.910" />
</dcdc>
<dcdc id="SW_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.284" />
<property name="dcdc_min" gettype="config" value="1.160" />
</dcdc>
<dcdc id="VDD2.5V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="2.620" />
<property name="dcdc_min" gettype="config" value="2.370" />
</dcdc>
<dcdc id="CONNECT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.437" />
<property name="dcdc_min" gettype="config" value="3.110" />
</dcdc>
<dcdc id="VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.700" />
<property name="dcdc_min" gettype="config" value="11.300" />
</dcdc>
<dcdc id="VDD3.3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.489" />
<property name="dcdc_min" gettype="config" value="3.160" />
</dcdc>
<dcdc id="SSD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.475" />
<property name="dcdc_min" gettype="config" value="3.140" />
</dcdc>
<dcdc id="VCCIN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0060/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.879" />
<property name="dcdc_min" gettype="config" value="1.700" />
</dcdc>
<dcdc id="P1V05" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0060/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.103" />
<property name="dcdc_min" gettype="config" value="1.000" />
</dcdc>
<dcdc id="P1V2_VDDQ" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.258" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="P2V5_VPP" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in4_input" type="6" coefficient="1.124" />
<property name="dcdc_max" gettype="config" value="2.632" />
<property name="dcdc_min" gettype="config" value="2.380" />
</dcdc>
<dcdc id="P3V3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.476" />
<property name="dcdc_min" gettype="config" value="3.140" />
</dcdc>
<dcdc id="P5V_AUX_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.229" />
<property name="dcdc_min" gettype="config" value="4.730" />
</dcdc>
<dcdc id="P1V7_VCCSCFUSESUS_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.789" />
<property name="dcdc_min" gettype="config" value="1.620" />
</dcdc>
</dcdcs>
<mactemps>
<mactemp id="MAC_DIE_0" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp1_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_1" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp2_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_2" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp3_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_3" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp4_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_4" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp5_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_5" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp6_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_6" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp7_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_7" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp8_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_8" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp9_input" type="1"/>
</mactemp>
</mactemps>
<macpowers>
<macpower id="MAC_Core" >
<property name="power_input" location="/sys/bus/i2c/devices/43-005b/hwmon/hwmon*/power1_input" type="5"/>
</macpower>
<macpower id="MAC_Analog" >
<property name="power_input" location="/sys/bus/i2c/devices/43-005b/hwmon/hwmon*/power2_input" type="5"/>
</macpower>
</macpowers>
<cpus location="/sys/class/hwmon/hwmon0"/>
<decode>
<fanpresent>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</fanpresent>
<fanstatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</fanstatus>
<psucheck>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</psucheck>
<psustatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</psustatus>
<psutype>
<code key="DPS-1300AB-6" value="PSA1300CRPS-F"/>
<code key="GW-CRPS1300D" value="PSA1300CRPS-F"/>
<code key="DPS-1300AB-11" value="PSA1300CRPS-R"/>
<code key="CRPS1300D3R" value="PSA1300CRPS-R"/>
</psutype>
<fan_display_name>
<code key="FAN24K4056-F" value="FAN24K4056-F"/>
<code key="FAN24K4056S-F" value="FAN24K4056-F"/>
<code key="FAN24K4056S-R" value="FAN24K4056-R"/>
</fan_display_name>
<slotpresent>
<code key="1" value="ABSENT"/>
<code key="0" value="PRESENT"/>
</slotpresent>
</decode>
</catalog>

View File

@@ -0,0 +1,349 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
### type 1 result/1000
type 2 result/100
type 3 read bit
### property need check must add int front
-->
<catalog>
<fans>
<fan id="fan1" >
<property name="present" location="/sys/rg_plat/fan/fan1/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan1/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan1/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/35-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan1/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan1/motor1/speed"/>
</fan>
<fan id="fan2" >
<property name="present" location="/sys/rg_plat/fan/fan2/present" type="4" decode="fanpresent" default="1" />
<property name="status" location="/sys/rg_plat/fan/fan2/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan2/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/34-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan2/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan2/motor1/speed"/>
</fan>
<fan id="fan3" >
<property name="present" location="/sys/rg_plat/fan/fan3/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan3/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan3/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/33-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan3/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan3/motor1/speed"/>
</fan>
<fan id="fan4" >
<property name="present" location="/sys/rg_plat/fan/fan4/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan4/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan4/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/32-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan4/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan4/motor1/speed"/>
</fan>
<fan id="fan5" >
<property name="present" location="/sys/rg_plat/fan/fan5/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan5/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan5/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/31-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan5/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan5/motor1/speed"/>
</fan>
<fan id="fan6" >
<property name="present" location="/sys/rg_plat/fan/fan6/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan6/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan6/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/30-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan6/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan6/motor1/speed"/>
</fan>
</fans>
<temps>
<temp id="air_inlet_TL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_input" type="1" addend="-3"/>
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_inlet_BL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/39-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_outlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/36-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_outlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/36-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="air_hotlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004e/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_PACKAGE0" >
<property name="temp1_input" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/39-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="MAC_PACKAGE1" >
<property name="temp1_input" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/40-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
</temps>
<psus>
<psu id="psu1" >
<property name="present" location="/sys/rg_plat/psu/psu1/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu1/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/41-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/41-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/41-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/41-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/41-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/41-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/41-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/41-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/41-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu2" >
<property name="present" location="/sys/rg_plat/psu/psu2/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu2/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/42-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/42-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/42-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/42-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/42-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/42-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/42-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/42-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/42-0058/hwmon/*/power2_input" type="5"/>
</psu>
</psus>
<dcdcs>
<dcdc id="VDD5V_CLK_MCU" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.345" />
<property name="dcdc_min" gettype="config" value="4.840" />
</dcdc>
<dcdc id="VDD3.3_CLK" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.560" />
<property name="dcdc_min" gettype="config" value="3.220" />
</dcdc>
<dcdc id="VDD1.0V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.049" />
<property name="dcdc_min" gettype="config" value="0.950" />
</dcdc>
<dcdc id="VDD1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.903" />
<property name="dcdc_min" gettype="config" value="1.720" />
</dcdc>
<dcdc id="MAC_BOARD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.499" />
<property name="dcdc_min" gettype="config" value="3.170" />
</dcdc>
<dcdc id="VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.272" />
<property name="dcdc_min" gettype="config" value="1.150" />
</dcdc>
<dcdc id="VDD_CORE" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.950" />
<property name="dcdc_min" gettype="config" value="0.670" />
</dcdc>
<dcdc id="ANALOG0.75V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.800" />
<property name="dcdc_min" gettype="config" value="0.700" />
</dcdc>
<dcdc id="MAC_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.259" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="VDDO1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.937" />
<property name="dcdc_min" gettype="config" value="1.750" />
</dcdc>
<dcdc id="MAC_ANA1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in11_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.276" />
<property name="dcdc_min" gettype="config" value="1.150" />
</dcdc>
<dcdc id="MAC_ANA1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in12_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.910" />
<property name="dcdc_min" gettype="config" value="1.730" />
</dcdc>
<dcdc id="QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in13_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.595" />
<property name="dcdc_min" gettype="config" value="3.250" />
</dcdc>
<dcdc id="QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in14_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.601" />
<property name="dcdc_min" gettype="config" value="3.260" />
</dcdc>
<dcdc id="QSFPDD_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in15_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.565" />
<property name="dcdc_min" gettype="config" value="3.230" />
</dcdc>
<dcdc id="QSFPDD_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in16_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.564" />
<property name="dcdc_min" gettype="config" value="3.220" />
</dcdc>
<dcdc id="VDD5.0V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.429" />
<property name="dcdc_min" gettype="config" value="4.910" />
</dcdc>
<dcdc id="CONNECT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.437" />
<property name="dcdc_min" gettype="config" value="3.110" />
</dcdc>
<dcdc id="VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.700" />
<property name="dcdc_min" gettype="config" value="11.300" />
</dcdc>
<dcdc id="VDD3.3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.489" />
<property name="dcdc_min" gettype="config" value="3.160" />
</dcdc>
<dcdc id="SSD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.475" />
<property name="dcdc_min" gettype="config" value="3.140" />
</dcdc>
<dcdc id="PHY_VDD1V0" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.050" />
<property name="dcdc_min" gettype="config" value="0.950" />
</dcdc>
<dcdc id="ODD_PHY_M" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in11_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.444" />
<property name="dcdc_min" gettype="config" value="3.116" />
</dcdc>
<dcdc id="VCCIN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0060/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.879" />
<property name="dcdc_min" gettype="config" value="1.700" />
</dcdc>
<dcdc id="P1V05" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0060/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.103" />
<property name="dcdc_min" gettype="config" value="1.000" />
</dcdc>
<dcdc id="P1V2_VDDQ" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.258" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="P2V5_VPP" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in4_input" type="6" coefficient="1.124" />
<property name="dcdc_max" gettype="config" value="2.632" />
<property name="dcdc_min" gettype="config" value="2.380" />
</dcdc>
<dcdc id="P3V3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.476" />
<property name="dcdc_min" gettype="config" value="3.140" />
</dcdc>
<dcdc id="P5V_AUX_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.229" />
<property name="dcdc_min" gettype="config" value="4.730" />
</dcdc>
<dcdc id="P1V7_VCCSCFUSESUS_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.789" />
<property name="dcdc_min" gettype="config" value="1.620" />
</dcdc>
</dcdcs>
<mactemps>
<mactemp id="MAC_DIE_0" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp1_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_1" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp2_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_2" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp3_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_3" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp4_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_4" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp5_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_5" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp6_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_6" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp7_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_7" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp8_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_8" >
<property name="temp_input" location="/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp9_input" type="1"/>
</mactemp>
</mactemps>
<macpowers>
<macpower id="MAC_Core" >
<property name="power_input" location="/sys/bus/i2c/devices/43-005b/hwmon/hwmon*/power1_input" type="5"/>
</macpower>
<macpower id="MAC_Analog" >
<property name="power_input" location="/sys/bus/i2c/devices/43-005b/hwmon/hwmon*/power2_input" type="5"/>
</macpower>
</macpowers>
<cpus location="/sys/class/hwmon/hwmon0"/>
<decode>
<fanpresent>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</fanpresent>
<fanstatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</fanstatus>
<psucheck>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</psucheck>
<psustatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</psustatus>
<psutype>
<code key="DPS-1300AB-6" value="PSA1300CRPS-F"/>
<code key="GW-CRPS1300D" value="PSA1300CRPS-F"/>
<code key="DPS-1300AB-11" value="PSA1300CRPS-R"/>
<code key="CRPS1300D3R" value="PSA1300CRPS-R"/>
</psutype>
<fan_display_name>
<code key="FAN24K4056-F" value="FAN24K4056-F"/>
<code key="FAN24K4056S-F" value="FAN24K4056-F"/>
<code key="FAN24K4056S-R" value="FAN24K4056-R"/>
</fan_display_name>
<slotpresent>
<code key="1" value="ABSENT"/>
<code key="0" value="PRESENT"/>
</slotpresent>
</decode>
</catalog>

View File

@@ -0,0 +1,953 @@
#!/usr/bin/python3
import collections
from bitarray import bitarray
from datetime import datetime, timedelta
__DEBUG__ = "N"
class FruException(Exception):
def __init__(self, message='fruerror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
def e_print(err):
print("ERROR: " + err)
def d_print(debug_info):
if(__DEBUG__ == "Y"):
print(debug_info)
class FruUtil():
@staticmethod
def decodeLength(value):
a = bitarray(8)
a.setall(True)
a[0:1] = 0
a[1:2] = 0
x = ord(a.tobytes())
return x & ord(value)
@staticmethod
def minToData():
starttime = datetime(1996, 1, 1, 0, 0, 0)
endtime = datetime.now()
seconds = (endtime - starttime).total_seconds()
mins = seconds // 60
m = int(round(mins))
return m
@staticmethod
def getTimeFormat():
return datetime.now().strftime('%Y-%m-%d')
@staticmethod
def getTypeLength(value):
if value is None or len(value) == 0:
return 0
a = bitarray(8)
a.setall(False)
a[0:1] = 1
a[1:2] = 1
x = ord(a.tobytes())
return x | len(value)
@staticmethod
def checksum(b):
result = 0
for i in range(len(b)):
result += ord(b[i])
return (0x100 - (result & 0xff)) & 0xff
class BaseArea(object):
SUGGESTED_SIZE_COMMON_HEADER = 8
SUGGESTED_SIZE_INTERNAL_USE_AREA = 72
SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32
SUGGESTED_SIZE_BOARD_INFO_AREA = 80
SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80
INITVALUE = b'\x00'
resultvalue = INITVALUE * 256
COMMON_HEAD_VERSION = b'\x01'
__childList = None
def __init__(self, name="", size=0, offset=0):
self.__childList = []
self._offset = offset
self.name = name
self._size = size
self._isPresent = False
self._data = b'\x00' * size
self.__dataoffset = 0
@property
def childList(self):
return self.__childList
@childList.setter
def childList(self, value):
self.__childList = value
@property
def offset(self):
return self._offset
@offset.setter
def offset(self, value):
self._offset = value
@property
def size(self):
return self._size
@size.setter
def size(self, value):
self._size = value
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
@property
def isPresent(self):
return self._isPresent
@isPresent.setter
def isPresent(self, value):
self._isPresent = value
class InternalUseArea(BaseArea):
pass
class ChassisInfoArea(BaseArea):
pass
class BoardInfoArea(BaseArea):
_boardTime = None
_fields = None
_mfg_date = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"mfg_date : %s \n" \
"boardManufacturer : %s \n" \
"boardProductName : %s \n" \
"boardSerialNumber : %s \n" \
"boardPartNumber : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.boardversion), self.size,
self.language, self.getMfgRealData(),
self.boardManufacturer, self.boardProductName,
self.boardSerialNumber, self.boardPartNumber,
self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "boardextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["boardversion"] = ord(self.boardversion)
dic["boardlength"] = self.size
dic["boardlanguage"] = self.language
dic["boardmfg_date"] = self.getMfgRealData()
dic["boardManufacturer"] = self.boardManufacturer
dic["boardProductName"] = self.boardProductName
dic["boardSerialNumber"] = self.boardSerialNumber
dic["boardPartNumber"] = self.boardPartNumber
dic["boardfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index]
index += 1
d_print("decode length :%d class size:%d" %
((ord(self.data[index]) * 8), self.size))
index += 2
timetmp = self.data[index: index + 3]
self.mfg_date = ord(timetmp[0]) | (
ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16)
d_print("decode getMfgRealData :%s" % self.getMfgRealData())
index += 3
templen = FruUtil.decodeLength(self.data[index])
self.boardManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardManufacturer:%s" % self.boardManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.boardProductName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardProductName:%s" % self.boardProductName)
templen = FruUtil.decodeLength(self.data[index])
self.boardSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardSerialNumber:%s" % self.boardSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.boardPartNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardPartNumber:%s" % self.boardPartNumber)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if self.data[index] != chr(0xc1):
templen = FruUtil.decodeLength(self.data[index])
tmpval = self.data[index + 1: index + templen + 1]
setattr(self, valtmp, tmpval)
index += templen + 1
d_print("decode boardextra%d:%s" % (i, tmpval))
else:
break
return
def recalcute(self):
d_print("boardInfoArea version:%x" % ord(self.boardversion))
d_print("boardInfoArea length:%d" % self.size)
d_print("boardInfoArea language:%x" % self.language)
self.mfg_date = FruUtil.minToData()
d_print("boardInfoArea mfg_date:%x" % self.mfg_date)
self.data = chr(ord(self.boardversion)) + \
chr(self.size // 8) + chr(self.language)
self.data += chr(self.mfg_date & 0xFF)
self.data += chr((self.mfg_date >> 8) & 0xFF)
self.data += chr((self.mfg_date >> 16) & 0xFF)
d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer)
typelength = FruUtil.getTypeLength(self.boardManufacturer)
self.data += chr(typelength)
self.data += self.boardManufacturer
d_print("boardInfoArea boardProductName:%s" % self.boardProductName)
self.data += chr(FruUtil.getTypeLength(self.boardProductName))
self.data += self.boardProductName
d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber)
self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber))
self.data += self.boardSerialNumber
d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber)
self.data += chr(FruUtil.getTypeLength(self.boardPartNumber))
self.data += self.boardPartNumber
d_print("boardInfoArea fruFileId:%s" % self.fruFileId)
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
d_print("self data:%d" % len(self.data))
d_print("self size:%d" % self.size)
d_print("adjust size:%d" % (self.size - len(self.data) - 1))
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
# checksum
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
def getMfgRealData(self):
starttime = datetime(1996, 1, 1, 0, 0, 0)
mactime = starttime + timedelta(minutes=self.mfg_date)
return mactime
@property
def language(self):
self._language = 25
return self._language
@property
def mfg_date(self):
return self._mfg_date
@mfg_date.setter
def mfg_date(self, val):
self._mfg_date = val
@property
def boardversion(self):
self._boardversion = self.COMMON_HEAD_VERSION
return self._boardversion
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, val):
self._FRUFileID = val
@property
def boardPartNumber(self):
return self._boardPartNumber
@boardPartNumber.setter
def boardPartNumber(self, val):
self._boardPartNumber = val
@property
def boardSerialNumber(self):
return self._boardSerialNumber
@boardSerialNumber.setter
def boardSerialNumber(self, val):
self._boardSerialNumber = val
@property
def boardProductName(self):
return self._boradProductName
@boardProductName.setter
def boardProductName(self, val):
self._boradProductName = val
@property
def boardManufacturer(self):
return self._boardManufacturer
@boardManufacturer.setter
def boardManufacturer(self, val):
self._boardManufacturer = val
@property
def boardTime(self):
return self._boardTime
@boardTime.setter
def boardTime(self, val):
self._boardTime = val
@property
def fields(self):
return self._fields
@fields.setter
def fields(self, val):
self._fields = val
class ProductInfoArea(BaseArea):
_productManufacturer = None
_productAssetTag = None
_FRUFileID = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"productAssetTag : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.areaversion), self.size,
self.language, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber,
self.productAssetTag, self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "productextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["productversion"] = ord(self.areaversion)
dic["productlength"] = self.size
dic["productlanguage"] = self.language
dic["productManufacturer"] = self.productManufacturer
dic["productName"] = self.productName
dic["productPartModelName"] = self.productPartModelName
dic["productVersion"] = int(self.productVersion, 16)
dic["productSerialNumber"] = self.productSerialNumber
dic["productAssetTag"] = self.productAssetTag
dic["productfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index] # 0
index += 1
d_print("decode length %d" % (ord(self.data[index]) * 8))
d_print("class size %d" % self.size)
index += 2
templen = FruUtil.decodeLength(self.data[index])
self.productManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productManufacturer:%s" % self.productManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.productName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productName:%s" % self.productName)
templen = FruUtil.decodeLength(self.data[index])
self.productPartModelName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productPartModelName:%s" % self.productPartModelName)
templen = FruUtil.decodeLength(self.data[index])
self.productVersion = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productVersion:%s" % self.productVersion)
templen = FruUtil.decodeLength(self.data[index])
self.productSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productSerialNumber:%s" % self.productSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.productAssetTag = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productAssetTag:%s" % self.productAssetTag)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if self.data[index] != chr(0xc1) and index < self.size - 1:
templen = FruUtil.decodeLength(self.data[index])
if templen == 0:
break
tmpval = self.data[index + 1: index + templen + 1]
d_print("decode boardextra%d:%s" % (i, tmpval))
setattr(self, valtmp, tmpval)
index += templen + 1
else:
break
@property
def productVersion(self):
return self._productVersion
@productVersion.setter
def productVersion(self, name):
self._productVersion = name
@property
def areaversion(self):
self._areaversion = self.COMMON_HEAD_VERSION
return self._areaversion
@areaversion.setter
def areaversion(self, name):
self._areaversion = name
@property
def language(self):
self._language = 25
return self._language
@property
def productManufacturer(self):
return self._productManufacturer
@productManufacturer.setter
def productManufacturer(self, name):
self._productManufacturer = name
@property
def productName(self):
return self._productName
@productName.setter
def productName(self, name):
self._productName = name
@property
def productPartModelName(self):
return self._productPartModelName
@productPartModelName.setter
def productPartModelName(self, name):
self._productPartModelName = name
@property
def productSerialNumber(self):
return self._productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, name):
self._productSerialNumber = name
@property
def productAssetTag(self):
return self._productAssetTag
@productAssetTag.setter
def productAssetTag(self, name):
self._productAssetTag = name
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, name):
self._FRUFileID = name
def recalcute(self):
d_print("product version:%x" % ord(self.areaversion))
d_print("product length:%d" % self.size)
d_print("product language:%x" % self.language)
self.data = chr(ord(self.areaversion)) + \
chr(self.size // 8) + chr(self.language)
typelength = FruUtil.getTypeLength(self.productManufacturer)
self.data += chr(typelength)
self.data += self.productManufacturer
self.data += chr(FruUtil.getTypeLength(self.productName))
self.data += self.productName
self.data += chr(FruUtil.getTypeLength(self.productPartModelName))
self.data += self.productPartModelName
self.data += chr(FruUtil.getTypeLength(self.productVersion))
self.data += self.productVersion
self.data += chr(FruUtil.getTypeLength(self.productSerialNumber))
self.data += self.productSerialNumber
self.data += chr(FruUtil.getTypeLength(self.productAssetTag))
if self.productAssetTag is not None:
self.data += self.productAssetTag
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea productextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
d_print("self.data:%d" % len(self.data))
d_print("self.size:%d" % self.size)
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
class MultiRecordArea(BaseArea):
pass
class Field(object):
def __init__(self, fieldType="ASCII", fieldData=""):
self.fieldData = fieldData
self.fieldType = fieldType
@property
def data(self):
return self._data
@property
def fieldType(self):
return self._fieldType
@property
def fieldData(self):
return self._fieldData
class ipmifru(BaseArea):
_BoardInfoArea = None
_ProductInfoArea = None
_InternalUseArea = None
_ChassisInfoArea = None
_multiRecordArea = None
_productinfoAreaOffset = BaseArea.INITVALUE
_boardInfoAreaOffset = BaseArea.INITVALUE
_internalUserAreaOffset = BaseArea.INITVALUE
_chassicInfoAreaOffset = BaseArea.INITVALUE
_multiRecordAreaOffset = BaseArea.INITVALUE
_bindata = None
_bodybin = None
_version = BaseArea.COMMON_HEAD_VERSION
_zeroCheckSum = None
_frusize = 256
def __str__(self):
tmpstr = ""
if self.boardInfoArea.isPresent:
tmpstr += "\nboardinfoarea: \n"
tmpstr += self.boardInfoArea.__str__()
if self.productInfoArea.isPresent:
tmpstr += "\nproductinfoarea: \n"
tmpstr += self.productInfoArea.__str__()
return tmpstr
def decodeBin(self, eeprom):
commonHead = eeprom[0:8]
d_print("decode version %x" % ord(commonHead[0]))
if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]):
raise FruException("HEAD VERSION error,not Fru format!", -10)
if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]):
strtemp = "check header checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(commonHead[0:7]), ord(commonHead[7]))
raise FruException(strtemp, -3)
if ord(commonHead[1]) != ord(self.INITVALUE):
d_print("Internal Use Area is present")
self.internalUseArea = InternalUseArea(
name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA)
self.internalUseArea.isPresent = True
self.internalUserAreaOffset = ord(commonHead[1])
self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: (
self.internalUserAreaOffset * 8 + self.internalUseArea.size)]
if ord(commonHead[2]) != ord(self.INITVALUE):
d_print("Chassis Info Area is present")
self.chassisInfoArea = ChassisInfoArea(
name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA)
self.chassisInfoArea.isPresent = True
self.chassicInfoAreaOffset = ord(commonHead[2])
self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: (
self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)]
if ord(commonHead[3]) != ord(self.INITVALUE):
self.boardInfoArea = BoardInfoArea(
name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA)
self.boardInfoArea.isPresent = True
self.boardInfoAreaOffset = ord(commonHead[3])
self.boardInfoArea.size = ord(
eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8
d_print("Board Info Area is present size:%d" %
(self.boardInfoArea.size))
self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: (
self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)]
if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]):
strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \
(FruUtil.checksum(
self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.boardInfoArea.decodedata()
if ord(commonHead[4]) != ord(self.INITVALUE):
d_print("Product Info Area is present")
self.productInfoArea = ProductInfoArea(
name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA)
self.productInfoArea.isPresent = True
self.productinfoAreaOffset = ord(commonHead[4])
d_print("length offset value: %02x" %
ord(eeprom[self.productinfoAreaOffset * 8 + 1]))
self.productInfoArea.size = ord(
eeprom[self.productinfoAreaOffset * 8 + 1]) * 8
d_print("Product Info Area is present size:%d" %
(self.productInfoArea.size))
self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: (
self.productinfoAreaOffset * 8 + self.productInfoArea.size)]
if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]):
strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.productInfoArea.decodedata()
if ord(commonHead[5]) != ord(self.INITVALUE):
self.multiRecordArea = MultiRecordArea(
name="MultiRecord record Area ")
d_print("MultiRecord record present")
self.multiRecordArea.isPresent = True
self.multiRecordAreaOffset = ord(commonHead[5])
self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: (
self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)]
def initDefault(self):
self.version = self.COMMON_HEAD_VERSION
self.internalUserAreaOffset = self.INITVALUE
self.chassicInfoAreaOffset = self.INITVALUE
self.boardInfoAreaOffset = self.INITVALUE
self.productinfoAreaOffset = self.INITVALUE
self.multiRecordAreaOffset = self.INITVALUE
self.PAD = self.INITVALUE
self.zeroCheckSum = self.INITVALUE
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
self.productInfoArea = None
self.internalUseArea = None
self.boardInfoArea = None
self.chassisInfoArea = None
self.multiRecordArea = None
# self.recalcute()
@property
def version(self):
return self._version
@version.setter
def version(self, name):
self._version = name
@property
def internalUserAreaOffset(self):
return self._internalUserAreaOffset
@internalUserAreaOffset.setter
def internalUserAreaOffset(self, obj):
self._internalUserAreaOffset = obj
@property
def chassicInfoAreaOffset(self):
return self._chassicInfoAreaOffset
@chassicInfoAreaOffset.setter
def chassicInfoAreaOffset(self, obj):
self._chassicInfoAreaOffset = obj
@property
def productinfoAreaOffset(self):
return self._productinfoAreaOffset
@productinfoAreaOffset.setter
def productinfoAreaOffset(self, obj):
self._productinfoAreaOffset = obj
@property
def boardInfoAreaOffset(self):
return self._boardInfoAreaOffset
@boardInfoAreaOffset.setter
def boardInfoAreaOffset(self, obj):
self._boardInfoAreaOffset = obj
@property
def multiRecordAreaOffset(self):
return self._multiRecordAreaOffset
@multiRecordAreaOffset.setter
def multiRecordAreaOffset(self, obj):
self._multiRecordAreaOffset = obj
@property
def zeroCheckSum(self):
return self._zeroCheckSum
@zeroCheckSum.setter
def zeroCheckSum(self, obj):
self._zeroCheckSum = obj
@property
def productInfoArea(self):
return self._ProductInfoArea
@productInfoArea.setter
def productInfoArea(self, obj):
self._ProductInfoArea = obj
@property
def internalUseArea(self):
return self._InternalUseArea
@internalUseArea.setter
def internalUseArea(self, obj):
self.internalUseArea = obj
@property
def boardInfoArea(self):
return self._BoardInfoArea
@boardInfoArea.setter
def boardInfoArea(self, obj):
self._BoardInfoArea = obj
@property
def chassisInfoArea(self):
return self._ChassisInfoArea
@chassisInfoArea.setter
def chassisInfoArea(self, obj):
self._ChassisInfoArea = obj
@property
def multiRecordArea(self):
return self._multiRecordArea
@multiRecordArea.setter
def multiRecordArea(self, obj):
self._multiRecordArea = obj
@property
def bindata(self):
return self._bindata
@bindata.setter
def bindata(self, obj):
self._bindata = obj
@property
def bodybin(self):
return self._bodybin
@bodybin.setter
def bodybin(self, obj):
self._bodybin = obj
def recalcuteCommonHead(self):
self.bindata = ""
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
d_print("common Header %d" % self.offset)
d_print("fru eeprom size %d" % self._frusize)
if self.internalUseArea is not None and self.internalUseArea.isPresent:
self.internalUserAreaOffset = self.offset // 8
self.offset += self.internalUseArea.size
d_print("internalUseArea is present offset:%d" % self.offset)
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
self.chassicInfoAreaOffset = self.offset // 8
self.offset += self.chassisInfoArea.size
d_print("chassisInfoArea is present offset:%d" % self.offset)
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
self.boardInfoAreaOffset = self.offset // 8
self.offset += self.boardInfoArea.size
d_print("boardInfoArea is present offset:%d" % self.offset)
d_print("boardInfoArea is present size:%d" %
self.boardInfoArea.size)
if self.productInfoArea is not None and self.productInfoArea.isPresent:
self.productinfoAreaOffset = self.offset // 8
self.offset += self.productInfoArea.size
d_print("productInfoArea is present offset:%d" % self.offset)
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
self.multiRecordAreaOffset = self.offset // 8
d_print("multiRecordArea is present offset:%d" % self.offset)
if self.internalUserAreaOffset == self.INITVALUE:
self.internalUserAreaOffset = 0
if self.productinfoAreaOffset == self.INITVALUE:
self.productinfoAreaOffset = 0
if self.chassicInfoAreaOffset == self.INITVALUE:
self.chassicInfoAreaOffset = 0
if self.boardInfoAreaOffset == self.INITVALUE:
self.boardInfoAreaOffset = 0
if self.multiRecordAreaOffset == self.INITVALUE:
self.multiRecordAreaOffset = 0
self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset
- self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff
d_print("zerochecksum:%x" % self.zeroCheckSum)
self.data = ""
self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr(
self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum)
self.bindata = self.data + self.bodybin
totallen = len(self.bindata)
d_print("totallen %d" % totallen)
if (totallen < self._frusize):
self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0]))
else:
raise FruException('bin data more than %d' % self._frusize, -2)
def recalcutebin(self):
self.bodybin = ""
if self.internalUseArea is not None and self.internalUseArea.isPresent:
d_print("internalUseArea present")
self.bodybin += self.internalUseArea.data
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
d_print("chassisInfoArea present")
self.bodybin += self.chassisInfoArea.data
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
d_print("boardInfoArea present")
self.boardInfoArea.recalcute()
self.bodybin += self.boardInfoArea.data
if self.productInfoArea is not None and self.productInfoArea.isPresent:
d_print("productInfoAreapresent")
self.productInfoArea.recalcute()
self.bodybin += self.productInfoArea.data
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
d_print("multiRecordArea present")
self.bodybin += self.productInfoArea.data
def recalcute(self, fru_eeprom_size=256):
self._frusize = fru_eeprom_size
self.recalcutebin()
self.recalcuteCommonHead()

View File

@@ -0,0 +1 @@
CONSOLE_SPEED=115200

View File

@@ -0,0 +1,6 @@
led auto on
led start
linkscan SwPortBitMap=all

View File

@@ -0,0 +1,431 @@
#!/usr/bin/python3
# * onboard temperature sensors
# * FAN trays
# * PSU
#
import os
import xml.etree.ElementTree as ET
import glob
from fru import ipmifru
from decimal import Decimal
MAILBOX_DIR = "/sys/bus/i2c/devices/"
BOARD_ID_PATH = "/sys/module/ruijie_common/parameters/dfd_my_type"
CONFIG_NAME = "dev.xml"
def byteTostr(val):
strtmp = ''
for i in range(len(val)):
strtmp += chr(val[i])
return strtmp
def typeTostr(val):
if isinstance(val, bytes):
strtmp = byteTostr(val)
return strtmp
return val
def get_board_id():
if not os.path.exists(BOARD_ID_PATH):
return "NA"
with open(BOARD_ID_PATH) as fd:
id_str = fd.read().strip()
return "0x%x" % (int(id_str, 10))
def dev_file_read(path, offset, read_len):
retval = "ERR"
val_list = []
msg = ""
ret = ""
fd = -1
if not os.path.exists(path):
return False, "%s %s not found" % (retval, path)
try:
fd = os.open(path, os.O_RDONLY)
os.lseek(fd, offset, os.SEEK_SET)
ret = os.read(fd, read_len)
for item in ret:
val_list.append(item)
except Exception as e:
msg = str(e)
return False, "%s %s" % (retval, msg)
finally:
if fd > 0:
os.close(fd)
return True, val_list
def getPMCreg(location):
retval = 'ERR'
if (not os.path.isfile(location)):
return "%s %s notfound"% (retval , location)
try:
with open(location, 'r') as fd:
retval = fd.read()
except Exception as error:
return "ERR %s" % str(error)
retval = retval.rstrip('\r\n')
retval = retval.lstrip(" ")
return retval
# Get a mailbox register
def get_pmc_register(reg_name):
retval = 'ERR'
mb_reg_file = reg_name
filepath = glob.glob(mb_reg_file)
if(len(filepath) == 0):
return "%s %s notfound"% (retval , mb_reg_file)
mb_reg_file = filepath[0]
if (not os.path.isfile(mb_reg_file)):
#print mb_reg_file, 'not found !'
return "%s %s notfound"% (retval , mb_reg_file)
try:
with open(mb_reg_file, 'rb') as fd:
retval = fd.read()
retval = typeTostr(retval)
except Exception as error:
retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error))
retval = retval.rstrip('\r\n')
retval = retval.lstrip(" ")
return retval
class checktype():
def __init__(self, test1):
self.test1 = test1
@staticmethod
def check(name,location, bit, value, tips , err1):
psu_status = int(get_pmc_register(location),16)
val = (psu_status & (1<< bit)) >> bit
if (val != value):
err1["errmsg"] = tips
err1["code"] = -1
return -1
else:
err1["errmsg"] = "none"
err1["code"] = 0
return 0
@staticmethod
def getValue(location, bit , type, coefficient = 1, addend = 0):
try:
value_t = get_pmc_register(location)
if value_t.startswith("ERR") :
return value_t
if (type == 1):
return float('%.1f' % ((float(value_t)/1000) + addend))
elif (type == 2):
return float('%.1f' % (float(value_t)/100))
elif (type == 3):
psu_status = int(value_t,16)
return (psu_status & (1<< bit)) >> bit
elif (type == 4):
return int(value_t,10)
elif (type == 5):
return float('%.1f' % (float(value_t)/1000/1000))
elif (type == 6):
return Decimal(float(value_t)*coefficient/1000).quantize(Decimal('0.000'))
else:
return value_t
except Exception as e:
value_t = "ERR %s" % str(e)
return value_t
#######temp
@staticmethod
def getTemp(self, name, location , ret_t):
ret2 = self.getValue(location + "temp1_input" ," " ,1);
ret3 = self.getValue(location + "temp1_max" ," ", 1);
ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1);
ret_t["temp1_input"] = ret2
ret_t["temp1_max"] = ret3
ret_t["temp1_max_hyst"] = ret4
@staticmethod
def getLM75(name, location, result):
c1=checktype
r1={}
c1.getTemp(c1, name, location, r1)
result[name] = r1
##########fanFRU
@staticmethod
def decodeBinByValue(retval):
fru = ipmifru()
fru.decodeBin(retval)
return fru
@staticmethod
def printbinvalue(b):
index = 0
print(" ",)
for width in range(16):
print("%02x " % width,)
print("")
for i in range(0, len(b)):
if index % 16 == 0:
print(" ")
print(" %02x " % i,)
print("%02x " % ord(b[i]),)
index += 1
print("")
@staticmethod
def getfruValue(prob_t, root, val):
try:
ret, binval_bytes = dev_file_read(val, 0, 256)
if ret == False:
return binval_bytes
binval = byteTostr(binval_bytes)
fanpro = {}
ret = checktype.decodeBinByValue(binval)
fanpro['fan_type'] = ret.productInfoArea.productName
fanpro['hw_version'] = ret.productInfoArea.productVersion
fanpro['sn'] = ret.productInfoArea.productSerialNumber
fanpro['fanid'] = ret.productInfoArea.productextra2
fan_display_name_dict = status.getDecodValue(root, "fan_display_name")
fan_name = fanpro['fan_type'].strip()
if len(fan_display_name_dict) == 0:
return fanpro
if fan_name not in fan_display_name_dict.keys():
prob_t['errcode']= -1
prob_t['errmsg'] = '%s'% ("ERR fan name: %s not support" % fan_name)
else:
fanpro['fan_type'] = fan_display_name_dict[fan_name]
return fanpro
except Exception as error:
return "ERR " + str(error)
@staticmethod
def getslotfruValue(val):
try:
binval = checktype.getValue(val, 0 , 0)
if binval.startswith("ERR"):
return binval
slotpro = {}
ret = checktype.decodeBinByValue(binval)
slotpro['slot_type'] = ret.boardInfoArea.boardProductName
slotpro['hw_version'] = ret.boardInfoArea.boardextra1
slotpro['sn'] = ret.boardInfoArea.boardSerialNumber
return slotpro
except Exception as error:
return "ERR " + str(error)
@staticmethod
def getpsufruValue(prob_t, root, val):
try:
psu_match = False
binval = checktype.getValue(val, 0 , 0)
if binval.startswith("ERR"):
return binval
psupro = {}
ret = checktype.decodeBinByValue(binval)
psupro['type1'] = ret.productInfoArea.productPartModelName
psupro['sn'] = ret.productInfoArea.productSerialNumber
psupro['hw_version'] = ret.productInfoArea.productVersion
psu_dict = status.getDecodValue(root, "psutype")
psupro['type1'] = psupro['type1'].strip()
if len(psu_dict) == 0:
return psupro
for psu_name in psu_dict.keys():
if psu_name in psupro['type1']:
psupro['type1'] = psu_dict[psu_name]
psu_match = True
break
if psu_match is not True:
prob_t['errcode']= -1
prob_t['errmsg'] = '%s'% ("ERR psu name: %s not support" % psupro['type1'])
return psupro
except Exception as error:
return "ERR " + str(error)
class status():
def __init__(self, productname):
self.productname = productname
@staticmethod
def getETroot(filename):
tree = ET.parse(filename)
root = tree.getroot()
return root;
@staticmethod
def getDecodValue(collection, decode):
decodes = collection.find('decode')
testdecode = decodes.find(decode)
test={}
if testdecode is None:
return test
for neighbor in testdecode.iter('code'):
test[neighbor.attrib["key"]]=neighbor.attrib["value"]
return test
@staticmethod
def getfileValue(location):
return checktype.getValue(location," "," ")
@staticmethod
def getETValue(a, filename, tagname):
root = status.getETroot(filename)
for neighbor in root.iter(tagname):
prob_t = {}
prob_t = neighbor.attrib
prob_t['errcode']= 0
prob_t['errmsg'] = ''
for pros in neighbor.iter("property"):
ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items()))
if ret.get('e2type') == 'fru' and ret.get("name") == "fru":
fruval = checktype.getfruValue(prob_t, root, ret["location"])
if isinstance(fruval, str) and fruval.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= fruval
break
else:
prob_t.update(fruval)
continue
if ret.get("name") == "psu" and ret.get('e2type') == 'fru':
psuval = checktype.getpsufruValue(prob_t, root, ret["location"])
if isinstance(psuval, str) and psuval.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= psuval
break
else:
prob_t.update(psuval)
continue
if ret.get("gettype") == "config":
prob_t[ret["name"]] = ret["value"]
continue
if ('type' not in ret.keys()):
val = "0";
else:
val = ret["type"]
if ('bit' not in ret.keys()):
bit = "0";
else:
bit = ret["bit"]
if ('coefficient' not in ret.keys()):
coefficient = 1;
else:
coefficient = float(ret["coefficient"])
if ('addend' not in ret.keys()):
addend = 0;
else:
addend = float(ret["addend"])
s = checktype.getValue(ret["location"], int(bit),int(val), coefficient, addend)
if isinstance(s, str) and s.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= s
break
if ('default' in ret.keys()):
rt = status.getDecodValue(root,ret['decode'])
prob_t['errmsg']= rt[str(s)]
if str(s) != ret["default"]:
prob_t['errcode']= -1
break
else:
if ('decode' in ret.keys()):
rt = status.getDecodValue(root,ret['decode'])
if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()):
prob_t['errcode']= -1
prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % (s.replace("\x00","").rstrip()))
else:
s = rt[str(s).replace("\x00","").rstrip()]
name = ret["name"]
prob_t[name]=str(s)
a.append(prob_t)
@staticmethod
def getCPUValue(a, filename, tagname):
root = status.getETroot(filename)
for neighbor in root.iter(tagname):
location = neighbor.attrib["location"]
L=[]
for dirpath, dirnames, filenames in os.walk(location):
for file in filenames :
if file.endswith("input"):
L.append(os.path.join(dirpath, file))
L =sorted(L,reverse=False)
for i in range(len(L)):
prob_t = {}
prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1))
prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000
prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000
prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000
prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000
a.append(prob_t)
@staticmethod
def getFileName():
fpath = os.path.dirname(os.path.realpath(__file__))
board_id = get_board_id()
dev_id_xml = fpath + "/" + "dev_%s.xml" % board_id
if os.path.exists(dev_id_xml):
return dev_id_xml
return fpath + "/"+ CONFIG_NAME
@staticmethod
def getFan(ret):
_filename = status.getFileName()
_tagname = "fan"
status.getvalue(ret, _filename, _tagname)
@staticmethod
def checkFan(ret):
_filename = status.getFileName()
# _filename = "/usr/local/bin/" + status.getFileName()
_tagname = "fan"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getTemp(ret):
_filename = status.getFileName()
#_filename = "/usr/local/bin/" + status.getFileName()
_tagname = "temp"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getPsu(ret):
_filename = status.getFileName()
# _filename = "/usr/local/bin/" + status.getFileName()
_tagname = "psu"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getcputemp(ret):
_filename = status.getFileName()
_tagname = "cpus"
status.getCPUValue(ret, _filename, _tagname)
@staticmethod
def getDcdc(ret):
_filename = status.getFileName()
_tagname = "dcdc"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getmactemp(ret):
_filename = status.getFileName()
_tagname = "mactemp"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getmacpower(ret):
_filename = status.getFileName()
_tagname = "macpower"
status.getETValue(ret, _filename, _tagname)

View File

@@ -0,0 +1 @@
broadcom

View File

@@ -0,0 +1,2 @@
SYNCD_SHM_SIZE=1g
is_ltsw_chip=1

View File

@@ -0,0 +1,17 @@
void set_port_prbs(int unit_port, int enable){
int status;
bcm_port_control_set(0, unit_port, bcmPortControlPrbsPolynomial, 6);
bcm_port_control_set(0, unit_port, bcmPortControlPrbsRxEnable, 0);
bcm_port_control_set(0, unit_port, bcmPortControlPrbsTxEnable, 0);
if(enable == 1){
bcm_port_control_set(0, unit_port, bcmPortControlPrbsRxEnable, 1);
bcm_port_control_set(0, unit_port, bcmPortControlPrbsTxEnable, 1);
bcm_port_control_get(0, unit_port, bcmPortControlPrbsRxStatus, &status);
}
}
int get_port_prbs_result(int unit_port){
int status;
bcm_port_control_get(0, unit_port, bcmPortControlPrbsRxStatus, &status);
return status;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
# name lanes alias index speed
Ethernet1 81,82,83,84 Eth200GE0/1 1 200000
Ethernet2 83,84,85,86 Eth200GE0/2 2 200000
Ethernet3 89,90,91,92 Eth200GE0/3 3 200000
Ethernet4 91,92,93,94 Eth200GE0/4 4 200000
Ethernet5 93,94,95,96 Eth200GE0/5 5 200000
Ethernet6 95,96,97,98 Eth200GE0/6 6 200000
Ethernet7 85,86,87,88 Eth200GE0/7 7 200000
Ethernet8 87,88,89,90 Eth200GE0/8 8 200000
Ethernet9 41,42,43,44 Eth200GE0/9 9 200000
Ethernet10 43,44,45,46 Eth200GE0/10 10 200000
Ethernet11 37,38,39,40 Eth200GE0/11 11 200000
Ethernet12 39,40,41,42 Eth200GE0/12 12 200000
Ethernet13 45,46,47,48 Eth200GE0/13 13 200000
Ethernet14 47,48,49,50 Eth200GE0/14 14 200000
Ethernet15 33,34,35,36 Eth200GE0/15 15 200000
Ethernet16 35,36,37,38 Eth200GE0/16 16 200000
Ethernet17 221,222,223,224 Eth200GE0/17 17 200000
Ethernet18 223,224,225,226 Eth200GE0/18 18 200000
Ethernet19 209,210,211,212 Eth200GE0/19 19 200000
Ethernet20 211,212,213,214 Eth200GE0/20 20 200000
Ethernet21 217,218,219,220 Eth200GE0/21 21 200000
Ethernet22 219,220,221,222 Eth200GE0/22 22 200000
Ethernet23 213,214,215,216 Eth200GE0/23 23 200000
Ethernet24 215,216,217,218 Eth200GE0/24 24 200000
Ethernet25 165,166,167,168 Eth200GE0/25 25 200000
Ethernet26 167,168,169,170 Eth200GE0/26 26 200000
Ethernet27 173,174,175,176 Eth200GE0/27 27 200000
Ethernet28 175,176,177,178 Eth200GE0/28 28 200000
Ethernet29 161,162,163,164 Eth200GE0/29 29 200000
Ethernet30 163,164,165,166 Eth200GE0/30 30 200000
Ethernet31 169,170,171,172 Eth200GE0/31 31 200000
Ethernet32 171,172,173,174 Eth200GE0/32 32 200000
Ethernet33 9,10,11,12 Eth200GE0/33 33 200000
Ethernet34 11,12,13,14 Eth200GE0/34 34 200000
Ethernet35 13,14,15,16 Eth200GE0/35 35 200000
Ethernet36 15,16,17,18 Eth200GE0/36 36 200000
Ethernet37 21,22,23,24 Eth200GE0/37 37 200000
Ethernet38 23,24,25,26 Eth200GE0/38 38 200000
Ethernet39 29,30,31,32 Eth200GE0/39 39 200000
Ethernet40 31,32,33,34 Eth200GE0/40 40 200000
Ethernet41 101,102,103,104 Eth200GE0/41 41 200000
Ethernet42 103,104,105,106 Eth200GE0/42 42 200000
Ethernet43 109,110,111,112 Eth200GE0/43 43 200000
Ethernet44 111,112,113,114 Eth200GE0/44 44 200000
Ethernet45 113,114,115,116 Eth200GE0/45 45 200000
Ethernet46 115,116,117,118 Eth200GE0/46 46 200000
Ethernet47 117,118,119,120 Eth200GE0/47 47 200000
Ethernet48 119,120,121,122 Eth200GE0/48 48 200000
Ethernet49 137,138,139,140 Eth200GE0/49 49 200000
Ethernet50 139,140,141,142 Eth200GE0/50 50 200000
Ethernet51 141,142,143,144 Eth200GE0/51 51 200000
Ethernet52 143,144,145,146 Eth200GE0/52 52 200000
Ethernet53 145,146,147,148 Eth200GE0/53 53 200000
Ethernet54 147,148,149,150 Eth200GE0/54 54 200000
Ethernet55 153,154,155,156 Eth200GE0/55 55 200000
Ethernet56 155,156,157,158 Eth200GE0/56 56 200000
Ethernet57 225,226,227,228 Eth200GE0/57 57 200000
Ethernet58 227,228,229,230 Eth200GE0/58 58 200000
Ethernet59 233,234,235,236 Eth200GE0/59 59 200000
Ethernet60 235,236,237,238 Eth200GE0/60 60 200000
Ethernet61 241,242,243,244 Eth200GE0/61 61 200000
Ethernet62 243,244,245,246 Eth200GE0/62 62 200000
Ethernet63 245,246,247,248 Eth200GE0/63 63 200000
Ethernet64 247,248,249,250 Eth200GE0/64 64 200000
Ethernet65 5,6,7,8 Eth200GE0/65 65 200000
Ethernet66 7,8,9,10 Eth200GE0/66 66 200000
Ethernet67 1,2,3,4 Eth200GE0/67 67 200000
Ethernet68 3,4,5,6 Eth200GE0/68 68 200000
Ethernet69 17,18,19,20 Eth200GE0/69 69 200000
Ethernet70 19,20,21,22 Eth200GE0/70 70 200000
Ethernet71 25,26,27,28 Eth200GE0/71 71 200000
Ethernet72 27,28,29,30 Eth200GE0/72 72 200000
Ethernet73 97,98,99,100 Eth200GE0/73 73 200000
Ethernet74 99,100,101,102 Eth200GE0/74 74 200000
Ethernet75 105,106,107,108 Eth200GE0/75 75 200000
Ethernet76 107,108,109,110 Eth200GE0/76 76 200000
Ethernet77 125,126,127,128 Eth200GE0/77 77 200000
Ethernet78 127,128,129,130 Eth200GE0/78 78 200000
Ethernet79 121,122,123,124 Eth200GE0/79 79 200000
Ethernet80 123,124,125,126 Eth200GE0/80 80 200000
Ethernet81 133,134,135,136 Eth200GE0/81 81 200000
Ethernet82 135,136,137,138 Eth200GE0/82 82 200000
Ethernet83 129,130,131,132 Eth200GE0/83 83 200000
Ethernet84 131,132,133,134 Eth200GE0/84 84 200000
Ethernet85 149,150,151,152 Eth200GE0/85 85 200000
Ethernet86 151,152,153,154 Eth200GE0/86 86 200000
Ethernet87 157,158,159,160 Eth200GE0/87 87 200000
Ethernet88 159,160,161,162 Eth200GE0/88 88 200000
Ethernet89 229,230,231,232 Eth200GE0/89 89 200000
Ethernet90 231,232,233,234 Eth200GE0/90 90 200000
Ethernet91 237,238,239,240 Eth200GE0/91 91 200000
Ethernet92 239,240,241,242 Eth200GE0/92 92 200000
Ethernet93 253,254,255,256 Eth200GE0/93 93 200000
Ethernet94 255,256,257,258 Eth200GE0/94 94 200000
Ethernet95 249,250,251,252 Eth200GE0/95 95 200000
Ethernet96 251,252,253,254 Eth200GE0/96 96 200000
Ethernet97 65,66,67,68 Eth200GE0/97 97 200000
Ethernet98 67,68,69,70 Eth200GE0/98 98 200000
Ethernet99 73,74,75,76 Eth200GE0/99 99 200000
Ethernet100 75,76,77,78 Eth200GE0/100 100 200000
Ethernet101 69,70,71,72 Eth200GE0/101 101 200000
Ethernet102 71,72,73,74 Eth200GE0/102 102 200000
Ethernet103 77,78,79,80 Eth200GE0/103 103 200000
Ethernet104 79,80,81,82 Eth200GE0/104 104 200000
Ethernet105 57,58,59,60 Eth200GE0/105 105 200000
Ethernet106 59,60,61,62 Eth200GE0/106 106 200000
Ethernet107 53,54,55,56 Eth200GE0/107 107 200000
Ethernet108 55,56,57,58 Eth200GE0/108 108 200000
Ethernet109 61,62,63,64 Eth200GE0/109 109 200000
Ethernet110 63,64,65,66 Eth200GE0/110 110 200000
Ethernet111 49,50,51,52 Eth200GE0/111 111 200000
Ethernet112 51,52,53,54 Eth200GE0/112 112 200000
Ethernet113 205,206,207,208 Eth200GE0/113 113 200000
Ethernet114 207,208,209,210 Eth200GE0/114 114 200000
Ethernet115 193,194,195,196 Eth200GE0/115 115 200000
Ethernet116 195,196,197,198 Eth200GE0/116 116 200000
Ethernet117 201,202,203,204 Eth200GE0/117 117 200000
Ethernet118 203,204,205,206 Eth200GE0/118 118 200000
Ethernet119 197,198,199,200 Eth200GE0/119 119 200000
Ethernet120 199,200,201,202 Eth200GE0/120 120 200000
Ethernet121 177,178,179,180 Eth200GE0/121 121 200000
Ethernet122 179,180,181,182 Eth200GE0/122 122 200000
Ethernet123 185,186,187,188 Eth200GE0/123 123 200000
Ethernet124 187,188,189,190 Eth200GE0/124 124 200000
Ethernet125 181,182,183,184 Eth200GE0/125 125 200000
Ethernet126 183,184,185,186 Eth200GE0/126 126 200000
Ethernet127 189,190,191,192 Eth200GE0/127 127 200000

View File

@@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/TCS9400-128CC.yml

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1 @@
TCS9400-128CC t1

View File

@@ -0,0 +1,572 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
### type 1 result/1000
type 2 result/100
type 3 read bit
### property need check must add int front
-->
<catalog>
<fans>
<fan id="fan1" >
<property name="present" location="/sys/rg_plat/fan/fan1/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan1/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan1/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/90-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan1/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan1/motor1/speed"/>
</fan>
<fan id="fan2" >
<property name="present" location="/sys/rg_plat/fan/fan2/present" type="4" decode="fanpresent" default="1" />
<property name="status" location="/sys/rg_plat/fan/fan2/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan2/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/98-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan2/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan2/motor1/speed"/>
</fan>
<fan id="fan3" >
<property name="present" location="/sys/rg_plat/fan/fan3/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan3/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan3/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/91-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan3/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan3/motor1/speed"/>
</fan>
<fan id="fan4" >
<property name="present" location="/sys/rg_plat/fan/fan4/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan4/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan4/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/99-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan4/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan4/motor1/speed"/>
</fan>
<fan id="fan5" >
<property name="present" location="/sys/rg_plat/fan/fan5/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan5/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan5/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/92-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan5/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan5/motor1/speed"/>
</fan>
<fan id="fan6" >
<property name="present" location="/sys/rg_plat/fan/fan6/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan6/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan6/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/100-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan6/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan6/motor1/speed"/>
</fan>
<fan id="fan7" >
<property name="present" location="/sys/rg_plat/fan/fan7/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan7/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan7/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/93-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan7/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan7/motor1/speed"/>
</fan>
<fan id="fan8" >
<property name="present" location="/sys/rg_plat/fan/fan8/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan8/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan8/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/101-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan8/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan8/motor1/speed"/>
</fan>
</fans>
<temps>
<temp id="air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Uport_air_inlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Uport_air_inlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Dport_air_inlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Dport_air_inlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Base_air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_air_outlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_TEMPDIODE0" >
<property name="temp1_input" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="MAC_TEMPDIODE1" >
<property name="temp1_input" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_UL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_UR" >
<property name="temp1_input" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_DL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_DR" >
<property name="temp1_input" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
</temps>
<psus>
<psu id="psu1" >
<property name="present" location="/sys/rg_plat/psu/psu1/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu1/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/79-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/79-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/79-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/79-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/79-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/79-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/79-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/79-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/79-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu2" >
<property name="present" location="/sys/rg_plat/psu/psu2/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu2/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/80-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/80-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/80-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/80-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/80-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/80-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/80-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/80-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/80-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu3" >
<property name="present" location="/sys/rg_plat/psu/psu3/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu3/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/82-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/82-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/82-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/82-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/82-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/82-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/82-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/82-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/82-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu4" >
<property name="present" location="/sys/rg_plat/psu/psu4/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu4/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/81-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/81-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/81-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/81-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/81-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/81-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/81-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/81-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/81-0058/hwmon/*/power2_input" type="5"/>
</psu>
</psus>
<dcdcs>
<dcdc id="MAC_VDD_ANALOG1" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.809" />
<property name="dcdc_min" gettype="config" value="0.731" />
</dcdc>
<dcdc id="MAC_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="MAC_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.071" />
<property name="dcdc_min" gettype="config" value="0.969" />
</dcdc>
<dcdc id="MAC_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.890" />
<property name="dcdc_min" gettype="config" value="1.710" />
</dcdc>
<dcdc id="MAC_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="MAC_SW_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD5V_CLK_MCU" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.334" />
<property name="dcdc_min" gettype="config" value="4.826" />
</dcdc>
<dcdc id="MAC_VDD5V_VR" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.334" />
<property name="dcdc_min" gettype="config" value="4.826" />
</dcdc>
<dcdc id="MAC_VDD3.3_CLK" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.486" />
<property name="dcdc_min" gettype="config" value="3.154" />
</dcdc>
<dcdc id="MAC_VDDO1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in11_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="MAC_VDDO1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in12_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD_CORE" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in13_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.950" />
<property name="dcdc_min" gettype="config" value="0.700" />
</dcdc>
<dcdc id="MAC_VDD_ANALOG" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in14_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.809" />
<property name="dcdc_min" gettype="config" value="0.731" />
</dcdc>
<dcdc id="MAC_VDD1.2V_MAC" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in15_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_AVDD1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in16_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.890" />
<property name="dcdc_min" gettype="config" value="1.710" />
</dcdc>
<dcdc id="BASE_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="BASE_SW_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="BASE_VDD2.5V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="2.615" />
<property name="dcdc_min" gettype="config" value="2.365" />
</dcdc>
<dcdc id="BASE_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.444" />
<property name="dcdc_min" gettype="config" value="3.116" />
</dcdc>
<dcdc id="BASE_SSD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="CPU_VCCIN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0060/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.950" />
<property name="dcdc_min" gettype="config" value="1.600" />
</dcdc>
<dcdc id="CPU_P1V05" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0060/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.100" />
<property name="dcdc_min" gettype="config" value="1.000" />
</dcdc>
<dcdc id="CPU_P1V2_VDDQ" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-006c/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.160" />
</dcdc>
<dcdc id="CPU_P2V5_VPP" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-006c/hwmon/hwmon*/in4_input" type="6" coefficient="1.124" />
<property name="dcdc_max" gettype="config" value="2.750" />
<property name="dcdc_min" gettype="config" value="2.375" />
</dcdc>
<dcdc id="CPU_P3V3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="CPU_P5V_AUX_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.500" />
<property name="dcdc_min" gettype="config" value="4.250" />
</dcdc>
<dcdc id="CPU_P1V7_VCCSCFUSESUS_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.785" />
<property name="dcdc_min" gettype="config" value="1.615" />
</dcdc>
<dcdc id="UPORT_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.061" />
<property name="dcdc_min" gettype="config" value="0.959" />
</dcdc>
<dcdc id="UPORT_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="UPORT_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="UPORT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_VDD3.3_MON" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="UPORT_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="DPORT_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.061" />
<property name="dcdc_min" gettype="config" value="0.959" />
</dcdc>
<dcdc id="DPORT_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="DPORT_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="DPORT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_VDD3.3_MON" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="DPORT_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in0/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in1/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in2/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in3/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_E" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in4/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_F" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in5/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_G" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in6/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_H" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in7/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
</dcdcs>
<mactemps>
<mactemp id="MAC_DIE_0" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp1_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_1" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp2_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_2" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp3_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_3" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp4_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_4" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp5_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_5" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp6_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_6" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp7_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_7" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp8_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_8" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp9_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_9" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp10_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_10" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp11_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_11" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp12_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_12" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp13_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_13" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp14_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_14" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp15_input" type="1"/>
</mactemp>
</mactemps>
<macpowers>
<macpower id="MAC_Core" >
<property name="power_input" location="/sys/bus/i2c/devices/75-0010/hwmon/*/power1_input" type="5"/>
</macpower>
<macpower id="MAC_Analog" >
<property name="power_input" location="/sys/bus/i2c/devices/76-005a/hwmon/*/power3_input" type="5"/>
</macpower>
</macpowers>
<cpus location="/sys/class/hwmon/hwmon0"/>
<decode>
<fanpresent>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</fanpresent>
<fanstatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</fanstatus>
<psucheck>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</psucheck>
<psustatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</psustatus>
<psutype>
<code key="DPS-1300AB-6" value="PSA1300CRPS-F"/>
<code key="GW-CRPS1300D" value="PSA1300CRPS-F"/>
<code key="DPS-1300AB-11" value="PSA1300CRPS-R"/>
<code key="CRPS1300D3R" value="PSA1300CRPS-R"/>
</psutype>
<fan_display_name>
<code key="FAN12K8080-F" value="FAN12K8080-F"/>
</fan_display_name>
<slotpresent>
<code key="1" value="ABSENT"/>
<code key="0" value="PRESENT"/>
</slotpresent>
</decode>
</catalog>

View File

@@ -0,0 +1,572 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
### type 1 result/1000
type 2 result/100
type 3 read bit
### property need check must add int front
-->
<catalog>
<fans>
<fan id="fan1" >
<property name="present" location="/sys/rg_plat/fan/fan1/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan1/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan1/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/90-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan1/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan1/motor1/speed"/>
</fan>
<fan id="fan2" >
<property name="present" location="/sys/rg_plat/fan/fan2/present" type="4" decode="fanpresent" default="1" />
<property name="status" location="/sys/rg_plat/fan/fan2/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan2/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/98-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan2/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan2/motor1/speed"/>
</fan>
<fan id="fan3" >
<property name="present" location="/sys/rg_plat/fan/fan3/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan3/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan3/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/91-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan3/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan3/motor1/speed"/>
</fan>
<fan id="fan4" >
<property name="present" location="/sys/rg_plat/fan/fan4/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan4/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan4/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/99-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan4/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan4/motor1/speed"/>
</fan>
<fan id="fan5" >
<property name="present" location="/sys/rg_plat/fan/fan5/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan5/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan5/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/92-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan5/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan5/motor1/speed"/>
</fan>
<fan id="fan6" >
<property name="present" location="/sys/rg_plat/fan/fan6/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan6/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan6/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/100-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan6/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan6/motor1/speed"/>
</fan>
<fan id="fan7" >
<property name="present" location="/sys/rg_plat/fan/fan7/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan7/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan7/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/93-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan7/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan7/motor1/speed"/>
</fan>
<fan id="fan8" >
<property name="present" location="/sys/rg_plat/fan/fan8/present" type="4" decode="fanpresent" default="1"/>
<property name="status" location="/sys/rg_plat/fan/fan8/motor0/status" type="4" decode="fanstatus" default="1"/>
<property name="status2" location="/sys/rg_plat/fan/fan8/motor1/status" type="4" decode="fanstatus" default="1"/>
<property name="fru" e2type="fru" location="/sys/bus/i2c/devices/101-0050/eeprom"/>
<property name="rotor1_speed" location="/sys/rg_plat/fan/fan8/motor0/speed"/>
<property name="rotor2_speed" location="/sys/rg_plat/fan/fan8/motor1/speed"/>
</fan>
</fans>
<temps>
<temp id="air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/107-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Uport_air_inlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/64-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Uport_air_inlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/63-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Dport_air_inlet_L" >
<property name="temp1_input" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/114-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Dport_air_inlet_R" >
<property name="temp1_input" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/115-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/69-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="Base_air_inlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/109-004b/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_air_outlet" >
<property name="temp1_input" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/70-004f/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="MAC_TEMPDIODE0" >
<property name="temp1_input" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/71-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="MAC_TEMPDIODE1" >
<property name="temp1_input" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/72-004c/hwmon/*/temp2_crit_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_UL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/88-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_UR" >
<property name="temp1_input" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/89-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_DL" >
<property name="temp1_input" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/96-0048/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
<temp id="FCB_air_outlet_DR" >
<property name="temp1_input" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_input" type="1" />
<property name="temp1_max" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_max" type="1" />
<property name="temp1_max_hyst" location="/sys/bus/i2c/devices/97-0049/hwmon/*/temp1_max_hyst" type="1"/>
</temp>
</temps>
<psus>
<psu id="psu1" >
<property name="present" location="/sys/rg_plat/psu/psu1/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu1/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/79-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/79-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/79-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/79-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/79-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/79-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/79-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/79-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/79-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu2" >
<property name="present" location="/sys/rg_plat/psu/psu2/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu2/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/80-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/80-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/80-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/80-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/80-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/80-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/80-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/80-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/80-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu3" >
<property name="present" location="/sys/rg_plat/psu/psu3/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu3/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/82-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/82-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/82-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/82-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/82-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/82-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/82-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/82-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/82-0058/hwmon/*/power2_input" type="5"/>
</psu>
<psu id="psu4" >
<property name="present" location="/sys/rg_plat/psu/psu4/present" type="4" decode="psucheck" default="1"/>
<property name="status" location="/sys/rg_plat/psu/psu4/output" type="4" decode="psustatus" default="1"/>
<property name="psu" e2type="fru" location="/sys/bus/i2c/devices/81-0050/eeprom"/>
<property name="in_current" location="/sys/bus/i2c/devices/81-0058/hwmon/*/curr1_input" type="1" />
<property name="in_voltage" location="/sys/bus/i2c/devices/81-0058/hwmon/*/in1_input" type="1"/>
<property name="out_voltage" location="/sys/bus/i2c/devices/81-0058/hwmon/*/in2_input" type="1" />
<property name="out_current" location="/sys/bus/i2c/devices/81-0058/hwmon/*/curr2_input" type="1" />
<property name="temp" location="/sys/bus/i2c/devices/81-0058/hwmon/*/temp1_input" type="1"/>
<property name="fan_speed" location="/sys/bus/i2c/devices/81-0058/hwmon/*/fan1_input" />
<property name="in_power" location="/sys/bus/i2c/devices/81-0058/hwmon/*/power1_input" type="5"/>
<property name="out_power" location="/sys/bus/i2c/devices/81-0058/hwmon/*/power2_input" type="5"/>
</psu>
</psus>
<dcdcs>
<dcdc id="MAC_VDD_ANALOG1" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.809" />
<property name="dcdc_min" gettype="config" value="0.731" />
</dcdc>
<dcdc id="MAC_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="MAC_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.071" />
<property name="dcdc_min" gettype="config" value="0.969" />
</dcdc>
<dcdc id="MAC_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.890" />
<property name="dcdc_min" gettype="config" value="1.710" />
</dcdc>
<dcdc id="MAC_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="MAC_SW_VDD1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD5V_CLK_MCU" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.334" />
<property name="dcdc_min" gettype="config" value="4.826" />
</dcdc>
<dcdc id="MAC_VDD5V_VR" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.334" />
<property name="dcdc_min" gettype="config" value="4.826" />
</dcdc>
<dcdc id="MAC_VDD3.3_CLK" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.486" />
<property name="dcdc_min" gettype="config" value="3.154" />
</dcdc>
<dcdc id="MAC_VDDO1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in11_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="MAC_VDDO1.2V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in12_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_VDD_CORE" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in13_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.950" />
<property name="dcdc_min" gettype="config" value="0.700" />
</dcdc>
<dcdc id="MAC_VDD_ANALOG" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in14_input" type="6" />
<property name="dcdc_max" gettype="config" value="0.809" />
<property name="dcdc_min" gettype="config" value="0.731" />
</dcdc>
<dcdc id="MAC_VDD1.2V_MAC" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in15_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="MAC_AVDD1.8V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/73-005b/hwmon/hwmon*/in16_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.890" />
<property name="dcdc_min" gettype="config" value="1.710" />
</dcdc>
<dcdc id="BASE_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="BASE_SW_VDD1.0V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.050" />
<property name="dcdc_min" gettype="config" value="0.950" />
</dcdc>
<dcdc id="BASE_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.444" />
<property name="dcdc_min" gettype="config" value="3.116" />
</dcdc>
<dcdc id="BASE_SW_OVDD" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.444" />
<property name="dcdc_min" gettype="config" value="3.116" />
</dcdc>
<dcdc id="BASE_SSD_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/105-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="CPU_VCCIN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0060/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.950" />
<property name="dcdc_min" gettype="config" value="1.600" />
</dcdc>
<dcdc id="CPU_P1V05" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0060/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.100" />
<property name="dcdc_min" gettype="config" value="1.000" />
</dcdc>
<dcdc id="CPU_P1V2_VDDQ" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-006c/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.160" />
</dcdc>
<dcdc id="CPU_P2V5_VPP" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-006c/hwmon/hwmon*/in4_input" type="6" coefficient="1.124" />
<property name="dcdc_max" gettype="config" value="2.750" />
<property name="dcdc_min" gettype="config" value="2.375" />
</dcdc>
<dcdc id="CPU_P3V3_STBY" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="CPU_P5V_AUX_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="5.500" />
<property name="dcdc_min" gettype="config" value="4.250" />
</dcdc>
<dcdc id="CPU_P1V7_VCCSCFUSESUS_IN" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/106-0043/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.785" />
<property name="dcdc_min" gettype="config" value="1.615" />
</dcdc>
<dcdc id="UPORT_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.061" />
<property name="dcdc_min" gettype="config" value="0.959" />
</dcdc>
<dcdc id="UPORT_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="UPORT_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="UPORT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_QSFP56_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="UPORT_VDD3.3_MON" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="UPORT_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/62-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="DPORT_VDD1.0V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in1_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.061" />
<property name="dcdc_min" gettype="config" value="0.959" />
</dcdc>
<dcdc id="DPORT_VDD1.8V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in2_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.901" />
<property name="dcdc_min" gettype="config" value="1.719" />
</dcdc>
<dcdc id="DPORT_VDD1.2V_FPGA" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in3_input" type="6" />
<property name="dcdc_max" gettype="config" value="1.260" />
<property name="dcdc_min" gettype="config" value="1.140" />
</dcdc>
<dcdc id="DPORT_VDD3.3V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in4_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in5_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in6_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in7_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_QSFP56_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in8_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="DPORT_VDD3.3_MON" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in9_input" type="6" />
<property name="dcdc_max" gettype="config" value="3.465" />
<property name="dcdc_min" gettype="config" value="3.135" />
</dcdc>
<dcdc id="DPORT_VDD12V" >
<property name="dcdc_input" location="/sys/bus/i2c/devices/113-005b/hwmon/hwmon*/in10_input" type="6" />
<property name="dcdc_max" gettype="config" value="12.600" />
<property name="dcdc_min" gettype="config" value="11.400" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_A" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in0/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_B" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in1/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_C" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in2/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_D" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in3/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_E" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in4/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_F" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in5/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_G" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in6/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
<dcdc id="MAC_QSFPDD_VDD3.3V_H" >
<property name="dcdc_input" location="/sys/rg_plat/sensor/in7/in_input" type="0" />
<property name="dcdc_max" gettype="config" value="3.600" />
<property name="dcdc_min" gettype="config" value="3.200" />
</dcdc>
</dcdcs>
<mactemps>
<mactemp id="MAC_DIE_0" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp1_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_1" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp2_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_2" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp3_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_3" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp4_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_4" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp5_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_5" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp6_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_6" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp7_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_7" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp8_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_8" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp9_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_9" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp10_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_10" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp11_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_11" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp12_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_12" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp13_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_13" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp14_input" type="1"/>
</mactemp>
<mactemp id="MAC_DIE_14" >
<property name="temp_input" location="/sys/bus/i2c/devices/74-0044/hwmon/hwmon*/temp15_input" type="1"/>
</mactemp>
</mactemps>
<macpowers>
<macpower id="MAC_Core" >
<property name="power_input" location="/sys/bus/i2c/devices/75-0010/hwmon/*/power1_input" type="5"/>
</macpower>
<macpower id="MAC_Analog" >
<property name="power_input" location="/sys/bus/i2c/devices/76-005a/hwmon/*/power3_input" type="5"/>
</macpower>
</macpowers>
<cpus location="/sys/class/hwmon/hwmon0"/>
<decode>
<fanpresent>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</fanpresent>
<fanstatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</fanstatus>
<psucheck>
<code key="1" value="PRESENT"/>
<code key="0" value="ABSENT"/>
</psucheck>
<psustatus>
<code key="1" value="OK"/>
<code key="0" value="NOT OK"/>
</psustatus>
<psutype>
<code key="DPS-1300AB-6" value="PSA1300CRPS-F"/>
<code key="GW-CRPS1300D" value="PSA1300CRPS-F"/>
<code key="DPS-1300AB-11" value="PSA1300CRPS-R"/>
<code key="CRPS1300D3R" value="PSA1300CRPS-R"/>
</psutype>
<fan_display_name>
<code key="FAN12K8080-F" value="FAN12K8080-F"/>
</fan_display_name>
<slotpresent>
<code key="1" value="ABSENT"/>
<code key="0" value="PRESENT"/>
</slotpresent>
</decode>
</catalog>

View File

@@ -0,0 +1,953 @@
#!/usr/bin/python3
import collections
from bitarray import bitarray
from datetime import datetime, timedelta
__DEBUG__ = "N"
class FruException(Exception):
def __init__(self, message='fruerror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
def e_print(err):
print("ERROR: " + err)
def d_print(debug_info):
if(__DEBUG__ == "Y"):
print(debug_info)
class FruUtil():
@staticmethod
def decodeLength(value):
a = bitarray(8)
a.setall(True)
a[0:1] = 0
a[1:2] = 0
x = ord(a.tobytes())
return x & ord(value)
@staticmethod
def minToData():
starttime = datetime(1996, 1, 1, 0, 0, 0)
endtime = datetime.now()
seconds = (endtime - starttime).total_seconds()
mins = seconds // 60
m = int(round(mins))
return m
@staticmethod
def getTimeFormat():
return datetime.now().strftime('%Y-%m-%d')
@staticmethod
def getTypeLength(value):
if value is None or len(value) == 0:
return 0
a = bitarray(8)
a.setall(False)
a[0:1] = 1
a[1:2] = 1
x = ord(a.tobytes())
return x | len(value)
@staticmethod
def checksum(b):
result = 0
for i in range(len(b)):
result += ord(b[i])
return (0x100 - (result & 0xff)) & 0xff
class BaseArea(object):
SUGGESTED_SIZE_COMMON_HEADER = 8
SUGGESTED_SIZE_INTERNAL_USE_AREA = 72
SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32
SUGGESTED_SIZE_BOARD_INFO_AREA = 80
SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80
INITVALUE = b'\x00'
resultvalue = INITVALUE * 256
COMMON_HEAD_VERSION = b'\x01'
__childList = None
def __init__(self, name="", size=0, offset=0):
self.__childList = []
self._offset = offset
self.name = name
self._size = size
self._isPresent = False
self._data = b'\x00' * size
self.__dataoffset = 0
@property
def childList(self):
return self.__childList
@childList.setter
def childList(self, value):
self.__childList = value
@property
def offset(self):
return self._offset
@offset.setter
def offset(self, value):
self._offset = value
@property
def size(self):
return self._size
@size.setter
def size(self, value):
self._size = value
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
@property
def isPresent(self):
return self._isPresent
@isPresent.setter
def isPresent(self, value):
self._isPresent = value
class InternalUseArea(BaseArea):
pass
class ChassisInfoArea(BaseArea):
pass
class BoardInfoArea(BaseArea):
_boardTime = None
_fields = None
_mfg_date = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"mfg_date : %s \n" \
"boardManufacturer : %s \n" \
"boardProductName : %s \n" \
"boardSerialNumber : %s \n" \
"boardPartNumber : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.boardversion), self.size,
self.language, self.getMfgRealData(),
self.boardManufacturer, self.boardProductName,
self.boardSerialNumber, self.boardPartNumber,
self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "boardextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["boardversion"] = ord(self.boardversion)
dic["boardlength"] = self.size
dic["boardlanguage"] = self.language
dic["boardmfg_date"] = self.getMfgRealData()
dic["boardManufacturer"] = self.boardManufacturer
dic["boardProductName"] = self.boardProductName
dic["boardSerialNumber"] = self.boardSerialNumber
dic["boardPartNumber"] = self.boardPartNumber
dic["boardfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index]
index += 1
d_print("decode length :%d class size:%d" %
((ord(self.data[index]) * 8), self.size))
index += 2
timetmp = self.data[index: index + 3]
self.mfg_date = ord(timetmp[0]) | (
ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16)
d_print("decode getMfgRealData :%s" % self.getMfgRealData())
index += 3
templen = FruUtil.decodeLength(self.data[index])
self.boardManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardManufacturer:%s" % self.boardManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.boardProductName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardProductName:%s" % self.boardProductName)
templen = FruUtil.decodeLength(self.data[index])
self.boardSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardSerialNumber:%s" % self.boardSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.boardPartNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardPartNumber:%s" % self.boardPartNumber)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if self.data[index] != chr(0xc1):
templen = FruUtil.decodeLength(self.data[index])
tmpval = self.data[index + 1: index + templen + 1]
setattr(self, valtmp, tmpval)
index += templen + 1
d_print("decode boardextra%d:%s" % (i, tmpval))
else:
break
return
def recalcute(self):
d_print("boardInfoArea version:%x" % ord(self.boardversion))
d_print("boardInfoArea length:%d" % self.size)
d_print("boardInfoArea language:%x" % self.language)
self.mfg_date = FruUtil.minToData()
d_print("boardInfoArea mfg_date:%x" % self.mfg_date)
self.data = chr(ord(self.boardversion)) + \
chr(self.size // 8) + chr(self.language)
self.data += chr(self.mfg_date & 0xFF)
self.data += chr((self.mfg_date >> 8) & 0xFF)
self.data += chr((self.mfg_date >> 16) & 0xFF)
d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer)
typelength = FruUtil.getTypeLength(self.boardManufacturer)
self.data += chr(typelength)
self.data += self.boardManufacturer
d_print("boardInfoArea boardProductName:%s" % self.boardProductName)
self.data += chr(FruUtil.getTypeLength(self.boardProductName))
self.data += self.boardProductName
d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber)
self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber))
self.data += self.boardSerialNumber
d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber)
self.data += chr(FruUtil.getTypeLength(self.boardPartNumber))
self.data += self.boardPartNumber
d_print("boardInfoArea fruFileId:%s" % self.fruFileId)
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
d_print("self data:%d" % len(self.data))
d_print("self size:%d" % self.size)
d_print("adjust size:%d" % (self.size - len(self.data) - 1))
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
# checksum
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
def getMfgRealData(self):
starttime = datetime(1996, 1, 1, 0, 0, 0)
mactime = starttime + timedelta(minutes=self.mfg_date)
return mactime
@property
def language(self):
self._language = 25
return self._language
@property
def mfg_date(self):
return self._mfg_date
@mfg_date.setter
def mfg_date(self, val):
self._mfg_date = val
@property
def boardversion(self):
self._boardversion = self.COMMON_HEAD_VERSION
return self._boardversion
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, val):
self._FRUFileID = val
@property
def boardPartNumber(self):
return self._boardPartNumber
@boardPartNumber.setter
def boardPartNumber(self, val):
self._boardPartNumber = val
@property
def boardSerialNumber(self):
return self._boardSerialNumber
@boardSerialNumber.setter
def boardSerialNumber(self, val):
self._boardSerialNumber = val
@property
def boardProductName(self):
return self._boradProductName
@boardProductName.setter
def boardProductName(self, val):
self._boradProductName = val
@property
def boardManufacturer(self):
return self._boardManufacturer
@boardManufacturer.setter
def boardManufacturer(self, val):
self._boardManufacturer = val
@property
def boardTime(self):
return self._boardTime
@boardTime.setter
def boardTime(self, val):
self._boardTime = val
@property
def fields(self):
return self._fields
@fields.setter
def fields(self, val):
self._fields = val
class ProductInfoArea(BaseArea):
_productManufacturer = None
_productAssetTag = None
_FRUFileID = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"productAssetTag : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.areaversion), self.size,
self.language, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber,
self.productAssetTag, self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "productextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["productversion"] = ord(self.areaversion)
dic["productlength"] = self.size
dic["productlanguage"] = self.language
dic["productManufacturer"] = self.productManufacturer
dic["productName"] = self.productName
dic["productPartModelName"] = self.productPartModelName
dic["productVersion"] = int(self.productVersion, 16)
dic["productSerialNumber"] = self.productSerialNumber
dic["productAssetTag"] = self.productAssetTag
dic["productfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index] # 0
index += 1
d_print("decode length %d" % (ord(self.data[index]) * 8))
d_print("class size %d" % self.size)
index += 2
templen = FruUtil.decodeLength(self.data[index])
self.productManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productManufacturer:%s" % self.productManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.productName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productName:%s" % self.productName)
templen = FruUtil.decodeLength(self.data[index])
self.productPartModelName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productPartModelName:%s" % self.productPartModelName)
templen = FruUtil.decodeLength(self.data[index])
self.productVersion = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productVersion:%s" % self.productVersion)
templen = FruUtil.decodeLength(self.data[index])
self.productSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productSerialNumber:%s" % self.productSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.productAssetTag = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productAssetTag:%s" % self.productAssetTag)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if self.data[index] != chr(0xc1) and index < self.size - 1:
templen = FruUtil.decodeLength(self.data[index])
if templen == 0:
break
tmpval = self.data[index + 1: index + templen + 1]
d_print("decode boardextra%d:%s" % (i, tmpval))
setattr(self, valtmp, tmpval)
index += templen + 1
else:
break
@property
def productVersion(self):
return self._productVersion
@productVersion.setter
def productVersion(self, name):
self._productVersion = name
@property
def areaversion(self):
self._areaversion = self.COMMON_HEAD_VERSION
return self._areaversion
@areaversion.setter
def areaversion(self, name):
self._areaversion = name
@property
def language(self):
self._language = 25
return self._language
@property
def productManufacturer(self):
return self._productManufacturer
@productManufacturer.setter
def productManufacturer(self, name):
self._productManufacturer = name
@property
def productName(self):
return self._productName
@productName.setter
def productName(self, name):
self._productName = name
@property
def productPartModelName(self):
return self._productPartModelName
@productPartModelName.setter
def productPartModelName(self, name):
self._productPartModelName = name
@property
def productSerialNumber(self):
return self._productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, name):
self._productSerialNumber = name
@property
def productAssetTag(self):
return self._productAssetTag
@productAssetTag.setter
def productAssetTag(self, name):
self._productAssetTag = name
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, name):
self._FRUFileID = name
def recalcute(self):
d_print("product version:%x" % ord(self.areaversion))
d_print("product length:%d" % self.size)
d_print("product language:%x" % self.language)
self.data = chr(ord(self.areaversion)) + \
chr(self.size // 8) + chr(self.language)
typelength = FruUtil.getTypeLength(self.productManufacturer)
self.data += chr(typelength)
self.data += self.productManufacturer
self.data += chr(FruUtil.getTypeLength(self.productName))
self.data += self.productName
self.data += chr(FruUtil.getTypeLength(self.productPartModelName))
self.data += self.productPartModelName
self.data += chr(FruUtil.getTypeLength(self.productVersion))
self.data += self.productVersion
self.data += chr(FruUtil.getTypeLength(self.productSerialNumber))
self.data += self.productSerialNumber
self.data += chr(FruUtil.getTypeLength(self.productAssetTag))
if self.productAssetTag is not None:
self.data += self.productAssetTag
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea productextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
d_print("self.data:%d" % len(self.data))
d_print("self.size:%d" % self.size)
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
class MultiRecordArea(BaseArea):
pass
class Field(object):
def __init__(self, fieldType="ASCII", fieldData=""):
self.fieldData = fieldData
self.fieldType = fieldType
@property
def data(self):
return self._data
@property
def fieldType(self):
return self._fieldType
@property
def fieldData(self):
return self._fieldData
class ipmifru(BaseArea):
_BoardInfoArea = None
_ProductInfoArea = None
_InternalUseArea = None
_ChassisInfoArea = None
_multiRecordArea = None
_productinfoAreaOffset = BaseArea.INITVALUE
_boardInfoAreaOffset = BaseArea.INITVALUE
_internalUserAreaOffset = BaseArea.INITVALUE
_chassicInfoAreaOffset = BaseArea.INITVALUE
_multiRecordAreaOffset = BaseArea.INITVALUE
_bindata = None
_bodybin = None
_version = BaseArea.COMMON_HEAD_VERSION
_zeroCheckSum = None
_frusize = 256
def __str__(self):
tmpstr = ""
if self.boardInfoArea.isPresent:
tmpstr += "\nboardinfoarea: \n"
tmpstr += self.boardInfoArea.__str__()
if self.productInfoArea.isPresent:
tmpstr += "\nproductinfoarea: \n"
tmpstr += self.productInfoArea.__str__()
return tmpstr
def decodeBin(self, eeprom):
commonHead = eeprom[0:8]
d_print("decode version %x" % ord(commonHead[0]))
if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]):
raise FruException("HEAD VERSION error,not Fru format!", -10)
if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]):
strtemp = "check header checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(commonHead[0:7]), ord(commonHead[7]))
raise FruException(strtemp, -3)
if ord(commonHead[1]) != ord(self.INITVALUE):
d_print("Internal Use Area is present")
self.internalUseArea = InternalUseArea(
name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA)
self.internalUseArea.isPresent = True
self.internalUserAreaOffset = ord(commonHead[1])
self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: (
self.internalUserAreaOffset * 8 + self.internalUseArea.size)]
if ord(commonHead[2]) != ord(self.INITVALUE):
d_print("Chassis Info Area is present")
self.chassisInfoArea = ChassisInfoArea(
name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA)
self.chassisInfoArea.isPresent = True
self.chassicInfoAreaOffset = ord(commonHead[2])
self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: (
self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)]
if ord(commonHead[3]) != ord(self.INITVALUE):
self.boardInfoArea = BoardInfoArea(
name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA)
self.boardInfoArea.isPresent = True
self.boardInfoAreaOffset = ord(commonHead[3])
self.boardInfoArea.size = ord(
eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8
d_print("Board Info Area is present size:%d" %
(self.boardInfoArea.size))
self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: (
self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)]
if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]):
strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \
(FruUtil.checksum(
self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.boardInfoArea.decodedata()
if ord(commonHead[4]) != ord(self.INITVALUE):
d_print("Product Info Area is present")
self.productInfoArea = ProductInfoArea(
name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA)
self.productInfoArea.isPresent = True
self.productinfoAreaOffset = ord(commonHead[4])
d_print("length offset value: %02x" %
ord(eeprom[self.productinfoAreaOffset * 8 + 1]))
self.productInfoArea.size = ord(
eeprom[self.productinfoAreaOffset * 8 + 1]) * 8
d_print("Product Info Area is present size:%d" %
(self.productInfoArea.size))
self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: (
self.productinfoAreaOffset * 8 + self.productInfoArea.size)]
if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]):
strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.productInfoArea.decodedata()
if ord(commonHead[5]) != ord(self.INITVALUE):
self.multiRecordArea = MultiRecordArea(
name="MultiRecord record Area ")
d_print("MultiRecord record present")
self.multiRecordArea.isPresent = True
self.multiRecordAreaOffset = ord(commonHead[5])
self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: (
self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)]
def initDefault(self):
self.version = self.COMMON_HEAD_VERSION
self.internalUserAreaOffset = self.INITVALUE
self.chassicInfoAreaOffset = self.INITVALUE
self.boardInfoAreaOffset = self.INITVALUE
self.productinfoAreaOffset = self.INITVALUE
self.multiRecordAreaOffset = self.INITVALUE
self.PAD = self.INITVALUE
self.zeroCheckSum = self.INITVALUE
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
self.productInfoArea = None
self.internalUseArea = None
self.boardInfoArea = None
self.chassisInfoArea = None
self.multiRecordArea = None
# self.recalcute()
@property
def version(self):
return self._version
@version.setter
def version(self, name):
self._version = name
@property
def internalUserAreaOffset(self):
return self._internalUserAreaOffset
@internalUserAreaOffset.setter
def internalUserAreaOffset(self, obj):
self._internalUserAreaOffset = obj
@property
def chassicInfoAreaOffset(self):
return self._chassicInfoAreaOffset
@chassicInfoAreaOffset.setter
def chassicInfoAreaOffset(self, obj):
self._chassicInfoAreaOffset = obj
@property
def productinfoAreaOffset(self):
return self._productinfoAreaOffset
@productinfoAreaOffset.setter
def productinfoAreaOffset(self, obj):
self._productinfoAreaOffset = obj
@property
def boardInfoAreaOffset(self):
return self._boardInfoAreaOffset
@boardInfoAreaOffset.setter
def boardInfoAreaOffset(self, obj):
self._boardInfoAreaOffset = obj
@property
def multiRecordAreaOffset(self):
return self._multiRecordAreaOffset
@multiRecordAreaOffset.setter
def multiRecordAreaOffset(self, obj):
self._multiRecordAreaOffset = obj
@property
def zeroCheckSum(self):
return self._zeroCheckSum
@zeroCheckSum.setter
def zeroCheckSum(self, obj):
self._zeroCheckSum = obj
@property
def productInfoArea(self):
return self._ProductInfoArea
@productInfoArea.setter
def productInfoArea(self, obj):
self._ProductInfoArea = obj
@property
def internalUseArea(self):
return self._InternalUseArea
@internalUseArea.setter
def internalUseArea(self, obj):
self.internalUseArea = obj
@property
def boardInfoArea(self):
return self._BoardInfoArea
@boardInfoArea.setter
def boardInfoArea(self, obj):
self._BoardInfoArea = obj
@property
def chassisInfoArea(self):
return self._ChassisInfoArea
@chassisInfoArea.setter
def chassisInfoArea(self, obj):
self._ChassisInfoArea = obj
@property
def multiRecordArea(self):
return self._multiRecordArea
@multiRecordArea.setter
def multiRecordArea(self, obj):
self._multiRecordArea = obj
@property
def bindata(self):
return self._bindata
@bindata.setter
def bindata(self, obj):
self._bindata = obj
@property
def bodybin(self):
return self._bodybin
@bodybin.setter
def bodybin(self, obj):
self._bodybin = obj
def recalcuteCommonHead(self):
self.bindata = ""
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
d_print("common Header %d" % self.offset)
d_print("fru eeprom size %d" % self._frusize)
if self.internalUseArea is not None and self.internalUseArea.isPresent:
self.internalUserAreaOffset = self.offset // 8
self.offset += self.internalUseArea.size
d_print("internalUseArea is present offset:%d" % self.offset)
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
self.chassicInfoAreaOffset = self.offset // 8
self.offset += self.chassisInfoArea.size
d_print("chassisInfoArea is present offset:%d" % self.offset)
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
self.boardInfoAreaOffset = self.offset // 8
self.offset += self.boardInfoArea.size
d_print("boardInfoArea is present offset:%d" % self.offset)
d_print("boardInfoArea is present size:%d" %
self.boardInfoArea.size)
if self.productInfoArea is not None and self.productInfoArea.isPresent:
self.productinfoAreaOffset = self.offset // 8
self.offset += self.productInfoArea.size
d_print("productInfoArea is present offset:%d" % self.offset)
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
self.multiRecordAreaOffset = self.offset // 8
d_print("multiRecordArea is present offset:%d" % self.offset)
if self.internalUserAreaOffset == self.INITVALUE:
self.internalUserAreaOffset = 0
if self.productinfoAreaOffset == self.INITVALUE:
self.productinfoAreaOffset = 0
if self.chassicInfoAreaOffset == self.INITVALUE:
self.chassicInfoAreaOffset = 0
if self.boardInfoAreaOffset == self.INITVALUE:
self.boardInfoAreaOffset = 0
if self.multiRecordAreaOffset == self.INITVALUE:
self.multiRecordAreaOffset = 0
self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset
- self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff
d_print("zerochecksum:%x" % self.zeroCheckSum)
self.data = ""
self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr(
self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum)
self.bindata = self.data + self.bodybin
totallen = len(self.bindata)
d_print("totallen %d" % totallen)
if (totallen < self._frusize):
self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0]))
else:
raise FruException('bin data more than %d' % self._frusize, -2)
def recalcutebin(self):
self.bodybin = ""
if self.internalUseArea is not None and self.internalUseArea.isPresent:
d_print("internalUseArea present")
self.bodybin += self.internalUseArea.data
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
d_print("chassisInfoArea present")
self.bodybin += self.chassisInfoArea.data
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
d_print("boardInfoArea present")
self.boardInfoArea.recalcute()
self.bodybin += self.boardInfoArea.data
if self.productInfoArea is not None and self.productInfoArea.isPresent:
d_print("productInfoAreapresent")
self.productInfoArea.recalcute()
self.bodybin += self.productInfoArea.data
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
d_print("multiRecordArea present")
self.bodybin += self.productInfoArea.data
def recalcute(self, fru_eeprom_size=256):
self._frusize = fru_eeprom_size
self.recalcutebin()
self.recalcuteCommonHead()

View File

@@ -0,0 +1 @@
CONSOLE_SPEED=115200

View File

@@ -0,0 +1,6 @@
led auto on
led start
linkscan SwPortBitMap=all

View File

@@ -0,0 +1,431 @@
#!/usr/bin/python3
# * onboard temperature sensors
# * FAN trays
# * PSU
#
import os
import xml.etree.ElementTree as ET
import glob
from fru import ipmifru
from decimal import Decimal
MAILBOX_DIR = "/sys/bus/i2c/devices/"
BOARD_ID_PATH = "/sys/module/ruijie_common/parameters/dfd_my_type"
CONFIG_NAME = "dev.xml"
def byteTostr(val):
strtmp = ''
for i in range(len(val)):
strtmp += chr(val[i])
return strtmp
def typeTostr(val):
if isinstance(val, bytes):
strtmp = byteTostr(val)
return strtmp
return val
def get_board_id():
if not os.path.exists(BOARD_ID_PATH):
return "NA"
with open(BOARD_ID_PATH) as fd:
id_str = fd.read().strip()
return "0x%x" % (int(id_str, 10))
def dev_file_read(path, offset, read_len):
retval = "ERR"
val_list = []
msg = ""
ret = ""
fd = -1
if not os.path.exists(path):
return False, "%s %s not found" % (retval, path)
try:
fd = os.open(path, os.O_RDONLY)
os.lseek(fd, offset, os.SEEK_SET)
ret = os.read(fd, read_len)
for item in ret:
val_list.append(item)
except Exception as e:
msg = str(e)
return False, "%s %s" % (retval, msg)
finally:
if fd > 0:
os.close(fd)
return True, val_list
def getPMCreg(location):
retval = 'ERR'
if (not os.path.isfile(location)):
return "%s %s notfound"% (retval , location)
try:
with open(location, 'r') as fd:
retval = fd.read()
except Exception as error:
return "ERR %s" % str(error)
retval = retval.rstrip('\r\n')
retval = retval.lstrip(" ")
return retval
# Get a mailbox register
def get_pmc_register(reg_name):
retval = 'ERR'
mb_reg_file = reg_name
filepath = glob.glob(mb_reg_file)
if(len(filepath) == 0):
return "%s %s notfound"% (retval , mb_reg_file)
mb_reg_file = filepath[0]
if (not os.path.isfile(mb_reg_file)):
#print mb_reg_file, 'not found !'
return "%s %s notfound"% (retval , mb_reg_file)
try:
with open(mb_reg_file, 'rb') as fd:
retval = fd.read()
retval = typeTostr(retval)
except Exception as error:
retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error))
retval = retval.rstrip('\r\n')
retval = retval.lstrip(" ")
return retval
class checktype():
def __init__(self, test1):
self.test1 = test1
@staticmethod
def check(name,location, bit, value, tips , err1):
psu_status = int(get_pmc_register(location),16)
val = (psu_status & (1<< bit)) >> bit
if (val != value):
err1["errmsg"] = tips
err1["code"] = -1
return -1
else:
err1["errmsg"] = "none"
err1["code"] = 0
return 0
@staticmethod
def getValue(location, bit , type, coefficient = 1, addend = 0):
try:
value_t = get_pmc_register(location)
if value_t.startswith("ERR") :
return value_t
if (type == 1):
return float('%.1f' % ((float(value_t)/1000) + addend))
elif (type == 2):
return float('%.1f' % (float(value_t)/100))
elif (type == 3):
psu_status = int(value_t,16)
return (psu_status & (1<< bit)) >> bit
elif (type == 4):
return int(value_t,10)
elif (type == 5):
return float('%.1f' % (float(value_t)/1000/1000))
elif (type == 6):
return Decimal(float(value_t)*coefficient/1000).quantize(Decimal('0.000'))
else:
return value_t
except Exception as e:
value_t = "ERR %s" % str(e)
return value_t
#######temp
@staticmethod
def getTemp(self, name, location , ret_t):
ret2 = self.getValue(location + "temp1_input" ," " ,1);
ret3 = self.getValue(location + "temp1_max" ," ", 1);
ret4 = self.getValue(location + "temp1_max_hyst" ," ", 1);
ret_t["temp1_input"] = ret2
ret_t["temp1_max"] = ret3
ret_t["temp1_max_hyst"] = ret4
@staticmethod
def getLM75(name, location, result):
c1=checktype
r1={}
c1.getTemp(c1, name, location, r1)
result[name] = r1
##########fanFRU
@staticmethod
def decodeBinByValue(retval):
fru = ipmifru()
fru.decodeBin(retval)
return fru
@staticmethod
def printbinvalue(b):
index = 0
print(" ",)
for width in range(16):
print("%02x " % width,)
print("")
for i in range(0, len(b)):
if index % 16 == 0:
print(" ")
print(" %02x " % i,)
print("%02x " % ord(b[i]),)
index += 1
print("")
@staticmethod
def getfruValue(prob_t, root, val):
try:
ret, binval_bytes = dev_file_read(val, 0, 256)
if ret == False:
return binval_bytes
binval = byteTostr(binval_bytes)
fanpro = {}
ret = checktype.decodeBinByValue(binval)
fanpro['fan_type'] = ret.productInfoArea.productName
fanpro['hw_version'] = ret.productInfoArea.productVersion
fanpro['sn'] = ret.productInfoArea.productSerialNumber
fanpro['fanid'] = ret.productInfoArea.productextra2
fan_display_name_dict = status.getDecodValue(root, "fan_display_name")
fan_name = fanpro['fan_type'].strip()
if len(fan_display_name_dict) == 0:
return fanpro
if fan_name not in fan_display_name_dict.keys():
prob_t['errcode']= -1
prob_t['errmsg'] = '%s'% ("ERR fan name: %s not support" % fan_name)
else:
fanpro['fan_type'] = fan_display_name_dict[fan_name]
return fanpro
except Exception as error:
return "ERR " + str(error)
@staticmethod
def getslotfruValue(val):
try:
binval = checktype.getValue(val, 0 , 0)
if binval.startswith("ERR"):
return binval
slotpro = {}
ret = checktype.decodeBinByValue(binval)
slotpro['slot_type'] = ret.boardInfoArea.boardProductName
slotpro['hw_version'] = ret.boardInfoArea.boardextra1
slotpro['sn'] = ret.boardInfoArea.boardSerialNumber
return slotpro
except Exception as error:
return "ERR " + str(error)
@staticmethod
def getpsufruValue(prob_t, root, val):
try:
psu_match = False
binval = checktype.getValue(val, 0 , 0)
if binval.startswith("ERR"):
return binval
psupro = {}
ret = checktype.decodeBinByValue(binval)
psupro['type1'] = ret.productInfoArea.productPartModelName
psupro['sn'] = ret.productInfoArea.productSerialNumber
psupro['hw_version'] = ret.productInfoArea.productVersion
psu_dict = status.getDecodValue(root, "psutype")
psupro['type1'] = psupro['type1'].strip()
if len(psu_dict) == 0:
return psupro
for psu_name in psu_dict.keys():
if psu_name in psupro['type1']:
psupro['type1'] = psu_dict[psu_name]
psu_match = True
break
if psu_match is not True:
prob_t['errcode']= -1
prob_t['errmsg'] = '%s'% ("ERR psu name: %s not support" % psupro['type1'])
return psupro
except Exception as error:
return "ERR " + str(error)
class status():
def __init__(self, productname):
self.productname = productname
@staticmethod
def getETroot(filename):
tree = ET.parse(filename)
root = tree.getroot()
return root;
@staticmethod
def getDecodValue(collection, decode):
decodes = collection.find('decode')
testdecode = decodes.find(decode)
test={}
if testdecode is None:
return test
for neighbor in testdecode.iter('code'):
test[neighbor.attrib["key"]]=neighbor.attrib["value"]
return test
@staticmethod
def getfileValue(location):
return checktype.getValue(location," "," ")
@staticmethod
def getETValue(a, filename, tagname):
root = status.getETroot(filename)
for neighbor in root.iter(tagname):
prob_t = {}
prob_t = neighbor.attrib
prob_t['errcode']= 0
prob_t['errmsg'] = ''
for pros in neighbor.iter("property"):
ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items()))
if ret.get('e2type') == 'fru' and ret.get("name") == "fru":
fruval = checktype.getfruValue(prob_t, root, ret["location"])
if isinstance(fruval, str) and fruval.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= fruval
break
else:
prob_t.update(fruval)
continue
if ret.get("name") == "psu" and ret.get('e2type') == 'fru':
psuval = checktype.getpsufruValue(prob_t, root, ret["location"])
if isinstance(psuval, str) and psuval.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= psuval
break
else:
prob_t.update(psuval)
continue
if ret.get("gettype") == "config":
prob_t[ret["name"]] = ret["value"]
continue
if ('type' not in ret.keys()):
val = "0";
else:
val = ret["type"]
if ('bit' not in ret.keys()):
bit = "0";
else:
bit = ret["bit"]
if ('coefficient' not in ret.keys()):
coefficient = 1;
else:
coefficient = float(ret["coefficient"])
if ('addend' not in ret.keys()):
addend = 0;
else:
addend = float(ret["addend"])
s = checktype.getValue(ret["location"], int(bit),int(val), coefficient, addend)
if isinstance(s, str) and s.startswith("ERR"):
prob_t['errcode']= -1
prob_t['errmsg']= s
break
if ('default' in ret.keys()):
rt = status.getDecodValue(root,ret['decode'])
prob_t['errmsg']= rt[str(s)]
if str(s) != ret["default"]:
prob_t['errcode']= -1
break
else:
if ('decode' in ret.keys()):
rt = status.getDecodValue(root,ret['decode'])
if(ret['decode'] == "psutype" and s.replace("\x00","").rstrip() not in rt.keys()):
prob_t['errcode']= -1
prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % (s.replace("\x00","").rstrip()))
else:
s = rt[str(s).replace("\x00","").rstrip()]
name = ret["name"]
prob_t[name]=str(s)
a.append(prob_t)
@staticmethod
def getCPUValue(a, filename, tagname):
root = status.getETroot(filename)
for neighbor in root.iter(tagname):
location = neighbor.attrib["location"]
L=[]
for dirpath, dirnames, filenames in os.walk(location):
for file in filenames :
if file.endswith("input"):
L.append(os.path.join(dirpath, file))
L =sorted(L,reverse=False)
for i in range(len(L)):
prob_t = {}
prob_t["name"] = getPMCreg("%s/temp%d_label"%(location,i+1))
prob_t["temp"] = float(getPMCreg("%s/temp%d_input"%(location,i+1)))/1000
prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm"%(location,i+1)))/1000
prob_t["crit"] = float(getPMCreg("%s/temp%d_crit"%(location,i+1)))/1000
prob_t["max"] = float(getPMCreg("%s/temp%d_max"%(location,i+1)))/1000
a.append(prob_t)
@staticmethod
def getFileName():
fpath = os.path.dirname(os.path.realpath(__file__))
board_id = get_board_id()
dev_id_xml = fpath + "/" + "dev_%s.xml" % board_id
if os.path.exists(dev_id_xml):
return dev_id_xml
return fpath + "/"+ CONFIG_NAME
@staticmethod
def getFan(ret):
_filename = status.getFileName()
_tagname = "fan"
status.getvalue(ret, _filename, _tagname)
@staticmethod
def checkFan(ret):
_filename = status.getFileName()
# _filename = "/usr/local/bin/" + status.getFileName()
_tagname = "fan"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getTemp(ret):
_filename = status.getFileName()
#_filename = "/usr/local/bin/" + status.getFileName()
_tagname = "temp"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getPsu(ret):
_filename = status.getFileName()
# _filename = "/usr/local/bin/" + status.getFileName()
_tagname = "psu"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getcputemp(ret):
_filename = status.getFileName()
_tagname = "cpus"
status.getCPUValue(ret, _filename, _tagname)
@staticmethod
def getDcdc(ret):
_filename = status.getFileName()
_tagname = "dcdc"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getmactemp(ret):
_filename = status.getFileName()
_tagname = "mactemp"
status.getETValue(ret, _filename, _tagname)
@staticmethod
def getmacpower(ret):
_filename = status.getFileName()
_tagname = "macpower"
status.getETValue(ret, _filename, _tagname)

View File

@@ -0,0 +1 @@
broadcom

View File

@@ -0,0 +1,2 @@
SYNCD_SHM_SIZE=1g
is_ltsw_chip=1

4
platform/broadcom/one-image.mk Normal file → Executable file
View File

@@ -81,7 +81,9 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
$(RAGILE_RA_B6910_64C_PLATFORM_MODULE) \
$(RAGILE_RA_B6510_32C_PLATFORM_MODULE) \
$(RAGILE_RA_B6920_4S_PLATFORM_MODULE) \
$(NOKIA_IXR7250_PLATFORM_MODULE)
$(NOKIA_IXR7250_PLATFORM_MODULE) \
$(TENCENT_TCS8400_PLATFORM_MODULE) \
$(TENCENT_TCS9400_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_LAZY_BUILD_INSTALLS = $(BRCM_OPENNSL_KERNEL) $(BRCM_DNX_OPENNSL_KERNEL)
ifeq ($(INSTALL_DEBUG_TOOLS),y)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES)

View File

@@ -0,0 +1,8 @@
MPATH := $($(TENCENT_TCS8400_PLATFORM_MODULE)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/platform-modules-tencent.mk platform/broadcom/platform-modules-tencent.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(shell git ls-files $(MPATH))
$(TENCENT_TCS8400_PLATFORM_MODULE)_CACHE_MODE := GIT_CONTENT_SHA
$(TENCENT_TCS8400_PLATFORM_MODULE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(TENCENT_TCS8400_PLATFORM_MODULE)_DEP_FILES := $(DEP_FILES)

View File

@@ -0,0 +1,18 @@
# Tencent platform modules
TENCENT_TCS8400_PLATFORM_MODULE_VERSION = 1.0
export TENCENT_TCS8400_PLATFORM_MODULE_VERSION
TENCENT_TCS8400_PLATFORM_MODULE = platform-modules-ruijie-tcs8400_$(TENCENT_TCS8400_PLATFORM_MODULE_VERSION)_amd64.deb
$(TENCENT_TCS8400_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-tencent
$(TENCENT_TCS8400_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON)
$(TENCENT_TCS8400_PLATFORM_MODULE)_PLATFORM = x86_64-tencent_tcs8400-r0
SONIC_DPKG_DEBS += $(TENCENT_TCS8400_PLATFORM_MODULE)
SONIC_STRETCH_DEBS += $(TENCENT_TCS8400_PLATFORM_MODULE)
## TCS9400
TENCENT_TCS9400_PLATFORM_MODULE_VERSION = 1.0
export TENCENT_TCS9400_PLATFORM_MODULE_VERSION
TENCENT_TCS9400_PLATFORM_MODULE = platform-modules-ruijie-tcs9400_$(TENCENT_TCS9400_PLATFORM_MODULE_VERSION)_amd64.deb
$(TENCENT_TCS9400_PLATFORM_MODULE)_PLATFORM = x86_64-tencent_tcs9400-r0
$(eval $(call add_extra_package,$(TENCENT_TCS8400_PLATFORM_MODULE),$(TENCENT_TCS9400_PLATFORM_MODULE)))

1
platform/broadcom/rules.mk Normal file → Executable file
View File

@@ -15,6 +15,7 @@ include $(PLATFORM_PATH)/platform-modules-juniper.mk
#include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.mk
#include $(PLATFORM_PATH)/platform-modules-ruijie.mk
#include $(PLATFORM_PATH)/platform-modules-ragile.mk
#include $(PLATFORM_PATH)/platform-modules-tencent.mk
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
include $(PLATFORM_PATH)/docker-saiserver-brcm.mk

View File

@@ -0,0 +1,15 @@
Copyright (C) 2016 Microsoft, Inc
Copyright (C) 2022 Ruijie Network Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@@ -0,0 +1,37 @@
PWD = $(shell pwd)
CC ?=gcc
INSTALL_MOD_DIR ?=extra
KVERSION ?= $(shell uname -r)
KERNEL_SRC ?= /lib/modules/$(KVERSION)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
SUB_BUILD_DIR = $(PWD)/build
DIR_KERNEL_SRC = $(PWD)/modules
SCRIPT_DIR = $(PWD)/script
SERVICE_DIR = $(PWD)/service
BLACK_DRIVER_CONF_DIR = $(PWD)/modprobe_conf
modules_build_dir = $(DIR_KERNEL_SRC)/build
INSTALL_MODULE_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR)
INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin
INSTALL_SERVICE_DIR = $(SUB_BUILD_DIR)/lib/systemd/system
INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages
INSTALL_BLACK_DRIVER = $(SUB_BUILD_DIR)/etc/modprobe.d
all:
$(MAKE) -C $(DIR_KERNEL_SRC)
@if [ ! -d ${INSTALL_MODULE_DIR} ]; then mkdir -p ${INSTALL_MODULE_DIR} ;fi
@if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi
@if [ ! -d ${INSTALL_SERVICE_DIR} ]; then mkdir -p ${INSTALL_SERVICE_DIR} ;fi
@if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi
@if [ -d $(PWD)/lib/ ]; then cp -r $(PWD)/lib/* ${INSTALL_LIB_DIR} ;fi
@if [ -d $(PWD)/sonic_platform/ ]; then cp -rf $(PWD)/sonic_platform ${INSTALL_LIB_DIR} ;fi
cp -r $(modules_build_dir)/*.ko $(INSTALL_MODULE_DIR)
cp -r $(SCRIPT_DIR)/* $(INSTALL_SCRIPT_DIR)
cp -r $(SERVICE_DIR)/* $(INSTALL_SERVICE_DIR)
@if [ -d $(INSTALL_SCRIPT_DIR) ]; then chmod +x $(INSTALL_SCRIPT_DIR)/* ;fi
@if [ ! -d ${INSTALL_BLACK_DRIVER} ]; then mkdir -p ${INSTALL_BLACK_DRIVER} ;fi
cp -r $(BLACK_DRIVER_CONF_DIR)/* $(INSTALL_BLACK_DRIVER)
clean:
rm -rf $(SUB_BUILD_DIR)

View File

@@ -0,0 +1,167 @@
#!/usr/bin/env python3
import os
import syslog
import copy
from plat_hal.baseutil import baseutil
HYST_DEBUG_FILE = "/etc/.hysteresis_debug_flag"
HYSTERROR = 1
HYSTDEBUG = 2
debuglevel = 0
def hyst_debug(s):
if HYSTDEBUG & debuglevel:
syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID)
syslog.syslog(syslog.LOG_DEBUG, s)
def hyst_error(s):
if HYSTERROR & debuglevel:
syslog.openlog("FANCONTROL-HYST", syslog.LOG_PID)
syslog.syslog(syslog.LOG_ERR, s)
class hysteresis(object):
__config = None
__hyst_config = None
def __init__(self):
self.__config = baseutil.get_monitor_config()
self.__hyst_config = copy.deepcopy(self.__config.get("hyst", {}))
# init check
errcnt = 0
errmsg = ""
self.debug_init()
for temp_hyst_conf in self.__hyst_config.values():
if temp_hyst_conf["flag"] == 0:
continue
for i in range(temp_hyst_conf["temp_min"], temp_hyst_conf["temp_max"] + 1):
if i not in temp_hyst_conf["rising"]:
errcnt -= 1
msg = "%s hyst config error, temp value %d not in rising curve;" % (temp_hyst_conf["name"], i)
hyst_error(msg)
errmsg += msg
if i not in temp_hyst_conf["descending"]:
errcnt -= 1
msg = "%s hyst config error, temp value %d not in descending curve;" %(temp_hyst_conf["name"], i)
hyst_error(msg)
errmsg += msg
if errcnt < 0:
raise KeyError(errmsg)
def debug_init(self):
global debuglevel
if os.path.exists(HYST_DEBUG_FILE):
debuglevel = debuglevel | HYSTDEBUG | HYSTERROR
else:
debuglevel = debuglevel & ~(HYSTDEBUG | HYSTERROR)
def get_temp_hyst_conf(self, temp_name):
temp_hyst_conf = self.__hyst_config.get(temp_name)
return temp_hyst_conf
def get_temp_update(self, hyst_para, current_temp):
temp = hyst_para["value"]
if temp is None:
return None
temp.append(current_temp)
del temp[0]
return temp
def duty_to_pwm(self, duty):
pwm = int(round(float(duty) * 255 / 100))
return pwm
def pwm_to_duty(self, pwm):
duty = int(round(float(pwm) * 100 / 255))
return duty
def calc_hyst_val(self, temp_name, temp_list):
temp_hyst_conf = self.get_temp_hyst_conf(temp_name)
hyst_min = temp_hyst_conf["hyst_min"]
hyst_max = temp_hyst_conf["hyst_max"]
temp_min = temp_hyst_conf["temp_min"]
temp_max = temp_hyst_conf["temp_max"]
rising = temp_hyst_conf["rising"]
descending = temp_hyst_conf["descending"]
last_hyst_value = temp_hyst_conf["last_hyst_value"]
current_temp = temp_list[1]
last_temp = temp_list[0]
hyst_debug("calc_hyst_val, temp_name: %s, current_temp: %s, last_temp: %s, last_hyst_value: %s" %
(temp_name, current_temp, last_temp, last_hyst_value))
if current_temp < temp_min:
hyst_debug("%s current_temp %s less than temp_min %s, set min hyst value: %s" %
(temp_name, current_temp, temp_min, hyst_min))
return hyst_min
if current_temp > temp_max:
hyst_debug("%s current_temp %s more than temp_max %s, set max hyst value: %s" %
(temp_name, current_temp, temp_max, hyst_max))
return hyst_max
if last_temp is None: # first time
hyst_value = rising[current_temp]
hyst_debug("last_temp is None, it's first hysteresis, using rising hyst value: %s" % hyst_value)
return hyst_value
if current_temp == last_temp: # temp unchanging
hyst_debug("current_temp equal last_temp, keep last hyst value: %s" % last_hyst_value)
return last_hyst_value
if current_temp > last_temp:
calc_hyst_value = rising[current_temp]
if calc_hyst_value < last_hyst_value:
hyst_value = last_hyst_value
else:
hyst_value = calc_hyst_value
hyst_debug("temp rising, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" %
(last_hyst_value, calc_hyst_value, hyst_value))
return hyst_value
calc_hyst_value = descending[current_temp]
if calc_hyst_value > last_hyst_value:
hyst_value = last_hyst_value
else:
hyst_value = calc_hyst_value
hyst_debug("temp descending, last_hyst_value: %s, calc_hyst_value: %s, set hyst value: %s" %
(last_hyst_value, calc_hyst_value, hyst_value))
return hyst_value
def cacl(self, temp_name, current_temp):
self.debug_init()
try:
temp_hyst_conf = self.get_temp_hyst_conf(temp_name)
if temp_hyst_conf is None:
hyst_debug("get %s hysteresis config failed" % temp_name)
return None
flag = temp_hyst_conf["flag"]
if flag != 1:
hyst_debug("%s hysteresis flag == 0, skip" % temp_name)
return None
temp = self.get_temp_update(temp_hyst_conf, current_temp)
if temp is None:
hyst_debug("get %s update failed" % temp_name)
return None
value = self.calc_hyst_val(temp_name, temp)
temp_hyst_conf["last_hyst_value"] = value
type = temp_hyst_conf["type"]
if type == "duty":
pwm = self.duty_to_pwm(value)
else:
pwm = value
hyst_debug("temp_name: %s, current_temp: %s, set pwm 0x%x" % (temp_name, current_temp, pwm))
return pwm
except Exception as e:
hyst_error("temp_name: %s calc hysteresis pwm error, msg: %s" % (temp_name, str(e)))
return None

View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python3
import os
import syslog
from plat_hal.baseutil import baseutil
OPENLOOP_DEBUG_FILE = "/etc/.openloop_debug_flag"
OPENLOOPERROR = 1
OPENLOOPDEBUG = 2
debuglevel = 0
def openloop_debug(s):
if OPENLOOPDEBUG & debuglevel:
syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID)
syslog.syslog(syslog.LOG_DEBUG, s)
def openloop_error(s):
if OPENLOOPERROR & debuglevel:
syslog.openlog("FANCONTROL-OPENLOOP", syslog.LOG_PID)
syslog.syslog(syslog.LOG_ERR, s)
class openloop(object):
__config = None
__openloop_config = None
def __init__(self):
self.__config = baseutil.get_monitor_config()
self.__openloop_config = self.__config["openloop"]
def debug_init(self):
global debuglevel
if os.path.exists(OPENLOOP_DEBUG_FILE):
debuglevel = debuglevel | OPENLOOPDEBUG | OPENLOOPERROR
else:
debuglevel = debuglevel & ~(OPENLOOPDEBUG | OPENLOOPERROR)
def get_para(self, type):
para = self.__openloop_config.get(type)
return para
def linear_cacl(self, temp):
self.debug_init()
openloop_para = self.get_para("linear")
if openloop_para is None:
openloop_debug("linear openloop: get para failed")
return None
K = openloop_para["K"]
tin_min = openloop_para["tin_min"]
pwm_min = openloop_para["pwm_min"]
pwm_max = openloop_para["pwm_max"]
flag = openloop_para["flag"]
if flag != 1:
openloop_debug("linear openloop: flag == 0")
return None
if temp <= tin_min:
openloop_debug("linear openloop: temp = %d less than tin_min[%d]" % (temp, tin_min))
return pwm_min
pwm = int(pwm_min + (temp - tin_min) * K)
openloop_debug("linear openloop: cacl_pwm = 0x%x" % pwm)
pwm = min(pwm, pwm_max)
pwm = max(pwm, pwm_min)
openloop_debug("linear openloop: temp = %d, pwm = 0x%x" % (temp, pwm))
return pwm
def curve_cacl(self, temp):
self.debug_init()
openloop_para = self.get_para("curve")
if openloop_para is None:
openloop_debug("curve openloop: get para failed")
return None
a = openloop_para["a"]
b = openloop_para["b"]
c = openloop_para["c"]
tin_min = openloop_para["tin_min"]
pwm_min = openloop_para["pwm_min"]
pwm_max = openloop_para["pwm_max"]
flag = openloop_para["flag"]
if flag != 1:
openloop_debug("curve openloop: flag == 0")
return None
if temp <= tin_min:
openloop_debug("curve openloop: temp = %d less than tin_min[%d]" % (temp, tin_min))
return pwm_min
pwm = int(a * temp * temp + b * temp + c)
openloop_debug("curve openloop: cacl_pwm = 0x%x" % pwm)
pwm = min(pwm, pwm_max)
pwm = max(pwm, pwm_min)
openloop_debug("curve openloop: temp = %d, pwm = 0x%x" % (temp, pwm))
return pwm

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env python3
import os
import syslog
import copy
from plat_hal.baseutil import baseutil
PID_DEBUG_FILE = "/etc/.pid_debug_flag"
PIDERROR = 1
PIDDEBUG = 2
debuglevel = 0
def pid_debug(s):
if PIDDEBUG & debuglevel:
syslog.openlog("FANCONTROL-PID", syslog.LOG_PID)
syslog.syslog(syslog.LOG_DEBUG, s)
def pid_error(s):
if PIDERROR & debuglevel:
syslog.openlog("FANCONTROL-PID", syslog.LOG_PID)
syslog.syslog(syslog.LOG_ERR, s)
class pid(object):
__config = None
__pid_config = None
def __init__(self):
self.__config = baseutil.get_monitor_config()
self.__pid_config = copy.deepcopy(self.__config["pid"])
def debug_init(self):
global debuglevel
if os.path.exists(PID_DEBUG_FILE):
debuglevel = debuglevel | PIDDEBUG | PIDERROR
else:
debuglevel = debuglevel & ~(PIDDEBUG | PIDERROR)
def get_para(self, name):
para = self.__pid_config.get(name)
return para
def get_temp_update(self, pid_para, current_temp):
temp = pid_para["value"]
if temp is None:
return None
temp.append(current_temp)
del temp[0]
return temp
def cacl(self, last_pwm, name, current_temp):
delta_pwm = 0
self.debug_init()
pid_debug("last_pwm = %d" % last_pwm)
pid_para = self.get_para(name)
if pid_para is None:
pid_debug("get %s pid para failed" % name)
return None
temp = self.get_temp_update(pid_para, current_temp)
if temp is None:
pid_debug("get %s update failed" % name)
return None
type = pid_para["type"]
Kp = pid_para["Kp"]
Ki = pid_para["Ki"]
Kd = pid_para["Kd"]
target = pid_para["target"]
pwm_min = pid_para["pwm_min"]
pwm_max = pid_para["pwm_max"]
flag = pid_para["flag"]
if flag != 1:
pid_debug("%s pid flag == 0" % name)
return None
if type == "duty":
current_pwm = round(last_pwm * 100 / 255)
else:
current_pwm = last_pwm
if (temp[2] is None):
tmp_pwm = current_pwm
elif ((temp[0] is None) or (temp[1] is None)):
delta_pwm = Ki * (temp[2] - target)
tmp_pwm = current_pwm + delta_pwm
else:
delta_pwm = Kp * (temp[2] - temp[1]) + Ki * (temp[2] - target) + Kd * (temp[2] - 2 * temp[1] + temp[0])
tmp_pwm = current_pwm + delta_pwm
pid_debug("delta_pwm = %d" % delta_pwm)
if type == "duty":
pwm = round(tmp_pwm * 255 / 100)
else:
pwm = int(tmp_pwm)
pwm = min(pwm, pwm_max)
pwm = max(pwm, pwm_min)
pid_debug("last_pwm = 0x%x, pwm = 0x%x" % (last_pwm, pwm))
return pwm

View File

@@ -0,0 +1,953 @@
#!/usr/bin/python3
import collections
from bitarray import bitarray
from datetime import datetime, timedelta
__DEBUG__ = "N"
class FruException(Exception):
def __init__(self, message='fruerror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
def e_print(err):
print("ERROR: " + err)
def d_print(debug_info):
if(__DEBUG__ == "Y"):
print(debug_info)
class FruUtil():
@staticmethod
def decodeLength(value):
a = bitarray(8)
a.setall(True)
a[0:1] = 0
a[1:2] = 0
x = ord(a.tobytes())
return x & ord(value)
@staticmethod
def minToData():
starttime = datetime(1996, 1, 1, 0, 0, 0)
endtime = datetime.now()
seconds = (endtime - starttime).total_seconds()
mins = seconds // 60
m = int(round(mins))
return m
@staticmethod
def getTimeFormat():
return datetime.now().strftime('%Y-%m-%d')
@staticmethod
def getTypeLength(value):
if value is None or len(value) == 0:
return 0
a = bitarray(8)
a.setall(False)
a[0:1] = 1
a[1:2] = 1
x = ord(a.tobytes())
return x | len(value)
@staticmethod
def checksum(b):
result = 0
for i in range(len(b)):
result += ord(b[i])
return (0x100 - (result & 0xff)) & 0xff
class BaseArea(object):
SUGGESTED_SIZE_COMMON_HEADER = 8
SUGGESTED_SIZE_INTERNAL_USE_AREA = 72
SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32
SUGGESTED_SIZE_BOARD_INFO_AREA = 80
SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80
INITVALUE = b'\x00'
resultvalue = INITVALUE * 256
COMMON_HEAD_VERSION = b'\x01'
__childList = None
def __init__(self, name="", size=0, offset=0):
self.__childList = []
self._offset = offset
self.name = name
self._size = size
self._isPresent = False
self._data = b'\x00' * size
self.__dataoffset = 0
@property
def childList(self):
return self.__childList
@childList.setter
def childList(self, value):
self.__childList = value
@property
def offset(self):
return self._offset
@offset.setter
def offset(self, value):
self._offset = value
@property
def size(self):
return self._size
@size.setter
def size(self, value):
self._size = value
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
@property
def isPresent(self):
return self._isPresent
@isPresent.setter
def isPresent(self, value):
self._isPresent = value
class InternalUseArea(BaseArea):
pass
class ChassisInfoArea(BaseArea):
pass
class BoardInfoArea(BaseArea):
_boardTime = None
_fields = None
_mfg_date = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"mfg_date : %s \n" \
"boardManufacturer : %s \n" \
"boardProductName : %s \n" \
"boardSerialNumber : %s \n" \
"boardPartNumber : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.boardversion), self.size,
self.language, self.getMfgRealData(),
self.boardManufacturer, self.boardProductName,
self.boardSerialNumber, self.boardPartNumber,
self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "boardextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["boardversion"] = ord(self.boardversion)
dic["boardlength"] = self.size
dic["boardlanguage"] = self.language
dic["boardmfg_date"] = self.getMfgRealData()
dic["boardManufacturer"] = self.boardManufacturer
dic["boardProductName"] = self.boardProductName
dic["boardSerialNumber"] = self.boardSerialNumber
dic["boardPartNumber"] = self.boardPartNumber
dic["boardfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index]
index += 1
d_print("decode length :%d class size:%d" %
((ord(self.data[index]) * 8), self.size))
index += 2
timetmp = self.data[index: index + 3]
self.mfg_date = ord(timetmp[0]) | (
ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16)
d_print("decode getMfgRealData :%s" % self.getMfgRealData())
index += 3
templen = FruUtil.decodeLength(self.data[index])
self.boardManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardManufacturer:%s" % self.boardManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.boardProductName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardProductName:%s" % self.boardProductName)
templen = FruUtil.decodeLength(self.data[index])
self.boardSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardSerialNumber:%s" % self.boardSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.boardPartNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode boardPartNumber:%s" % self.boardPartNumber)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "boardextra%d" % i
if self.data[index] != chr(0xc1):
templen = FruUtil.decodeLength(self.data[index])
tmpval = self.data[index + 1: index + templen + 1]
setattr(self, valtmp, tmpval)
index += templen + 1
d_print("decode boardextra%d:%s" % (i, tmpval))
else:
break
return
def recalcute(self):
d_print("boardInfoArea version:%x" % ord(self.boardversion))
d_print("boardInfoArea length:%d" % self.size)
d_print("boardInfoArea language:%x" % self.language)
self.mfg_date = FruUtil.minToData()
d_print("boardInfoArea mfg_date:%x" % self.mfg_date)
self.data = chr(ord(self.boardversion)) + \
chr(self.size // 8) + chr(self.language)
self.data += chr(self.mfg_date & 0xFF)
self.data += chr((self.mfg_date >> 8) & 0xFF)
self.data += chr((self.mfg_date >> 16) & 0xFF)
d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer)
typelength = FruUtil.getTypeLength(self.boardManufacturer)
self.data += chr(typelength)
self.data += self.boardManufacturer
d_print("boardInfoArea boardProductName:%s" % self.boardProductName)
self.data += chr(FruUtil.getTypeLength(self.boardProductName))
self.data += self.boardProductName
d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber)
self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber))
self.data += self.boardSerialNumber
d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber)
self.data += chr(FruUtil.getTypeLength(self.boardPartNumber))
self.data += self.boardPartNumber
d_print("boardInfoArea fruFileId:%s" % self.fruFileId)
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "boardextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
d_print("self data:%d" % len(self.data))
d_print("self size:%d" % self.size)
d_print("adjust size:%d" % (self.size - len(self.data) - 1))
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
# checksum
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
def getMfgRealData(self):
starttime = datetime(1996, 1, 1, 0, 0, 0)
mactime = starttime + timedelta(minutes=self.mfg_date)
return mactime
@property
def language(self):
self._language = 25
return self._language
@property
def mfg_date(self):
return self._mfg_date
@mfg_date.setter
def mfg_date(self, val):
self._mfg_date = val
@property
def boardversion(self):
self._boardversion = self.COMMON_HEAD_VERSION
return self._boardversion
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, val):
self._FRUFileID = val
@property
def boardPartNumber(self):
return self._boardPartNumber
@boardPartNumber.setter
def boardPartNumber(self, val):
self._boardPartNumber = val
@property
def boardSerialNumber(self):
return self._boardSerialNumber
@boardSerialNumber.setter
def boardSerialNumber(self, val):
self._boardSerialNumber = val
@property
def boardProductName(self):
return self._boradProductName
@boardProductName.setter
def boardProductName(self, val):
self._boradProductName = val
@property
def boardManufacturer(self):
return self._boardManufacturer
@boardManufacturer.setter
def boardManufacturer(self, val):
self._boardManufacturer = val
@property
def boardTime(self):
return self._boardTime
@boardTime.setter
def boardTime(self, val):
self._boardTime = val
@property
def fields(self):
return self._fields
@fields.setter
def fields(self, val):
self._fields = val
class ProductInfoArea(BaseArea):
_productManufacturer = None
_productAssetTag = None
_FRUFileID = None
def __str__(self):
formatstr = "version : %x\n" \
"length : %d \n" \
"language : %x \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"productAssetTag : %s \n" \
"fruFileId : %s \n"
tmpstr = formatstr % (ord(self.areaversion), self.size,
self.language, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber,
self.productAssetTag, self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
tmpstr += "productextra%d : %s \n" % (i, valtmpval)
else:
break
return tmpstr
def todict(self):
dic = collections.OrderedDict()
dic["productversion"] = ord(self.areaversion)
dic["productlength"] = self.size
dic["productlanguage"] = self.language
dic["productManufacturer"] = self.productManufacturer
dic["productName"] = self.productName
dic["productPartModelName"] = self.productPartModelName
dic["productVersion"] = int(self.productVersion, 16)
dic["productSerialNumber"] = self.productSerialNumber
dic["productAssetTag"] = self.productAssetTag
dic["productfruFileId"] = self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
dic[valtmp] = valtmpval
else:
break
return dic
def decodedata(self):
index = 0
self.areaversion = self.data[index] # 0
index += 1
d_print("decode length %d" % (ord(self.data[index]) * 8))
d_print("class size %d" % self.size)
index += 2
templen = FruUtil.decodeLength(self.data[index])
self.productManufacturer = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productManufacturer:%s" % self.productManufacturer)
templen = FruUtil.decodeLength(self.data[index])
self.productName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productName:%s" % self.productName)
templen = FruUtil.decodeLength(self.data[index])
self.productPartModelName = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productPartModelName:%s" % self.productPartModelName)
templen = FruUtil.decodeLength(self.data[index])
self.productVersion = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productVersion:%s" % self.productVersion)
templen = FruUtil.decodeLength(self.data[index])
self.productSerialNumber = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productSerialNumber:%s" % self.productSerialNumber)
templen = FruUtil.decodeLength(self.data[index])
self.productAssetTag = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode productAssetTag:%s" % self.productAssetTag)
templen = FruUtil.decodeLength(self.data[index])
self.fruFileId = self.data[index + 1: index + templen + 1]
index += templen + 1
d_print("decode fruFileId:%s" % self.fruFileId)
for i in range(1, 11):
valtmp = "productextra%d" % i
if self.data[index] != chr(0xc1) and index < self.size - 1:
templen = FruUtil.decodeLength(self.data[index])
if templen == 0:
break
tmpval = self.data[index + 1: index + templen + 1]
d_print("decode boardextra%d:%s" % (i, tmpval))
setattr(self, valtmp, tmpval)
index += templen + 1
else:
break
@property
def productVersion(self):
return self._productVersion
@productVersion.setter
def productVersion(self, name):
self._productVersion = name
@property
def areaversion(self):
self._areaversion = self.COMMON_HEAD_VERSION
return self._areaversion
@areaversion.setter
def areaversion(self, name):
self._areaversion = name
@property
def language(self):
self._language = 25
return self._language
@property
def productManufacturer(self):
return self._productManufacturer
@productManufacturer.setter
def productManufacturer(self, name):
self._productManufacturer = name
@property
def productName(self):
return self._productName
@productName.setter
def productName(self, name):
self._productName = name
@property
def productPartModelName(self):
return self._productPartModelName
@productPartModelName.setter
def productPartModelName(self, name):
self._productPartModelName = name
@property
def productSerialNumber(self):
return self._productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, name):
self._productSerialNumber = name
@property
def productAssetTag(self):
return self._productAssetTag
@productAssetTag.setter
def productAssetTag(self, name):
self._productAssetTag = name
@property
def fruFileId(self):
return self._FRUFileID
@fruFileId.setter
def fruFileId(self, name):
self._FRUFileID = name
def recalcute(self):
d_print("product version:%x" % ord(self.areaversion))
d_print("product length:%d" % self.size)
d_print("product language:%x" % self.language)
self.data = chr(ord(self.areaversion)) + \
chr(self.size // 8) + chr(self.language)
typelength = FruUtil.getTypeLength(self.productManufacturer)
self.data += chr(typelength)
self.data += self.productManufacturer
self.data += chr(FruUtil.getTypeLength(self.productName))
self.data += self.productName
self.data += chr(FruUtil.getTypeLength(self.productPartModelName))
self.data += self.productPartModelName
self.data += chr(FruUtil.getTypeLength(self.productVersion))
self.data += self.productVersion
self.data += chr(FruUtil.getTypeLength(self.productSerialNumber))
self.data += self.productSerialNumber
self.data += chr(FruUtil.getTypeLength(self.productAssetTag))
if self.productAssetTag is not None:
self.data += self.productAssetTag
self.data += chr(FruUtil.getTypeLength(self.fruFileId))
self.data += self.fruFileId
for i in range(1, 11):
valtmp = "productextra%d" % i
if hasattr(self, valtmp):
valtmpval = getattr(self, valtmp)
d_print("boardInfoArea productextra%d:%s" % (i, valtmpval))
self.data += chr(FruUtil.getTypeLength(valtmpval))
if valtmpval is None:
pass
else:
self.data += valtmpval
else:
break
self.data += chr(0xc1)
if len(self.data) > (self.size - 1):
incr = (len(self.data) - self.size) // 8 + 1
self.size += incr * 8
d_print("self.data:%d" % len(self.data))
d_print("self.size:%d" % self.size)
self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:]
self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0]))
checksum = FruUtil.checksum(self.data)
d_print("board info checksum:%x" % checksum)
self.data += chr(checksum)
class MultiRecordArea(BaseArea):
pass
class Field(object):
def __init__(self, fieldType="ASCII", fieldData=""):
self.fieldData = fieldData
self.fieldType = fieldType
@property
def data(self):
return self._data
@property
def fieldType(self):
return self._fieldType
@property
def fieldData(self):
return self._fieldData
class ipmifru(BaseArea):
_BoardInfoArea = None
_ProductInfoArea = None
_InternalUseArea = None
_ChassisInfoArea = None
_multiRecordArea = None
_productinfoAreaOffset = BaseArea.INITVALUE
_boardInfoAreaOffset = BaseArea.INITVALUE
_internalUserAreaOffset = BaseArea.INITVALUE
_chassicInfoAreaOffset = BaseArea.INITVALUE
_multiRecordAreaOffset = BaseArea.INITVALUE
_bindata = None
_bodybin = None
_version = BaseArea.COMMON_HEAD_VERSION
_zeroCheckSum = None
_frusize = 256
def __str__(self):
tmpstr = ""
if self.boardInfoArea.isPresent:
tmpstr += "\nboardinfoarea: \n"
tmpstr += self.boardInfoArea.__str__()
if self.productInfoArea.isPresent:
tmpstr += "\nproductinfoarea: \n"
tmpstr += self.productInfoArea.__str__()
return tmpstr
def decodeBin(self, eeprom):
commonHead = eeprom[0:8]
d_print("decode version %x" % ord(commonHead[0]))
if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]):
raise FruException("HEAD VERSION error,not Fru format!", -10)
if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]):
strtemp = "check header checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(commonHead[0:7]), ord(commonHead[7]))
raise FruException(strtemp, -3)
if ord(commonHead[1]) != ord(self.INITVALUE):
d_print("Internal Use Area is present")
self.internalUseArea = InternalUseArea(
name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA)
self.internalUseArea.isPresent = True
self.internalUserAreaOffset = ord(commonHead[1])
self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: (
self.internalUserAreaOffset * 8 + self.internalUseArea.size)]
if ord(commonHead[2]) != ord(self.INITVALUE):
d_print("Chassis Info Area is present")
self.chassisInfoArea = ChassisInfoArea(
name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA)
self.chassisInfoArea.isPresent = True
self.chassicInfoAreaOffset = ord(commonHead[2])
self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: (
self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)]
if ord(commonHead[3]) != ord(self.INITVALUE):
self.boardInfoArea = BoardInfoArea(
name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA)
self.boardInfoArea.isPresent = True
self.boardInfoAreaOffset = ord(commonHead[3])
self.boardInfoArea.size = ord(
eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8
d_print("Board Info Area is present size:%d" %
(self.boardInfoArea.size))
self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: (
self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)]
if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]):
strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \
(FruUtil.checksum(
self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.boardInfoArea.decodedata()
if ord(commonHead[4]) != ord(self.INITVALUE):
d_print("Product Info Area is present")
self.productInfoArea = ProductInfoArea(
name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA)
self.productInfoArea.isPresent = True
self.productinfoAreaOffset = ord(commonHead[4])
d_print("length offset value: %02x" %
ord(eeprom[self.productinfoAreaOffset * 8 + 1]))
self.productInfoArea.size = ord(
eeprom[self.productinfoAreaOffset * 8 + 1]) * 8
d_print("Product Info Area is present size:%d" %
(self.productInfoArea.size))
self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: (
self.productinfoAreaOffset * 8 + self.productInfoArea.size)]
if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]):
strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % (
FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:]))
raise FruException(strtmp, -3)
self.productInfoArea.decodedata()
if ord(commonHead[5]) != ord(self.INITVALUE):
self.multiRecordArea = MultiRecordArea(
name="MultiRecord record Area ")
d_print("MultiRecord record present")
self.multiRecordArea.isPresent = True
self.multiRecordAreaOffset = ord(commonHead[5])
self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: (
self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)]
def initDefault(self):
self.version = self.COMMON_HEAD_VERSION
self.internalUserAreaOffset = self.INITVALUE
self.chassicInfoAreaOffset = self.INITVALUE
self.boardInfoAreaOffset = self.INITVALUE
self.productinfoAreaOffset = self.INITVALUE
self.multiRecordAreaOffset = self.INITVALUE
self.PAD = self.INITVALUE
self.zeroCheckSum = self.INITVALUE
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
self.productInfoArea = None
self.internalUseArea = None
self.boardInfoArea = None
self.chassisInfoArea = None
self.multiRecordArea = None
# self.recalcute()
@property
def version(self):
return self._version
@version.setter
def version(self, name):
self._version = name
@property
def internalUserAreaOffset(self):
return self._internalUserAreaOffset
@internalUserAreaOffset.setter
def internalUserAreaOffset(self, obj):
self._internalUserAreaOffset = obj
@property
def chassicInfoAreaOffset(self):
return self._chassicInfoAreaOffset
@chassicInfoAreaOffset.setter
def chassicInfoAreaOffset(self, obj):
self._chassicInfoAreaOffset = obj
@property
def productinfoAreaOffset(self):
return self._productinfoAreaOffset
@productinfoAreaOffset.setter
def productinfoAreaOffset(self, obj):
self._productinfoAreaOffset = obj
@property
def boardInfoAreaOffset(self):
return self._boardInfoAreaOffset
@boardInfoAreaOffset.setter
def boardInfoAreaOffset(self, obj):
self._boardInfoAreaOffset = obj
@property
def multiRecordAreaOffset(self):
return self._multiRecordAreaOffset
@multiRecordAreaOffset.setter
def multiRecordAreaOffset(self, obj):
self._multiRecordAreaOffset = obj
@property
def zeroCheckSum(self):
return self._zeroCheckSum
@zeroCheckSum.setter
def zeroCheckSum(self, obj):
self._zeroCheckSum = obj
@property
def productInfoArea(self):
return self._ProductInfoArea
@productInfoArea.setter
def productInfoArea(self, obj):
self._ProductInfoArea = obj
@property
def internalUseArea(self):
return self._InternalUseArea
@internalUseArea.setter
def internalUseArea(self, obj):
self.internalUseArea = obj
@property
def boardInfoArea(self):
return self._BoardInfoArea
@boardInfoArea.setter
def boardInfoArea(self, obj):
self._BoardInfoArea = obj
@property
def chassisInfoArea(self):
return self._ChassisInfoArea
@chassisInfoArea.setter
def chassisInfoArea(self, obj):
self._ChassisInfoArea = obj
@property
def multiRecordArea(self):
return self._multiRecordArea
@multiRecordArea.setter
def multiRecordArea(self, obj):
self._multiRecordArea = obj
@property
def bindata(self):
return self._bindata
@bindata.setter
def bindata(self, obj):
self._bindata = obj
@property
def bodybin(self):
return self._bodybin
@bodybin.setter
def bodybin(self, obj):
self._bodybin = obj
def recalcuteCommonHead(self):
self.bindata = ""
self.offset = self.SUGGESTED_SIZE_COMMON_HEADER
d_print("common Header %d" % self.offset)
d_print("fru eeprom size %d" % self._frusize)
if self.internalUseArea is not None and self.internalUseArea.isPresent:
self.internalUserAreaOffset = self.offset // 8
self.offset += self.internalUseArea.size
d_print("internalUseArea is present offset:%d" % self.offset)
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
self.chassicInfoAreaOffset = self.offset // 8
self.offset += self.chassisInfoArea.size
d_print("chassisInfoArea is present offset:%d" % self.offset)
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
self.boardInfoAreaOffset = self.offset // 8
self.offset += self.boardInfoArea.size
d_print("boardInfoArea is present offset:%d" % self.offset)
d_print("boardInfoArea is present size:%d" %
self.boardInfoArea.size)
if self.productInfoArea is not None and self.productInfoArea.isPresent:
self.productinfoAreaOffset = self.offset // 8
self.offset += self.productInfoArea.size
d_print("productInfoArea is present offset:%d" % self.offset)
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
self.multiRecordAreaOffset = self.offset // 8
d_print("multiRecordArea is present offset:%d" % self.offset)
if self.internalUserAreaOffset == self.INITVALUE:
self.internalUserAreaOffset = 0
if self.productinfoAreaOffset == self.INITVALUE:
self.productinfoAreaOffset = 0
if self.chassicInfoAreaOffset == self.INITVALUE:
self.chassicInfoAreaOffset = 0
if self.boardInfoAreaOffset == self.INITVALUE:
self.boardInfoAreaOffset = 0
if self.multiRecordAreaOffset == self.INITVALUE:
self.multiRecordAreaOffset = 0
self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset
- self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff
d_print("zerochecksum:%x" % self.zeroCheckSum)
self.data = ""
self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr(
self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum)
self.bindata = self.data + self.bodybin
totallen = len(self.bindata)
d_print("totallen %d" % totallen)
if (totallen < self._frusize):
self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0]))
else:
raise FruException('bin data more than %d' % self._frusize, -2)
def recalcutebin(self):
self.bodybin = ""
if self.internalUseArea is not None and self.internalUseArea.isPresent:
d_print("internalUseArea present")
self.bodybin += self.internalUseArea.data
if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent:
d_print("chassisInfoArea present")
self.bodybin += self.chassisInfoArea.data
if self.boardInfoArea is not None and self.boardInfoArea.isPresent:
d_print("boardInfoArea present")
self.boardInfoArea.recalcute()
self.bodybin += self.boardInfoArea.data
if self.productInfoArea is not None and self.productInfoArea.isPresent:
d_print("productInfoAreapresent")
self.productInfoArea.recalcute()
self.bodybin += self.productInfoArea.data
if self.multiRecordArea is not None and self.multiRecordArea.isPresent:
d_print("multiRecordArea present")
self.bodybin += self.productInfoArea.data
def recalcute(self, fru_eeprom_size=256):
self._frusize = fru_eeprom_size
self.recalcutebin()
self.recalcuteCommonHead()

View File

@@ -0,0 +1,449 @@
#!/usr/bin/python3
import binascii
class OnietlvException(Exception):
def __init__(self, message='onietlverror', code=-100):
err = 'errcode: {0} message:{1}'.format(code, message)
Exception.__init__(self, err)
self.code = code
self.message = message
class onie_tlv(object):
TLV_INFO_ID_STRING = "TlvInfo\x00"
TLV_INFO_INIA_ID = "\x00\x00\x13\x11"
TLV_INFO_VERSION = 0x01
TLV_INFO_LENGTH = 0x00
TLV_INFO_LENGTH_VALUE = 0xba
TLV_CODE_PRODUCT_NAME = 0x21
TLV_CODE_PART_NUMBER = 0x22
TLV_CODE_SERIAL_NUMBER = 0x23
TLV_CODE_MAC_BASE = 0x24
TLV_CODE_MANUF_DATE = 0x25
TLV_CODE_DEVICE_VERSION = 0x26
TLV_CODE_LABEL_REVISION = 0x27
TLV_CODE_PLATFORM_NAME = 0x28
TLV_CODE_ONIE_VERSION = 0x29
TLV_CODE_MAC_SIZE = 0x2A
TLV_CODE_MANUF_NAME = 0x2B
TLV_CODE_MANUF_COUNTRY = 0x2C
TLV_CODE_VENDOR_NAME = 0x2D
TLV_CODE_DIAG_VERSION = 0x2E
TLV_CODE_SERVICE_TAG = 0x2F
TLV_CODE_VENDOR_EXT = 0xFD
TLV_CODE_CRC_32 = 0xFE
_TLV_DISPLAY_VENDOR_EXT = 1
TLV_CODE_RJ_CARID = 0x01
_TLV_INFO_HDR_LEN = 11
TLV_CODE_PRODUCT_ID = 0x40
TLV_CODE_HW_VERSION = 0x41
TLV_CODE_MAIN_FILENAME = 0x42
TLV_CODE_DTS_FINENAME = 0x43
TLV_CODE_SY_SERIAL0 = 0x44
TLV_CODE_SY_SERIAL1 = 0x45
TLV_CODE_SY_SERIAL2 = 0x46
TLV_CODE_SY_SERIAL3 = 0x47
TLV_CODE_PROJECT_ID = 0x48
TLV_CODE_SETMAC_VERSION = 0x49
TLV_CODE_EEPROM_TYPE = 0x4A
@property
def dstatus(self):
return self._dstatus
@property
def cardid(self):
return self._cardid
@property
def productname(self):
return self._productname
@property
def partnum(self):
return self._partnum
@property
def serialnum(self):
return self._serialnum
@property
def macbase(self):
return self._macbase
@property
def manufdate(self):
return self._manufdate
@property
def deviceversion(self):
return self._deviceversion
@property
def labelrevision(self):
return self._labelrevision
@property
def platformname(self):
return self._platformname
@property
def onieversion(self):
return self._onieversion
@property
def macsize(self):
return self._macsize
@property
def manufname(self):
return self._manufname
@property
def manufcountry(self):
return self._manufcountry
@property
def vendorname(self):
return self._vendorname
@property
def diagname(self):
return self._diagname
@property
def servicetag(self):
return self._servicetag
@property
def vendorext(self):
return self._vendorext
@property
def fanbus(self):
return self._fanbus
@property
def fanloc(self):
return self._fanloc
def __init__(self):
self._cardid = ""
self._productname = ""
self._partnum = ""
self._serialnum = ""
self._macbase = ""
self._manufdate = ""
self._deviceversion = ""
self._labelrevision = ""
self._platformname = ""
self._onieversion = ""
self._macsize = ""
self._manufname = ""
self._manufcountry = ""
self._vendorname = ""
self._diagname = ""
self._servicetag = ""
self._vendorext = ""
self._productid = ""
self._hwversion = ""
self._mainfilename = ""
self._dtsfilename = ""
self._syserial0 = ""
self._syserial1 = ""
self._syserial2 = ""
self._syserial3 = ""
self._projectid = ""
self._setmacversion = ""
self._eepromtype = ""
self._crc32 = ""
self._dstatus = 0
def oniecrc32(self, v):
data_array = bytearray()
for x in v:
data_array.append(ord(x))
return '0x%08x' % (binascii.crc32(bytes(data_array)) & 0xffffffff)
def getTLV_BODY(self, type, value):
x = []
temp_t = ""
if type == self.TLV_CODE_MAC_BASE:
arr = value.split(':')
for tt in arr:
temp_t += chr(int(tt, 16))
elif type == self.TLV_CODE_DEVICE_VERSION:
temp_t = chr(value)
elif type == self.TLV_CODE_MAC_SIZE:
temp_t = chr(value >> 8) + chr(value & 0x00ff)
else:
temp_t = value
x.append(chr(type))
x.append(chr(len(temp_t)))
for i in temp_t:
x.append(i)
return x
def generate_ext(self, cardid):
s = "%08x" % cardid
ret = ""
for t in range(0, 4):
ret += chr(int(s[2 * t:2 * t + 2], 16))
ret = chr(0x01) + chr(len(ret)) + ret
return ret
def generate_value(self, _t):
ret = []
for i in self.TLV_INFO_ID_STRING:
ret.append(i)
ret.append(chr(self.TLV_INFO_VERSION))
ret.append(chr(self.TLV_INFO_LENGTH))
ret.append(chr(self.TLV_INFO_LENGTH_VALUE))
total_len = 0
for key in _t:
x = self.getTLV_BODY(key, _t[key])
ret += x
total_len += len(x)
ret[10] = chr(total_len + 6)
ret.append(chr(0xFE))
ret.append(chr(0x04))
s = self.oniecrc32(''.join(ret))
for t in range(0, 4):
ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16)))
totallen = len(ret)
if (totallen < 256):
for left_t in range(0, 256 - totallen):
ret.append(chr(0x00))
return (ret, True)
def decode_tlv(self, e):
tlv_index = 0
tlv_end = len(e)
ret = []
while tlv_index < tlv_end and (tlv_index + 2 + ord(e[tlv_index + 1])) <= len(e):
rt = self.decoder(e[tlv_index:tlv_index + 2 + ord(e[tlv_index + 1])])
ret.append(rt)
if ord(e[tlv_index]) == self.TLV_CODE_CRC_32:
break
tlv_index += ord(e[tlv_index + 1]) + 2
return ret
def decode(self, e):
if e[0:8] != self.TLV_INFO_ID_STRING:
raise OnietlvException("ONIE tlv head info error,not onie tlv type", -1)
total_len = (ord(e[9]) << 8) | ord(e[10])
tlv_index = self._TLV_INFO_HDR_LEN
tlv_end = self._TLV_INFO_HDR_LEN + total_len
if tlv_end > len(e):
raise OnietlvException("ONIE tlv length error", -2)
ret = []
ret = self.decode_tlv(e[tlv_index:tlv_end])
for item in ret:
if item['code'] == self.TLV_CODE_VENDOR_EXT:
if item["value"][0:4] == self.TLV_INFO_INIA_ID:
rt = self.decode_tlv(item["value"][4:])
else:
rt = self.decode_tlv(item["value"][0:])
ret.extend(rt)
return ret
def decoder(self, t):
if ord(t[0]) == self.TLV_CODE_PRODUCT_NAME:
name = "Product Name"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._productname = value
elif ord(t[0]) == self.TLV_CODE_PART_NUMBER:
name = "Part Number"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._partnum = value
elif ord(t[0]) == self.TLV_CODE_SERIAL_NUMBER:
name = "Serial Number"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._serialnum = value
elif ord(t[0]) == self.TLV_CODE_MAC_BASE:
name = "Base MAC Address"
_len = ord(t[1])
value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper()
self._macbase = value
elif ord(t[0]) == self.TLV_CODE_MANUF_DATE:
name = "Manufacture Date"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._manufdate = value
elif ord(t[0]) == self.TLV_CODE_DEVICE_VERSION:
name = "Device Version"
_len = ord(t[1])
value = ord(t[2])
self._deviceversion = value
elif ord(t[0]) == self.TLV_CODE_LABEL_REVISION:
name = "Label Revision"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._labelrevision = value
elif ord(t[0]) == self.TLV_CODE_PLATFORM_NAME:
name = "Platform Name"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._platformname = value
elif ord(t[0]) == self.TLV_CODE_ONIE_VERSION:
name = "ONIE Version"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._onieversion = value
elif ord(t[0]) == self.TLV_CODE_MAC_SIZE:
name = "MAC Addresses"
_len = ord(t[1])
value = str((ord(t[2]) << 8) | ord(t[3]))
self._macsize = value
elif ord(t[0]) == self.TLV_CODE_MANUF_NAME:
name = "Manufacturer"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._manufname = value
elif ord(t[0]) == self.TLV_CODE_MANUF_COUNTRY:
name = "Manufacture Country"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._manufcountry = value
elif ord(t[0]) == self.TLV_CODE_VENDOR_NAME:
name = "Vendor Name"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._vendorname = value
elif ord(t[0]) == self.TLV_CODE_DIAG_VERSION:
name = "Diag Version"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._diagname = value
elif ord(t[0]) == self.TLV_CODE_SERVICE_TAG:
name = "Service Tag"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._servicetag = value
elif ord(t[0]) == self.TLV_CODE_VENDOR_EXT:
name = "Vendor Extension"
_len = ord(t[1])
value = ""
if self._TLV_DISPLAY_VENDOR_EXT:
value = t[2:2 + ord(t[1])]
self._vendorext = value
elif ord(t[0]) == self.TLV_CODE_CRC_32 and len(t) == 6:
name = "CRC-32"
_len = ord(t[1])
value = "0x%08X" % (((ord(t[2]) << 24) | (
ord(t[3]) << 16) | (ord(t[4]) << 8) | ord(t[5])),)
self._crc32 = value
elif ord(t[0]) == self.TLV_CODE_RJ_CARID:
name = "Card id"
_len = ord(t[1])
value = ""
for c in t[2:2 + ord(t[1])]:
value += "%02X" % (ord(c),)
self._cardid = value
elif ord(t[0]) == self.TLV_CODE_PRODUCT_ID:
name = "Product id"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._productid = value
elif ord(t[0]) == self.TLV_CODE_HW_VERSION:
name = "Hardware Version"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._hwversion = value
elif ord(t[0]) == self.TLV_CODE_MAIN_FILENAME:
name = "Main File Name"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._mainfilename = value
elif ord(t[0]) == self.TLV_CODE_DTS_FINENAME:
name = "DTS File Name"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._dtsfilename = value
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL0:
name = "SY Serial 0"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._syserial0 = value
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL1:
name = "SY Serial 1"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._syserial1 = value
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL2:
name = "SY Serial 2"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._syserial2 = value
elif ord(t[0]) == self.TLV_CODE_SY_SERIAL3:
name = "SY Serial 3"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._syserial3 = value
elif ord(t[0]) == self.TLV_CODE_PROJECT_ID:
name = "Project id"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._projectid = value
elif ord(t[0]) == self.TLV_CODE_SETMAC_VERSION:
name = "Setmac Version"
_len = ord(t[1])
value = t[2:2 + ord(t[1])]
self._setmacversion = value
elif ord(t[0]) == self.TLV_CODE_EEPROM_TYPE:
name = "EEPROM Type"
_len = ord(t[1])
value = ""
for c in t[2:2 + ord(t[1])]:
value += "%02X" % (ord(c),)
self._eepromtype = value
else:
name = "Unknown"
_len = ord(t[1])
value = ""
for c in t[2:2 + ord(t[1])]:
value += "0x%02X " % (ord(c),)
return {"name": name, "code": ord(t[0]), "value": value, "lens": _len}
def __str__(self):
formatstr = "Card id : %s \n" \
"Product Name : %s \n" \
"Part Number : %s \n" \
"Serial Number : %s \n" \
"Base MAC Address : %s \n" \
"Manufacture Date : %s \n" \
"Device Version : %s \n" \
"Label Revision : %s \n" \
"Platform Name : %s \n" \
"ONIE Version : %s \n" \
"MAC Addresses : %s \n" \
"Manufacturer : %s \n" \
"Manufacture Country : %s \n" \
"Vendor Name : %s \n" \
"Diag Version : %s \n" \
"Service Tag : %s \n" \
"CRC-32 : %s \n"
return formatstr % (self._cardid,
self._productname,
self._partnum,
self._serialnum,
self._macbase,
self._manufdate,
self._deviceversion,
self._labelrevision,
self._platformname,
self._onieversion,
self._macsize,
self._manufname,
self._manufcountry,
self._vendorname,
self._diagname,
self._servicetag,
self._crc32)

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env python3
#######################################################
#
# baseutil.py
# Python implementation of the Class baseutil
# Original author: rd@ruijie.com.cn
#
#######################################################
import importlib.machinery
import os
import syslog
from plat_hal.osutil import osutil
SYSLOG_IDENTIFIER = "HAL"
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
BOARD_ID_PATH = "/sys/module/ruijie_common/parameters/dfd_my_type"
def getonieplatform(path):
if not os.path.isfile(path):
return ""
machine_vars = {}
with open(path) as machine_file:
for line in machine_file:
tokens = line.split('=')
if len(tokens) < 2:
continue
machine_vars[tokens[0]] = tokens[1].strip()
return machine_vars.get("onie_platform")
def getboardid():
if not os.path.exists(BOARD_ID_PATH):
return "NA"
with open(BOARD_ID_PATH) as fd:
id_str = fd.read().strip()
return "0x%x" % (int(id_str, 10))
def getplatform_config_db():
if not os.path.isfile(CONFIG_DB_PATH):
return ""
val = os.popen("sonic-cfggen -j %s -v DEVICE_METADATA.localhost.platform" % CONFIG_DB_PATH).read().strip()
if len(val) <= 0:
return ""
else:
return val
def getplatform_name():
if os.path.isfile('/host/machine.conf'):
return getonieplatform('/host/machine.conf')
elif os.path.isfile('/usr/share/sonic/hwsku/machine.conf'):
return getonieplatform('/usr/share/sonic/hwsku/machine.conf')
else:
return getplatform_config_db()
CONFIG_FILE_LIST = ["/usr/local/bin/", "/usr/lib/python3/dist-packages/", "/usr/local/lib/python3.7/dist-packages/hal-config/", "/usr/local/lib/python3.9/dist-packages/hal-config/"]
platform = (getplatform_name()).replace("-", "_")
boardid = getboardid()
boardid_devicefile = (platform + "_"+ boardid + "_device.py")
boardid_monitorfile = (platform + "_"+ boardid + "_monitor.py")
devicefile = (platform + "_device.py")
monitorfile = (platform + "_monitor.py")
class baseutil:
CONFIG_NAME = 'devices'
MONITOR_CONFIG_NAME = 'monitor'
UBOOT_ENV_URL = '/etc/device/uboot_env'
@staticmethod
def get_config():
real_path = None
for configfile_path in CONFIG_FILE_LIST:
boardid_config_file_path = (configfile_path + boardid_devicefile)
config_file_path = (configfile_path + devicefile)
if os.path.exists(boardid_config_file_path):
real_path = boardid_config_file_path
break
elif os.path.exists(config_file_path):
real_path = config_file_path
break
if real_path is None:
raise Exception("get hal device config error")
devices = importlib.machinery.SourceFileLoader(baseutil.CONFIG_NAME, real_path).load_module()
return devices.devices
@staticmethod
def get_monitor_config():
real_path = None
for configfile_path in CONFIG_FILE_LIST:
boardid_config_file_path = (configfile_path + boardid_monitorfile)
config_file_path = (configfile_path + monitorfile)
if os.path.exists(boardid_config_file_path):
real_path = boardid_config_file_path
break
elif os.path.exists(config_file_path):
real_path = config_file_path
break
if real_path is None:
raise Exception("get hal monitor config error")
monitor = importlib.machinery.SourceFileLoader(baseutil.MONITOR_CONFIG_NAME, real_path).load_module()
return monitor.monitor
@staticmethod
def get_productname():
ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL)
tmp = val.lower().replace('-', '_')
if ret != 0 or len(val) <= 0:
raise Exception("get productname error")
else:
return tmp
@staticmethod
def get_platform():
ret, val = osutil.command("cat %s |grep conffitname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL)
if ret != 0 or len(val) <= 0:
raise Exception("get platform error")
else:
return val
@staticmethod
def get_product_fullname():
ret, val = osutil.command("cat %s |grep productname | awk -F\"=\" '{print $2;}'" % baseutil.UBOOT_ENV_URL)
if ret != 0 or len(val) <= 0:
raise Exception("get productname error")
else:
return val
@staticmethod
def logger_debug(msg):
syslog.openlog(SYSLOG_IDENTIFIER)
syslog.syslog(syslog.LOG_DEBUG, msg)
syslog.closelog()

View File

@@ -0,0 +1,322 @@
#!/usr/bin/env python3
#######################################################
#
# chassisbase.py
# Python implementation of the Class chassisbase
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.dcdc import dcdc
from plat_hal.onie_e2 import onie_e2
from plat_hal.psu import psu
from plat_hal.led import led
from plat_hal.temp import temp
from plat_hal.fan import fan
from plat_hal.cpld import cpld
from plat_hal.component import component
from plat_hal.cpu import cpu
from plat_hal.baseutil import baseutil
class chassisbase(object):
__onie_e2_list = []
__psu_list = []
__led_list = []
__temp_list = []
__fan_list = []
__card_list = []
__sensor_list = []
__dcdc_list = []
__cpld_list = []
__comp_list = []
__bios_list = []
__bmc_list = []
__cpu = None
def __init__(self, conftype=0, conf=None):
# type: (object, object, object) -> object
"""
init chassisbase as order
type = 0 use default conf, maybe auto find by platform
type = 1 use given conf, conf is not None
BITMAP
bit 16
bit 0 PSU
bit 1 LED
bit 2 TEMP
bit 3 fan
bit 4 card
bit 5 sensor
"""
__confTemp = None
if conftype == 0:
# user
__confTemp = baseutil.get_config()
elif conftype == 1:
__confTemp = conf
# onie_e2
onie_e2temp = []
onie_e2config = __confTemp.get('onie_e2', [])
for i in range(len((onie_e2config))):
onie_e2_1 = onie_e2(onie_e2config[i])
onie_e2temp.append(onie_e2_1)
self.onie_e2_list = onie_e2temp
# psu
psutemp = []
psuconfig = __confTemp.get('psus', [])
for i in range(len((psuconfig))):
psu1 = psu(psuconfig[i])
psutemp.append(psu1)
self.psu_list = psutemp
# led
ledtemp = []
ledconfig = __confTemp.get('leds', [])
for i in range(len((ledconfig))):
led1 = led(ledconfig[i])
ledtemp.append(led1)
self.led_list = ledtemp
# temp
temptemp = []
tempconfig = __confTemp.get('temps', [])
for i in range(len((tempconfig))):
temp1 = temp(tempconfig[i])
temptemp.append(temp1)
self.temp_list = temptemp
# fan
fantemp = []
fanconfig = __confTemp.get('fans', [])
for i in range(len((fanconfig))):
fan1 = fan(fanconfig[i])
fantemp.append(fan1)
self.fan_list = fantemp
# dcdc
dcdctemp = []
dcdcconfig = __confTemp.get('dcdc', [])
for i in dcdcconfig:
dcdc1 = dcdc(i)
dcdctemp.append(dcdc1)
self.dcdc_list = dcdctemp
# cpld
cpldtemp = []
cpldconfig = __confTemp.get('cplds', [])
for i in range(len((cpldconfig))):
cpld1 = cpld(cpldconfig[i])
cpldtemp.append(cpld1)
self.cpld_list = cpldtemp
# compoment: cpld/fpga/bios
comptemp = []
compconfig = __confTemp.get('comp_cpld', [])
for i in range(len((compconfig))):
comp1 = component(compconfig[i])
comptemp.append(comp1)
self.comp_list = comptemp
compconfig = __confTemp.get('comp_fpga', [])
for i in range(len((compconfig))):
comp1 = component(compconfig[i])
self.comp_list.append(comp1)
compconfig = __confTemp.get('comp_bios', [])
for i in range(len((compconfig))):
comp1 = component(compconfig[i])
self.comp_list.append(comp1)
# cpu
cpuconfig = __confTemp.get('cpu', [])
if len(cpuconfig):
self.cpu = cpu(cpuconfig[0])
# dcdc
@property
def dcdc_list(self):
return self.__dcdc_list
@dcdc_list.setter
def dcdc_list(self, val):
self.__dcdc_list = val
# sensor
@property
def sensor_list(self):
return self.__sensor_list
@sensor_list.setter
def sensor_list(self, val):
self.__sensor_list = val
def get_sensor_byname(self, name):
tmp = self.sensor_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# onie_e2
@property
def onie_e2_list(self):
return self.__onie_e2_list
@onie_e2_list.setter
def onie_e2_list(self, val):
self.__onie_e2_list = val
def get_onie_e2_byname(self, name):
tmp = self.onie_e2_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# psu
@property
def psu_list(self):
return self.__psu_list
@psu_list.setter
def psu_list(self, val):
self.__psu_list = val
def get_psu_byname(self, name):
tmp = self.psu_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# fan
@property
def fan_list(self):
return self.__fan_list
@fan_list.setter
def fan_list(self, val):
self.__fan_list = val
def get_fan_byname(self, name):
tmp = self.fan_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# led
@property
def led_list(self):
return self.__led_list
@led_list.setter
def led_list(self, val):
self.__led_list = val
def get_ledlist_config(self):
pass
def get_led_byname(self, name):
tmp = self.led_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# temp
@property
def temp_list(self):
return self.__temp_list
@temp_list.setter
def temp_list(self, val):
self.__temp_list = val
def get_temp_byname(self, name):
tmp = self.temp_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# cpld
@property
def cpld_list(self):
return self.__cpld_list
@cpld_list.setter
def cpld_list(self, val):
self.__cpld_list = val
def get_cpld_byname(self, name):
tmp = self.cpld_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
@property
def comp_list(self):
return self.__comp_list
@comp_list.setter
def comp_list(self, val):
self.__comp_list = val
def get_comp_byname(self, name):
tmp = self.comp_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# bios
@property
def bios_list(self):
return self.__bios_list
@bios_list.setter
def bios_list(self, val):
self.__bios_list = val
def get_bios_byname(self, name):
tmp = self.bios_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# bmc
@property
def bmc_list(self):
return self.__bmc_list
@bmc_list.setter
def bmc_list(self, val):
self.__bmc_list = val
def get_bmc_byname(self, name):
tmp = self.bmc_list
for i in range(len(tmp)):
if name == tmp[i].name:
return tmp[i]
return None
# cpu
@property
def cpu(self):
return self.__cpu
@cpu.setter
def cpu(self, val):
self.__cpu = val
def get_cpu_byname(self, name):
return self.cpu

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env python3
#######################################################
#
# component.py
# Python implementation of the Class fan
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from plat_hal.osutil import osutil
class component(devicebase):
__user_reg = None
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.version_file = conf.get('VersionFile', None)
self.comp_id = conf.get("comp_id", None)
self.desc = conf.get("desc", None)
self.slot = conf.get("slot", None)
def get_version(self):
version = "NA"
try:
ret, version = self.get_value(self.version_file)
if (ret == False):
return version
pattern = self.version_file.get('pattern', None)
version = osutil.std_match(version, pattern)
except Exception as e:
return version
return version

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
#######################################################
#
# fan.py
# Python implementation of the Class fan
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
class cpld(devicebase):
__user_reg = None
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.user_reg = conf.get('UserReg', None)
self.console_reg = conf.get('ConsoleReg', None)
self.console_reg_attrs = conf.get('ConsoleRegAttrs', None)
self.version_file = conf.get('VersionFile', None)
self.cpld_id = conf.get("cpld_id", None)
self.desc = conf.get("desc", None)
self.slot = conf.get("slot", None)
self.format = conf.get("format", "big_endian")
def get_user_reg(self):
if (self.user_reg is None):
return False
ret, val = self.get_value(self.user_reg)
return val
def set_user_reg(self, value):
if (self.user_reg is None):
return False
byte = value & 0xFF
ret, val = self.set_value(self.user_reg, byte)
return ret
def set_console_owner(self, owner):
ret = False
if (self.console_reg is None):
return False
tmpattr = self.console_reg_attrs.get(owner, None)
if tmpattr is not None:
ret, val = self.set_value(self.console_reg, tmpattr)
return ret
def get_version(self):
ret, val = self.get_value(self.version_file)
if (ret == False):
val = "N/A"
return val
val = val.strip('\n').split(" ")
if len(val) < 4:
val = "N/A"
return val
if self.format == "little_endian":
cpld_version = "%s%s%s%s" % (val[3], val[2], val[1], val[0])
else:
cpld_version = "%s%s%s%s" % (val[0], val[1], val[2], val[3])
return cpld_version

View File

@@ -0,0 +1,36 @@
#!/usr/bin/env python3
###############################################################################
#
# Hardware Abstraction Layer APIs -- CPU APIs.
#
# Copyright (C) Ruijie, INC.
#
###############################################################################
from plat_hal.devicebase import devicebase
class cpu(devicebase):
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.cpu_reset_cnt_reg = conf.get('CpuResetCntReg', None)
def get_cpu_reset_num(self):
"""
get cpu reset num.
@return cpu reset number, -1 for failure
"""
ret = -1
if self.cpu_reset_cnt_reg is None:
self.logger_debug("ERR: no support get cpu reset num")
return ret
ret, reset_num = self.get_value(self.cpu_reset_cnt_reg)
if ret is False or reset_num is None:
self.logger_debug("ERR: i2c read cpu_reset_cnt_reg,result:%s" % reset_num)
else:
if isinstance(reset_num, str):
ret = int(reset_num, 16)
else:
ret = reset_num
return ret

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env python3
from plat_hal.devicebase import devicebase
from plat_hal.sensor import sensor
class dcdc(devicebase):
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.dcdc_id = conf.get("dcdc_id", None)
self.sensor = sensor(conf)

View File

@@ -0,0 +1,223 @@
#!/usr/bin/env python3
#######################################################
#
# devicebase.py
# Python implementation of the Class devicebase
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.osutil import osutil
from plat_hal.baseutil import baseutil
import subprocess
class devicebase(object):
_name = None
__error_ret = -99999
@property
def name(self):
return self._name
@name.setter
def name(self, val):
self._name = val
def dumpValueByI2c(self, bus, loc):
str = ""
for i in range(256):
ret, val = self.get_i2c(bus, loc, i)
str += chr(val)
return str
def byteTostr(self, val):
strtmp = ''
for i in range(len(val)):
strtmp += chr(val[i])
return strtmp
def get_eeprom_info(self, conf):
if conf.get('way') == 'sysfs' or conf.get('way') == 'devfile':
ret, eeprom = self.get_value(conf)
if ret is False:
return None
else:
eeprom = self.dumpValueByI2c(conf.get('bus'), conf.get('addr'))
return eeprom
def exec_os_cmd(self, cmd):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
return proc.returncode, stdout
def get_value(self, config):
'''
get value by config way
way i2c/sysfs/lpc
'''
way = config.get("way")
if way == 'sysfs':
return self.get_sysfs(config.get("loc"), config.get("flock_path"))
elif way == "i2c":
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.get_i2c(bus, addr, offset)
elif way == "io":
io_addr = config.get('io_addr')
read_len = config.get('read_len', 1)
return self.get_io(io_addr, read_len)
elif way == "i2cword":
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.get_i2cword(bus, addr, offset)
elif way == "devmem":
addr = config.get("addr")
digit = config.get("digit")
mask = config.get("mask", None)
return self.get_devmem(addr, digit, mask)
elif way == "sdk":
type = config.get("type")
if type == "bcm_temp":
return self.getbcmtemp()
elif type == "bcm_reg":
reg = config.get("reg")
return self.getbcmreg(reg)
else:
raise Exception("cannot found sdk type deal")
elif way == "devfile":
loc = config.get("loc")
offset = config.get("offset")
len = config.get("len")
return self.devfile_read(loc, offset, len)
elif way == "devfile_ascii":
loc = config.get("loc")
offset = config.get("offset")
len = config.get("len")
return self.devfile_read_ascii(loc, offset, len)
elif way == 'cmd':
cmd = config.get("cmd")
ret, log = self.exec_os_cmd(cmd)
if ret:
return False, ("cmd write exec %s failed, log: %s" % (cmd, log))
else:
return True, log
else:
raise Exception("cannot found way deal")
def devfile_read(self, loc, offset, len):
return osutil.readdevfile(loc, offset, len)
def devfile_read_ascii(self, loc, offset, len):
return osutil.readdevfile_ascii(loc, offset, len)
def get_sysfs(self, loc, flock_path=None):
return self.getsysfs(loc, flock_path)
def getsysfs(self, loc, flock_path=None):
ret, val = osutil.readsysfs(loc, flock_path)
return ret, val
def get_devmem(self, addr, digit, mask):
return osutil.getdevmem(addr, digit, mask)
def get_i2cword(self, bus, addr, offset):
return self.geti2cword(bus, addr, offset)
def geti2cword(self, bus, addr, offset):
ret, val = osutil.geti2cword(bus, addr, offset)
return ret, val
def get_io(self, reg_addr, read_len):
return self.getio(reg_addr, read_len)
def getio(self, reg_addr, read_len):
ret, val = osutil.io_rd(reg_addr, read_len)
return ret, val
def get_i2c(self, bus, addr, offset):
return self.geti2c(bus, addr, offset)
def geti2c(self, bus, addr, offset):
ret, val = osutil.rji2cget(bus, addr, offset)
return ret, val
def set_value(self, config, val):
'''
get value by config way
way i2c/sysfs/lpc
'''
way = config.get("way")
if way == 'sysfs':
return self.set_sysfs(config.get("loc"), "0x%02x" % val)
elif way == "i2c":
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.set_i2c(bus, addr, offset, val)
elif way == "i2cpec":
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.seti2c_byte_pec(bus, addr, offset, val)
elif way == 'i2cword':
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.set_i2cword(bus, addr, offset, val)
elif way == "i2cwordpec":
bus = config.get("bus")
addr = config.get("addr")
offset = config.get("offset")
return self.set_i2cwordpec(bus, addr, offset, val)
return False, "unsupport ways: %s" % way
def set_sysfs(self, loc, value):
return self.setsysfs(loc, value)
def setsysfs(self, loc, value):
return osutil.writesysfs(loc, value)
def set_i2cword(self, bus, addr, offset, byte):
return self.seti2cword(bus, addr, offset, byte)
def seti2cword(self, bus, addr, offset, byte):
return osutil.seti2cword(bus, addr, offset, byte)
def set_i2cwordpec(self, bus, addr, offset, val):
return osutil.seti2cwordpec(bus, addr, offset, val)
def seti2c_byte_pec(self, bus, addr, offset, val):
return osutil.seti2c_byte_pec(bus, addr, offset, val)
def set_i2c(self, bus, addr, offset, byte):
return self.seti2c(bus, addr, offset, byte)
def seti2c(self, bus, addr, offset, byte):
ret, val = osutil.rji2cset(bus, addr, offset, byte)
return ret, val
def getbcmtemp(self):
try:
sta, ret = osutil.getmactemp()
if sta == True:
mac_aver = float(ret.get("average", self.__error_ret))
mac_aver = mac_aver * 1000
else:
return False, ret
except AttributeError as e:
return False, str(e)
return True, mac_aver
def getbcmreg(self, reg):
ret, val = osutil.getsdkreg(reg)
return ret, val
def logger_debug(self, msg):
baseutil.logger_debug(msg)
def command(self, cmd):
ret, output = osutil.command(cmd)
return ret, output

View File

@@ -0,0 +1,381 @@
#!/usr/bin/env python3
#######################################################
#
# fan.py
# Python implementation of the Class fan
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from eepromutil.fru import ipmifru
from plat_hal.rotor import rotor
class fan(devicebase):
__rotor_list = []
__pn = None
__raweeprom = None
__sn = None
__hw_version = None
__present = None
__e2loc = None
__rotors = None
__AirFlow = None
__SpeedMin = None
__SpeedMax = None
__productName = None
__productSerialNumber = None
__WatchdogStatus = None
__led_attrs_config = None
__led_config = None
__WatchdogStatus_config = None
__AirFlowconifg = None
__EnableWatchdogConf = None
__Rotor_config = None
__fan_display_name = None # 'N/A'
__fan_display_name_conifg = None
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.sn = conf.get('sn', None)
self.present = conf.get('present', None)
self.e2loc = conf.get('e2loc', None)
self.SpeedMin = conf.get('SpeedMin', None)
self.SpeedMax = conf.get('SpeedMax', None)
self.AirFlowconifg = conf.get("airflow", None)
self.WatchdogStatus_config = conf.get('WatchdogStatus', None)
self.EnableWatchdogConf = conf.get('EnableWatchdogConf', None)
self.led_attrs_config = conf.get('led_attrs', None)
self.led_config = conf.get('led', None)
self.Rotor_config = conf.get('Rotor', None)
self.fan_display_name_conifg = conf.get("fan_display_name", None)
rotor_tmp = []
for key, value in (self.Rotor_config).items():
rotor_tmp.append(rotor(value))
rotor_tmp.sort(key=lambda x: x.name, reverse=False)
self.rotor_list = rotor_tmp
self.rotors = len(self.rotor_list)
@property
def EnableWatchdogConf(self):
return self.__EnableWatchdogConf
@EnableWatchdogConf.setter
def EnableWatchdogConf(self, val):
self.__EnableWatchdogConf = val
@property
def rotor_list(self):
return self.__rotor_list
@rotor_list.setter
def rotor_list(self, val):
self.__rotor_list = val
@property
def Rotor_config(self):
return self.__Rotor_config
@Rotor_config.setter
def Rotor_config(self, val):
self.__Rotor_config = val
@property
def productName(self):
return self.__productName
@productName.setter
def productName(self, val):
self.__productName = val
@property
def productSerialNumber(self):
return self.__productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, val):
self.__productSerialNumber = val
@property
def hw_version(self):
return self.__hw_version
@hw_version.setter
def hw_version(self, val):
self.__hw_version = val
@property
def sn(self):
return self.__sn
@sn.setter
def sn(self, val):
self.__sn = val
@property
def pn(self):
return self.__pn
@pn.setter
def pn(self, val):
self.__pn = val
@property
def raweeprom(self):
return self.__raweeprom
@raweeprom.setter
def raweeprom(self, val):
self.__raweeprom = val
@property
def SpeedMax(self):
return self.__SpeedMax
@SpeedMax.setter
def SpeedMax(self, val):
self.__SpeedMax = val
@property
def SpeedMin(self):
return self.__SpeedMin
@SpeedMin.setter
def SpeedMin(self, val):
self.__SpeedMin = val
@property
def rotors(self):
return self.__rotors
@property
def AirFlow(self):
return self.__AirFlow
@AirFlow.setter
def AirFlow(self, val):
self.__AirFlow = val
@rotors.setter
def rotors(self, val):
self.__rotors = val
@property
def fan_display_name_conifg(self):
return self.__fan_display_name_conifg
@fan_display_name_conifg.setter
def fan_display_name_conifg(self, val):
self.__fan_display_name_conifg = val
@property
def fan_display_name(self):
return self.__fan_display_name
@fan_display_name.setter
def fan_display_name(self, val):
self.__fan_display_name = val
def getspeed(self, conf):
tmp = None
if conf is None:
return -1
ret, val = self.get_value(conf)
if ret == True:
tmp = int(str(val), 10)
else:
val = None
if val is not None:
return int(15000000 / tmp)
return -1
def get_speed(self, rotor_index):
rotor = self.get_rotor_index(rotor_index)
if rotor is None:
return None
speed = rotor.rotor_Speed.Value
if speed is None:
return None
return int(speed)
def set_led(self, color):
status = self.led_attrs_config.get(color, None)
if status is None:
return False
mask = self.led_attrs_config.get('mask', 0xff)
ret, value = self.get_value(self.led_config)
if ret is False or value is None:
return False
setval = (int(value) & ~mask) | (status)
ret, val = self.set_value(self.led_config, setval)
return ret
def get_led(self):
mask = self.led_attrs_config.get('mask', 0xff)
ret, value = self.get_value(self.led_config)
if ret is False or value is None:
return False, 'N/A'
ledval = (int(value) & mask)
for key, val in self.led_attrs_config.items():
if (ledval == val) and (key != "mask"):
return True, key
return False, 'N/A'
def set_speed(self, rotor_index, level):
if level > 255 or level < 0:
return False
rotor = self.get_rotor_index(rotor_index)
if rotor is None:
return False
ret, val = self.set_value(rotor.Speedconfig, int(level))
return ret
def get_rotor_index(self, rotor_index):
if rotor_index > len(self.rotor_list):
return None
rotor = self.rotor_list[rotor_index - 1]
return rotor
def get_rotor_byname(self, rotor_index):
for rotor in self.rotor_list:
if rotor.name == rotor_index:
return rotor
return None
def get_presence(self):
ret, val = self.get_value(self.present)
if ret is False or val is None:
return -1
if isinstance(val, str):
value = int(val, 16)
else:
value = val
mask = self.present.get("mask")
flag = value & mask
okval = self.present.get("okval", 0)
if flag == okval:
return True
else:
return False
def get_speed_pwm(self, rotor_index):
rotor = self.get_rotor_index(rotor_index)
if rotor is None:
return False
if rotor.i2c_speed is None:
return False
val = round(rotor.i2c_speed * 100 / 255)
return val
def feed_watchdog(self, pwm):
ret = False
for rotor in self.rotor_list:
ret, val = rotor.feed_watchdog()
if ret is False:
return ret
return ret
def get_fru_info(self):
try:
if self.get_presence() is False:
raise Exception("%s: not present" % self.name)
eeprom = self.get_eeprom_info(self.e2loc)
if eeprom is None:
raise Exception("%s: value is none" % self.name)
fru = ipmifru()
if isinstance(eeprom, bytes):
eeprom = self.byteTostr(eeprom)
fru.decodeBin(eeprom)
self.productName = fru.productInfoArea.productName.strip() # PN
self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip() # SN
self.hw_version = fru.productInfoArea.productVersion.strip() # HW
except Exception as e:
self.productName = None
self.productSerialNumber = None
self.hw_version = None
return False
return True
def decode_eeprom_info(self):
'''get fan name, hw version, sn'''
return self.get_fru_info()
def get_AirFlow(self):
if self.productName is None:
ret = self.decode_eeprom_info()
if ret is False:
self.AirFlow = None
return False
if self.AirFlowconifg is None:
self.AirFlow = None
return False
else:
for i in self.AirFlowconifg:
if self.productName in self.AirFlowconifg[i]:
self.AirFlow = i
return True
self.AirFlow = None
return False
def enable_watchdog(self, enable, timeout_sec):
ret = False
if enable == True:
byte = self.EnableWatchdogConf.get("enable_byte", None)
ret, val = self.set_value(self.EnableWatchdogConf, byte)
elif enable == False:
byte = self.EnableWatchdogConf.get("disable_byte", None)
ret, val = self.set_value(self.EnableWatchdogConf, byte)
return ret
def get_watchdog_status(self):
dic = {"support": None, "open": None, "work_full": None, "work_allow_set": None}
if self.WatchdogStatus_config is None:
return None
ret, val = self.get_value(self.WatchdogStatus_config)
if ret is False or val is None:
return None
support_watchdog_off = self.WatchdogStatus_config.get("support_watchdog_off", None)
is_open_off = self.WatchdogStatus_config.get("is_open_off", None)
full_running_off = self.WatchdogStatus_config.get("full_running_off", None)
running_setting_off = self.WatchdogStatus_config.get("running_setting_off", None)
if support_watchdog_off is not None:
if support_watchdog_off & val == self.WatchdogStatus_config.get("support_watchdog_mask", None):
dic["support"] = True
else:
dic["support"] = False
return dic
if is_open_off is not None:
if is_open_off & val == self.WatchdogStatus_config.get("is_open_mask", None):
dic["open"] = True
else:
dic["open"] = False
if full_running_off is not None:
if full_running_off & val == self.WatchdogStatus_config.get("full_running_mask", None):
dic["work_full"] = True
else:
dic["work_full"] = False
if running_setting_off is not None:
if running_setting_off & val == self.WatchdogStatus_config.get("running_setting_mask", None):
dic["work_allow_set"] = True
else:
dic["work_allow_set"] = False
return dic
def get_fan_display_name(self):
if self.productName is None:
ret = self.get_fru_info()
if ret is False:
self.fan_display_name = None
return False
if self.fan_display_name_conifg is None:
self.fan_display_name = self.productName
return False
else:
for i in self.fan_display_name_conifg:
if self.productName in self.fan_display_name_conifg[i]:
self.fan_display_name = i
return True
self.fan_display_name = self.productName
return False

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
#######################################################
#
# led.py
# Python implementation of the Class led
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
class led(devicebase):
def __init__(self, conf=None):
if conf is not None:
self.name = conf.get('name', None)
self.led_type = conf.get('led_type', None)
self.led_attrs_config = conf.get('led_attrs', None)
self.led_config = conf.get('led', None)
def set_color(self, color):
status = self.led_attrs_config.get(color, None)
if status is None:
return False
mask = self.led_attrs_config.get('mask', 0xff)
if isinstance(self.led_config, list):
for led_config_index in self.led_config:
ret, value = self.get_value(led_config_index)
if (ret is False) or (value is None):
return False
setval = (int(value) & ~mask) | (status)
ret, val = self.set_value(led_config_index, setval)
if ret is False:
return ret
else:
ret, value = self.get_value(self.led_config)
if (ret is False) or (value is None):
return False
setval = (int(value) & ~mask) | (status)
ret, val = self.set_value(self.led_config, setval)
return ret
def get_color(self):
mask = self.led_attrs_config.get('mask', 0xff)
ret, value = self.get_value(self.led_config)
if ret is False or value is None:
return False, 'N/A'
ledval = (int(value) & mask)
for key, val in self.led_attrs_config.items():
if (ledval == val) and (key != "mask"):
return True, key
return False, 'N/A'

View File

@@ -0,0 +1,127 @@
#!/usr/bin/env python3
#######################################################
#
# onie_e2.py
# Python implementation of the Class onie_e2
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from eepromutil.onietlv import onie_tlv
class onie_e2(devicebase):
def __init__(self, conf=None):
self._cardid = ""
self._productname = ""
self._partnum = ""
self._serialnum = ""
self._macbase = ""
self._manufdate = ""
self._deviceversion = ""
self._labelrevision = ""
self._platformname = ""
self._onieversion = ""
self._macsize = ""
self._manufname = ""
self._manufcountry = ""
self._vendorname = ""
self._diagname = ""
self._servicetag = ""
if conf is not None:
self.name = conf.get('name', None)
self.e2loc = conf.get('e2loc', None)
self.e2_path = self.e2loc.get('loc', None)
@property
def cardid(self):
return self._cardid
@property
def productname(self):
return self._productname
@property
def partnum(self):
return self._partnum
@property
def serialnum(self):
return self._serialnum
@property
def macbase(self):
return self._macbase
@property
def manufdate(self):
return self._manufdate
@property
def deviceversion(self):
return self._deviceversion
@property
def labelrevision(self):
return self._labelrevision
@property
def platformname(self):
return self._platformname
@property
def onieversion(self):
return self._onieversion
@property
def macsize(self):
return self._macsize
@property
def manufname(self):
return self._manufname
@property
def manufcountry(self):
return self._manufcountry
@property
def vendorname(self):
return self._vendorname
@property
def diagname(self):
return self._diagname
@property
def servicetag(self):
return self._servicetag
def get_onie_e2_info(self):
try:
eeprom = self.get_eeprom_info(self.e2loc)
if eeprom is None:
raise Exception("%s: value is none" % self.name)
onietlv = onie_tlv()
onietlv.decode(eeprom)
self._cardid = onietlv.cardid
self._productname = onietlv.productname
self._partnum = onietlv.partnum
self._serialnum = onietlv.serialnum
self._macbase = onietlv.macbase
self._manufdate = onietlv.manufdate
self._deviceversion = onietlv.deviceversion
self._labelrevision = onietlv.labelrevision
self._platformname = onietlv.platformname
self._onieversion = onietlv.onieversion
self._macsize = onietlv.macsize
self._manufname = onietlv.manufname
self._manufcountry = onietlv.manufcountry
self._vendorname = onietlv.vendorname
self._diagname = onietlv.diagname
self._servicetag = onietlv.servicetag
except Exception as e:
return False
return True

View File

@@ -0,0 +1,401 @@
#!/usr/bin/env python3
#######################################################
#
# osutil.py
# Python implementation of the Class osutil
# Original author: rd@ruijie.com.cn
#
#######################################################
import os
import time
import glob
import re
from rjutil.smbus import SMBus
import time
import subprocess
from functools import wraps
import fcntl
import syslog
PLATFORM_HAL_DEBUG_FILE = "/etc/.platform_hal_debug_flag"
def platform_hal_debug(s):
if os.path.exists(PLATFORM_HAL_DEBUG_FILE):
syslog.openlog("PLATFORM_HAL", syslog.LOG_PID)
syslog.syslog(syslog.LOG_DEBUG, s)
def retry(maxretry=6, delay=0.01):
'''
maxretry: max retry times
delay : interval after last retry
'''
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
time_retry = maxretry
time_delay = delay
result_msg = ""
while time_retry:
try:
val, result_msg = f(*args, **kwargs)
if val is False:
time_retry -= 1
time.sleep(time_delay)
continue
else:
return val, result_msg
except Exception as e:
time_retry -= 1
result_msg = str(e)
time.sleep(time_delay)
return False, "max time retry last errmsg is {}".format(result_msg)
return wrapper
return decorator
pidfile = -1
def file_rw_lock(file_path):
global pidfile
pidfile = open(file_path, "r")
try:
fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
platform_hal_debug("file_rw_lock success")
return True
except Exception as e:
pidfile.close()
pidfile = -1
return False
def file_rw_unlock():
try:
global pidfile
if pidfile != -1:
fcntl.flock(pidfile, fcntl.LOCK_UN)
pidfile.close()
pidfile = -1
platform_hal_debug("file_rw_unlock success")
else:
platform_hal_debug("pidfile is invalid, do nothing")
return True
except Exception as e:
platform_hal_debug("file_rw_unlock err, msg: %s" % (str(e)))
return False
def take_file_rw_lock(file_path):
loop = 1000
ret = False
for i in range(0, loop):
ret = file_rw_lock(file_path)
if ret is True:
break
time.sleep(0.001)
return ret
class osutil(object):
"""
osutil
"""
@staticmethod
@retry(maxretry=6)
def rji2cget_python(bus, addr, reg):
with SMBus(bus) as y:
val, ind = y.read_byte_data(addr, reg, True)
return val, ind
@staticmethod
@retry(maxretry=6)
def rji2cset_python(bus, addr, reg, value):
with SMBus(bus) as y:
val, ind = y.write_byte_data(addr, reg, value, True)
return val, ind
@staticmethod
@retry(maxretry=6)
def rji2cgetword_python(bus, addr, reg):
with SMBus(bus) as y:
val, ind = y.read_word_data(addr, reg, True)
return val, ind
@staticmethod
@retry(maxretry=6)
def rji2csetword_python(bus, addr, reg, value):
with SMBus(bus) as y:
val, ind = y.write_word_data(addr, reg, value, True)
return val, ind
@staticmethod
@retry(maxretry=6)
def rji2csetwordpec_python(bus, addr, reg, value):
with SMBus(bus) as y:
val, ind = y.write_word_data_pec(addr, reg, value, True)
return val, ind
@staticmethod
@retry(maxretry=6)
def rji2cset_byte_pec_python(bus, addr, reg, value):
with SMBus(bus) as y:
val, ind = y.write_byte_data_pec(addr, reg, value, True)
return val, ind
@staticmethod
def command(cmdstr):
retcode, output = subprocess.getstatusoutput(cmdstr)
return retcode, output
@staticmethod
def geti2cword_i2ctool(bus, addr, offset):
command_line = "i2cget -f -y %d 0x%02x 0x%02x wp" % (bus, addr, offset)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = osutil.command(command_line)
if ret == 0:
return True, int(ret_t, 16)
time.sleep(0.1)
return False, ret_t
@staticmethod
def seti2cword_i2ctool(bus, addr, offset, val):
command_line = "i2cset -f -y %d 0x%02x 0x%0x 0x%04x wp" % (bus, addr, offset, val)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = osutil.command(command_line)
if ret == 0:
return True, ret_t
time.sleep(0.1)
return False, ret_t
@staticmethod
def rji2cget_i2ctool(bus, devno, address):
command_line = "i2cget -f -y %d 0x%02x 0x%02x " % (bus, devno, address)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = osutil.command(command_line)
if ret == 0:
return True, int(ret_t, 16)
time.sleep(0.1)
return False, ret_t
@staticmethod
def rji2cset_i2ctool(bus, devno, address, byte):
command_line = "i2cset -f -y %d 0x%02x 0x%02x 0x%02x" % (
bus, devno, address, byte)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = osutil.command(command_line)
if ret == 0:
return True, ret_t
return False, ret_t
@staticmethod
def geti2cword(bus, addr, offset):
return osutil.rji2cgetword_python(bus, addr, offset)
@staticmethod
def seti2cword(bus, addr, offset, val):
return osutil.rji2csetword_python(bus, addr, offset, val)
@staticmethod
def seti2cwordpec(bus, addr, offset, val):
return osutil.rji2csetwordpec_python(bus, addr, offset, val)
@staticmethod
def seti2c_byte_pec(bus, addr, offset, val):
return osutil.rji2cset_byte_pec_python(bus, addr, offset, val)
@staticmethod
def rji2cget(bus, devno, address):
return osutil.rji2cget_python(bus, devno, address)
@staticmethod
def rji2cset(bus, devno, address, byte):
return osutil.rji2cset_python(bus, devno, address, byte)
@staticmethod
def byteTostr(val):
strtmp = ''
for i in range(len(val)):
strtmp += chr(val[i])
return strtmp
@staticmethod
def io_rd(reg_addr, read_len=1):
try:
regaddr = 0
if isinstance(reg_addr, int):
regaddr = reg_addr
else:
regaddr = int(reg_addr, 16)
devfile = "/dev/port"
fd = os.open(devfile, os.O_RDWR | os.O_CREAT)
os.lseek(fd, regaddr, os.SEEK_SET)
str = os.read(fd, read_len)
return True, "".join(["%02x" % item for item in str])
except ValueError as e:
return False, str(e)
except Exception as e:
return False, str(e)
finally:
os.close(fd)
@staticmethod
def readsysfs(location, flock_path=None):
flock_path_tmp = None
platform_hal_debug("readsysfs, location:%s, flock_path:%s" % (location, flock_path))
try:
if flock_path is not None:
flock_paths = glob.glob(flock_path)
if len(flock_paths) != 0:
flock_path_tmp = flock_paths[0]
platform_hal_debug("try to get file lock, path:%s" % flock_path_tmp)
ret = take_file_rw_lock(flock_path_tmp)
if ret is False:
platform_hal_debug("take file lock timeout, path:%s" % flock_path_tmp)
return False, ("take file rw lock timeout, path:%s" % flock_path_tmp)
else:
platform_hal_debug("config error, can't find flock_path:%s" % flock_path)
locations = glob.glob(location)
with open(locations[0], 'rb') as fd1:
retval = fd1.read()
retval = osutil.byteTostr(retval)
if flock_path_tmp is not None:
file_rw_unlock()
retval = retval.rstrip('\r\n')
retval = retval.lstrip(" ")
except Exception as e:
if flock_path_tmp is not None:
file_rw_unlock()
platform_hal_debug("readsysfs error, msg:%s" % str(e))
return False, (str(e) + " location[%s]" % location)
return True, retval
@staticmethod
def writesysfs(location, value):
try:
if not os.path.isfile(location):
print(location, 'not found !')
return False, ("location[%s] not found !" % location)
with open(location, 'w') as fd1:
fd1.write(value)
except Exception as e:
return False, (str(e) + " location[%s]" % location)
return True, ("set location[%s] %s success !" % (location, value))
@staticmethod
def getdevmem(addr, digit, mask):
command_line = "devmem 0x%02x %d" % (addr, digit)
retrytime = 6
ret_t = ""
for i in range(retrytime):
ret, ret_t = osutil.command(command_line)
if ret == 0:
if mask is not None:
ret_t = str(int(ret_t, 16) & mask)
return True, ret_t
return False, ret_t
@staticmethod
def readdevfile_ascii(path, offset, len):
msg = ""
ret = ""
joinstr = ''
fd = -1
if not os.path.exists(path):
msg = path + " not found !"
return False, msg
try:
fd = os.open(path, os.O_RDONLY)
os.lseek(fd, offset, os.SEEK_SET)
ret = os.read(fd, len)
for item in ret:
joinstr += '%02x ' % item # like sysfs, display in hex
except Exception as e:
msg = str(e)
return False, msg
finally:
if fd > 0:
os.close(fd)
return True, joinstr
@staticmethod
def readdevfile(path, offset, len):
msg = ""
ret = ""
fd = -1
if not os.path.exists(path):
msg = path + " not found !"
return False, msg
try:
fd = os.open(path, os.O_RDONLY)
os.lseek(fd, offset, os.SEEK_SET)
ret = os.read(fd, len)
except Exception as e:
msg = str(e)
return False, msg
finally:
if fd > 0:
os.close(fd)
return True, ret
@staticmethod
def rj_os_system(cmd):
status, output = subprocess.getstatusoutput(cmd)
return status, output
@staticmethod
def getsdkreg(reg):
try:
cmd = "bcmcmd -t 1 'getr %s ' < /dev/null" % reg
ret, result = osutil.rj_os_system(cmd)
result_t = result.strip().replace("\r", "").replace("\n", "")
if ret != 0 or "Error:" in result_t:
return False, result
patt = r"%s.(.*):(.*)>drivshell" % reg
rt = re.findall(patt, result_t, re.S)
test = re.findall("=(.*)", rt[0][0])[0]
except Exception as e:
return False, 'get sdk register error'
return True, test
@staticmethod
def getmactemp():
try:
result = {}
# waitForDocker()
# need to exec twice
osutil.rj_os_system("bcmcmd -t 1 \"show temp\" < /dev/null")
ret, log = osutil.rj_os_system("bcmcmd -t 1 \"show temp\" < /dev/null")
if ret:
return False, result
else:
logs = log.splitlines()
for line in logs:
if "average" in line:
b = re.findall(r'\d+.\d+', line)
result["average"] = b[0]
elif "maximum" in line:
b = re.findall(r'\d+.\d+', line)
result["maximum"] = b[0]
except Exception as e:
return False, str(e)
return True, result

View File

@@ -0,0 +1,620 @@
#!/usr/bin/env python3
#######################################################
#
# psu.py
# Python implementation of the Class psu
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from eepromutil.fru import ipmifru
from plat_hal.sensor import sensor
class psu(devicebase):
__pmbus = None
__e2loc = None
__present = None
__productManufacturer = None # : ARTESYN
__productName = None # : CRPS550W
__productPartModelName = None # : CSU550AP-3-300
__productVersion = None # : AB
__productSerialNumber = None # : M623UZ00JYABL
__AirFlow = None # 'N/A'
__AirFlowconifg = None
__psu_display_name = None # 'N/A'
__psu_display_name_conifg = None
__psu_not_present_pwm = None
__InputStatus_config = None
__OutputStatus_config = None
__FanSpeed_config = None
__Temperature_config = None
__InputStatus = None
__OutputStatus = None
__FanSpeed = None
__Temperature = None
__FanSpeedMin = None
__FanSpeedMax = None
__FanSpeedTolerance = None
__InputsVoltage_config = None
__InputsCurrent_config = None
__InputsPower_config = None
__OutputsVoltage_config = None
__OutputsCurrent_config = None
__OutputsPower_config = None
__InputsVoltage = {}
__InputsCurrent = None
__InputsPower = None
__OutputsVoltage = None
__OutputsCurrent = None
__OutputsPower = None
__InputsType_config = None
__InputsType = None
__psu_sn_config = None
__psu_hw_config = None
__psu_pn_config = None
__psu_vendor_config = None
__TempStatus_config = None
__FanStatus_config = None
__TempStatus = None
__FanStatus = None
def __init__(self, conf=None):
self.pmbus = conf.get("pmbusloc", None)
self.e2loc = conf.get("e2loc", None)
self.__presentconfig = conf.get("present", None)
self.name = conf.get("name", None)
self.AirFlowconifg = conf.get("airflow", None)
self.psu_display_name_conifg = conf.get("psu_display_name", None)
self.psu_not_present_pwm = conf.get("psu_not_present_pwm", 100)
self.Temperature_config = conf.get("Temperature", None)
self.Temperature = sensor(self.Temperature_config)
self.FanSpeedTolerance = conf.get('psu_fan_tolerance', 30)
self.FanSpeed_config = conf.get("FanSpeed", None)
self.FanSpeed = sensor(self.FanSpeed_config)
self.__InputsVoltage_config = conf.get("InputsVoltage", None)
self.generate_psu_input_vol(self.__InputsVoltage_config)
self.__InputsCurrent_config = conf.get("InputsCurrent", None)
self.InputsCurrent = sensor(self.__InputsCurrent_config)
self.__InputsPower_config = conf.get("InputsPower", None)
self.InputsPower = sensor(self.__InputsPower_config)
self.__OutputsVoltage_config = conf.get("OutputsVoltage", None)
self.OutputsVoltage = sensor(self.__OutputsVoltage_config)
self.__OutputsCurrent_config = conf.get("OutputsCurrent", None)
self.OutputsCurrent = sensor(self.__OutputsCurrent_config)
self.__OutputsPower_config = conf.get("OutputsPower", None)
self.OutputsPower = sensor(self.__OutputsPower_config)
self.__InputStatus_config = conf.get("InputsStatus", None)
self.__OutputStatus_config = conf.get("OutputsStatus", None)
self.__InputsType_config = conf.get('InputsType', None)
self.__psu_sn_config = conf.get('psu_sn', None)
self.__psu_hw_config = conf.get('psu_hw', None)
self.__psu_pn_config = conf.get('psu_pn', None)
self.__psu_vendor_config = conf.get('psu_vendor', None)
self.__TempStatus_config = conf.get("TempStatus", None)
self.__FanStatus_config = conf.get("FanStatus", None)
def generate_psu_input_vol(self, config):
tmp = {}
for (key, item) in config.items():
tmp.setdefault(key, sensor(item))
self.__InputsVoltage = tmp
def get_psu_sensor_by_name(self, psutype):
return self.__InputsVoltage.get(psutype) or self.__InputsVoltage.get('other')
@property
def InputsVoltage(self):
psutype = self.InputsType
input_sensor = self.get_psu_sensor_by_name(psutype)
if input_sensor is None:
return None
else:
return input_sensor
@InputsVoltage.setter
def InputsVoltage(self, val):
self.__InputsVoltage = val
@property
def InputsCurrent(self):
return self.__InputsCurrent
@InputsCurrent.setter
def InputsCurrent(self, val):
self.__InputsCurrent = val
@property
def InputsPower(self):
return self.__InputsPower
@InputsPower.setter
def InputsPower(self, val):
self.__InputsPower = val
@property
def OutputsVoltage(self):
return self.__OutputsVoltage
@OutputsVoltage.setter
def OutputsVoltage(self, val):
self.__OutputsVoltage = val
@property
def OutputsCurrent(self):
return self.__OutputsCurrent
@OutputsCurrent.setter
def OutputsCurrent(self, val):
self.__OutputsCurrent = val
@property
def OutputsPower(self):
return self.__OutputsPower
@OutputsPower.setter
def OutputsPower(self, val):
self.__OutputsPower = val
@property
def InputStatus(self):
if self.present == False:
self.__InputStatus = False
else:
ret, val = self.get_value(self.__InputStatus_config)
mask = self.__InputStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__InputStatus = True
else:
self.__InputStatus = False
else:
self.__InputStatus = False
return self.__InputStatus
@InputStatus.setter
def InputStatus(self, val):
self.__InputStatus = val
@property
def TempStatus(self):
if self.__TempStatus_config is None:
return None
if self.present == False:
self.__TempStatus = False
else:
ret, val = self.get_value(self.__TempStatus_config)
mask = self.__TempStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__TempStatus = True
else:
self.__TempStatus = False
else:
self.__TempStatus = False
return self.__TempStatus
@TempStatus.setter
def TempStatus(self, val):
self.__TempStatus = val
@property
def FanStatus(self):
if self.__FanStatus_config is None:
return None
if self.present == False:
self.__FanStatus = False
else:
ret, val = self.get_value(self.__FanStatus_config)
mask = self.__FanStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__FanStatus = True
else:
self.__FanStatus = False
else:
self.__FanStatus = False
return self.__FanStatus
@FanStatus.setter
def FanStatus(self, val):
self.__FanStatus = val
@property
def InputsType(self):
psutypedecode = self.__InputsType_config.get('psutypedecode', None)
if self.present == False:
self.__InputsType = psutypedecode.get(0x00)
else:
ret, val = self.get_value(self.__InputsType_config)
self.__InputsType = self.__InputsType_config.get(val, None)
if self.__InputsType is not None:
return self.__InputsType
if ret == True and val in psutypedecode:
self.__InputsType = psutypedecode.get(val)
else:
self.__InputsType = psutypedecode.get(0x00)
return self.__InputsType
@InputsType.setter
def InputsType(self, val):
self.__InputsType = val
@property
def FanSpeedMin(self):
return self.__FanSpeedMin
@FanSpeedMin.setter
def FanSpeedMin(self, val):
self.__FanSpeedMin = val
@property
def FanSpeedMax(self):
return self.__FanSpeedMax
@FanSpeedMax.setter
def FanSpeedMax(self, val):
self.__FanSpeedMax = val
@property
def FanSpeedTolerance(self):
return self.__FanSpeedTolerance
@FanSpeedTolerance.setter
def FanSpeedTolerance(self, val):
self.__FanSpeedTolerance = val
@property
def OutputStatus(self):
if self.present == False:
self.__OutputStatus = False
else:
ret, val = self.get_value(self.__OutputStatus_config)
mask = self.__OutputStatus_config.get("mask")
if ret == True:
ttt = val & mask
if ttt == 0:
self.__OutputStatus = True
else:
self.__OutputStatus = False
else:
self.__OutputStatus = False
return self.__OutputStatus
@OutputStatus.setter
def OutputStatus(self, val):
self.__OutputStatus = val
@property
def FanSpeed(self):
return self.__FanSpeed
@FanSpeed.setter
def FanSpeed(self, val):
self.__FanSpeed = val
@property
def Temperature(self):
return self.__Temperature
@Temperature.setter
def Temperature(self, val):
self.__Temperature = val
@property
def Temperature_config(self):
return self.__Temperature_config
@Temperature_config.setter
def Temperature_config(self, val):
self.__Temperature_config = val
@property
def AirFlowconifg(self):
return self.__AirFlowconifg
@AirFlowconifg.setter
def AirFlowconifg(self, val):
self.__AirFlowconifg = val
@property
def psu_display_name_conifg(self):
return self.__psu_display_name_conifg
@psu_display_name_conifg.setter
def psu_display_name_conifg(self, val):
self.__psu_display_name_conifg = val
@property
def pmbus(self):
return self.__pmbus
@pmbus.setter
def pmbus(self, val):
self.__pmbus = val
@property
def e2loc(self):
return self.__e2loc
@e2loc.setter
def e2loc(self, val):
self.__e2loc = val
@property
def AirFlow(self):
return self.__AirFlow
@AirFlow.setter
def AirFlow(self, val):
self.__AirFlow = val
@property
def psu_display_name(self):
return self.__psu_display_name
@psu_display_name.setter
def psu_display_name(self, val):
self.__psu_display_name = val
@property
def psu_not_present_pwm(self):
return self.__psu_not_present_pwm
@psu_not_present_pwm.setter
def psu_not_present_pwm(self, val):
self.__psu_not_present_pwm = val
@property
def present(self):
ret, val = self.get_value(self.__presentconfig)
if ret is False or val is None:
return False
mask = self.__presentconfig.get("mask")
if isinstance(val, str):
value = int(val, 16)
else:
value = val
ttt = value & mask
okval = self.__presentconfig.get("okval", 0)
if ttt == okval:
return True
else:
return False
@present.setter
def present(self, val):
self.__present = val
@property
def productManufacturer(self):
return self.__productManufacturer
@productManufacturer.setter
def productManufacturer(self, val):
self.__productManufacturer = val
@property
def productName(self):
return self.__productName
@productName.setter
def productName(self, val):
self.__productName = val
@property
def productPartModelName(self):
return self.__productPartModelName
@productPartModelName.setter
def productPartModelName(self, val):
self.__productPartModelName = val
@property
def productVersion(self):
return self.__productVersion
@productVersion.setter
def productVersion(self, val):
self.__productVersion = val
@property
def productSerialNumber(self):
return self.__productSerialNumber
@productSerialNumber.setter
def productSerialNumber(self, val):
self.__productSerialNumber = val
@property
def psu_sn_sysfs(self):
if self.__psu_sn_config is None:
return None
ret, val = self.get_value(self.__psu_sn_config)
if ret is False or val is None:
return None
return val
@property
def psu_hw_sysfs(self):
if self.__psu_hw_config is None:
return None
ret, val = self.get_value(self.__psu_hw_config)
if ret is False or val is None:
return None
return val
@property
def psu_pn_sysfs(self):
if self.__psu_pn_config is None:
return None
ret, val = self.get_value(self.__psu_pn_config)
if ret is False or val is None:
return None
return val
@property
def psu_vendor_sysfs(self):
if self.__psu_vendor_config is None:
return None
ret, val = self.get_value(self.__psu_vendor_config)
if ret is False or val is None:
return None
return val
def __str__(self):
formatstr = \
"name : %s \n" \
"productManufacturer : %s \n" \
"productName : %s \n" \
"productPartModelName: %s \n" \
"productVersion : %s \n" \
"productSerialNumber : %s \n" \
"AirFlow : %s \n" \
tmpstr = formatstr % (self.name, self.productManufacturer,
self.productName, self.productPartModelName,
self.productVersion, self.productSerialNumber, self.AirFlow)
return tmpstr
def get_fan_speed_pwm(self):
if self.present == False:
return self.psu_not_present_pwm
selfconfig = {}
selfconfig['bus'] = self.pmbus['bus']
selfconfig['addr'] = self.pmbus['addr']
selfconfig['way'] = 'i2cword'
selfconfig['offset'] = 0x3b
ret, val = self.get_value(selfconfig)
if ret == True:
return val
else:
return None
def set_fan_speed_pwm(self, pwm):
'''
pmbus
if duty:
i2cset -f -y 0x3b 0x0064 wp
'''
if self.present == False:
return None
if 0 <= pwm <= 100:
'''enable duty first '''
selfconfig = {}
selfconfig['bus'] = self.pmbus['bus']
selfconfig['addr'] = self.pmbus['addr']
selfconfig['way'] = 'i2cpec'
selfconfig['offset'] = 0x3a
self.set_value(selfconfig, 0x80)
selfconfig['way'] = 'i2cwordpec'
selfconfig['offset'] = 0x3b
bytetmp = pwm
ret, val = self.set_value(selfconfig, int(bytetmp))
if ret == True:
return True
else:
return None
else:
raise Exception("pwm not in range [0,100]")
def get_fru_info_by_sysfs(self):
try:
psu_sn = self.psu_sn_sysfs
psu_hw = self.psu_hw_sysfs
psu_pn = self.psu_pn_sysfs
psu_vendor = self.psu_vendor_sysfs
if psu_sn is None or psu_hw is None or psu_pn is None or psu_vendor is None:
return False
self.productSerialNumber = psu_sn.strip().replace(chr(0), "")
self.productVersion = psu_hw.strip()
self.productPartModelName = psu_pn.strip()
self.productManufacturer = psu_vendor.strip().replace(chr(0), "")
except Exception as e:
self.productSerialNumber = None
self.productVersion = None
self.productPartModelName = None
self.productManufacturer = None
return False
return True
def get_fru_info_by_decode(self):
try:
eeprom = self.get_eeprom_info(self.e2loc)
if eeprom is None:
raise Exception("%s:value is none" % self.name)
fru = ipmifru()
if isinstance(eeprom, bytes):
eeprom = self.byteTostr(eeprom)
fru.decodeBin(eeprom)
if fru.productInfoArea is not None:
self.productManufacturer = fru.productInfoArea.productManufacturer.strip()
self.productName = fru.productInfoArea.productName.strip()
self.productPartModelName = fru.productInfoArea.productPartModelName.strip()
self.productVersion = fru.productInfoArea.productVersion.strip()
self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip().replace(chr(0), "")
except Exception as e:
self.productManufacturer = None
self.productName = None
self.productPartModelName = None
self.productVersion = None
self.productSerialNumber = None
return False
return True
def get_fru_info(self):
try:
if self.present is not True:
raise Exception("%s: not present" % self.name)
if self.get_fru_info_by_sysfs() is True:
return True
return self.get_fru_info_by_decode()
except Exception as e:
self.productManufacturer = None
self.productName = None
self.productPartModelName = None
self.productVersion = None
self.productSerialNumber = None
return False
def get_AirFlow(self):
if self.productPartModelName is None:
ret = self.get_fru_info()
if ret is False:
self.AirFlow = None
return False
if self.AirFlowconifg is None:
self.AirFlow = None
return False
else:
for i in self.AirFlowconifg:
if self.productPartModelName in self.AirFlowconifg[i]:
self.AirFlow = i
return True
self.AirFlow = None
return False
def get_psu_display_name(self):
if self.productPartModelName is None:
ret = self.get_fru_info()
if ret is False:
self.psu_display_name = None
return False
if self.psu_display_name_conifg is None:
self.psu_display_name = self.productPartModelName
return False
else:
for i in self.psu_display_name_conifg:
if self.productPartModelName in self.psu_display_name_conifg[i]:
self.psu_display_name = i
return True
self.psu_display_name = self.productPartModelName
return False

View File

@@ -0,0 +1,156 @@
#!/usr/bin/env python3
#######################################################
#
# rotor.py
# Python implementation of the Class rotor
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.devicebase import devicebase
from plat_hal.sensor import sensor
class rotor(devicebase):
__rotor_Running = None
__rotor_HwAlarm_conf = None
__rotor_Speed = None
__rotor_run_conf = None
__Speedconfig = None
__i2c_speed = None
__SpeedMin = None
__SpeedMax = None
__SpeedTolerance = None
def __init__(self, conf=None):
self.name = conf.get('name', None)
self.rotor_HwAlarm_conf = conf.get('HwAlarm', None)
self.rotor_run_conf = conf.get('Running', None)
self.SpeedMin = conf.get('SpeedMin', None)
self.SpeedMax = conf.get('SpeedMax', None)
self.Tolerance = conf.get('tolerance', 30)
self.rotor_Speed = sensor(conf.get('Speed', None))
self.Speedconfig = conf.get('Set_speed', None)
def getRunning(self):
ret, val = self.get_value(self.rotor_run_conf)
if ret is False or val is None:
return False
if isinstance(val, str):
value = int(val, 16)
else:
value = val
mask = self.rotor_run_conf.get("mask")
is_runing_value = self.rotor_run_conf.get("is_runing")
flag = value & mask
if flag == is_runing_value:
return True
else:
return False
@property
def SpeedMin(self):
return self.__SpeedMin
@SpeedMin.setter
def SpeedMin(self, val):
self.__SpeedMin = val
@property
def SpeedMax(self):
return self.__SpeedMax
@SpeedMax.setter
def SpeedMax(self, val):
self.__SpeedMax = val
@property
def Tolerance(self):
return self.__SpeedTolerance
@Tolerance.setter
def Tolerance(self, val):
self.__SpeedTolerance = val
@property
def i2c_speed(self):
ret, val = self.get_value(self.Speedconfig)
if ret == False:
return None
if val is not None:
self.__i2c_speed = val
return self.__i2c_speed
def feed_watchdog(self):
ret, val = self.get_value(self.Speedconfig)
if ret == False:
return False, None
if val is not None:
ret, val = self.set_value(self.Speedconfig, val)
return ret, val
return False, None
@i2c_speed.setter
def i2c_speed(self, val):
self.__i2c_speed = val
@property
def Speedconfig(self):
return self.__Speedconfig
@Speedconfig.setter
def Speedconfig(self, val):
self.__Speedconfig = val
@property
def rotor_run_conf(self):
return self.__rotor_run_conf
@rotor_run_conf.setter
def rotor_run_conf(self, val):
self.__rotor_run_conf = val
@property
def rotor_Speed(self):
return self.__rotor_Speed
@rotor_Speed.setter
def rotor_Speed(self, val):
self.__rotor_Speed = val
@property
def rotor_HwAlarm(self):
ret, val = self.get_value(self.rotor_HwAlarm_conf)
mask = self.rotor_HwAlarm_conf.get("mask")
no_alarm_value = self.rotor_HwAlarm_conf.get("no_alarm")
if ret is False or val is None:
return False
if isinstance(val, str):
value = int(val, 16)
else:
value = val
flag = value & mask
if flag == no_alarm_value:
return False
else:
return True
@rotor_HwAlarm.setter
def rotor_HwAlarm(self, val):
self.__rotor_HwAlarm = val
@property
def rotor_HwAlarm_conf(self):
return self.__rotor_HwAlarm_conf
@rotor_HwAlarm_conf.setter
def rotor_HwAlarm_conf(self, val):
self.__rotor_HwAlarm_conf = val
@property
def rotor_Running(self):
self.__rotor_Running = self.getRunning()
return self.__rotor_Running
@rotor_Running.setter
def rotor_Running(self, val):
self.__rotor_Running = val

View File

@@ -0,0 +1,220 @@
#!/usr/bin/env python3
#######################################################
#
# sensor.py
# Python implementation of the Class sensor
# Original author: rd@ruijie.com.cn
#
#######################################################
import time
from plat_hal.devicebase import devicebase
class sensor(devicebase):
__Value = None
__Min = None
__Max = None
__Low = None
__High = None
__ValueConfig = None
__Flag = None
__Unit = None
__format = None
__read_times = None
__Min_config = None
__Max_config = None
__Low_config = None
__High_config = None
@property
def Min_config(self):
return self.__Min_config
@Min_config.setter
def Min_config(self, val):
self.__Min_config = val
@property
def Max_config(self):
return self.__Max_config
@Max_config.setter
def Max_config(self, val):
self.__Max_config = val
@property
def Low_config(self):
return self.__Low_config
@Low_config.setter
def Low_config(self, val):
self.__Low_config = val
@property
def High_config(self):
return self.__High_config
@High_config.setter
def High_config(self, val):
self.__High_config = val
@property
def Unit(self):
return self.__Unit
@Unit.setter
def Unit(self, val):
self.__Unit = val
@property
def format(self):
return self.__format
@format.setter
def format(self, val):
self.__format = val
@property
def read_times(self):
return self.__read_times
@read_times.setter
def read_times(self, val):
self.__read_times = val
@property
def ValueConfig(self):
return self.__ValueConfig
@ValueConfig.setter
def ValueConfig(self, val):
self.__ValueConfig = val
@property
def Flag(self):
return self.__Flag
@Flag.setter
def Flag(self, val):
self.__Flag = val
def get_median(self, value_config, read_times):
val_list = []
for i in range(0, read_times):
ret, real_value = self.get_value(value_config)
if i != (read_times - 1):
time.sleep(0.01)
if ret is False or real_value is None:
continue
val_list.append(real_value)
val_list.sort()
if val_list:
return True, val_list[int((len(val_list) - 1) / 2)]
return False, None
@property
def Value(self):
try:
ret, val = self.get_median(self.ValueConfig, self.read_times)
if ret is False or val is None:
return None
if self.format is None:
self.__Value = int(val)
else:
self.__Value = eval(self.format % val)
self.__Value = round(float(self.__Value), 3)
except Exception as e:
return None
return self.__Value
@Value.setter
def Value(self, val):
self.__Value = val
@property
def Min(self):
try:
if self.format is None:
self.__Min = self.Min_config
else:
self.__Min = eval(self.format % self.Min_config)
self.__Min = round(float(self.__Min), 3)
except Exception as e:
return None
return self.__Min
@Min.setter
def Min(self, val):
self.__Min = val
@property
def Max(self):
try:
if self.format is None:
self.__Max = self.Max_config
else:
self.__Max = eval(self.format % self.Max_config)
self.__Max = round(float(self.__Max), 3)
except Exception as e:
return None
return self.__Max
@Max.setter
def Max(self, val):
self.__Max = val
@property
def Low(self):
try:
if self.format is None:
self.__Low = self.Low_config
else:
self.__Low = eval(self.format % self.Low_config)
except Exception as e:
return None
return self.__Low
@Low.setter
def Low(self, val):
self.__Low = val
@property
def High(self):
try:
if self.format is None:
self.__High = self.High_config
else:
self.__High = eval(self.format % self.High_config)
except Exception as e:
return None
return self.__High
@High.setter
def High(self, val):
self.__High = val
def __init__(self, conf=None):
self.ValueConfig = conf.get("value", None)
self.Flag = conf.get("flag", None)
self.Min_config = conf.get("Min", None)
self.Max_config = conf.get("Max", None)
self.Low_config = conf.get("Low", None)
self.High_config = conf.get("High", None)
self.Unit = conf.get('Unit', None)
self.format = conf.get('format', None)
self.read_times = conf.get('read_times', 1)
def __str__(self):
formatstr = \
"ValueConfig: : %s \n" \
"Min : %s \n" \
"Max : %s \n" \
"Unit : %s \n" \
"format: : %s \n"
tmpstr = formatstr % (self.ValueConfig, self.Min,
self.Max, self.Unit,
self.format)
return tmpstr

View File

@@ -0,0 +1,138 @@
#!/usr/bin/env python3
#######################################################
#
# temp.py
# Python implementation of the Class temp
# Original author: rd@ruijie.com.cn
#
#######################################################
from plat_hal.sensor import sensor
import os
import syslog
PLATFORM_HAL_TEMP_DEBUG_FILE = "/etc/.platform_hal_temp_debug_flag"
def platform_hal_temp_debug(s):
if os.path.exists(PLATFORM_HAL_TEMP_DEBUG_FILE):
syslog.openlog("PLATFORM_HAL_TEPM", syslog.LOG_PID)
syslog.syslog(syslog.LOG_DEBUG, s)
class temp(sensor):
def __init__(self, conf=None):
super(temp, self).__init__(conf.get('Temperature', None))
self.name = conf.get("name", None)
self.temp_id = conf.get("temp_id", None)
self.api_name = conf.get("api_name", self.name)
self.fix_value = conf.get("fix_value", None)
self.temp_invalid = conf.get("invalid", None)
self.temp_error = conf.get("error", None)
def __str__(self):
super(temp, self).__str__()
def temp_cali_by_fan_pwm(self, param, origin_value):
fan_pwm_conf = param.get("fan_pwm")
temp_fix_list = param.get("temp_fix_list")
ret, val = self.get_value(fan_pwm_conf)
if ret is False or val is None:
platform_hal_temp_debug("temp calibration get fan pwm failed, msg: %s, return None" % (val))
return None
fan_pwm = int(val)
for item in temp_fix_list:
if fan_pwm >= item["min"] and fan_pwm <= item["max"]:
fix_value = origin_value + item["fix"]
platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, fix_value: %s" %
(origin_value, fan_pwm, fix_value))
return fix_value
platform_hal_temp_debug("temp calibration by fan pwm, origin_value: %s, pwm: %s, not match return None" %
(origin_value, fan_pwm))
return None
def fix_temp_value(self, origin_value):
try:
fix_type = self.fix_value.get("fix_type")
if fix_type == "func":
func_name = self.fix_value.get("func_name")
func_param = self.fix_value.get("func_param")
value = eval(func_name)(func_param, origin_value)
return value
if fix_type == "config":
coefficient = self.fix_value.get("coefficient", 1)
addend = self.fix_value.get("addend", 0)
value = (origin_value + addend) * coefficient
platform_hal_temp_debug("temp calibration by config, coefficient: %s, addend: %s, origin_value: %s, fix_value: %s" %
(coefficient, addend, origin_value, value))
return value
platform_hal_temp_debug("unsupport fix type: %s, return origin value: %s" % (fix_type, origin_value))
return origin_value
except Exception as e:
platform_hal_temp_debug("fix_temp_value raise exception, msg: %s" % (str(e)))
return None
def get_max_value(self, conf):
try:
ret, val = self.get_value(conf)
if ret is False or val is None:
return None
return val
except Exception as e:
return None
def check_flag(self):
try:
okbit = self.Flag.get('okbit')
okval = self.Flag.get('okval')
ret, val = self.get_value(self.Flag)
if (ret == False) or (val is None):
return False
val_t = (int(val) & (1 << okbit)) >> okbit
if val_t != okval:
return False
except Exception as e:
return False
return True
@property
def Value(self):
try:
if self.Flag is not None:
if self.check_flag() == False:
return None
if isinstance(self.ValueConfig, list):
max = None
for i in self.ValueConfig:
tmp = self.get_max_value(i)
if tmp is None:
continue
if max is None or max < tmp:
max = tmp
if max is None:
return None
if self.format is None:
self.__Value = int(max)
else:
self.__Value = eval(self.format % max)
else:
ret, val = self.get_value(self.ValueConfig)
if ret is False or val is None:
return None
if self.format is None:
self.__Value = int(val)
else:
self.__Value = eval(self.format % val)
except Exception as e:
return None
if self.fix_value is not None and self.__Value != self.temp_invalid and self.__Value != self.temp_error:
self.__Value = self.fix_temp_value(self.__Value)
return self.__Value
@Value.setter
def Value(self, val):
self.__Value = val

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python3
import os
def get_machine_info():
if not os.path.isfile('/host/machine.conf'):
return None
machine_vars = {}
with open('/host/machine.conf') as machine_file:
for line in machine_file:
tokens = line.split('=')
if len(tokens) < 2:
continue
machine_vars[tokens[0]] = tokens[1].strip()
return machine_vars
def get_platform_info(machine_info):
if machine_info is not None:
if 'onie_platform' in machine_info:
return machine_info['onie_platform']
elif 'aboot_platform' in machine_info:
return machine_info['aboot_platform']
return None
def get_board_id(machine_info):
if machine_info is not None:
if 'onie_board_id' in machine_info:
return machine_info['onie_board_id'].lower()
return "NA"
def get_onie_machine(machine_info):
if machine_info is not None:
if 'onie_machine' in machine_info:
return machine_info['onie_machine']
return None

View File

@@ -0,0 +1,777 @@
#!/usr/bin/env python3
# smbus2 - A drop-in replacement for smbus-cffi/smbus-python
# The MIT License (MIT)
# Copyright (c) 2017 Karl-Petter Lindegaard
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import sys
from fcntl import ioctl
from ctypes import c_uint32, c_uint8, c_uint16, c_char, POINTER, Structure, Array, Union, create_string_buffer, string_at
# Commands from uapi/linux/i2c-dev.h
I2C_SLAVE = 0x0703 # Use this slave address
I2C_SLAVE_FORCE = 0x0706 # Use this slave address, even if it is already in use by a driver!
I2C_FUNCS = 0x0705 # Get the adapter functionality mask
I2C_RDWR = 0x0707 # Combined R/W transfer (one STOP only)
I2C_SMBUS = 0x0720 # SMBus transfer. Takes pointer to i2c_smbus_ioctl_data
I2C_PEC = 0x0708
# SMBus transfer read or write markers from uapi/linux/i2c.h
I2C_SMBUS_WRITE = 0
I2C_SMBUS_READ = 1
# Size identifiers uapi/linux/i2c.h
I2C_SMBUS_QUICK = 0
I2C_SMBUS_BYTE = 1
I2C_SMBUS_BYTE_DATA = 2
I2C_SMBUS_WORD_DATA = 3
I2C_SMBUS_PROC_CALL = 4
# This isn't supported by Pure-I2C drivers with SMBUS emulation, like those in RaspberryPi, OrangePi, etc :(
I2C_SMBUS_BLOCK_DATA = 5
I2C_SMBUS_BLOCK_PROC_CALL = 7 # Like I2C_SMBUS_BLOCK_DATA, it isn't supported by Pure-I2C drivers either.
I2C_SMBUS_I2C_BLOCK_DATA = 8
I2C_SMBUS_BLOCK_MAX = 32
# To determine what functionality is present (uapi/linux/i2c.h)
try:
from enum import IntFlag
except Exception as e:
IntFlag = int
class I2cFunc(IntFlag):
"""
These flags identify the operations supported by an I2C/SMBus device.
You can test these flags on your `smbus.funcs`
On newer python versions, I2cFunc is an IntFlag enum, but it
falls back to class with a bunch of int constants on older releases.
"""
I2C = 0x00000001
ADDR_10BIT = 0x00000002
PROTOCOL_MANGLING = 0x00000004 # I2C_M_IGNORE_NAK etc.
SMBUS_PEC = 0x00000008
NOSTART = 0x00000010 # I2C_M_NOSTART
SLAVE = 0x00000020
SMBUS_BLOCK_PROC_CALL = 0x00008000 # SMBus 2.0
SMBUS_QUICK = 0x00010000
SMBUS_READ_BYTE = 0x00020000
SMBUS_WRITE_BYTE = 0x00040000
SMBUS_READ_BYTE_DATA = 0x00080000
SMBUS_WRITE_BYTE_DATA = 0x00100000
SMBUS_READ_WORD_DATA = 0x00200000
SMBUS_WRITE_WORD_DATA = 0x00400000
SMBUS_PROC_CALL = 0x00800000
SMBUS_READ_BLOCK_DATA = 0x01000000
SMBUS_WRITE_BLOCK_DATA = 0x02000000
SMBUS_READ_I2C_BLOCK = 0x04000000 # I2C-like block xfer
SMBUS_WRITE_I2C_BLOCK = 0x08000000 # w/ 1-byte reg. addr.
SMBUS_HOST_NOTIFY = 0x10000000
SMBUS_BYTE = 0x00060000
SMBUS_BYTE_DATA = 0x00180000
SMBUS_WORD_DATA = 0x00600000
SMBUS_BLOCK_DATA = 0x03000000
SMBUS_I2C_BLOCK = 0x0c000000
SMBUS_EMUL = 0x0eff0008
# i2c_msg flags from uapi/linux/i2c.h
I2C_M_RD = 0x0001
# Pointer definitions
LP_c_uint8 = POINTER(c_uint8)
LP_c_uint16 = POINTER(c_uint16)
LP_c_uint32 = POINTER(c_uint32)
#############################################################
# Type definitions as in i2c.h
class i2c_smbus_data(Array):
"""
Adaptation of the i2c_smbus_data union in ``i2c.h``.
Data for SMBus messages.
"""
_length_ = I2C_SMBUS_BLOCK_MAX + 2
_type_ = c_uint8
class union_i2c_smbus_data(Union):
_fields_ = [
("byte", c_uint8),
("word", c_uint16),
("block", i2c_smbus_data)
]
union_pointer_type = POINTER(union_i2c_smbus_data)
class i2c_smbus_ioctl_data(Structure):
"""
As defined in ``i2c-dev.h``.
"""
_fields_ = [
('read_write', c_uint8),
('command', c_uint8),
('size', c_uint32),
('data', union_pointer_type)]
__slots__ = [name for name, type in _fields_]
@staticmethod
def create(read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE_DATA):
u = union_i2c_smbus_data()
return i2c_smbus_ioctl_data(
read_write=read_write, command=command, size=size,
data=union_pointer_type(u))
#############################################################
# Type definitions for i2c_rdwr combined transactions
class i2c_msg(Structure):
"""
As defined in ``i2c.h``.
"""
_fields_ = [
('addr', c_uint16),
('flags', c_uint16),
('len', c_uint16),
('buf', POINTER(c_char))]
def __iter__(self):
""" Iterator / Generator
:return: iterates over :py:attr:`buf`
:rtype: :py:class:`generator` which returns int values
"""
idx = 0
while idx < self.len:
yield ord(self.buf[idx])
idx += 1
def __len__(self):
return self.len
def __bytes__(self):
return string_at(self.buf, self.len)
def __repr__(self):
return 'i2c_msg(%d,%d,%r)' % (self.addr, self.flags, self.__bytes__())
def __str__(self):
s = self.__bytes__()
if sys.version_info.major >= 3:
s = ''.join(map(chr, s))
return s
@staticmethod
def read(address, length):
"""
Prepares an i2c read transaction.
:param address: Slave address.
:type: address: int
:param length: Number of bytes to read.
:type: length: int
:return: New :py:class:`i2c_msg` instance for read operation.
:rtype: :py:class:`i2c_msg`
"""
arr = create_string_buffer(length)
return i2c_msg(
addr=address, flags=I2C_M_RD, len=length,
buf=arr)
@staticmethod
def write(address, buf):
"""
Prepares an i2c write transaction.
:param address: Slave address.
:type address: int
:param buf: Bytes to write. Either list of values or str.
:type buf: list
:return: New :py:class:`i2c_msg` instance for write operation.
:rtype: :py:class:`i2c_msg`
"""
if sys.version_info.major >= 3:
if isinstance(buf, str):
buf = bytes(map(ord, buf))
else:
buf = bytes(buf)
else:
if not isinstance(buf, str):
buf = ''.join([chr(x) for x in buf])
arr = create_string_buffer(buf, len(buf))
return i2c_msg(
addr=address, flags=0, len=len(arr),
buf=arr)
class i2c_rdwr_ioctl_data(Structure):
"""
As defined in ``i2c-dev.h``.
"""
_fields_ = [
('msgs', POINTER(i2c_msg)),
('nmsgs', c_uint32)
]
__slots__ = [name for name, type in _fields_]
@staticmethod
def create(*i2c_msg_instances):
"""
Factory method for creating a i2c_rdwr_ioctl_data struct that can
be called with ``ioctl(fd, I2C_RDWR, data)``.
:param i2c_msg_instances: Up to 42 i2c_msg instances
:rtype: i2c_rdwr_ioctl_data
"""
n_msg = len(i2c_msg_instances)
msg_array = (i2c_msg * n_msg)(*i2c_msg_instances)
return i2c_rdwr_ioctl_data(
msgs=msg_array,
nmsgs=n_msg
)
#############################################################
class SMBus(object):
def __init__(self, bus=None, force=False):
"""
Initialize and (optionally) open an i2c bus connection.
:param bus: i2c bus number (e.g. 0 or 1)
or an absolute file path (e.g. `/dev/i2c-42`).
If not given, a subsequent call to ``open()`` is required.
:type bus: int or str
:param force: force using the slave address even when driver is
already using it.
:type force: boolean
"""
self.fd = None
self.funcs = I2cFunc(0)
if bus is not None:
self.open(bus)
self.address = None
self.force = force
self._force_last = None
def __enter__(self):
"""Enter handler."""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Exit handler."""
self.close()
def open(self, bus):
"""
Open a given i2c bus.
:param bus: i2c bus number (e.g. 0 or 1)
or an absolute file path (e.g. '/dev/i2c-42').
:type bus: int or str
:raise TypeError: if type(bus) is not in (int, str)
"""
if isinstance(bus, int):
filepath = "/dev/i2c-{}".format(bus)
elif isinstance(bus, str):
filepath = bus
else:
raise TypeError("Unexpected type(bus)={}".format(type(bus)))
self.fd = os.open(filepath, os.O_RDWR)
self.funcs = self._get_funcs()
def close(self):
"""
Close the i2c connection.
"""
if self.fd:
os.close(self.fd)
self.fd = None
def _set_address(self, address, force=None):
"""
Set i2c slave address to use for subsequent calls.
:param address:
:type address: int
:param force:
:type force: Boolean
"""
force = force if force is not None else self.force
if self.address != address or self._force_last != force:
if force is True:
ioctl(self.fd, I2C_SLAVE_FORCE, address)
else:
ioctl(self.fd, I2C_SLAVE, address)
self.address = address
self._force_last = force
def _get_funcs(self):
"""
Returns a 32-bit value stating supported I2C functions.
:rtype: int
"""
f = c_uint32()
ioctl(self.fd, I2C_FUNCS, f)
return f.value
def write_quick(self, i2c_addr, force=None):
"""
Perform quick transaction. Throws IOError if unsuccessful.
:param i2c_addr: i2c address
:type i2c_addr: int
:param force:
:type force: Boolean
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=0, size=I2C_SMBUS_QUICK)
ioctl(self.fd, I2C_SMBUS, msg)
def read_byte(self, i2c_addr, force=None):
"""
Read a single byte from a device.
:rtype: int
:param i2c_addr: i2c address
:type i2c_addr: int
:param force:
:type force: Boolean
:return: Read byte value
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=0, size=I2C_SMBUS_BYTE
)
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.byte
def write_byte(self, i2c_addr, value, force=None):
"""
Write a single byte to a device.
:param i2c_addr: i2c address
:type i2c_addr: int
:param value: value to write
:type value: int
:param force:
:type force: Boolean
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=value, size=I2C_SMBUS_BYTE
)
ioctl(self.fd, I2C_SMBUS, msg)
def read_byte_data(self, i2c_addr, register, force=None):
"""
Read a single byte from a designated register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read
:type register: int
:param force:
:type force: Boolean
:return: Read byte value
:rtype: int
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BYTE_DATA
)
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
self.close()
returnmsg = str(e)
if val_t < 0:
return False, returnmsg
else:
return True, msg.data.contents.byte
def write_byte_data(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Byte value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA
)
msg.data.contents.byte = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def write_byte_data_pec(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Byte value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
val_t = ioctl(self.fd, I2C_PEC, 1)
if val_t < 0:
raise Exception("set pec mod error")
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA
)
msg.data.contents.byte = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def read_word_data(self, i2c_addr, register, force=None):
"""
Read a single word (2 bytes) from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read
:type register: int
:param force:
:type force: Boolean
:return: 2-byte word
:rtype: int
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_WORD_DATA
)
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, msg.data.contents.word
def write_word_data_pec(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
val_t = ioctl(self.fd, I2C_PEC, 1)
if val_t < 0:
raise Exception("set pec mod error")
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA
)
msg.data.contents.word = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def write_word_data(self, i2c_addr, register, value, force=None):
"""
Write a byte to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: None
"""
val_t = -1
returnmsg = ""
try:
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_WORD_DATA
)
msg.data.contents.word = value
val_t = ioctl(self.fd, I2C_SMBUS, msg)
except Exception as e:
returnmsg = str(e)
self.close()
if val_t < 0:
return False, returnmsg or ""
else:
return True, ""
def process_call(self, i2c_addr, register, value, force=None):
"""
Executes a SMBus Process Call, sending a 16-bit value and receiving a 16-bit response
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read/write to
:type register: int
:param value: Word value to transmit
:type value: int
:param force:
:type force: Boolean
:rtype: int
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_PROC_CALL
)
msg.data.contents.word = value
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.word
def read_block_data(self, i2c_addr, register, force=None):
"""
Read a block of up to 32-bytes from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_BLOCK_DATA
)
ioctl(self.fd, I2C_SMBUS, msg)
length = msg.data.contents.block[0]
return msg.data.contents.block[1:length + 1]
def write_block_data(self, i2c_addr, register, data, force=None):
"""
Write a block of byte data to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:rtype: None
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_DATA
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
def block_process_call(self, i2c_addr, register, data, force=None):
"""
Executes a SMBus Block Process Call, sending a variable-size data
block and receiving another variable-size response
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Register to read/write to
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BLOCK_PROC_CALL
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
length = msg.data.contents.block[0]
return msg.data.contents.block[1:length + 1]
def read_i2c_block_data(self, i2c_addr, register, length, force=None):
"""
Read a block of byte data from a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param length: Desired block length
:type length: int
:param force:
:type force: Boolean
:return: List of bytes
:rtype: list
"""
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Desired block length over %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_READ, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA
)
msg.data.contents.byte = length
ioctl(self.fd, I2C_SMBUS, msg)
return msg.data.contents.block[1:length + 1]
def write_i2c_block_data(self, i2c_addr, register, data, force=None):
"""
Write a block of byte data to a given register.
:param i2c_addr: i2c address
:type i2c_addr: int
:param register: Start register
:type register: int
:param data: List of bytes
:type data: list
:param force:
:type force: Boolean
:rtype: None
"""
length = len(data)
if length > I2C_SMBUS_BLOCK_MAX:
raise ValueError("Data length cannot exceed %d bytes" % I2C_SMBUS_BLOCK_MAX)
self._set_address(i2c_addr, force=force)
msg = i2c_smbus_ioctl_data.create(
read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_I2C_BLOCK_DATA
)
msg.data.contents.block[0] = length
msg.data.contents.block[1:length + 1] = data
ioctl(self.fd, I2C_SMBUS, msg)
def i2c_rdwr(self, *i2c_msgs):
"""
Combine a series of i2c read and write operations in a single
transaction (with repeated start bits but no stop bits in between).
This method takes i2c_msg instances as input, which must be created
first with :py:meth:`i2c_msg.read` or :py:meth:`i2c_msg.write`.
:param i2c_msgs: One or more i2c_msg class instances.
:type i2c_msgs: i2c_msg
:rtype: None
"""
ioctl_data = i2c_rdwr_ioctl_data.create(*i2c_msgs)
ioctl(self.fd, I2C_RDWR, ioctl_data)
class SMBusWrapper:
"""
Wrapper class around the SMBus.
Deprecated as of version 0.3.0. Please replace with :py:class:`SMBus`.
Enables the user to wrap access to the :py:class:`SMBus` class in a
"with" statement. If auto_cleanup is True (default), the
:py:class:`SMBus` handle will be automatically closed
upon exit of the ``with`` block.
"""
def __init__(self, bus_number=0, auto_cleanup=True, force=False):
"""
:param auto_cleanup: Close bus when leaving scope.
:type auto_cleanup: Boolean
:param force: Force using the slave address even when driver is already using it.
:type force: Boolean
"""
self.bus_number = bus_number
self.auto_cleanup = auto_cleanup
self.force = force
def __enter__(self):
self.bus = SMBus(bus=self.bus_number, force=self.force)
return self.bus
def __exit__(self, exc_type, exc_val, exc_tb):
if self.auto_cleanup:
self.bus.close()

View File

@@ -0,0 +1,2 @@
blacklist rg_fpga_pcie
blacklist rg_spi_gpio

View File

@@ -0,0 +1,50 @@
PWD = $(shell pwd)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
KVERSION ?= $(shell uname -r)
KERNEL_SRC ?= /lib/modules/$(KVERSION)
module_out_put_dir := $(PWD)/build
export module_out_put_dir
RG_PLAT_SYSFS_DIR = $(PWD)/rg_plat_sysfs
export RG_PLAT_SYSFS_DIR
ruijie_common-objs := ruijie_common_module.o dfd_tlveeprom.o
obj-m += rg_pmbus_core.o
obj-m += rg_csu550.o
obj-m += ruijie_common.o
obj-m += rg_ina3221.o
obj-m += rg_mac_bsc.o
obj-m += rg_tps53622.o
obj-m += rg_fpga_pcie.o
obj-m += rg_pcie_dev.o
obj-m += rg_fpga_i2c_bus_drv.o
obj-m += rg_fpga_pca954x_drv.o
obj-m += rg_lpc_drv.o
obj-m += rg_i2c_dev.o
obj-m += rg_io_dev.o
obj-m += rg_eeprom_93xx46.o
obj-m += rg_ucd9000.o
obj-m += rg_spi_93xx46.o
obj-m += rg_gpio_d1500.o
obj-m += rg_gpio_device.o
obj-m += rg_wdt.o
obj-m += rg_optoe.o
obj-m += rg_spi_gpio.o
obj-m += rg_spi_gpio_device.o
obj-m += rg_xdpe132g5c.o
obj-m += rg_i2c_gpio_device.o
all :
$(MAKE) -C $(RG_PLAT_SYSFS_DIR)
$(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules
@if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi
cp -p $(PWD)/*.ko $(module_out_put_dir)
clean :
rm -rf $(module_out_put_dir)
rm -f ${PWD}/*.o ${PWD}/*.ko ${PWD}/*.mod.c ${PWD}/.*.cmd ${PWD}/.*.o.d ${PWD}/*.mod
rm -f ${PWD}/Module.markers ${PWD}/Module.symvers ${PWD}/modules.order
rm -rf ${PWD}/.tmp_versions

View File

@@ -0,0 +1,516 @@
/*
* Copyright (C) 2003-2014 FreeIPMI Core Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*****************************************************************************\
* Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Albert Chu <chu11@llnl.gov>
* UCRL-CODE-232183
*
* This file is part of Ipmi-fru, a tool used for retrieving
* motherboard field replaceable unit (FRU) information. For details,
* see http://www.llnl.gov/linux/.
*
* Ipmi-fru is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* Ipmi-fru is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Ipmi-fru. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include "ruijie.h"
#include "dfd_tlveeprom.h"
/* using in is_valid_tlvinfo_header */
static u_int32_t eeprom_size;
/*
* List of TLV codes and names.
*/
static const struct tlv_code_desc tlv_code_list[] = {
{ TLV_CODE_PRODUCT_NAME , "Product Name"},
{ TLV_CODE_PART_NUMBER , "Part Number"},
{ TLV_CODE_SERIAL_NUMBER , "Serial Number"},
{ TLV_CODE_MAC_BASE , "Base MAC Address"},
{ TLV_CODE_MANUF_DATE , "Manufacture Date"},
{ TLV_CODE_DEVICE_VERSION , "Device Version"},
{ TLV_CODE_LABEL_REVISION , "Label Revision"},
{ TLV_CODE_PLATFORM_NAME , "Platform Name"},
{ TLV_CODE_ONIE_VERSION , "ONIE Version"},
{ TLV_CODE_MAC_SIZE , "MAC Addresses"},
{ TLV_CODE_MANUF_NAME , "Manufacturer"},
{ TLV_CODE_MANUF_COUNTRY , "Country Code"},
{ TLV_CODE_VENDOR_NAME , "Vendor Name"},
{ TLV_CODE_DIAG_VERSION , "Diag Version"},
{ TLV_CODE_SERVICE_TAG , "Service Tag"},
{ TLV_CODE_VENDOR_EXT , "Vendor Extension"},
{ TLV_CODE_CRC_32 , "CRC-32"},
};
#if 0
#define OPENBMC_VPD_KEY_INVAIL_VAL 0
static const tlv_code_map_t tlv_code_map[] = {
{ TLV_CODE_PRODUCT_NAME , OPENBMC_VPD_KEY_PRODUCT_NAME},
{ TLV_CODE_PART_NUMBER , OPENBMC_VPD_KEY_PRODUCT_PART_MODEL_NUM},
{ TLV_CODE_SERIAL_NUMBER , OPENBMC_VPD_KEY_PRODUCT_SERIAL_NUM},
{ TLV_CODE_MAC_BASE , OPENBMC_VPD_KEY_INVAIL_VAL},
{ TLV_CODE_MANUF_DATE , OPENBMC_VPD_KEY_BOARD_MFG_DATE},
{ TLV_CODE_DEVICE_VERSION , OPENBMC_VPD_KEY_PRODUCT_VER},
{ TLV_CODE_LABEL_REVISION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM7},
{ TLV_CODE_PLATFORM_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM1},
{ TLV_CODE_ONIE_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM2},
{ TLV_CODE_MAC_SIZE , OPENBMC_VPD_KEY_INVAIL_VAL},
{ TLV_CODE_MANUF_NAME , OPENBMC_VPD_KEY_PRODUCT_MFR},
{ TLV_CODE_MANUF_COUNTRY , OPENBMC_VPD_KEY_PRODUCT_CUSTOM3},
{ TLV_CODE_VENDOR_NAME , OPENBMC_VPD_KEY_PRODUCT_CUSTOM4},
{ TLV_CODE_DIAG_VERSION , OPENBMC_VPD_KEY_PRODUCT_CUSTOM8},
{ TLV_CODE_SERVICE_TAG , OPENBMC_VPD_KEY_PRODUCT_CUSTOM5},
{ TLV_CODE_VENDOR_EXT , OPENBMC_VPD_KEY_PRODUCT_CUSTOM6},
{ TLV_CODE_CRC_32 , OPENBMC_VPD_KEY_INVAIL_VAL},
};
#endif
#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0]))
#if 0
#define TLV_CODE_MAP_NUM (sizeof(tlv_code_map) / sizeof(tlv_code_map[0]))
#endif
const unsigned long crc_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len)
{
unsigned i;
if (len < 1)
return 0xffffffff;
for (i = 0; i != len; ++i)
{
crc = crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
}
crc = crc ^ 0xffffffff;
return crc;
}
/*
* is_valid_tlv
*
* Perform basic sanity checks on a TLV field. The TLV is pointed to
* by the parameter provided.
* 1. The type code is not reserved (0x00 or 0xFF)
*/
static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv)
{
return ((tlv->type != 0x00) && (tlv->type != 0xFF));
}
/*
* is_valid_tlvinfo_header
*
* Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM
* data pointed to by the parameter:
* 1. First 8 bytes contain null-terminated ASCII string "TlvInfo"
* 2. Version byte is 1
* 3. Total length bytes contain value which is less than or equal
* to the allowed maximum (2048-11)
*
*/
static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr)
{
int max_size = eeprom_size;
return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
(hdr->version == TLV_INFO_VERSION) &&
(be16_to_cpu(hdr->totallen) <= max_size) );
}
/*
* decode_tlv_value
*
* Decode a single TLV value into a string.
* The validity of EEPROM contents and the TLV field have been verified
* prior to calling this function.
*/
static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value)
{
int i;
char *value;
u_int32_t length;
value = (char *)decode_value->value;
switch (tlv->type) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_MANUF_DATE:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
case TLV_CODE_VENDOR_EXT:
memcpy(value, tlv->value, tlv->length);
value[tlv->length] = 0;
length = tlv->length;
break;
case TLV_CODE_MAC_BASE:
length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3], tlv->value[4], tlv->value[5]);
break;
case TLV_CODE_DEVICE_VERSION:
length = sprintf(value, "%u", tlv->value[0]);
break;
case TLV_CODE_MAC_SIZE:
length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]);
break;
#if 0
case TLV_CODE_VENDOR_EXT:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s 0x%02X", value, tlv->value[i]);
}
break;
#endif
case TLV_CODE_CRC_32:
length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0],
tlv->value[1], tlv->value[2], tlv->value[3]);
break;
default:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s 0x%02X", value, tlv->value[i]);
}
break;
}
decode_value->length = length;
}
/*
* is_checksum_valid
*
* Validate the checksum in the provided TlvInfo EEPROM data. First,
* verify that the TlvInfo header is valid, then make sure the last
* TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
* and compare it to the value stored in the EEPROM CRC-32 TLV.
*/
static bool is_checksum_valid(u_int8_t *eeprom)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_crc;
unsigned int calc_crc;
unsigned int stored_crc;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
// Is the eeprom header valid?
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return false;
}
// Is the last TLV a CRC?
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)];
if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) {
return false;
}
// Calculate the checksum
calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) |
(eeprom_crc->value[2] << 8) | eeprom_crc->value[3]);
return (calc_crc == stored_crc);
}
/*
* tlvinfo_find_tlv
*
* This function finds the TLV with the supplied code in the EERPOM.
* An offset from the beginning of the EEPROM is returned in the
* eeprom_index parameter if the TLV is found.
*/
static bool tlvinfo_find_tlv(u_int8_t *eeprom, u_int8_t tcode, int *eeprom_index)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
// Search through the TLVs, looking for the first one which matches the
// supplied type code.
*eeprom_index = sizeof(tlvinfo_header_t);
eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while (*eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index];
if (!is_valid_tlv(eeprom_tlv)) {
return false;
}
if (eeprom_tlv->type == tcode) {
return true;
}
*eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
return false;
}
/*
* tlvinfo_decode_tlv
*
* This function finds the TLV with the supplied code in the EERPOM
* and decodes the value into the buffer provided.
*/
static bool tlvinfo_decode_tlv(u_int8_t *eeprom, u_int8_t tcode, tlv_decode_value_t *decode_value)
{
int eeprom_index;
tlvinfo_tlv_t *eeprom_tlv;
// Find the TLV and then decode it
if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
decode_tlv_value(eeprom_tlv, decode_value);
return true;
}
return false;
}
/*
* parse_tlv_eeprom
*
* parse the EEPROM into memory, if it hasn't already been read.
*/
int parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size)
{
unsigned int i;
bool ret;
tlvinfo_header_t *eeprom_hdr;
//tlv_info_vec_t tlv_info;
tlv_decode_value_t decode_value;
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_ERROR("Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_ERROR("Failed to check tlv crc.\n");
return -1;
}
for (i = 0; i < TLV_CODE_NUM; i++) {
memset((void *)&decode_value, 0, sizeof(tlv_decode_value_t));
ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value);
if (!ret) {
DBG_ERROR("No found type: %s\n", tlv_code_list[i].m_name);
continue;
}
DBG_DEBUG("i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code,
decode_value.value);
for (j = 0; j < decode_value.length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", decode_value.value[j]);
}
DBG_DEBUG("\n\n");
}
return 0;
}
static int dfd_parse_tlv_eeprom(u_int8_t *eeprom, u_int32_t size, u_int8_t main_type, tlv_decode_value_t *decode_value)
{
bool ret;
tlvinfo_header_t *eeprom_hdr;
//tlv_info_vec_t tlv_info;
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_ERROR("Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_ERROR("Failed to check tlv crc.\n");
return -1;
}
ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value);
if (!ret) {
DBG_ERROR("No found type: %d\n", main_type);
return -1;
}
DBG_DEBUG("Found type: %d, value: %s\n", main_type,decode_value->value);
for (j = 0; j < decode_value->length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", decode_value->value[j]);
}
DBG_DEBUG("\n\n");
return 0;
}
static int tlvinfo_find_rg_ext_tlv(tlv_decode_value_t *ext_tlv_value, u_int8_t ext_type,
u_int8_t *buf, u_int8_t *buf_len)
{
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end, eeprom_index;
// Search through the TLVs, looking for the first one which matches the
// supplied type code.
DBG_DEBUG("ext_tlv_value->length: %d.\n", ext_tlv_value->length);
for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) {
if ((eeprom_index % 16) == 0) {
DBG_DEBUG("\n");
}
DBG_DEBUG("%02x ", ext_tlv_value->value[eeprom_index]);
}
DBG_DEBUG("\n");
eeprom_index = 0;
eeprom_end = ext_tlv_value->length;
while (eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]);
if (!is_valid_tlv(eeprom_tlv)) {
DBG_ERROR("tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type);
return -1;
}
DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length);
if (eeprom_tlv->type == ext_type) {
if (*buf_len >= eeprom_tlv->length) {
memcpy(buf, eeprom_tlv->value, eeprom_tlv->length);
DBG_DEBUG("eeprom_tlv->length %d.\n", eeprom_tlv->length);
*buf_len = eeprom_tlv->length;
return 0;
}
DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length);
return -1;
}
eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
DBG_ERROR("ext_type %d: tlv is not found.\n", ext_type);
return -1;
}
int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len)
{
tlv_decode_value_t decode_value;
int ret;
if (eeprom == NULL || tlv_type == NULL || buf == NULL) {
DBG_ERROR("Input para invalid.\n");
return -1;
}
memset((void *)&decode_value, 0, sizeof(tlv_decode_value_t));
ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value);
if (ret) {
DBG_ERROR("dfd_parse_tlv_eeprom failed ret %d.\n", ret);
return ret;
}
if (tlv_type->main_type != TLV_CODE_VENDOR_EXT) {
if (*buf_len >= decode_value.length) {
memcpy(buf, decode_value.value, decode_value.length);
*buf_len = decode_value.length;
return 0;
}
DBG_ERROR("buf_len %d small than info_len %d.\n", *buf_len, decode_value.length);
return -1;
}
DBG_DEBUG("info_len %d.\n", decode_value.length);
return tlvinfo_find_rg_ext_tlv(&decode_value, tlv_type->ext_type, buf, buf_len);
}

View File

@@ -0,0 +1,121 @@
#ifndef DFD_OPENBMC_TLVEEPROM_H
#define DFD_OPENBMC_TLVEEPROM_H
#ifndef u_int8_t
#define u_int8_t unsigned char
#endif
#ifndef u_int16_t
#define u_int16_t unsigned short
#endif
#ifndef u_int32_t
#define u_int32_t unsigned int
#endif
#ifndef be16_to_cpu
#define be16_to_cpu(x) ntohs(x)
#endif
#ifndef cpu_to_be16
#define cpu_to_be16(x) htons(x)
#endif
/**
* The TLV Types.
*
* Keep these in sync with tlv_code_list in cmd_sys_eeprom.c
*/
#define TLV_CODE_PRODUCT_NAME 0x21
#define TLV_CODE_PART_NUMBER 0x22
#define TLV_CODE_SERIAL_NUMBER 0x23
#define TLV_CODE_MAC_BASE 0x24
#define TLV_CODE_MANUF_DATE 0x25
#define TLV_CODE_DEVICE_VERSION 0x26
#define TLV_CODE_LABEL_REVISION 0x27
#define TLV_CODE_PLATFORM_NAME 0x28
#define TLV_CODE_ONIE_VERSION 0x29
#define TLV_CODE_MAC_SIZE 0x2A
#define TLV_CODE_MANUF_NAME 0x2B
#define TLV_CODE_MANUF_COUNTRY 0x2C
#define TLV_CODE_VENDOR_NAME 0x2D
#define TLV_CODE_DIAG_VERSION 0x2E
#define TLV_CODE_SERVICE_TAG 0x2F
#define TLV_CODE_VENDOR_EXT 0xFD
#define TLV_CODE_CRC_32 0xFE
#define TLV_CODE_NAME_LEN 64
/*
* Struct for displaying the TLV codes and names.
*/
struct tlv_code_desc {
u_int8_t m_code;
char m_name[TLV_CODE_NAME_LEN];
};
typedef struct dfd_tlv_type_s {
u_int8_t main_type;
u_int8_t ext_type;
} dfd_tlv_type_t;
// Header Field Constants
#define TLV_INFO_ID_STRING "TlvInfo"
#define TLV_INFO_VERSION 0x01
/*#define TLV_TOTAL_LEN_MAX (XXXXXXXX - sizeof(tlvinfo_header_t))*/
struct __attribute__ ((__packed__)) tlvinfo_header_s {
char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */
u_int8_t version; /* 0x08 Structure version */
u_int16_t totallen; /* 0x09 - 0x0A Length of all data which follows */
};
typedef struct tlvinfo_header_s tlvinfo_header_t;
/*
* TlvInfo TLV: Layout of a TLV field
*/
struct __attribute__ ((__packed__)) tlvinfo_tlv_s {
u_int8_t type;
u_int8_t length;
u_int8_t value[0];
};
typedef struct tlvinfo_tlv_s tlvinfo_tlv_t;
#define TLV_VALUE_MAX_LEN 255
/*
* The max decode value is currently for the 'raw' type or the 'vendor
* extension' type, both of which have the same decode format. The
* max decode string size is computed as follows:
*
* strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1
*
*/
#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1)
typedef struct tlv_decode_value_s {
u_int8_t value[TLV_DECODE_VALUE_MAX_LEN];
u_int32_t length;
} tlv_decode_value_t;
typedef enum dfd_tlvinfo_ext_tlv_type_e {
DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1,
} dfd_tlvinfo_ext_tlv_type_t;
#if 0
#define TLV_TIME_LEN 64
int ipmi_tlv_validate_fru_area(const uint8_t fruid, const char *fru_file_name,
sd_bus *bus_type, const bool bmc_fru);
extern const char *get_vpd_key_names(int key_id);
extern std::string getService(sdbusplus::bus::bus& bus,
const std::string& intf,
const std::string& path);
extern std::string getFRUValue(const std::string& section,
const std::string& key,
const std::string& delimiter,
IPMIFruInfo& fruData);
#endif
int dfd_tlvinfo_get_e2prom_info(u_int8_t *eeprom, u_int32_t size, dfd_tlv_type_t *tlv_type, u_int8_t* buf, u_int8_t *buf_len);
#endif /* endif DFD_OPENBMC_TLVEEPROM_H */

View File

@@ -0,0 +1,129 @@
#ifndef _FPGA_I2C_H
#define _FPGA_I2C_H
#include <linux/i2c.h>
#include <linux/device.h>
#include <linux/kallsyms.h>
#if 0
#define FPGA_I2C_EXT_9548_ADDR (0x00)
#define FPGA_I2C_EXT_9548_CHAN (0x04)
#define FPGA_I2C_DEV_SLAVE_ADDR (0x08)
#define FPGA_I2C_DEV_REG_ADDR (0x0C)
#define FPGA_I2C_DEV_RDWR_LEN (0x10)
#define FPGA_I2C_CTRL_REG (0x14)
#define FPGA_I2C_STATUS_REG (0x18)
#define FPGA_I2C_SCALE_REG (0x1C)
#define FPGA_I2C_FILTER_REG (0x20)
#define FPGA_I2C_STRETCH_REG (0x24)
#define FPGA_I2C_EXT_9548_EXITS_FLAG (0x28)
#define FPGA_I2C_INTERNAL_9548_CHAN (0x2C)
#define FPGA_I2C_RDWR_DATA_BUF (0x80)
#endif
#define FPGA_I2C_RDWR_MAX_LEN_DEFAULT (128)
#define I2C_REG_MAX_WIDTH (16)
#define DEV_NAME_MAX_LEN (64)
#define FPGA_I2C_MAX_TIMES (10)
#define FPGA_I2C_XFER_TIME_OUT (100000)
#define FPGA_I2C_SLEEP_TIME (40)
typedef struct fpga_i2c_reg_s {
uint32_t i2c_scale;
uint32_t i2c_filter;
uint32_t i2c_stretch;
uint32_t i2c_ext_9548_exits_flag;
uint32_t i2c_ext_9548_addr;
uint32_t i2c_ext_9548_chan;
uint32_t i2c_in_9548_chan;
uint32_t i2c_slave;
uint32_t i2c_reg;
uint32_t i2c_reg_len;
uint32_t i2c_data_len;
uint32_t i2c_ctrl;
uint32_t i2c_status;
uint32_t i2c_err_vec;
uint32_t i2c_data_buf;
uint32_t i2c_data_buf_len;
} fpga_i2c_reg_t;
typedef struct fpga_i2c_reset_cfg_s {
uint32_t i2c_adap_reset_flag;
uint32_t reset_addr;
uint32_t reset_on;
uint32_t reset_off;
uint32_t reset_delay_b;
uint32_t reset_delay;
uint32_t reset_delay_a;
} fpga_i2c_reset_cfg_t;
typedef struct fpga_i2c_reg_addr_s {
uint8_t reg_addr_len;
uint8_t read_reg_addr[I2C_REG_MAX_WIDTH];
} fpga_i2c_reg_addr_t;
typedef struct fpga_i2c_dev_s {
fpga_i2c_reg_t reg;
fpga_i2c_reset_cfg_t reset_cfg;
fpga_i2c_reg_addr_t i2c_addr_desc;
const char *dev_name;
uint32_t i2c_scale_value;
uint32_t i2c_filter_value;
uint32_t i2c_stretch_value;
uint32_t i2c_timeout;
uint32_t i2c_func_mode;
wait_queue_head_t queue;
struct i2c_adapter adap;
int adap_nr;
struct device *dev;
bool i2c_params_check;
} fpga_i2c_dev_t;
typedef struct fpga_i2c_bus_device_s {
int i2c_timeout;
int i2c_scale;
int i2c_filter;
int i2c_stretch;
int i2c_ext_9548_exits_flag;
int i2c_ext_9548_addr;
int i2c_ext_9548_chan;
int i2c_in_9548_chan;
int i2c_slave;
int i2c_reg;
int i2c_reg_len;
int i2c_data_len;
int i2c_ctrl;
int i2c_status;
int i2c_err_vec;
int i2c_data_buf;
int i2c_data_buf_len;
char dev_name[DEV_NAME_MAX_LEN];
int adap_nr;
int i2c_scale_value;
int i2c_filter_value;
int i2c_stretch_value;
int i2c_func_mode;
int i2c_adap_reset_flag;
int i2c_reset_addr;
int i2c_reset_on;
int i2c_reset_off;
int i2c_rst_delay_b; /* delay time before reset(us) */
int i2c_rst_delay; /* reset time(us) */
int i2c_rst_delay_a; /* delay time after reset(us) */
int device_flag;
bool i2c_params_check;
int i2c_data_buf_len_reg;
int i2c_offset_reg;
} fpga_i2c_bus_device_t;
typedef struct fpga_pca954x_device_s {
struct i2c_client *client;
uint32_t i2c_bus;
uint32_t i2c_addr;
uint32_t fpga_9548_flag;
uint32_t fpga_9548_reset_flag;
uint32_t pca9548_base_nr;
} fpga_pca954x_device_t;
#endif /* _FPGA_I2C_H */

View File

@@ -0,0 +1,203 @@
/*
* csu550.c - PMBUS for csu550
*
* Copyright (c) 2018 sonic_rd <sonic_rd@ruijie.com.cn>
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152)
#include <linux/i2c/pmbus.h>
#else
#include <linux/pmbus.h>
#endif
#include <linux/err.h>
#include <linux/mutex.h>
#include "rg_pmbus.h"
/*
* Find sensor groups and status registers on each page.
*/
static void pmbus_find_sensor_groups(struct i2c_client *client,
struct pmbus_driver_info *info)
{
int page;
/* Sensors detected on page 0 only */
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_VIN))
info->func[0] |= PMBUS_HAVE_VIN;
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_IIN))
info->func[0] |= PMBUS_HAVE_IIN;
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_PIN))
info->func[0] |= PMBUS_HAVE_PIN;
if (info->func[0]
&& rg_pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
if (rg_pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
rg_pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
info->func[0] |= PMBUS_HAVE_FAN12;
if (rg_pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
}
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
info->func[0] |= PMBUS_HAVE_TEMP;
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
info->func[0] |= PMBUS_HAVE_TEMP2;
if (rg_pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
info->func[0] |= PMBUS_HAVE_TEMP3;
if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
| PMBUS_HAVE_TEMP3)
&& rg_pmbus_check_byte_register(client, 0,
PMBUS_STATUS_TEMPERATURE))
info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
/* Sensors detected on all pages */
for (page = 0; page < info->pages; page++) {
if (rg_pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) {
info->func[page] |= PMBUS_HAVE_VOUT;
if (rg_pmbus_check_byte_register(client, page,
PMBUS_STATUS_VOUT))
info->func[page] |= PMBUS_HAVE_STATUS_VOUT;
}
if (rg_pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) {
info->func[page] |= PMBUS_HAVE_IOUT;
if (rg_pmbus_check_byte_register(client, 0,
PMBUS_STATUS_IOUT))
info->func[page] |= PMBUS_HAVE_STATUS_IOUT;
}
if (rg_pmbus_check_word_register(client, page, PMBUS_READ_POUT))
info->func[page] |= PMBUS_HAVE_POUT;
}
}
/*
* Identify chip parameters.
*/
static int pmbus_identify(struct i2c_client *client,
struct pmbus_driver_info *info)
{
int ret = 0;
if (!info->pages) {
/*
* Check if the PAGE command is supported. If it is,
* keep setting the page number until it fails or until the
* maximum number of pages has been reached. Assume that
* this is the number of pages supported by the chip.
*/
if (rg_pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
int page;
for (page = 1; page < PMBUS_PAGES; page++) {
if (rg_pmbus_set_page(client, page) < 0)
break;
}
(void)rg_pmbus_set_page(client, 0);
info->pages = page;
} else {
info->pages = 1;
}
}
if (rg_pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
int vout_mode;
vout_mode = rg_pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
if (vout_mode >= 0 && vout_mode != 0xff) {
switch (vout_mode >> 5) {
case 0:
break;
case 1:
info->format[PSC_VOLTAGE_OUT] = vid;
break;
case 2:
info->format[PSC_VOLTAGE_OUT] = direct;
break;
default:
ret = -ENODEV;
goto abort;
}
}
}
/*
* We should check if the COEFFICIENTS register is supported.
* If it is, and the chip is configured for direct mode, we can read
* the coefficients from the chip, one set per group of sensor
* registers.
*
* To do this, we will need access to a chip which actually supports the
* COEFFICIENTS command, since the command is too complex to implement
* without testing it. Until then, abort if a chip configured for direct
* mode was detected.
*/
if (info->format[PSC_VOLTAGE_OUT] == direct) {
ret = -ENODEV;
goto abort;
}
/* Try to find sensor groups */
pmbus_find_sensor_groups(client, info);
abort:
return ret;
}
static int pmbus_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pmbus_driver_info *info;
struct pmbus_platform_data *pdata = NULL;
struct device *dev = &client->dev;
info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
GFP_KERNEL);
if (!info)
return -ENOMEM;
if (!strncmp(id->name, "dps460", sizeof("dps460")) ||
!strncmp(id->name, "rg_fsp1200", sizeof("rg_fsp1200")) || !strncmp(id->name, "rg_dps550", sizeof("rg_dps550"))) {
pdata = kzalloc(sizeof(struct pmbus_platform_data), GFP_KERNEL);
if (!pdata) {
kfree(info);
return -ENOMEM;
}
pdata->flags = PMBUS_SKIP_STATUS_CHECK;
}
info->pages = id->driver_data;
info->identify = pmbus_identify;
dev->platform_data = pdata;
return rg_pmbus_do_probe(client, id, info);
}
static const struct i2c_device_id pmbus_id[] = {
{"rg_csu550", 0},
{"rg_csu800", 1},
{"rg_fsp1200", 1},
{"rg_dps550", 1},
{}
};
MODULE_DEVICE_TABLE(i2c, pmbus_id);
/* This is the driver that will be inserted */
static struct i2c_driver pmbus_driver = {
.driver = {
.name = "rg_pmbus",
},
.probe = pmbus_probe,
.remove = rg_pmbus_do_remove,
.id_table = pmbus_id,
};
module_i2c_driver(pmbus_driver);
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");
MODULE_DESCRIPTION("ruijie psupmbus driver");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,555 @@
/*
* Driver for 93xx46 EEPROMs
*
* (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/nvmem-provider.h>
#include <linux/eeprom_93xx46.h>
#define OP_START 0x4
#define OP_WRITE (OP_START | 0x1)
#define OP_READ (OP_START | 0x2)
#define ADDR_EWDS 0x00
#define ADDR_ERAL 0x20
#define ADDR_EWEN 0x30
static int g_rg_eeprom_93xx46_debug = 0;
module_param(g_rg_eeprom_93xx46_debug, int, S_IRUGO | S_IWUSR);
#define SPI_93xx46_DEBUG_VERBOSE(fmt, args...) do { \
if (g_rg_eeprom_93xx46_debug) { \
printk(KERN_INFO "[EEPROM-93xx46][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
struct eeprom_93xx46_devtype_data {
unsigned int quirks;
};
static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = {
.quirks = EEPROM_93XX46_QUIRK_SINGLE_WORD_READ |
EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH,
};
struct eeprom_93xx46_dev {
struct spi_device *spi;
struct eeprom_93xx46_platform_data *pdata;
struct mutex lock;
struct nvmem_config nvmem_config;
struct nvmem_device *nvmem;
int addrlen;
int size;
};
static inline bool has_quirk_single_word_read(struct eeprom_93xx46_dev *edev)
{
return edev->pdata->quirks & EEPROM_93XX46_QUIRK_SINGLE_WORD_READ;
}
static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev)
{
return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH;
}
static int eeprom_93xx46_read(void *priv, unsigned int off,
void *val, size_t count)
{
struct eeprom_93xx46_dev *edev = priv;
char *buf = val;
int err = 0;
if (unlikely(off >= edev->size))
return 0;
if ((off + count) > edev->size)
count = edev->size - off;
if (unlikely(!count))
return count;
mutex_lock(&edev->lock);
if (edev->pdata->prepare)
edev->pdata->prepare(edev);
while (count) {
struct spi_message m;
struct spi_transfer t[2] = { { 0 } };
u16 cmd_addr = OP_READ << edev->addrlen;
size_t nbytes = count;
int bits;
int data_bit;
if (edev->addrlen == 7) {
cmd_addr |= off & 0x7f;
bits = 10;
data_bit = 8;
if (has_quirk_single_word_read(edev))
nbytes = 1;
} else {
cmd_addr |= (off >> 1) & 0x3f;
bits = 9;
data_bit = 16;
if (has_quirk_single_word_read(edev))
nbytes = 2;
}
dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n",
cmd_addr, edev->spi->max_speed_hz);
spi_message_init(&m);
t[0].tx_buf = (char *)&cmd_addr;
t[0].len = 2;
t[0].bits_per_word = bits;
spi_message_add_tail(&t[0], &m);
t[1].rx_buf = buf;
t[1].len = nbytes;
t[1].bits_per_word = data_bit;
spi_message_add_tail(&t[1], &m);
err = spi_sync(edev->spi, &m);
/* have to wait at least Tcsl ns */
ndelay(250);
if (err) {
dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n",
nbytes, (int)off, err);
break;
}
buf += nbytes;
off += nbytes;
count -= nbytes;
}
if (edev->pdata->finish)
edev->pdata->finish(edev);
mutex_unlock(&edev->lock);
return err;
}
static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on)
{
struct spi_message m;
struct spi_transfer t;
int bits, ret;
u16 cmd_addr;
cmd_addr = OP_START << edev->addrlen;
if (edev->addrlen == 7) {
cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << 1;
bits = 10;
} else {
cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS);
bits = 9;
}
if (has_quirk_instruction_length(edev)) {
cmd_addr <<= 2;
bits += 2;
}
dev_dbg(&edev->spi->dev, "ew%s cmd 0x%04x, %d bits\n",
is_on ? "en" : "ds", cmd_addr, bits);
spi_message_init(&m);
memset(&t, 0, sizeof(t));
t.tx_buf = &cmd_addr;
t.len = 2;
t.bits_per_word = bits;
spi_message_add_tail(&t, &m);
mutex_lock(&edev->lock);
if (edev->pdata->prepare)
edev->pdata->prepare(edev);
ret = spi_sync(edev->spi, &m);
/* have to wait at least Tcsl ns */
ndelay(250);
if (ret)
dev_err(&edev->spi->dev, "erase/write %sable error %d\n",
is_on ? "en" : "dis", ret);
if (edev->pdata->finish)
edev->pdata->finish(edev);
mutex_unlock(&edev->lock);
return ret;
}
static ssize_t
eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev,
char *buf, unsigned off)
{
struct spi_message m;
struct spi_transfer t[2];
int bits, data_len, ret;
u16 cmd_addr;
int data_bit;
cmd_addr = OP_WRITE << edev->addrlen;
if (edev->addrlen == 7) {
cmd_addr |= off & 0x7f;
bits = 10;
data_len = 1;
data_bit = 8;
} else {
cmd_addr |= (off >> 1) & 0x3f;
bits = 9;
data_len = 2;
data_bit = 16;
}
dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr);
spi_message_init(&m);
memset(t, 0, sizeof(t));
t[0].tx_buf = (char *)&cmd_addr;
t[0].len = 2;
t[0].bits_per_word = bits;
spi_message_add_tail(&t[0], &m);
t[1].tx_buf = buf;
t[1].len = data_len;
t[1].bits_per_word = data_bit;
spi_message_add_tail(&t[1], &m);
ret = spi_sync(edev->spi, &m);
/* have to wait program cycle time Twc ms */
mdelay(6);
return ret;
}
static int eeprom_93xx46_write(void *priv, unsigned int off,
void *val, size_t count)
{
struct eeprom_93xx46_dev *edev = priv;
char *buf = val;
int i, ret, step = 1;
if (unlikely(off >= edev->size))
return -EFBIG;
if ((off + count) > edev->size)
count = edev->size - off;
if (unlikely(!count))
return count;
/* only write even number of bytes on 16-bit devices */
if (edev->addrlen == 6) {
step = 2;
count &= ~1;
}
/* erase/write enable */
ret = eeprom_93xx46_ew(edev, 1);
if (ret)
return ret;
mutex_lock(&edev->lock);
if (edev->pdata->prepare)
edev->pdata->prepare(edev);
for (i = 0; i < count; i += step) {
ret = eeprom_93xx46_write_word(edev, &buf[i], off + i);
if (ret) {
dev_err(&edev->spi->dev, "write failed at %d: %d\n",
(int)off + i, ret);
break;
}
}
if (edev->pdata->finish)
edev->pdata->finish(edev);
mutex_unlock(&edev->lock);
/* erase/write disable */
eeprom_93xx46_ew(edev, 0);
return ret;
}
static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev)
{
struct eeprom_93xx46_platform_data *pd = edev->pdata;
struct spi_message m;
struct spi_transfer t;
int bits, ret;
u16 cmd_addr;
cmd_addr = OP_START << edev->addrlen;
if (edev->addrlen == 7) {
cmd_addr |= ADDR_ERAL << 1;
bits = 10;
} else {
cmd_addr |= ADDR_ERAL;
bits = 9;
}
if (has_quirk_instruction_length(edev)) {
cmd_addr <<= 2;
bits += 2;
}
dev_dbg(&edev->spi->dev, "eral cmd 0x%04x, %d bits\n", cmd_addr, bits);
spi_message_init(&m);
memset(&t, 0, sizeof(t));
t.tx_buf = &cmd_addr;
t.len = 2;
t.bits_per_word = bits;
spi_message_add_tail(&t, &m);
mutex_lock(&edev->lock);
if (edev->pdata->prepare)
edev->pdata->prepare(edev);
ret = spi_sync(edev->spi, &m);
if (ret)
dev_err(&edev->spi->dev, "erase error %d\n", ret);
/* have to wait erase cycle time Tec ms */
mdelay(6);
if (pd->finish)
pd->finish(edev);
mutex_unlock(&edev->lock);
return ret;
}
static ssize_t eeprom_93xx46_store_erase(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct eeprom_93xx46_dev *edev = dev_get_drvdata(dev);
int erase = 0, ret;
sscanf(buf, "%d", &erase);
if (erase) {
ret = eeprom_93xx46_ew(edev, 1);
if (ret)
return ret;
ret = eeprom_93xx46_eral(edev);
if (ret)
return ret;
ret = eeprom_93xx46_ew(edev, 0);
if (ret)
return ret;
}
return count;
}
static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase);
static void select_assert(void *context)
{
struct eeprom_93xx46_dev *edev = context;
gpiod_set_value_cansleep(edev->pdata->select, 1);
}
static void select_deassert(void *context)
{
struct eeprom_93xx46_dev *edev = context;
gpiod_set_value_cansleep(edev->pdata->select, 0);
}
static const struct of_device_id eeprom_93xx46_of_table[] = {
{ .compatible = "eeprom-93xx46", },
{ .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, },
{}
};
MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table);
static int eeprom_93xx46_probe_dt(struct spi_device *spi)
{
const struct of_device_id *of_id =
of_match_device(eeprom_93xx46_of_table, &spi->dev);
struct device_node *np = spi->dev.of_node;
struct eeprom_93xx46_platform_data *pd;
u32 tmp;
int gpio;
enum of_gpio_flags of_flags;
int ret;
pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL);
if (!pd)
return -ENOMEM;
ret = of_property_read_u32(np, "data-size", &tmp);
if (ret < 0) {
dev_err(&spi->dev, "data-size property not found\n");
return ret;
}
if (tmp == 8) {
pd->flags |= EE_ADDR8;
} else if (tmp == 16) {
pd->flags |= EE_ADDR16;
} else {
dev_err(&spi->dev, "invalid data-size (%d)\n", tmp);
return -EINVAL;
}
if (of_property_read_bool(np, "read-only"))
pd->flags |= EE_READONLY;
gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags);
if (gpio_is_valid(gpio)) {
unsigned long flags =
of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0;
ret = devm_gpio_request_one(&spi->dev, gpio, flags,
"eeprom_93xx46_select");
if (ret)
return ret;
pd->select = gpio_to_desc(gpio);
pd->prepare = select_assert;
pd->finish = select_deassert;
gpiod_direction_output(pd->select, 0);
}
if (of_id) {
if (of_id->data) {
const struct eeprom_93xx46_devtype_data *data = of_id->data;
pd->quirks = data->quirks;
}
}
spi->dev.platform_data = pd;
return 0;
}
static int eeprom_93xx46_probe(struct spi_device *spi)
{
struct eeprom_93xx46_platform_data *pd;
struct eeprom_93xx46_dev *edev;
int err;
if (spi->dev.of_node) {
err = eeprom_93xx46_probe_dt(spi);
if (err < 0)
return err;
}
pd = spi->dev.platform_data;
if (!pd) {
dev_err(&spi->dev, "missing platform data\n");
return -ENODEV;
}
edev = kzalloc(sizeof(*edev), GFP_KERNEL);
if (!edev)
return -ENOMEM;
if (pd->flags & EE_ADDR8)
edev->addrlen = 7;
else if (pd->flags & EE_ADDR16)
edev->addrlen = 6;
else {
dev_err(&spi->dev, "unspecified address type\n");
err = -EINVAL;
goto fail;
}
mutex_init(&edev->lock);
edev->spi = spi;
edev->pdata = pd;
edev->size = 128;
edev->nvmem_config.name = dev_name(&spi->dev);
edev->nvmem_config.dev = &spi->dev;
edev->nvmem_config.read_only = pd->flags & EE_READONLY;
edev->nvmem_config.root_only = true;
edev->nvmem_config.owner = THIS_MODULE;
edev->nvmem_config.compat = true;
edev->nvmem_config.base_dev = &spi->dev;
edev->nvmem_config.reg_read = eeprom_93xx46_read;
edev->nvmem_config.reg_write = eeprom_93xx46_write;
edev->nvmem_config.priv = edev;
edev->nvmem_config.stride = 4;
edev->nvmem_config.word_size = 1;
edev->nvmem_config.size = edev->size;
edev->nvmem = nvmem_register(&edev->nvmem_config);
if (IS_ERR(edev->nvmem)) {
err = PTR_ERR(edev->nvmem);
goto fail;
}
if (g_rg_eeprom_93xx46_debug) {
dev_info(&spi->dev, "%d-bit eeprom %s\n",
(pd->flags & EE_ADDR8) ? 8 : 16,
(pd->flags & EE_READONLY) ? "(readonly)" : "");
}
if (!(pd->flags & EE_READONLY)) {
if (device_create_file(&spi->dev, &dev_attr_erase))
dev_err(&spi->dev, "can't create erase interface\n");
}
spi_set_drvdata(spi, edev);
return 0;
fail:
kfree(edev);
return err;
}
static int eeprom_93xx46_remove(struct spi_device *spi)
{
struct eeprom_93xx46_dev *edev = spi_get_drvdata(spi);
nvmem_unregister(edev->nvmem);
if (!(edev->pdata->flags & EE_READONLY))
device_remove_file(&spi->dev, &dev_attr_erase);
kfree(edev);
return 0;
}
static struct spi_driver rg_eeprom_93xx46_driver = {
.driver = {
.name = "rg_93xx46",
.of_match_table = of_match_ptr(eeprom_93xx46_of_table),
},
.probe = eeprom_93xx46_probe,
.remove = eeprom_93xx46_remove,
};
module_spi_driver(rg_eeprom_93xx46_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
MODULE_ALIAS("spi:93xx46");

View File

@@ -0,0 +1,531 @@
/*
* Copyright(C) 2016 Ruijie Network. All rights reserved.
*
* fpga_pca954x_drv.c
* Original Author: sonic_rd@ruijie.com.cn 2020-08-10
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/delay.h>
#include <linux/version.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include "fpga_i2c.h"
extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size);
extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count);
#define PCA954X_MAX_NCHANS (8)
#define FPGA_INTERNAL_PCA9548 (1)
#define FPGA_EXTERNAL_PCA9548 (2)
#define FPGA_I2C_EXT_9548_EXITS (0x01 << 0)
#define FPGA_I2C_9548_NO_RESET (0x01 << 1)
#define SYMBOL_I2C_DEV_MODE (1)
#define FILE_MODE (2)
#define SYMBOL_PCIE_DEV_MODE (3)
#define SYMBOL_IO_DEV_MODE (4)
int g_fpga_pca954x_debug = 0;
int g_fpga_pca954x_error = 0;
module_param(g_fpga_pca954x_debug, int, S_IRUGO | S_IWUSR);
module_param(g_fpga_pca954x_error, int, S_IRUGO | S_IWUSR);
#define FPGA_PCA954X_VERBOSE(fmt, args...) do { \
if (g_fpga_pca954x_debug) { \
printk(KERN_INFO "[FPGA_PCA954X][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define FPGA_PCA954X_ERROR(fmt, args...) do { \
if (g_fpga_pca954x_error) { \
printk(KERN_ERR "[FPGA_PCA954X][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
enum pca_type {
pca_9540,
pca_9541,
pca_9542,
pca_9543,
pca_9544,
pca_9545,
pca_9546,
pca_9547,
pca_9548,
};
struct pca954x {
enum pca_type type;
struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
u8 last_chan; /* last register value */
uint32_t fpga_9548_flag;
uint32_t fpga_9548_reset_flag;
uint32_t pca9548_base_nr;
struct i2c_client *client;
};
struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
} muxtype;
};
/* Provide specs for the PCA954x types we know about */
static const struct chip_desc chips[] = {
[pca_9540] = {
.nchans = 2,
.enable = 0x4,
.muxtype = pca954x_ismux,
},
[pca_9541] = {
.nchans = 1,
.muxtype = pca954x_isswi,
},
[pca_9543] = {
.nchans = 2,
.muxtype = pca954x_isswi,
},
[pca_9544] = {
.nchans = 4,
.enable = 0x4,
.muxtype = pca954x_ismux,
},
[pca_9545] = {
.nchans = 4,
.muxtype = pca954x_isswi,
},
[pca_9547] = {
.nchans = 8,
.enable = 0x8,
.muxtype = pca954x_ismux,
},
[pca_9548] = {
.nchans = 8,
.muxtype = pca954x_isswi,
},
};
static const struct i2c_device_id fpga_pca954x_id[] = {
{ "rg_fpga_pca9540", pca_9540 },
{ "rg_fpga_pca9541", pca_9541 },
{ "rg_fpga_pca9542", pca_9543 },
{ "rg_fpga_pca9543", pca_9543 },
{ "rg_fpga_pca9544", pca_9544 },
{ "rg_fpga_pca9545", pca_9545 },
{ "rg_fpga_pca9546", pca_9545 },
{ "rg_fpga_pca9547", pca_9547 },
{ "rg_fpga_pca9548", pca_9548 },
{ }
};
MODULE_DEVICE_TABLE(i2c, fpga_pca954x_id);
static int fpga_file_write(const char *path, int pos, unsigned char *val, size_t size)
{
int ret;
struct file *filp;
loff_t tmp_pos;
filp = filp_open(path, O_RDWR, 777);
if (IS_ERR(filp)) {
FPGA_PCA954X_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp));
filp = NULL;
goto exit;
}
tmp_pos = (loff_t)pos;
ret = kernel_write(filp, val, size, &tmp_pos);
if (ret < 0) {
FPGA_PCA954X_ERROR("kernel_write failed, path=%s, addr=%d, size=%ld, ret=%d\r\n", path, pos, size, ret);
goto exit;
}
vfs_fsync(filp, 1);
filp_close(filp, NULL);
return ret;
exit:
if (filp != NULL) {
filp_close(filp, NULL);
}
return -1;
}
static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, int pos, unsigned char *val, size_t size)
{
int ret;
switch (fpga_i2c->i2c_func_mode) {
case SYMBOL_I2C_DEV_MODE:
ret = i2c_device_func_write(fpga_i2c->dev_name, pos, val, size);
break;
case FILE_MODE:
ret = fpga_file_write(fpga_i2c->dev_name, pos, val, size);
break;
case SYMBOL_PCIE_DEV_MODE:
ret = pcie_device_func_write(fpga_i2c->dev_name, pos, val, size);
break;
default:
FPGA_PCA954X_ERROR("err func mode, write failed.\n");
return -EINVAL;
}
return ret;
}
static int fpga_reg_write(fpga_i2c_dev_t *fpga_i2c, uint32_t addr, uint8_t val)
{
int ret;
ret = fpga_device_write(fpga_i2c, addr, &val, sizeof(uint8_t));
if (ret < 0) {
FPGA_PCA954X_ERROR("fpga_device_write failed. name:%s, addr:0x%x, value:0x%x.\n",
fpga_i2c->dev_name, addr, val);
return ret;
}
FPGA_PCA954X_VERBOSE("fpga reg write success, dev name:%s, offset:0x%x, value:0x%x.\n",
fpga_i2c->dev_name, addr, val);
return 0;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,7)
static int pca954x_select_chan(struct i2c_adapter *adap, void *client, u32 chan)
{
struct pca954x *data = i2c_get_clientdata(client);
fpga_i2c_dev_t *fpga_i2c;
fpga_i2c_reg_t *reg;
int ret;
u8 regval, i2c_9548_opt;
while(i2c_parent_is_i2c_adapter(adap)){
adap = to_i2c_adapter(adap->dev.parent);
}
FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n",
adap->nr, chan, data->fpga_9548_flag, client->addr);
fpga_i2c = i2c_get_adapdata(adap);
reg = &fpga_i2c->reg;
regval = 1 << chan;
if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) {
ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval);
} else {
if (data->fpga_9548_reset_flag == 1) {
i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET);
} else {
i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET;
}
FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n",
data->fpga_9548_reset_flag, i2c_9548_opt);
ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval);
}
return ret;
}
static int pca954x_deselect_mux(struct i2c_adapter *adap, void *client, u32 chan)
{
struct pca954x *data = i2c_get_clientdata(client);
fpga_i2c_dev_t *fpga_i2c;
fpga_i2c_reg_t *reg;
int ret;
while(i2c_parent_is_i2c_adapter(adap)){
adap = to_i2c_adapter(adap->dev.parent);
}
fpga_i2c = i2c_get_adapdata(adap);
reg = &fpga_i2c->reg;
/* Deselect active channel */
data->last_chan = 0;
if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) {
ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0);
} else {
ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0);
}
return ret;
}
#else
static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
{
struct pca954x *data = i2c_mux_priv(muxc);
struct i2c_client *client = data->client;
struct i2c_adapter *adap;
fpga_i2c_dev_t *fpga_i2c;
fpga_i2c_reg_t *reg;
int ret;
u8 regval, i2c_9548_opt;
adap = muxc->parent;
while(i2c_parent_is_i2c_adapter(adap)){
adap = to_i2c_adapter(adap->dev.parent);
}
FPGA_PCA954X_VERBOSE("root bus:%d, chan:0x%x, 9548 flag:0x%x, 9548 addr:0x%x.\n",
adap->nr, chan, data->fpga_9548_flag, client->addr);
fpga_i2c = i2c_get_adapdata(adap);
reg = &fpga_i2c->reg;
regval = 1 << chan;
if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) {
ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, regval);
} else {
if (data->fpga_9548_reset_flag == 1) {
i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS & ~(FPGA_I2C_9548_NO_RESET);
} else {
i2c_9548_opt = FPGA_I2C_EXT_9548_EXITS | FPGA_I2C_9548_NO_RESET;
}
FPGA_PCA954X_VERBOSE("fpga pca9548 reset flag:0x%x, opt:0x%x.\n",
data->fpga_9548_reset_flag, i2c_9548_opt);
ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, i2c_9548_opt);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_addr, client->addr);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, regval);
}
return ret;
}
static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
{
struct pca954x *data = i2c_mux_priv(muxc);
struct i2c_adapter *adap;
fpga_i2c_dev_t *fpga_i2c;
fpga_i2c_reg_t *reg;
int ret;
adap = muxc->parent;
while(i2c_parent_is_i2c_adapter(adap)){
adap = to_i2c_adapter(adap->dev.parent);
}
fpga_i2c = i2c_get_adapdata(adap);
reg = &fpga_i2c->reg;
ret = 0;
/* Deselect active channel */
data->last_chan = 0;
if (data->fpga_9548_flag == FPGA_INTERNAL_PCA9548) {
ret = fpga_reg_write(fpga_i2c, reg->i2c_in_9548_chan, 0);
} else {
ret = fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_exits_flag, FPGA_I2C_9548_NO_RESET);
ret += fpga_reg_write(fpga_i2c, reg->i2c_ext_9548_chan, 0);
}
return ret;
}
#endif
/*
* I2C init/probing/exit functions
*/
static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
int num, force, class;
struct pca954x *data;
int ret = -ENODEV;
struct device *dev;
int dynamic_nr = 1;
fpga_pca954x_device_t *fpga_pca954x_device;
#if LINUX_VERSION_CODE > KERNEL_VERSION(4,6,7)
struct i2c_mux_core *muxc;
#endif
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "i2c adapter:%d, unsupport I2C_FUNC_SMBUS_BYTE.\n", adap->nr);
goto err;
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7)
data = kzalloc(sizeof(struct pca954x), GFP_KERNEL);
if (!data) {
dev_err(&client->dev, "kzalloc failed.\n");
ret = -ENOMEM;
goto err;
}
i2c_set_clientdata(client, data);
#else
muxc = i2c_mux_alloc(adap, &client->dev,
PCA954X_MAX_NCHANS, sizeof(*data), 0,
pca954x_select_chan, pca954x_deselect_mux);
if (!muxc) {
dev_err(&client->dev, "i2c_mux_alloc failed.\n");
return -ENOMEM;
}
data = i2c_mux_priv(muxc);
i2c_set_clientdata(client, muxc);
data->client = client;
#endif
dev = &client->dev;
if (dev == NULL) {
dev_err(&client->dev, "dev is NULL.\n");
ret = -ENODEV;
goto exit_free;
}
if (dev->of_node == NULL) {
if (client->dev.platform_data == NULL) {
dev_err(&client->dev, "Failed to get 954x platform data config.\n");
ret = -EINVAL;
goto exit_free;
}
fpga_pca954x_device = client->dev.platform_data;
data->fpga_9548_flag = fpga_pca954x_device->fpga_9548_flag;
data->fpga_9548_reset_flag = fpga_pca954x_device->fpga_9548_reset_flag;
data->pca9548_base_nr = fpga_pca954x_device->pca9548_base_nr;
if (data->pca9548_base_nr == 0) {
dynamic_nr = 1;
} else {
dynamic_nr = 0;
FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr);
}
} else {
data->type = id->driver_data;
/* BUS ID */
ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag);
ret += of_property_read_u32(dev->of_node, "fpga_9548_reset_flag", &data->fpga_9548_reset_flag);
if (ret != 0) {
dev_err(&client->dev, "Failed to get 954x dts config, ret:%d.\n", ret);
ret = -EINVAL;
goto exit_free;
}
if (of_property_read_u32(dev->of_node, "pca9548_base_nr", &data->pca9548_base_nr)) {
dynamic_nr = 1;
FPGA_PCA954X_VERBOSE("pca9548_base_nr not found, use dynamic adap number");
} else {
dynamic_nr = 0;
FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr);
}
}
if (data->fpga_9548_flag != FPGA_EXTERNAL_PCA9548 && data->fpga_9548_flag != FPGA_INTERNAL_PCA9548) {
dev_err(&client->dev, "Error: fpga 954x flag config error, value:0x%x.\n", data->fpga_9548_flag);
ret = -EINVAL;
goto exit_free;
}
data->type = id->driver_data;
data->last_chan = 0; /* force the first selection */
/* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) {
if (dynamic_nr == 1) {
force = 0; /* dynamic adap number */
} else {
force = data->pca9548_base_nr + num;
}
class = 0; /* no class by default */
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7)
data->virt_adaps[num] =
i2c_add_mux_adapter(adap, &client->dev, client,
force, num, class, pca954x_select_chan, pca954x_deselect_mux);
if (data->virt_adaps[num] == NULL) {
ret = -ENODEV;
dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n",
num, force);
goto virt_reg_failed;
}
#else
ret = i2c_mux_add_adapter(muxc, force, num, class);
if (ret) {
dev_err(&client->dev, "Failed to register multiplexed adapter %d as bus %d\n",
num, force);
goto virt_reg_failed;
}
#endif
} /* end for num = 0; num < chips[data->type].nchans... */
dev_info(&client->dev, "registered %d multiplexed busses for I2C %s %s\n",
num, chips[data->type].muxtype == pca954x_ismux ? "mux" : "switch", client->name);
return 0;
virt_reg_failed:
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7)
for (num--; num >= 0; num--)
i2c_del_mux_adapter(data->virt_adaps[num]);
exit_free:
kfree(data);
#else
exit_free:
i2c_mux_del_adapters(muxc);
#endif
err:
return ret;
}
static int fpga_i2c_pca954x_remove(struct i2c_client *client)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,6,7)
struct pca954x *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type];
int i;
for (i = 0; i < chip->nchans; ++i)
if (data->virt_adaps[i]) {
i2c_del_mux_adapter(data->virt_adaps[i]);
data->virt_adaps[i] = NULL;
}
kfree(data);
#else
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
i2c_mux_del_adapters(muxc);
#endif
return 0;
}
static struct i2c_driver fpga_i2c_pca954x_driver = {
.driver = {
.name = "rg_fpga_pca954x",
.owner = THIS_MODULE,
},
.probe = fpga_i2c_pca954x_probe,
.remove = fpga_i2c_pca954x_remove,
.id_table = fpga_pca954x_id,
};
static int __init fpga_i2c_pca954x_init(void)
{
int ret;
ret = i2c_add_driver(&fpga_i2c_pca954x_driver);
return ret;
}
static void __exit fpga_i2c_pca954x_exit(void)
{
i2c_del_driver(&fpga_i2c_pca954x_driver);
}
module_init(fpga_i2c_pca954x_init);
module_exit(fpga_i2c_pca954x_exit);
MODULE_DESCRIPTION("fpga pca954x driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,167 @@
/*
* Copyright(C) 2016 Ruijie Network. All rights reserved.
*
* rg_fpga_pcie.c
* ko to enable fpga pcie
* Original Author: sonic_rd@ruijie.com.cn 2020-08-10
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/pci.h>
#define FPGA_MSI_IRQ_NUM (14)
#define FPGA_MSI_IRQ_BEGIN (0)
#define XILINX_FPGA_USE_MSI (0)
#define XILINX_FPGA_NUSE_MSI (1)
int g_fpga_pcie_dev_debug = 0;
int g_fpga_pcie_dev_error = 0;
module_param(g_fpga_pcie_dev_debug, int, S_IRUGO | S_IWUSR);
module_param(g_fpga_pcie_dev_error, int, S_IRUGO | S_IWUSR);
#define FPGA_PCIE_DEV_VERBOSE(fmt, args...) do { \
if (g_fpga_pcie_dev_debug) { \
printk(KERN_INFO "[FPGA_PCIE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define FPGA_PCIE_DEV_ERROR(fmt, args...) do { \
if (g_fpga_pcie_dev_error) { \
printk(KERN_ERR "[FPGA_PCIE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
typedef struct rg_fpga_pcie_s {
struct pci_dev *pci_dev;
int driver_data;
} rg_fpga_pcie_t;
static void fpga_pcie_recover(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct resource *mem_base;
u32 bar0_val;
int ret;
mem_base = &pdev->resource[0];
ret = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0_val);
if (ret) {
FPGA_PCIE_DEV_ERROR("pci_read_config_dword failed ret %d.\n", ret);
return;
}
FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], ret %d.\n",
mem_base->start, bar0_val, ret);
if (bar0_val != mem_base->start) {
ret = pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, mem_base->start);
if (ret) {
FPGA_PCIE_DEV_ERROR("pci_write_config_dword mem_base->start[0x%llx], failed ret %d.\n", mem_base->start, ret);
return;
}
FPGA_PCIE_DEV_VERBOSE("pci_write_config_dword mem_base->start[0x%llx] success.\n", mem_base->start);
} else {
FPGA_PCIE_DEV_VERBOSE("mem_base->start[0x%llx], bar0_val[0x%x], do nothing.\n",
mem_base->start, bar0_val);
}
}
static int fpga_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
int err;
rg_fpga_pcie_t *rg_fpga_pcie;
FPGA_PCIE_DEV_VERBOSE("Enter vendor 0x%x, subsystem_vendor 0x%x.\n", pdev->vendor, pdev->subsystem_vendor);
rg_fpga_pcie = devm_kzalloc(&pdev->dev, sizeof(rg_fpga_pcie_t), GFP_KERNEL);
if (!rg_fpga_pcie) {
dev_err(&pdev->dev, "devm_kzalloc failed.\n");
return -ENOMEM;
}
fpga_pcie_recover(pdev, id);
/* enable device: ask low-level code to enable I/O and memory */
FPGA_PCIE_DEV_VERBOSE("start pci_enable_device!\n");
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev, "Failed to enable pci device, ret:%d.\n", err);
return err;
}
FPGA_PCIE_DEV_VERBOSE("start pci_set_master!\n");
pci_set_master(pdev);
rg_fpga_pcie->driver_data = id->driver_data;
rg_fpga_pcie->pci_dev = pdev;
pci_set_drvdata(pdev, rg_fpga_pcie);
if (rg_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) {
FPGA_PCIE_DEV_VERBOSE("start pci_enable_msi_range!\n");
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,19,152)
err = pci_enable_msi_range(pdev, FPGA_MSI_IRQ_BEGIN + 1, FPGA_MSI_IRQ_NUM);
#else
err = pci_alloc_irq_vectors_affinity(pdev, FPGA_MSI_IRQ_BEGIN + 1,
FPGA_MSI_IRQ_NUM, PCI_IRQ_MSI, NULL);
#endif
if (err != FPGA_MSI_IRQ_NUM) {
FPGA_PCIE_DEV_ERROR("pci_enable_msi_block err %d FPGA_MSI_IRQ_NUM %d.\n", err,
FPGA_MSI_IRQ_NUM);
dev_err(&pdev->dev, "Failed to enable pci msi, ret:%d.\n", err);
return -EINVAL;
}
}
dev_info(&pdev->dev, "fpga pci device init success.\n");
return 0;
}
static void fpga_pcie_remove(struct pci_dev *pdev)
{
rg_fpga_pcie_t *rg_fpga_pcie;
FPGA_PCIE_DEV_VERBOSE("fpga_pcie_remove.\n");
rg_fpga_pcie = pci_get_drvdata(pdev);
if (rg_fpga_pcie->driver_data == XILINX_FPGA_USE_MSI) {
FPGA_PCIE_DEV_VERBOSE("start pci_disable_msi!\n");
pci_disable_msi(pdev);
}
pci_disable_device(pdev);
return;
}
static const struct pci_device_id fpga_pci_ids[] = {
{ PCI_DEVICE(0x10ee, 0x7022), .driver_data = XILINX_FPGA_USE_MSI},
{ PCI_DEVICE(0x10ee, 0x7011), .driver_data = XILINX_FPGA_NUSE_MSI},
{0}
};
MODULE_DEVICE_TABLE(pci, fpga_pci_ids);
static struct pci_driver rg_fpga_pcie_driver = {
.name = "rg_fpga_pcie",
.id_table = fpga_pci_ids,/* only dynamic id's */
.probe = fpga_pcie_probe,
.remove = fpga_pcie_remove,
};
static int __init rg_fpga_pcie_init(void)
{
FPGA_PCIE_DEV_VERBOSE("rg_fpga_pcie_init enter!\n");
return pci_register_driver(&rg_fpga_pcie_driver);
}
static void __exit rg_fpga_pcie_exit(void)
{
FPGA_PCIE_DEV_VERBOSE("rg_fpga_pcie_exit enter!\n");
pci_unregister_driver(&rg_fpga_pcie_driver);
return;
}
module_init(rg_fpga_pcie_init);
module_exit(rg_fpga_pcie_exit);
MODULE_DESCRIPTION("fpga pcie driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,367 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2011, 2012 Cavium Inc.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#define GPIO_NAME "rg_gpio_d1500"
#define GPIO_BASE (0x500)
#define GP_IO_SEL (GPIO_BASE + 0x4)
#define GP_LVL (GPIO_BASE + 0xC)
#define GPI_NMI_EN (GPIO_BASE + 0x28)
#define GPI_NMI_STS (GPIO_BASE + 0x2a)
#define GPI_INV (GPIO_BASE + 0x2c)
#define GPIO_USE_SEL2 (GPIO_BASE + 0x30)
#define GP_IO_SEL2 (GPIO_BASE + 0x34)
#define GP_LVL2 (GPIO_BASE + 0x38)
#define GPI_NMI_EN_2 (GPIO_BASE + 0x3c)
#define GPI_NMI_STS_2 (GPIO_BASE + 0x3e)
#define GPIO_USE_SEL3 (GPIO_BASE + 0x40)
#define GP_IO_SEL3 (GPIO_BASE + 0x44)
#define GP_LVL3 (GPIO_BASE + 0x48)
#define GPI_NMI_EN_3 (GPIO_BASE + 0x50)
#define GPI_NMI_STS_3 (GPIO_BASE + 0x54)
#define GPIO_BASE_ID (0)
#define BANKSIZE (32)
#define D1500_GPIO_PIN_NUM (96)
#define CELL_NUM (2)
int g_gpio_d1500_debug = 0;
int g_gpio_d1500_error = 0;
module_param(g_gpio_d1500_debug, int, S_IRUGO | S_IWUSR);
module_param(g_gpio_d1500_error, int, S_IRUGO | S_IWUSR);
#define GPIO_DEBUG_VERBOSE(fmt, args...) do { \
if (g_gpio_d1500_debug) { \
printk(KERN_ERR "[GPIO-D1500][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define GPIO_DEBUG_ERROR(fmt, args...) do { \
if (g_gpio_d1500_error) { \
printk(KERN_ERR "[GPIO-D1500][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
static DEFINE_SPINLOCK(sio_lock);
struct gpio_d1500_t {
struct gpio_chip chip;
u64 register_base;
};
static int rg_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
{
u32 data = 0;
unsigned int bank, offset;
unsigned long flags;
bank = gpio_num / BANKSIZE;
offset = gpio_num % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GP_LVL) & (1 << offset);
if (data) {
data = 1;
}
} else if (bank == 1) {
data = inl(GP_LVL2) & (1 << offset);
if (data) {
data = 1;
}
} else if (bank == 2) {
data = inl(GP_LVL3) & (1 << offset);
if (data) {
data = 1;
}
}
spin_unlock_irqrestore(&sio_lock, flags);
return data;
}
static int rg_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
{
u32 data;
unsigned int bank, offset;
unsigned long flags;
bank = gpio_num / BANKSIZE;
offset = gpio_num % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GP_IO_SEL);
data = data | (1 << offset);
outl(data, GP_IO_SEL);
} else if (bank == 1) {
data = inl(GP_IO_SEL2);
data = data | (1 << offset);
outl(data, GP_IO_SEL2);
} else if (bank == 2) {
data = inl(GP_IO_SEL3);
data = data | (1 << offset);
outl(data, GP_IO_SEL3);
}
spin_unlock_irqrestore(&sio_lock, flags);
return 0;
}
static void rg_gpio_set(struct gpio_chip *gc,
unsigned gpio_num, int val)
{
u32 data;
unsigned int bank, offset;
unsigned long flags;
bank = gpio_num / BANKSIZE;
offset = gpio_num % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GP_LVL);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL);
} else if (bank == 1) {
data = inl(GP_LVL2);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL2);
} else if (bank == 2) {
data = inl(GP_LVL3);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL3);
}
spin_unlock_irqrestore(&sio_lock, flags);
return;
}
static int rg_gpio_direction_out(struct gpio_chip *gc,
unsigned gpio_num, int val)
{
u32 data;
unsigned int bank, offset;
unsigned long flags;
bank = gpio_num / BANKSIZE;
offset = gpio_num % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GP_IO_SEL);
data = data & ~(1 << offset);
outl(data, GP_IO_SEL);
data = inl(GP_LVL);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL);
} else if (bank == 1) {
data = inl(GP_IO_SEL2);
data = data & ~(1 << offset);
outl(data, GP_IO_SEL2);
data = inl(GP_LVL2);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL2);
} else if (bank == 2) {
data = inl(GP_IO_SEL3);
data = data & ~(1 << offset);
outl(data, GP_IO_SEL3);
data = inl(GP_LVL3);
if (val) {
data = data | (1 << offset);
} else {
data = data & ~(1 << offset);
}
outl(data, GP_LVL3);
}
spin_unlock_irqrestore(&sio_lock, flags);
return 0;
}
#ifdef CONFIG_OF
static int rg_gpio_of_xlate(struct gpio_chip *chip,
const struct of_phandle_args *gpio_desc,
u32 *flags)
{
if (chip->of_gpio_n_cells < 2) {
return -EINVAL;
}
if (flags) {
*flags = gpio_desc->args[1];
}
return gpio_desc->args[0];
}
#endif
static int rg_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
u32 data;
unsigned int bank, tmp_offset;
unsigned long flags;
bank = offset / BANKSIZE;
tmp_offset = offset % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GPIO_BASE);
data = data | (1 << tmp_offset);
outl(data, GPIO_BASE);
} else if (bank == 1) {
data = inl(GPIO_USE_SEL2);
data = data | (1 << tmp_offset);
outl(data, GPIO_USE_SEL2);
} else if (bank == 2) {
data = inl(GPIO_USE_SEL3);
data = data | (1 << tmp_offset);
outl(data, GPIO_USE_SEL3);
}
spin_unlock_irqrestore(&sio_lock, flags);
return 0;
}
#if 0
static void rg_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
u32 data;
unsigned int bank, tmp_offset;
unsigned long flags;
bank = offset / BANKSIZE;
tmp_offset = offset % BANKSIZE;
spin_lock_irqsave(&sio_lock, flags);
if (bank == 0) {
data = inl(GPIO_BASE);
data = data & ~(1 << tmp_offset);
outl(data, GPIO_BASE);
} else if (bank == 1) {
data = inl(GPIO_USE_SEL2);
data = data & ~(1 << tmp_offset);
outl(data, GPIO_USE_SEL2);
} else if (bank == 2) {
data = inl(GPIO_USE_SEL3);
data = data & ~(1 << tmp_offset);
outl(data, GPIO_USE_SEL3);
}
spin_unlock_irqrestore(&sio_lock, flags);
return;
}
#endif
static struct gpio_chip rg_gpio_chip = {
.label = GPIO_NAME,
.owner = THIS_MODULE,
.base = GPIO_BASE_ID,
.get = rg_gpio_get,
.direction_input = rg_gpio_direction_in,
.set = rg_gpio_set,
.direction_output = rg_gpio_direction_out,
#ifdef CONFIG_OF
.of_xlate = rg_gpio_of_xlate,
#endif
.request = rg_gpio_request,
.ngpio = D1500_GPIO_PIN_NUM,
#ifdef CONFIG_OF
.of_gpio_n_cells = CELL_NUM,
#endif
.can_sleep = false,
};
static int rg_gpio_probe(struct platform_device *pdev)
{
struct gpio_d1500_t *gpio;
int err;
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio) {
dev_err(&pdev->dev, "gpio kzalloc failed\n");
return -ENOMEM;
}
rg_gpio_chip.parent = &pdev->dev;
gpio->register_base = GPIO_BASE;
gpio->chip = rg_gpio_chip;
pdev->dev.platform_data = &rg_gpio_chip;
err = devm_gpiochip_add_data(&pdev->dev, &rg_gpio_chip, gpio);
if (err) {
dev_err(&pdev->dev, "gpiochip add failed\n");
return err;
}
dev_info(&pdev->dev, "register %llu gpio success.\n", gpio->register_base);
return 0;
}
static int rg_gpio_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "unregister d1500 gpio success\n");
return 0;
}
static const struct of_device_id gpio_d1500_match[] = {
{
.compatible = "ruijie,rg_gpio_d1500",
},
{},
};
MODULE_DEVICE_TABLE(of, gpio_d1500_match);
static struct platform_driver rg_gpio_driver = {
.driver = {
.name = GPIO_NAME,
.of_match_table = gpio_d1500_match,
},
.probe = rg_gpio_probe,
.remove = rg_gpio_remove,
};
module_platform_driver(rg_gpio_driver);
MODULE_DESCRIPTION("d1500 gpio driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,54 @@
#include <linux/module.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
static int g_rg_gpio_device_debug = 0;
static int g_rg_gpio_device_error = 0;
module_param(g_rg_gpio_device_debug, int, S_IRUGO | S_IWUSR);
module_param(g_rg_gpio_device_error, int, S_IRUGO | S_IWUSR);
#define RG_GPIO_DEVICE_VERBOSE(fmt, args...) do { \
if (g_rg_gpio_device_debug) { \
printk(KERN_INFO "[RG_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define RG_GPIO_DEVICE_ERROR(fmt, args...) do { \
if (g_rg_gpio_device_error) { \
printk(KERN_ERR "[RG_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
static void rg_gpio_device_release(struct device *dev)
{
return;
}
static struct platform_device rg_gpio_d1500_device = {
.name = "rg_gpio_d1500",
.id = -1,
.dev = {
.release = rg_gpio_device_release,
},
};
static int __init rg_gpio_device_init(void)
{
RG_GPIO_DEVICE_VERBOSE("rg_gpio_device_init enter!\n");
return platform_device_register(&rg_gpio_d1500_device);
}
static void __exit rg_gpio_device_exit(void)
{
RG_GPIO_DEVICE_VERBOSE("rg_gpio_device_exit enter!\n");
return platform_device_unregister(&rg_gpio_d1500_device);
}
module_init(rg_gpio_device_init);
module_exit(rg_gpio_device_exit);
MODULE_DESCRIPTION("GPIO Devices");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd@ruijie.com.cn");

View File

@@ -0,0 +1,777 @@
/*
* Copyright(C) 2022 Ruijie Network. All rights reserved.
*
* rg_io_dev.c
* ko to read/write i2c client through /dev/XXX device
* Original Author: sonic_rd@ruijie.com.cn 2022-09-09
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/export.h>
#include <linux/uio.h>
#include "rg_i2c_dev.h"
#define MAX_I2C_DEV_NUM (256)
#define FPGA_MAX_LEN (256)
#define MAX_NAME_SIZE (20)
#define MAX_BUS_WIDTH (16)
#define TRANSFER_WRITE_BUFF (FPGA_MAX_LEN + MAX_BUS_WIDTH)
#define WIDTH_1Byte (1)
#define WIDTH_2Byte (2)
#define WIDTH_4Byte (4)
static int g_i2c_dev_debug = 0;
static int g_i2c_dev_error = 0;
module_param(g_i2c_dev_debug, int, S_IRUGO | S_IWUSR);
module_param(g_i2c_dev_error, int, S_IRUGO | S_IWUSR);
#define I2C_DEV_DEBUG_DMESG(fmt, args...) do { \
if (g_i2c_dev_debug) { \
printk(KERN_ERR "[I2C_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define I2C_DEV_DEBUG_ERROR(fmt, args...) do { \
if (g_i2c_dev_error) { \
printk(KERN_ERR "[I2C_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
static struct i2c_dev_info* i2c_dev_arry[MAX_I2C_DEV_NUM];
struct i2c_dev_info {
const char *name;
uint32_t data_bus_width;
uint32_t addr_bus_width;
uint32_t per_rd_len;
uint32_t per_wr_len;
uint32_t i2c_len;
struct miscdevice misc;
struct i2c_client *client;
};
static int transfer_read(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count)
{
struct i2c_adapter *adap;
int i;
u8 offset_buf[MAX_BUS_WIDTH];
struct i2c_msg msgs[2];
int msgs_num, ret;
struct i2c_dev_info *i2c_dev;
if (!client) {
I2C_DEV_DEBUG_ERROR("can't get read client\n");
return -ENODEV;
}
adap = client->adapter;
if (!adap) {
I2C_DEV_DEBUG_ERROR("can't get read adap\n");
return -ENODEV;
}
i2c_dev = i2c_get_clientdata(client);
if (!i2c_dev) {
I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n");
return -ENODEV;
}
i = 0;
memset(offset_buf, 0, sizeof(offset_buf));
switch (i2c_dev->addr_bus_width) {
case WIDTH_4Byte:
offset_buf[i++] = (regaddr >> 24) & 0xFF;
offset_buf[i++] = (regaddr >> 16) & 0xFF;
offset_buf[i++] = (regaddr >> 8) & 0xFF;
offset_buf[i++] = regaddr & 0xFF;
break;
case WIDTH_2Byte:
offset_buf[i++] = (regaddr >> 8) & 0xFF;
offset_buf[i++] = regaddr & 0xFF;
break;
case WIDTH_1Byte:
offset_buf[i++] = regaddr & 0xFF;
break;
default:
I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n",
i2c_dev->addr_bus_width);
return -EINVAL;
}
if (adap->algo->master_xfer) {
memset(msgs, 0, sizeof(msgs));
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = i2c_dev->addr_bus_width;
msgs[0].buf = offset_buf;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = count;
msgs[1].buf = buf;
msgs_num = 2;
ret = i2c_transfer(client->adapter, msgs, msgs_num);
if (ret != msgs_num) {
I2C_DEV_DEBUG_ERROR("i2c_transfer read error\n");
return -EINVAL;
}
} else {
I2C_DEV_DEBUG_ERROR("don't find read master_xfer\n");
return -EINVAL;
}
return 0;
}
static int transfer_write(struct i2c_client *client, u8 *buf, loff_t regaddr, size_t count)
{
struct i2c_adapter *adap;
int i;
u8 offset_buf[TRANSFER_WRITE_BUFF];
struct i2c_msg msgs[1];
int msgs_num, ret;
struct i2c_dev_info *i2c_dev;
if (!client) {
I2C_DEV_DEBUG_ERROR("can't get write client\n");
return -ENODEV;
}
adap = client->adapter;
if (!adap) {
I2C_DEV_DEBUG_ERROR("can't get write adap\n");
return -ENODEV;
}
i2c_dev = i2c_get_clientdata(client);
if (!i2c_dev) {
I2C_DEV_DEBUG_ERROR("can't get read i2c_dev\n");
return -ENODEV;
}
i = 0;
memset(offset_buf, 0, sizeof(offset_buf));
switch (i2c_dev->addr_bus_width) {
case WIDTH_4Byte:
offset_buf[i++] = (regaddr >> 24) & 0xFF;
offset_buf[i++] = (regaddr >> 16) & 0xFF;
offset_buf[i++] = (regaddr >> 8) & 0xFF;
offset_buf[i++] = regaddr & 0xFF;
break;
case WIDTH_2Byte:
offset_buf[i++] = (regaddr >> 8) & 0xFF;
offset_buf[i++] = regaddr & 0xFF;
break;
case WIDTH_1Byte:
offset_buf[i++] = regaddr & 0xFF;
break;
default:
I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Address Width,but set width = %u\n",
i2c_dev->addr_bus_width);
return -EINVAL;
}
memcpy(offset_buf + i2c_dev->addr_bus_width, buf, count);
if (adap->algo->master_xfer) {
memset(msgs, 0, sizeof(msgs));
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = i2c_dev->addr_bus_width + count;
msgs[0].buf = offset_buf;
msgs_num = 1;
ret = i2c_transfer(adap, msgs, msgs_num);
if (ret != msgs_num) {
I2C_DEV_DEBUG_ERROR("i2c_transfer write error\n");
return -EINVAL;
}
} else {
I2C_DEV_DEBUG_ERROR("don't find write master_xfer\n");
return -EINVAL;
}
return 0;
}
static long i2c_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
static int i2c_dev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct i2c_dev_info *i2c_dev;
i2c_dev = i2c_dev_arry[minor];
if (i2c_dev == NULL) {
return -ENODEV;
}
file->private_data = i2c_dev;
return 0;
}
static int i2c_dev_release(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return 0;
}
static int device_read(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int i, j, ret;
u8 tmp_offset;
u8 val[FPGA_MAX_LEN];
u32 width, rd_len, per_len, tmp;
u32 max_per_len;
if (offset > i2c_dev->i2c_len) {
I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n",
offset, i2c_dev->i2c_len, count);
return 0;
}
if (count > (i2c_dev->i2c_len - offset)) {
I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n",
count, i2c_dev->i2c_len - offset);
count = i2c_dev->i2c_len - offset;
}
if (count == 0) {
I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n",
offset, i2c_dev->i2c_len, count);
return 0;
}
width = i2c_dev->data_bus_width;
switch (width) {
case WIDTH_4Byte:
tmp_offset = offset & 0x3;
if (tmp_offset) {
I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
break;
case WIDTH_2Byte:
tmp_offset = offset & 0x1;
if (tmp_offset) {
I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
break;
case WIDTH_1Byte:
break;
default:
I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width);
return -EINVAL;
}
max_per_len = i2c_dev->per_rd_len;
tmp = (width - 1) & count;
rd_len = (tmp == 0) ? count : count + width - tmp;
per_len = (rd_len > max_per_len) ? (max_per_len) : (rd_len);
memset(val, 0, sizeof(val));
for (i = 0; i < rd_len; i += per_len) {
ret = transfer_read(i2c_dev->client, val + i, offset + i, per_len);
if (ret < 0) {
I2C_DEV_DEBUG_ERROR("read error.read offset = %u\n", (offset + i));
return -EFAULT;
}
}
if (width == WIDTH_1Byte) {
memcpy(buf, val, count);
} else {
for (i = 0; i < count; i += width) {
for (j = 0; (j < width) && (i + j < count); j++) {
buf[i + j] = val[i + width - j - 1];
}
}
}
return count;
}
static int device_write(struct i2c_dev_info *i2c_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int i, j, ret;
u8 tmp_offset;
u32 width;
u8 val[FPGA_MAX_LEN];
u32 wr_len, per_len, tmp;
u32 max_per_len;
if (offset > i2c_dev->i2c_len) {
I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, count: %lu, EOF.\n",
offset, i2c_dev->i2c_len, count);
return 0;
}
if (count > (i2c_dev->i2c_len - offset)) {
I2C_DEV_DEBUG_DMESG("read count out of range. input len:%lu, read len:%u.\n",
count, i2c_dev->i2c_len - offset);
count = i2c_dev->i2c_len - offset;
}
if (count == 0) {
I2C_DEV_DEBUG_DMESG("offset: 0x%x, i2c len: 0x%x, read len: %lu, EOF.\n",
offset, i2c_dev->i2c_len, count);
return 0;
}
width = i2c_dev->data_bus_width;
switch (width) {
case WIDTH_4Byte:
tmp_offset = offset & 0x3;
if (tmp_offset) {
I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
break;
case WIDTH_2Byte:
tmp_offset = offset & 0x1;
if (tmp_offset) {
I2C_DEV_DEBUG_ERROR("data bus width:%u, offset:%u, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
break;
case WIDTH_1Byte:
break;
default:
I2C_DEV_DEBUG_ERROR("Only support 1,2,4 Byte Data Width,but set width = %u\n", width);
return -EINVAL;
}
memset(val, 0, sizeof(val));
if (width == WIDTH_1Byte) {
memcpy(val, buf, count);
} else {
for (i = 0; i < count; i += width) {
for (j = 0; (j < width) && (i + j < count); j++) {
val[i + width - j - 1] = buf[i + j];
}
}
}
max_per_len = i2c_dev->per_wr_len;
tmp = (width - 1) & count;
wr_len = (tmp == 0) ? count : count + width - tmp;
per_len = (wr_len > max_per_len) ? (max_per_len) : (wr_len);
for (i = 0; i < wr_len; i += per_len) {
ret = transfer_write(i2c_dev->client, val + i, offset + i, per_len);
if (ret < 0) {
I2C_DEV_DEBUG_ERROR("write error.offset = %u\n", (offset + i));
return -EFAULT;
}
}
return count;
}
static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
u8 val[FPGA_MAX_LEN];
int ret, read_len;
struct i2c_dev_info *i2c_dev;
i2c_dev = file->private_data;
if (i2c_dev == NULL) {
I2C_DEV_DEBUG_ERROR("can't get read private_data.n");
return -EINVAL;
}
if (count == 0) {
I2C_DEV_DEBUG_ERROR("Invalid params, read count is 0.n");
return -EINVAL;
}
if (count > sizeof(val)) {
I2C_DEV_DEBUG_DMESG("read conut %lu exceed max %lu.\n", count, sizeof(val));
count = sizeof(val);
}
memset(val, 0, sizeof(val));
read_len = device_read(i2c_dev, (uint32_t)*offset, val, count);
if (read_len < 0) {
I2C_DEV_DEBUG_ERROR("i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n",
i2c_dev->name, (uint32_t)*offset, count);
return read_len;
}
if (access_ok(buf, read_len)) {
I2C_DEV_DEBUG_DMESG("user space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
if (copy_to_user(buf, val, read_len)) {
I2C_DEV_DEBUG_ERROR("copy_to_user failed.\n");
return -EFAULT;
}
} else {
I2C_DEV_DEBUG_DMESG("kernel space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
memcpy(buf, val, read_len);
}
*offset += read_len;
ret = read_len;
return ret;
}
static ssize_t i2c_dev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
int ret;
I2C_DEV_DEBUG_DMESG("i2c_dev_read_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, to->count, iocb->ki_pos);
ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos);
return ret;
}
static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
u8 val[FPGA_MAX_LEN];
int write_len;
struct i2c_dev_info *i2c_dev;
i2c_dev = file->private_data;
if (i2c_dev == NULL) {
I2C_DEV_DEBUG_ERROR("get write private_data error.\n");
return -EINVAL;
}
if (count == 0) {
I2C_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n");
return -EINVAL;
}
if (count > sizeof(val)) {
I2C_DEV_DEBUG_DMESG("write conut %lu exceed max %lu.\n", count, sizeof(val));
count = sizeof(val);
}
memset(val, 0, sizeof(val));
if (access_ok(buf, count)) {
I2C_DEV_DEBUG_DMESG("user space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
if (copy_from_user(val, buf, count)) {
I2C_DEV_DEBUG_ERROR("copy_from_user failed.\n");
return -EFAULT;
}
} else {
I2C_DEV_DEBUG_DMESG("kernel space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
memcpy(val, buf, count);
}
write_len = device_write(i2c_dev, (uint32_t)*offset, val, count);
if (write_len < 0) {
I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%llx, len:%lu.\n",
i2c_dev->name, *offset, count);
return write_len;
}
*offset += write_len;
return write_len;
}
static ssize_t i2c_dev_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
int ret;
I2C_DEV_DEBUG_DMESG("i2c_dev_write_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, from->count, iocb->ki_pos);
ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos);
return ret;
}
static loff_t i2c_dev_llseek(struct file *file, loff_t offset, int origin)
{
loff_t ret = 0;
struct i2c_dev_info *i2c_dev;
i2c_dev = file->private_data;
if (i2c_dev == NULL) {
I2C_DEV_DEBUG_ERROR("i2c_dev is NULL, llseek failed.\n");
return -EINVAL;
}
switch (origin) {
case SEEK_SET:
if (offset < 0) {
I2C_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset);
ret = -EINVAL;
break;
}
if (offset > i2c_dev->i2c_len) {
I2C_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n",
offset, i2c_dev->i2c_len);
ret = - EINVAL;
break;
}
file->f_pos = offset;
ret = file->f_pos;
break;
case SEEK_CUR:
if (((file->f_pos + offset) > i2c_dev->i2c_len) || ((file->f_pos + offset) < 0)) {
I2C_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, i2c_len:0x%x.\n",
file->f_pos, offset, i2c_dev->i2c_len);
ret = - EINVAL;
break;
}
file->f_pos += offset;
ret = file->f_pos;
break;
default:
I2C_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin);
ret = -EINVAL;
break;
}
return ret;
}
static const struct file_operations i2c_dev_fops = {
.owner = THIS_MODULE,
.llseek = i2c_dev_llseek,
.read_iter = i2c_dev_read_iter,
.write_iter = i2c_dev_write_iter,
.unlocked_ioctl = i2c_dev_ioctl,
.open = i2c_dev_open,
.release = i2c_dev_release,
};
static struct i2c_dev_info * dev_match(const char *path)
{
struct i2c_dev_info * i2c_dev;
char dev_name[MAX_NAME_SIZE];
int i;
for (i = 0; i < MAX_I2C_DEV_NUM; i++) {
if (i2c_dev_arry[ i ] == NULL) {
continue;
}
i2c_dev = i2c_dev_arry[ i ];
snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", i2c_dev->name);
if (!strcmp(path, dev_name)) {
I2C_DEV_DEBUG_DMESG("get dev_name = %s, minor = %d\n", dev_name, i);
return i2c_dev;
}
}
return NULL;
}
int i2c_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
struct i2c_dev_info *i2c_dev = NULL;
int ret;
if(path == NULL){
I2C_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if(buf == NULL){
I2C_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
if (count > FPGA_MAX_LEN) {
I2C_DEV_DEBUG_ERROR("read conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN);
return -EINVAL;
}
i2c_dev = dev_match(path);
if (i2c_dev == NULL) {
I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path);
return -EINVAL;
}
ret = device_read(i2c_dev, offset, buf, count);
if (ret < 0) {
I2C_DEV_DEBUG_ERROR("fpga i2c dev read failed, dev name:%s, offset:0x%x, len:%lu.\n",
i2c_dev->name, offset, count);
return -EINVAL;
}
return count;
}
EXPORT_SYMBOL(i2c_device_func_read);
int i2c_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
struct i2c_dev_info *i2c_dev = NULL;
int ret;
if(path == NULL){
I2C_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if(buf == NULL){
I2C_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
if (count > FPGA_MAX_LEN) {
I2C_DEV_DEBUG_ERROR("write conut %lu, beyond max:%d.\n", count, FPGA_MAX_LEN);
return -EINVAL;
}
i2c_dev = dev_match(path);
if (i2c_dev == NULL) {
I2C_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path);
return -EINVAL;
}
ret = device_write (i2c_dev, offset, buf, count);
if (ret < 0) {
I2C_DEV_DEBUG_ERROR("i2c dev write failed, dev name:%s, offset:0x%x, len:%lu.\n",
i2c_dev->name, offset, count);
return -EINVAL;
}
return count;
}
EXPORT_SYMBOL(i2c_device_func_write);
static int i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret = 0;
struct i2c_dev_info *i2c_dev;
struct miscdevice *misc;
i2c_dev_device_t *i2c_dev_device;
i2c_dev = devm_kzalloc(&client->dev, sizeof(struct i2c_dev_info), GFP_KERNEL);
if (!i2c_dev) {
dev_err(&client->dev, "devm_kzalloc error. \n");
return -ENOMEM;
}
i2c_set_clientdata(client, i2c_dev);
i2c_dev->client = client;
if (client->dev.of_node) {
ret += of_property_read_string(client->dev.of_node, "i2c_name", &i2c_dev->name);
ret += of_property_read_u32(client->dev.of_node, "data_bus_width", &i2c_dev->data_bus_width);
ret += of_property_read_u32(client->dev.of_node, "addr_bus_width", &i2c_dev->addr_bus_width);
ret += of_property_read_u32(client->dev.of_node, "per_rd_len", &i2c_dev->per_rd_len);
ret += of_property_read_u32(client->dev.of_node, "per_wr_len", &i2c_dev->per_wr_len);
ret += of_property_read_u32(client->dev.of_node, "i2c_len", &i2c_dev->i2c_len);
if (ret != 0) {
dev_err(&client->dev, "dts config error.ret:%d.\n", ret);
return -ENXIO;
}
} else {
if (client->dev.platform_data == NULL) {
dev_err(&client->dev, "Failed to get platform data config.\n");
return -ENXIO;
}
i2c_dev_device = client->dev.platform_data;
i2c_dev->name = i2c_dev_device->i2c_name;
i2c_dev->data_bus_width = i2c_dev_device->data_bus_width;
i2c_dev->addr_bus_width = i2c_dev_device->addr_bus_width;
i2c_dev->per_rd_len = i2c_dev_device->per_rd_len;
i2c_dev->per_wr_len = i2c_dev_device->per_wr_len;
i2c_dev->i2c_len = i2c_dev_device->i2c_len;
}
if ((i2c_dev->per_rd_len & (i2c_dev->data_bus_width - 1)) ||
(i2c_dev->per_wr_len & (i2c_dev->data_bus_width - 1))) {
dev_err(&client->dev, "Invalid config per_rd_len %d per_wr_len %d data bus_width %d.\n",
i2c_dev->per_rd_len, i2c_dev->per_wr_len, i2c_dev->data_bus_width);
return -ENXIO;
}
if ((i2c_dev->i2c_len == 0) || (i2c_dev->i2c_len & (i2c_dev->data_bus_width - 1))) {
dev_err(&client->dev, "Invalid config i2c_len %d, data bus_width %d.\n",
i2c_dev->i2c_len, i2c_dev->data_bus_width);
return -ENXIO;
}
misc = &i2c_dev->misc;
misc->minor = MISC_DYNAMIC_MINOR;
misc->name = i2c_dev->name;
misc->fops = &i2c_dev_fops;
misc->mode = 0666;
if (misc_register(misc) != 0) {
dev_err(&client->dev, "register %s faild.\n", misc->name);
return -ENXIO;
}
if (misc->minor >= MAX_I2C_DEV_NUM) {
dev_err(&client->dev, "minor number beyond the limit! is %d.\n", misc->minor);
misc_deregister(misc);
return -ENXIO;
}
i2c_dev_arry[misc->minor] = i2c_dev;
dev_info(&client->dev, "register %u addr_bus_width %u data_bus_width 0x%x i2c_len device %s with %u per_rd_len %u per_wr_len success.\n",
i2c_dev->addr_bus_width, i2c_dev->data_bus_width, i2c_dev->i2c_len, i2c_dev->name, i2c_dev->per_rd_len, i2c_dev->per_wr_len);
return 0;
}
static int i2c_dev_remove(struct i2c_client *client)
{
int i;
for (i = 0; i < MAX_I2C_DEV_NUM; i++) {
if (i2c_dev_arry[i] != NULL) {
misc_deregister(&i2c_dev_arry[i]->misc);
i2c_dev_arry[i] = NULL;
}
}
return 0;
}
static const struct i2c_device_id i2c_dev_id[] = {
{ "rg-i2c-dev", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, i2c_dev_id);
static const struct of_device_id i2c_dev_of_match[] = {
{ .compatible = "ruijie,rg-i2c-dev" },
{ },
};
MODULE_DEVICE_TABLE(of, i2c_dev_of_match);
static struct i2c_driver i2c_dev_driver = {
.driver = {
.name = "rg-i2c-dev",
.of_match_table = i2c_dev_of_match,
},
.probe = i2c_dev_probe,
.remove = i2c_dev_remove,
.id_table = i2c_dev_id,
};
module_i2c_driver(i2c_dev_driver);
MODULE_DESCRIPTION("i2c dev driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,18 @@
#ifndef __RG_I2C_DEV_H__
#define __RG_I2C_DEV_H__
#define I2C_DEV_NAME_MAX_LEN (64)
typedef struct i2c_dev_device_s {
struct i2c_client *client;
uint32_t i2c_bus;
uint32_t i2c_addr;
char i2c_name[I2C_DEV_NAME_MAX_LEN];
uint32_t data_bus_width;
uint32_t addr_bus_width;
uint32_t per_rd_len;
uint32_t per_wr_len;
uint32_t i2c_len;
} i2c_dev_device_t;
#endif

View File

@@ -0,0 +1,110 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/delay.h>
#include <asm/delay.h>
#include <linux/miscdevice.h>
static int gpio_sda = 17;
module_param(gpio_sda, int, S_IRUGO | S_IWUSR);
static int gpio_scl = 1;
module_param(gpio_scl, int, S_IRUGO | S_IWUSR);
static int gpio_udelay = 2;
module_param(gpio_udelay, int, S_IRUGO | S_IWUSR);
static int g_rg_i2c_gpio_device_debug = 0;
static int g_rg_i2c_gpio_device_error = 0;
module_param(g_rg_i2c_gpio_device_debug, int, S_IRUGO | S_IWUSR);
module_param(g_rg_i2c_gpio_device_error, int, S_IRUGO | S_IWUSR);
#define RG_I2C_GPIO_DEVICE_VERBOSE(fmt, args...) do { \
if (g_rg_i2c_gpio_device_debug) { \
printk(KERN_INFO "[RG_I2C_GPIO_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define RG_I2C_GPIO_DEVICE_ERROR(fmt, args...) do { \
if (g_rg_i2c_gpio_device_error) { \
printk(KERN_ERR "[RG_I2C_GPIO_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
/****************** i2c adapter with gpio ***********************/
static struct i2c_gpio_platform_data i2c_pdata = {
.udelay = 2,
.scl_is_output_only = 0,
.sda_is_open_drain = 0,
.scl_is_open_drain = 0,
};
static void i2c_gpio_release(struct device *dev)
{
return;
}
static struct platform_device rg_i2c_gpio_device = {
.name = "i2c-gpio",
.id = -1,
.num_resources = 0,
.resource = NULL,
.dev = {
.platform_data = &i2c_pdata,
.release = i2c_gpio_release,
},
};
/*
* i2c
*/
static struct gpiod_lookup_table rg_i2c_gpio_table = {
.dev_id = "i2c-gpio",
.table = {
GPIO_LOOKUP_IDX("rg_gpio_d1500", 17, NULL, 0,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
GPIO_LOOKUP_IDX("rg_gpio_d1500", 1, NULL, 1,
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
static int __init rg_i2c_gpio_device_init(void)
{
int err;
RG_I2C_GPIO_DEVICE_VERBOSE("rg_i2c_gpio_device_init enter!\n");
rg_i2c_gpio_table.table[0].chip_hwnum = gpio_sda;
rg_i2c_gpio_table.table[1].chip_hwnum = gpio_scl;
i2c_pdata.udelay = gpio_udelay;
gpiod_add_lookup_table(&rg_i2c_gpio_table);
err = platform_device_register(&rg_i2c_gpio_device);
if (err < 0) {
printk(KERN_ERR "register i2c gpio device fail(%d). \n", err);
gpiod_remove_lookup_table(&rg_i2c_gpio_table);
return -1;
}
return 0;
}
static void __exit rg_i2c_gpio_device_exit(void)
{
RG_I2C_GPIO_DEVICE_VERBOSE("rg_i2c_gpio_device_exit enter!\n");
platform_device_unregister(&rg_i2c_gpio_device);
gpiod_remove_lookup_table(&rg_i2c_gpio_table);
}
module_init(rg_i2c_gpio_device_init);
module_exit(rg_i2c_gpio_device_exit);
MODULE_DESCRIPTION("I2C GPIO Devices");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd@ruijie.com.cn");

View File

@@ -0,0 +1,445 @@
/*
* INA3221 Triple Current/Voltage Monitor
*
* Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
* Andrew F. Davis <afd@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#define INA3221_DRIVER_NAME "rg_ina3221"
#define INA3221_CONFIG 0x00
#define INA3221_SHUNT1 0x01
#define INA3221_BUS1 0x02
#define INA3221_SHUNT2 0x03
#define INA3221_BUS2 0x04
#define INA3221_SHUNT3 0x05
#define INA3221_BUS3 0x06
#define INA3221_CRIT1 0x07
#define INA3221_WARN1 0x08
#define INA3221_CRIT2 0x09
#define INA3221_WARN2 0x0a
#define INA3221_CRIT3 0x0b
#define INA3221_WARN3 0x0c
#define INA3221_MASK_ENABLE 0x0f
#define INA3221_CONFIG_MODE_SHUNT BIT(1)
#define INA3221_CONFIG_MODE_BUS BIT(2)
#define INA3221_CONFIG_MODE_CONTINUOUS BIT(3)
#define INA3221_RSHUNT_DEFAULT 10000
enum ina3221_fields {
/* Configuration */
F_RST,
/* Alert Flags */
F_WF3, F_WF2, F_WF1,
F_CF3, F_CF2, F_CF1,
/* sentinel */
F_MAX_FIELDS
};
static const struct reg_field ina3221_reg_fields[] = {
[F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15),
[F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3),
[F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4),
[F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5),
[F_CF3] = REG_FIELD(INA3221_MASK_ENABLE, 7, 7),
[F_CF2] = REG_FIELD(INA3221_MASK_ENABLE, 8, 8),
[F_CF1] = REG_FIELD(INA3221_MASK_ENABLE, 9, 9),
};
enum ina3221_channels {
INA3221_CHANNEL1,
INA3221_CHANNEL2,
INA3221_CHANNEL3,
INA3221_NUM_CHANNELS
};
static const unsigned int register_channel[] = {
[INA3221_SHUNT1] = INA3221_CHANNEL1,
[INA3221_SHUNT2] = INA3221_CHANNEL2,
[INA3221_SHUNT3] = INA3221_CHANNEL3,
[INA3221_CRIT1] = INA3221_CHANNEL1,
[INA3221_CRIT2] = INA3221_CHANNEL2,
[INA3221_CRIT3] = INA3221_CHANNEL3,
[INA3221_WARN1] = INA3221_CHANNEL1,
[INA3221_WARN2] = INA3221_CHANNEL2,
[INA3221_WARN3] = INA3221_CHANNEL3,
};
/**
* struct ina3221_data - device specific information
* @regmap: Register map of the device
* @fields: Register fields of the device
* @shunt_resistors: Array of resistor values per channel
*/
struct ina3221_data {
struct regmap *regmap;
struct regmap_field *fields[F_MAX_FIELDS];
int shunt_resistors[INA3221_NUM_CHANNELS];
};
static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg,
int *val)
{
unsigned int regval;
int ret;
ret = regmap_read(ina->regmap, reg, &regval);
if (ret)
return ret;
*val = sign_extend32(regval >> 3, 12);
return 0;
}
static ssize_t ina3221_show_bus_voltage(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int reg = sd_attr->index;
int val, voltage_mv, ret;
ret = ina3221_read_value(ina, reg, &val);
if (ret)
return ret;
voltage_mv = val * 8;
return snprintf(buf, PAGE_SIZE, "%d\n", voltage_mv);
}
static ssize_t ina3221_show_shunt_voltage(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int reg = sd_attr->index;
int val, voltage_uv, ret;
ret = ina3221_read_value(ina, reg, &val);
if (ret)
return ret;
voltage_uv = val * 40;
return snprintf(buf, PAGE_SIZE, "%d\n", voltage_uv);
}
static ssize_t ina3221_show_current(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int reg = sd_attr->index;
unsigned int channel = register_channel[reg];
int resistance_uo = ina->shunt_resistors[channel];
int val, current_ma, voltage_nv, ret;
ret = ina3221_read_value(ina, reg, &val);
if (ret)
return ret;
voltage_nv = val * 40000;
current_ma = DIV_ROUND_CLOSEST(voltage_nv, resistance_uo);
return snprintf(buf, PAGE_SIZE, "%d\n", current_ma);
}
static ssize_t ina3221_set_current(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int reg = sd_attr->index;
unsigned int channel = register_channel[reg];
int resistance_uo = ina->shunt_resistors[channel];
int val, current_ma, voltage_uv, ret;
ret = kstrtoint(buf, 0, &current_ma);
if (ret)
return ret;
/* clamp current */
current_ma = clamp_val(current_ma,
INT_MIN / resistance_uo,
INT_MAX / resistance_uo);
voltage_uv = DIV_ROUND_CLOSEST(current_ma * resistance_uo, 1000);
/* clamp voltage */
voltage_uv = clamp_val(voltage_uv, -163800, 163800);
/* 1 / 40uV(scale) << 3(register shift) = 5 */
val = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8;
ret = regmap_write(ina->regmap, reg, val);
if (ret)
return ret;
return count;
}
static ssize_t ina3221_show_shunt(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int channel = sd_attr->index;
unsigned int resistance_uo;
resistance_uo = ina->shunt_resistors[channel];
return snprintf(buf, PAGE_SIZE, "%d\n", resistance_uo);
}
static ssize_t ina3221_set_shunt(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int channel = sd_attr->index;
int val;
int ret;
ret = kstrtoint(buf, 0, &val);
if (ret)
return ret;
val = clamp_val(val, 1, INT_MAX);
ina->shunt_resistors[channel] = val;
return count;
}
static ssize_t ina3221_show_alert(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(attr);
struct ina3221_data *ina = dev_get_drvdata(dev);
unsigned int field = sd_attr->index;
unsigned int regval;
int ret;
ret = regmap_field_read(ina->fields[field], &regval);
if (ret)
return ret;
return snprintf(buf, PAGE_SIZE, "%d\n", regval);
}
/* bus voltage */
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO,
ina3221_show_bus_voltage, NULL, INA3221_BUS1);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO,
ina3221_show_bus_voltage, NULL, INA3221_BUS2);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO,
ina3221_show_bus_voltage, NULL, INA3221_BUS3);
/* calculated current */
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO,
ina3221_show_current, NULL, INA3221_SHUNT1);
static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO,
ina3221_show_current, NULL, INA3221_SHUNT2);
static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO,
ina3221_show_current, NULL, INA3221_SHUNT3);
/* shunt resistance */
static SENSOR_DEVICE_ATTR(shunt1_resistor, S_IRUGO | S_IWUSR,
ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL1);
static SENSOR_DEVICE_ATTR(shunt2_resistor, S_IRUGO | S_IWUSR,
ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL2);
static SENSOR_DEVICE_ATTR(shunt3_resistor, S_IRUGO | S_IWUSR,
ina3221_show_shunt, ina3221_set_shunt, INA3221_CHANNEL3);
/* critical current */
static SENSOR_DEVICE_ATTR(curr1_crit, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_CRIT1);
static SENSOR_DEVICE_ATTR(curr2_crit, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_CRIT2);
static SENSOR_DEVICE_ATTR(curr3_crit, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_CRIT3);
/* critical current alert */
static SENSOR_DEVICE_ATTR(curr1_crit_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_CF1);
static SENSOR_DEVICE_ATTR(curr2_crit_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_CF2);
static SENSOR_DEVICE_ATTR(curr3_crit_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_CF3);
/* warning current */
static SENSOR_DEVICE_ATTR(curr1_max, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_WARN1);
static SENSOR_DEVICE_ATTR(curr2_max, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_WARN2);
static SENSOR_DEVICE_ATTR(curr3_max, S_IRUGO | S_IWUSR,
ina3221_show_current, ina3221_set_current, INA3221_WARN3);
/* warning current alert */
static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_WF1);
static SENSOR_DEVICE_ATTR(curr2_max_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_WF2);
static SENSOR_DEVICE_ATTR(curr3_max_alarm, S_IRUGO,
ina3221_show_alert, NULL, F_WF3);
/* shunt voltage */
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO,
ina3221_show_shunt_voltage, NULL, INA3221_SHUNT1);
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO,
ina3221_show_shunt_voltage, NULL, INA3221_SHUNT2);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO,
ina3221_show_shunt_voltage, NULL, INA3221_SHUNT3);
static struct attribute *ina3221_attrs[] = {
/* channel 1 */
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_shunt1_resistor.dev_attr.attr,
&sensor_dev_attr_curr1_crit.dev_attr.attr,
&sensor_dev_attr_curr1_crit_alarm.dev_attr.attr,
&sensor_dev_attr_curr1_max.dev_attr.attr,
&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
&sensor_dev_attr_in4_input.dev_attr.attr,
/* channel 2 */
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_curr2_input.dev_attr.attr,
&sensor_dev_attr_shunt2_resistor.dev_attr.attr,
&sensor_dev_attr_curr2_crit.dev_attr.attr,
&sensor_dev_attr_curr2_crit_alarm.dev_attr.attr,
&sensor_dev_attr_curr2_max.dev_attr.attr,
&sensor_dev_attr_curr2_max_alarm.dev_attr.attr,
&sensor_dev_attr_in5_input.dev_attr.attr,
/* channel 3 */
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_curr3_input.dev_attr.attr,
&sensor_dev_attr_shunt3_resistor.dev_attr.attr,
&sensor_dev_attr_curr3_crit.dev_attr.attr,
&sensor_dev_attr_curr3_crit_alarm.dev_attr.attr,
&sensor_dev_attr_curr3_max.dev_attr.attr,
&sensor_dev_attr_curr3_max_alarm.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(ina3221);
static const struct regmap_range ina3221_yes_ranges[] = {
regmap_reg_range(INA3221_SHUNT1, INA3221_BUS3),
regmap_reg_range(INA3221_MASK_ENABLE, INA3221_MASK_ENABLE),
};
static const struct regmap_access_table ina3221_volatile_table = {
.yes_ranges = ina3221_yes_ranges,
.n_yes_ranges = ARRAY_SIZE(ina3221_yes_ranges),
};
static const struct regmap_config ina3221_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.cache_type = REGCACHE_RBTREE,
.volatile_table = &ina3221_volatile_table,
};
static int ina3221_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct ina3221_data *ina;
struct device *hwmon_dev;
int i, ret;
ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL);
if (!ina)
return -ENOMEM;
ina->regmap = devm_regmap_init_i2c(client, &ina3221_regmap_config);
if (IS_ERR(ina->regmap)) {
dev_err(dev, "Unable to allocate register map\n");
return PTR_ERR(ina->regmap);
}
for (i = 0; i < F_MAX_FIELDS; i++) {
ina->fields[i] = devm_regmap_field_alloc(dev,
ina->regmap,
ina3221_reg_fields[i]);
if (IS_ERR(ina->fields[i])) {
dev_err(dev, "Unable to allocate regmap fields\n");
return PTR_ERR(ina->fields[i]);
}
}
for (i = 0; i < INA3221_NUM_CHANNELS; i++)
ina->shunt_resistors[i] = INA3221_RSHUNT_DEFAULT;
ret = regmap_field_write(ina->fields[F_RST], true);
if (ret) {
dev_err(dev, "Unable to reset device\n");
return ret;
}
hwmon_dev = devm_hwmon_device_register_with_groups(dev,
client->name,
ina, ina3221_groups);
if (IS_ERR(hwmon_dev)) {
dev_err(dev, "Unable to register hwmon device\n");
return PTR_ERR(hwmon_dev);
}
return 0;
}
static const struct of_device_id ina3221_of_match_table[] = {
{ .compatible = "ruijie,rg_ina3221", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ina3221_of_match_table);
static const struct i2c_device_id ina3221_ids[] = {
{ "rg_ina3221", 0 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, ina3221_ids);
static struct i2c_driver ina3221_i2c_driver = {
.probe = ina3221_probe,
.driver = {
.name = INA3221_DRIVER_NAME,
.of_match_table = ina3221_of_match_table,
},
.id_table = ina3221_ids,
};
module_i2c_driver(ina3221_i2c_driver);
MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
MODULE_DESCRIPTION("Texas Instruments INA3221 HWMon Driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,574 @@
/*
* Copyright(C) 2022 Ruijie Network. All rights reserved.
*
* rg_io_dev.c
* ko to read/write ioports through /dev/XXX device
* Original Author: sonic_rd@ruijie.com.cn 2022-09-09
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/fs.h>
#include <linux/export.h>
#include <linux/uio.h>
#include "rg_io_dev.h"
#define PROXY_NAME "rg-io-dev"
#define MAX_IO_DEV_NUM (256)
#define IO_RDWR_MAX_LEN (256)
#define MAX_NAME_SIZE (20)
#define IO_INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff)
#define IO_INDIRECT_ADDR_L(addr) ((addr) & 0xff)
#define IO_INDIRECT_OP_WRITE (0x2)
#define IO_INDIRECT_OP_READ (0X3)
static int g_io_dev_debug = 0;
static int g_io_dev_error = 0;
module_param(g_io_dev_debug, int, S_IRUGO | S_IWUSR);
module_param(g_io_dev_error, int, S_IRUGO | S_IWUSR);
#define IO_DEV_DEBUG_VERBOSE(fmt, args...) do { \
if (g_io_dev_debug) { \
printk(KERN_INFO "[IO_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define IO_DEV_DEBUG_ERROR(fmt, args...) do { \
if (g_io_dev_error) { \
printk(KERN_ERR "[IO_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
typedef struct rg_io_dev_s {
const char *name;
uint32_t io_base;
uint32_t io_len;
uint32_t indirect_addr;
uint32_t wr_data;
uint32_t addr_low;
uint32_t addr_high;
uint32_t rd_data;
uint32_t opt_ctl;
spinlock_t io_dev_lock;
struct miscdevice misc;
} rg_io_dev_t;
static rg_io_dev_t* io_dev_arry[MAX_IO_DEV_NUM];
static int io_dev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
rg_io_dev_t *rg_io_dev;
if (minor >= MAX_IO_DEV_NUM) {
IO_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor);
return -ENODEV;
}
rg_io_dev = io_dev_arry[minor];
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("rg_io_dev is NULL, open failed, minor = %d\n", minor);
return -ENODEV;
}
file->private_data = rg_io_dev;
return 0;
}
static int io_dev_release(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return 0;
}
uint8_t io_indirect_addressing_read(rg_io_dev_t *rg_io_dev, uint32_t address)
{
uint8_t addr_l, addr_h, value;
unsigned long flags;
addr_h = IO_INDIRECT_ADDR_H(address);
addr_l = IO_INDIRECT_ADDR_L(address);
IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x\n", address);
spin_lock_irqsave(&rg_io_dev->io_dev_lock, flags);
outb(addr_l, rg_io_dev->io_base + rg_io_dev->addr_low);
outb(addr_h, rg_io_dev->io_base + rg_io_dev->addr_high);
outb(IO_INDIRECT_OP_READ, rg_io_dev->io_base + rg_io_dev->opt_ctl);
value = inb(rg_io_dev->io_base + rg_io_dev->rd_data);
spin_unlock_irqrestore(&rg_io_dev->io_dev_lock, flags);
return value;
}
static int io_dev_read_tmp(rg_io_dev_t *rg_io_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int i;
if (offset > rg_io_dev->io_len) {
IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, rg_io_dev->io_len);
return 0;
}
if (count > rg_io_dev->io_len - offset) {
IO_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n",
count, rg_io_dev->io_len - offset);
count = rg_io_dev->io_len - offset;
}
if (rg_io_dev->indirect_addr) {
for (i = 0; i < count; i++) {
buf[i] = io_indirect_addressing_read(rg_io_dev, offset + i);
}
} else {
for (i = 0; i < count; i++) {
buf[i] = inb(rg_io_dev->io_base + offset + i);
}
}
return count;
}
static ssize_t io_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
rg_io_dev_t *rg_io_dev;
int ret, read_len;
u8 buf_tmp[IO_RDWR_MAX_LEN];
rg_io_dev = file->private_data;
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("rg_io_dev is NULL, read failed.\n");
return -EINVAL;
}
if (count == 0) {
IO_DEV_DEBUG_ERROR("Invalid params, read count is 0.n");
return -EINVAL;
}
if (count > sizeof(buf_tmp)) {
IO_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp));
count = sizeof(buf_tmp);
}
memset(buf_tmp, 0, sizeof(buf_tmp));
read_len = io_dev_read_tmp(rg_io_dev, *offset, buf_tmp, count);
if (read_len < 0) {
IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len);
return read_len;
}
if (access_ok(buf, read_len)) {
IO_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
if (copy_to_user(buf, buf_tmp, read_len)) {
IO_DEV_DEBUG_ERROR("copy_to_user failed.\n");
return -EFAULT;
}
} else {
IO_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
memcpy(buf, buf_tmp, read_len);
}
*offset += read_len;
ret = read_len;
return ret;
}
static ssize_t io_dev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
int ret;
IO_DEV_DEBUG_VERBOSE("io_dev_read_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, to->count, iocb->ki_pos);
ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos);
return ret;
}
void io_indirect_addressing_write(rg_io_dev_t *rg_io_dev, uint32_t address, uint8_t reg_val)
{
uint8_t addr_l, addr_h;
unsigned long flags;
addr_h = IO_INDIRECT_ADDR_H(address);
addr_l = IO_INDIRECT_ADDR_L(address);
IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x\n", address);
spin_lock_irqsave(&rg_io_dev->io_dev_lock, flags);
outb(reg_val, rg_io_dev->io_base + rg_io_dev->wr_data);
outb(addr_l, rg_io_dev->io_base + rg_io_dev->addr_low);
outb(addr_h, rg_io_dev->io_base + rg_io_dev->addr_high);
outb(IO_INDIRECT_OP_WRITE, rg_io_dev->io_base + rg_io_dev->opt_ctl);
spin_unlock_irqrestore(&rg_io_dev->io_dev_lock, flags);
return;
}
static int io_dev_write_tmp(rg_io_dev_t *rg_io_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int i;
if (offset > rg_io_dev->io_len) {
IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, rg_io_dev->io_len);
return 0;
}
if (count > rg_io_dev->io_len - offset) {
IO_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n",
count, rg_io_dev->io_len - offset);
count = rg_io_dev->io_len - offset;
}
if (rg_io_dev->indirect_addr) {
for (i = 0; i < count; i++) {
io_indirect_addressing_write(rg_io_dev, offset + i, buf[i]);
}
} else {
for (i = 0; i < count; i++) {
outb(buf[i], rg_io_dev->io_base + offset + i);
}
}
return count;
}
static ssize_t io_dev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
rg_io_dev_t *rg_io_dev;
int write_len;
u8 buf_tmp[IO_RDWR_MAX_LEN];
rg_io_dev = file->private_data;
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("rg_io_dev is NULL, write failed.\n");
return -EINVAL;
}
if (count == 0) {
IO_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n");
return -EINVAL;
}
if (count > sizeof(buf_tmp)) {
IO_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp));
count = sizeof(buf_tmp);
}
memset(buf_tmp, 0, sizeof(buf_tmp));
if (access_ok(buf, count)) {
IO_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
if (copy_from_user(buf_tmp, buf, count)) {
IO_DEV_DEBUG_ERROR("copy_from_user failed.\n");
return -EFAULT;
}
} else {
IO_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
memcpy(buf_tmp, buf, count);
}
write_len = io_dev_write_tmp(rg_io_dev, *offset, buf_tmp, count);
if (write_len < 0) {
IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len);
return write_len;
}
*offset += write_len;
return write_len;
}
static ssize_t io_dev_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
int ret;
IO_DEV_DEBUG_VERBOSE("io_dev_write_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, from->count, iocb->ki_pos);
ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos);
return ret;
}
static loff_t io_dev_llseek(struct file *file, loff_t offset, int origin)
{
loff_t ret = 0;
rg_io_dev_t *rg_io_dev;
rg_io_dev = file->private_data;
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("rg_io_dev is NULL, llseek failed.\n");
return -EINVAL;
}
switch (origin) {
case SEEK_SET:
if (offset < 0) {
IO_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset);
ret = -EINVAL;
break;
}
if (offset > rg_io_dev->io_len) {
IO_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, io_len:0x%x.\n",
offset, rg_io_dev->io_len);
ret = - EINVAL;
break;
}
file->f_pos = offset;
ret = file->f_pos;
break;
case SEEK_CUR:
if (((file->f_pos + offset) > rg_io_dev->io_len) || ((file->f_pos + offset) < 0)) {
IO_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, io_len:0x%x.\n",
file->f_pos, offset, rg_io_dev->io_len);
ret = - EINVAL;
break;
}
file->f_pos += offset;
ret = file->f_pos;
break;
default:
IO_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin);
ret = -EINVAL;
break;
}
return ret;
}
static long io_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
static const struct file_operations io_dev_fops = {
.owner = THIS_MODULE,
.llseek = io_dev_llseek,
.read_iter = io_dev_read_iter,
.write_iter = io_dev_write_iter,
.unlocked_ioctl = io_dev_ioctl,
.open = io_dev_open,
.release = io_dev_release,
};
static rg_io_dev_t *dev_match(const char *path)
{
rg_io_dev_t *rg_io_dev;
char dev_name[MAX_NAME_SIZE];
int i;
for (i = 0; i < MAX_IO_DEV_NUM; i++) {
if (io_dev_arry[i] == NULL) {
continue;
}
rg_io_dev = io_dev_arry[i];
snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", rg_io_dev->name);
if (!strcmp(path, dev_name)) {
IO_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i);
return rg_io_dev;
}
}
return NULL;
}
int io_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
rg_io_dev_t *rg_io_dev;
int read_len;
if (path == NULL) {
IO_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if (buf == NULL) {
IO_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
rg_io_dev = dev_match(path);
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("io_dev match failed. dev path = %s", path);
return -EINVAL;
}
read_len = io_dev_read_tmp(rg_io_dev, offset, buf, count);
if (read_len < 0) {
IO_DEV_DEBUG_ERROR("io_dev_read_tmp failed, ret:%d.\n", read_len);
}
return read_len;
}
EXPORT_SYMBOL(io_device_func_read);
int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
rg_io_dev_t *rg_io_dev;
int write_len;
if (path == NULL) {
IO_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if (buf == NULL) {
IO_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
rg_io_dev = dev_match(path);
if (rg_io_dev == NULL) {
IO_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path);
return -EINVAL;
}
write_len = io_dev_write_tmp(rg_io_dev, offset, buf, count);
if (write_len < 0) {
IO_DEV_DEBUG_ERROR("io_dev_write_tmp failed, ret:%d.\n", write_len);
}
return write_len;
}
EXPORT_SYMBOL(io_device_func_write);
static int io_dev_probe(struct platform_device *pdev)
{
int ret;
rg_io_dev_t *rg_io_dev;
struct miscdevice *misc;
io_dev_device_t *io_dev_device;
rg_io_dev = devm_kzalloc(&pdev->dev, sizeof(rg_io_dev_t), GFP_KERNEL);
if (!rg_io_dev) {
dev_err(&pdev->dev, "devm_kzalloc failed.\n");
ret = -ENOMEM;
return ret;
}
spin_lock_init(&rg_io_dev->io_dev_lock);
if (pdev->dev.of_node) {
ret = 0;
ret += of_property_read_string(pdev->dev.of_node, "io_dev_name", &rg_io_dev->name);
ret += of_property_read_u32(pdev->dev.of_node, "io_base", &rg_io_dev->io_base);
ret += of_property_read_u32(pdev->dev.of_node, "io_len", &rg_io_dev->io_len);
if (of_property_read_bool(pdev->dev.of_node, "indirect_addr")) {
rg_io_dev->indirect_addr = 1;
ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &rg_io_dev->wr_data);
ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &rg_io_dev->addr_low);
ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &rg_io_dev->addr_high);
ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &rg_io_dev->rd_data);
ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &rg_io_dev->opt_ctl);
} else {
rg_io_dev->indirect_addr = 0;
}
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret);
return -ENXIO;
}
} else {
if (pdev->dev.platform_data == NULL) {
dev_err(&pdev->dev, "Failed to get platform data config.\n");
return -ENXIO;
}
io_dev_device = pdev->dev.platform_data;
rg_io_dev->name = io_dev_device->io_dev_name;
rg_io_dev->io_base = io_dev_device->io_base;
rg_io_dev->io_len = io_dev_device->io_len;
rg_io_dev->indirect_addr = io_dev_device->indirect_addr;
if (rg_io_dev->indirect_addr == 1) {
rg_io_dev->wr_data = io_dev_device->wr_data;
rg_io_dev->addr_low = io_dev_device->addr_low;
rg_io_dev->addr_high = io_dev_device->addr_high;
rg_io_dev->rd_data = io_dev_device->rd_data;
rg_io_dev->opt_ctl = io_dev_device->opt_ctl;
}
}
IO_DEV_DEBUG_VERBOSE("name:%s, io base:0x%x, io len:0x%x, addressing type:%s.\n",
rg_io_dev->name, rg_io_dev->io_base, rg_io_dev->io_len,
rg_io_dev->indirect_addr ? "indirect" : "direct");
misc = &rg_io_dev->misc;
misc->minor = MISC_DYNAMIC_MINOR;
misc->name = rg_io_dev->name;
misc->fops = &io_dev_fops;
misc->mode = 0666;
if (misc_register(misc) != 0) {
dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name);
return -ENXIO;
}
if (misc->minor >= MAX_IO_DEV_NUM) {
dev_err(&pdev->dev, "Error: device minor[%d] more than max io device num[%d].\n",
misc->minor, MAX_IO_DEV_NUM);
misc_deregister(misc);
return -EINVAL;
}
io_dev_arry[misc->minor] = rg_io_dev;
dev_info(&pdev->dev, "register %s device [0x%x][0x%x] with minor %d using %s addressing success.\n",
misc->name, rg_io_dev->io_base, rg_io_dev->io_len, misc->minor,
rg_io_dev->indirect_addr ? "indirect" : "direct");
return 0;
}
static int io_dev_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < MAX_IO_DEV_NUM ; i++) {
if (io_dev_arry[i] != NULL) {
misc_deregister(&io_dev_arry[i]->misc);
io_dev_arry[i] = NULL;
}
}
return 0;
}
static struct of_device_id io_dev_match[] = {
{
.compatible = "ruijie,rg-io-dev",
},
{},
};
MODULE_DEVICE_TABLE(of, io_dev_match);
static struct platform_driver rg_io_dev_driver = {
.probe = io_dev_probe,
.remove = io_dev_remove,
.driver = {
.owner = THIS_MODULE,
.name = PROXY_NAME,
.of_match_table = io_dev_match,
},
};
static int __init rg_io_dev_init(void)
{
return platform_driver_register(&rg_io_dev_driver);
}
static void __exit rg_io_dev_exit(void)
{
platform_driver_unregister(&rg_io_dev_driver);
}
module_init(rg_io_dev_init);
module_exit(rg_io_dev_exit);
MODULE_DESCRIPTION("IO device driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,19 @@
#ifndef __RG_IO_DEV_H__
#define __RG_IO_DEV_H__
#define IO_DEV_NAME_MAX_LEN (64)
typedef struct io_dev_device_s {
char io_dev_name[IO_DEV_NAME_MAX_LEN];
uint32_t io_base;
uint32_t io_len;
uint32_t indirect_addr;
uint32_t wr_data;
uint32_t addr_low;
uint32_t addr_high;
uint32_t rd_data;
uint32_t opt_ctl;
int device_flag;
} io_dev_device_t;
#endif

View File

@@ -0,0 +1,169 @@
/*
* Copyright(C) 2016 Ruijie Network. All rights reserved.
*
* rg_lpc_drv.c
* ko to set lpc pcie config io addr and enable lpc
* Original Author: sonic_rd@ruijie.com.cn 2020-08-14
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include "rg_lpc_drv.h"
#define LPC_DRIVER_NAME "rg-lpc"
#define LPC_MAKE_PCI_IO_RANGE(__base) ((0xfc0001) | ((__base) & (0xFFFC)))
int g_lpc_dev_debug = 0;
int g_lpc_dev_error = 0;
module_param(g_lpc_dev_debug, int, S_IRUGO | S_IWUSR);
module_param(g_lpc_dev_error, int, S_IRUGO | S_IWUSR);
#define LPC_DEV_DEBUG_VERBOSE(fmt, args...) do { \
if (g_lpc_dev_debug) { \
printk(KERN_INFO "[LPC_DEV][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define LPC_DEV_DEBUG_ERROR(fmt, args...) do { \
if (g_lpc_dev_error) { \
printk(KERN_ERR "[LPC_DEV][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
typedef struct rg_lpc_dev_s {
const char *lpc_io_name;
uint32_t domain;
uint32_t bus;
uint32_t slot;
uint32_t fn;
uint32_t lpc_io_base;
uint32_t lpc_io_size;
uint32_t lpc_gen_dec;
} rg_lpc_dev_t;
static int rg_lpc_probe(struct platform_device *pdev)
{
int ret, devfn;
rg_lpc_dev_t *rg_lpc_dev;
struct pci_dev *pci_dev;
lpc_drv_device_t *lpc_drv_device;
rg_lpc_dev = devm_kzalloc(&pdev->dev, sizeof(rg_lpc_dev_t), GFP_KERNEL);
if (!rg_lpc_dev) {
dev_err(&pdev->dev, "devm_kzalloc failed.\n");
ret = -ENOMEM;
return ret;
}
if (pdev->dev.of_node) {
ret = 0;
ret += of_property_read_string(pdev->dev.of_node, "lpc_io_name", &rg_lpc_dev->lpc_io_name);
ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &rg_lpc_dev->domain);
ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &rg_lpc_dev->bus);
ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &rg_lpc_dev->slot);
ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &rg_lpc_dev->fn);
ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_base", &rg_lpc_dev->lpc_io_base);
ret += of_property_read_u32(pdev->dev.of_node, "lpc_io_size", &rg_lpc_dev->lpc_io_size);
ret += of_property_read_u32(pdev->dev.of_node, "lpc_gen_dec", &rg_lpc_dev->lpc_gen_dec);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret);
return -ENXIO;
}
} else {
if (pdev->dev.platform_data == NULL) {
dev_err(&pdev->dev, "Failed to get platform data config.\n");
return -ENXIO;
}
lpc_drv_device = pdev->dev.platform_data;
rg_lpc_dev->lpc_io_name = lpc_drv_device->lpc_io_name;
rg_lpc_dev->domain = lpc_drv_device->pci_domain;
rg_lpc_dev->bus = lpc_drv_device->pci_bus;
rg_lpc_dev->slot = lpc_drv_device->pci_slot;
rg_lpc_dev->fn = lpc_drv_device->pci_fn;
rg_lpc_dev->lpc_io_base = lpc_drv_device->lpc_io_base;
rg_lpc_dev->lpc_io_size = lpc_drv_device->lpc_io_size;
rg_lpc_dev->lpc_gen_dec = lpc_drv_device->lpc_gen_dec;
}
LPC_DEV_DEBUG_VERBOSE("domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u\n",
rg_lpc_dev->domain,rg_lpc_dev->bus, rg_lpc_dev->slot, rg_lpc_dev->fn);
LPC_DEV_DEBUG_VERBOSE("lpc_io_name:%s, lpc_io_base:0x%x, lpc_io_size:%u, lpc_gen_dec:0x%x.\n",
rg_lpc_dev->lpc_io_name, rg_lpc_dev->lpc_io_base, rg_lpc_dev->lpc_io_size, rg_lpc_dev->lpc_gen_dec);
devfn = PCI_DEVFN(rg_lpc_dev->slot, rg_lpc_dev->fn);
pci_dev = pci_get_domain_bus_and_slot(rg_lpc_dev->domain, rg_lpc_dev->bus, devfn);
if (pci_dev == NULL) {
dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n",
rg_lpc_dev->domain, rg_lpc_dev->bus, devfn);
return -ENXIO;
}
pci_write_config_dword(pci_dev, rg_lpc_dev->lpc_gen_dec, LPC_MAKE_PCI_IO_RANGE(rg_lpc_dev->lpc_io_base));
if (!request_region(rg_lpc_dev->lpc_io_base, rg_lpc_dev->lpc_io_size, rg_lpc_dev->lpc_io_name)) {
dev_err(&pdev->dev, "Failed to request_region [0x%x][0x%x].\n", rg_lpc_dev->lpc_io_base, rg_lpc_dev->lpc_io_size);
return -EBUSY;
}
platform_set_drvdata(pdev, rg_lpc_dev);
dev_info(&pdev->dev, "lpc request_region [0x%x][0x%x] success.\n", rg_lpc_dev->lpc_io_base, rg_lpc_dev->lpc_io_size);
return 0;
}
static int rg_lpc_remove(struct platform_device *pdev)
{
rg_lpc_dev_t *rg_lpc_dev;
rg_lpc_dev = platform_get_drvdata(pdev);
if (rg_lpc_dev) {
release_region(rg_lpc_dev->lpc_io_base , rg_lpc_dev->lpc_io_size);
LPC_DEV_DEBUG_VERBOSE("lpc base:0x%x, len:0x%x.\n", rg_lpc_dev->lpc_io_base, rg_lpc_dev->lpc_io_size);
}
LPC_DEV_DEBUG_VERBOSE("lpc remove.\n");
return 0;
}
static struct of_device_id lpc_dev_match[] = {
{
.compatible = "ruijie,rg-lpc",
},
{},
};
MODULE_DEVICE_TABLE(of, lpc_dev_match);
static struct platform_driver rg_lpc_driver = {
.probe = rg_lpc_probe,
.remove = rg_lpc_remove,
.driver = {
.owner = THIS_MODULE,
.name = LPC_DRIVER_NAME,
.of_match_table = lpc_dev_match,
},
};
static int __init rg_lpc_init(void)
{
return platform_driver_register(&rg_lpc_driver);
}
static void __exit rg_lpc_exit(void)
{
platform_driver_unregister(&rg_lpc_driver);
}
module_init(rg_lpc_init);
module_exit(rg_lpc_exit);
MODULE_DESCRIPTION("lpc driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,18 @@
#ifndef __RG_LPC_DRV_H__
#define __RG_LPC_DRV_H__
#define LPC_IO_NAME_MAX_LEN (64)
typedef struct lpc_drv_device_s {
char lpc_io_name[LPC_IO_NAME_MAX_LEN];
int pci_domain;
int pci_bus;
int pci_slot;
int pci_fn;
int lpc_io_base;
int lpc_io_size;
int lpc_gen_dec;
int device_flag;
} lpc_drv_device_t;
#endif

View File

@@ -0,0 +1,658 @@
/*
* rg_mac_th3.c - A driver for control rg_mac_th3 base on rg_mac.c
*
* Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
* Copyright (c) 2018 ruijie <rd@ruijie.com.cn>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the 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/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#define MAC_TEMP_INVALID (99999999)
#define MAC_SIZE (256)
#define MAC_TEMP_NUM (16)
#define MAC_ID_REG (0x02000000)
typedef enum {
DBG_START,
DBG_VERBOSE,
DBG_KEY,
DBG_WARN,
DBG_ERROR,
DBG_END,
} dbg_level_t;
typedef enum{
MAC_TYPE_START,
TD4_X9 = 0xb780,
TD4_X9_8 = 0xb788,
TH3 = 0xb980,
TD3 = 0xb870,
TD4 = 0xb880,
TH4 = 0xb990,
MAC_TYPE_END,
} mac_type;
typedef struct sensor_regs_s {
int id;
u32 reg;
} sensor_reg_t;
typedef struct mac_temp_regs_s {
int mac_type;
sensor_reg_t sensor_reg[MAC_TEMP_NUM];
} mac_temp_reg_t;
typedef enum {
MAC_TEMP_START,
MAC_TEMP_INDEX1,
MAC_TEMP_INDEX2,
MAC_TEMP_INDEX3,
MAC_TEMP_INDEX4,
MAC_TEMP_INDEX5,
MAC_TEMP_INDEX6,
MAC_TEMP_INDEX7,
MAC_TEMP_INDEX8,
MAC_TEMP_INDEX9,
MAC_TEMP_INDEX10,
MAC_TEMP_INDEX11,
MAC_TEMP_INDEX12,
MAC_TEMP_INDEX13,
MAC_TEMP_INDEX14,
MAC_TEMP_INDEX15,
MAC_TEMP_END,
} mac_hwmon_index;
static mac_temp_reg_t mac_temp_reg[] = {
{
/* TD3 */
.mac_type = TD3,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x02004700},
{.id = MAC_TEMP_INDEX2, .reg = 0x02004800},
{.id = MAC_TEMP_INDEX3, .reg = 0x02004900},
{.id = MAC_TEMP_INDEX4, .reg = 0x02004a00},
{.id = MAC_TEMP_INDEX5, .reg = 0x02004b00},
{.id = MAC_TEMP_INDEX6, .reg = 0x02004c00},
{.id = MAC_TEMP_INDEX7, .reg = 0x02004d00},
{.id = MAC_TEMP_INDEX8, .reg = 0x02004e00},
{.id = MAC_TEMP_INDEX9, .reg = 0x02005200},
{.id = MAC_TEMP_INDEX10, .reg = 0x02005100},
{.id = MAC_TEMP_INDEX11, .reg = 0x02005000},
{.id = MAC_TEMP_INDEX12, .reg = 0x02004f00},
},
},
{
/* TD4 */
.mac_type = TD4,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x02004900},
{.id = MAC_TEMP_INDEX2, .reg = 0x02004b00},
{.id = MAC_TEMP_INDEX3, .reg = 0x02004d00},
{.id = MAC_TEMP_INDEX4, .reg = 0x02004f00},
{.id = MAC_TEMP_INDEX5, .reg = 0x02005100},
{.id = MAC_TEMP_INDEX6, .reg = 0x02005300},
{.id = MAC_TEMP_INDEX7, .reg = 0x02005500},
{.id = MAC_TEMP_INDEX8, .reg = 0x02005700},
{.id = MAC_TEMP_INDEX9, .reg = 0x02005900},
{.id = MAC_TEMP_INDEX10, .reg = 0x02005b00},
{.id = MAC_TEMP_INDEX11, .reg = 0x02005d00},
{.id = MAC_TEMP_INDEX12, .reg = 0x02005f00},
{.id = MAC_TEMP_INDEX13, .reg = 0x02006100},
{.id = MAC_TEMP_INDEX14, .reg = 0x02006300},
{.id = MAC_TEMP_INDEX15, .reg = 0x02006500},
},
},
{
/* TD4_X9 */
.mac_type = TD4_X9,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x02005a00},
{.id = MAC_TEMP_INDEX2, .reg = 0x02005c00},
{.id = MAC_TEMP_INDEX3, .reg = 0x02005e00},
{.id = MAC_TEMP_INDEX4, .reg = 0x02006000},
{.id = MAC_TEMP_INDEX5, .reg = 0x02006200},
{.id = MAC_TEMP_INDEX6, .reg = 0x02006400},
{.id = MAC_TEMP_INDEX7, .reg = 0x02006600},
{.id = MAC_TEMP_INDEX8, .reg = 0x02006800},
{.id = MAC_TEMP_INDEX9, .reg = 0x02006a00},
},
},
{
/* TD4_X9_8 */
.mac_type = TD4_X9_8,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x02005a00},
{.id = MAC_TEMP_INDEX2, .reg = 0x02005c00},
{.id = MAC_TEMP_INDEX3, .reg = 0x02005e00},
{.id = MAC_TEMP_INDEX4, .reg = 0x02006000},
{.id = MAC_TEMP_INDEX5, .reg = 0x02006200},
{.id = MAC_TEMP_INDEX6, .reg = 0x02006400},
{.id = MAC_TEMP_INDEX7, .reg = 0x02006600},
{.id = MAC_TEMP_INDEX8, .reg = 0x02006800},
{.id = MAC_TEMP_INDEX9, .reg = 0x02006a00},
},
},
{
/* TH3 */
.mac_type = TH3,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x02004a00},
{.id = MAC_TEMP_INDEX2, .reg = 0x02004b00},
{.id = MAC_TEMP_INDEX3, .reg = 0x02004c00},
{.id = MAC_TEMP_INDEX4, .reg = 0x02004d00},
{.id = MAC_TEMP_INDEX5, .reg = 0x02004e00},
{.id = MAC_TEMP_INDEX6, .reg = 0x02004f00},
{.id = MAC_TEMP_INDEX7, .reg = 0x02005000},
{.id = MAC_TEMP_INDEX8, .reg = 0x02005100},
{.id = MAC_TEMP_INDEX9, .reg = 0x02005200},
{.id = MAC_TEMP_INDEX10, .reg = 0x02005300},
{.id = MAC_TEMP_INDEX11, .reg = 0x02005400},
{.id = MAC_TEMP_INDEX12, .reg = 0x02005500},
{.id = MAC_TEMP_INDEX13, .reg = 0x02005600},
{.id = MAC_TEMP_INDEX14, .reg = 0x02005700},
{.id = MAC_TEMP_INDEX15, .reg = 0x02005800},
},
},
{
/* TH4 */
.mac_type = TH4,
.sensor_reg = {
{.id = MAC_TEMP_INDEX1, .reg = 0x0201d800},
{.id = MAC_TEMP_INDEX2, .reg = 0x0201e000},
{.id = MAC_TEMP_INDEX3, .reg = 0x0201e800},
{.id = MAC_TEMP_INDEX4, .reg = 0x0201f000},
{.id = MAC_TEMP_INDEX5, .reg = 0x0201f800},
{.id = MAC_TEMP_INDEX6, .reg = 0x02020000},
{.id = MAC_TEMP_INDEX7, .reg = 0x02020800},
{.id = MAC_TEMP_INDEX8, .reg = 0x02021000},
{.id = MAC_TEMP_INDEX9, .reg = 0x02021800},
{.id = MAC_TEMP_INDEX10, .reg = 0x02022000},
{.id = MAC_TEMP_INDEX11, .reg = 0x02022800},
{.id = MAC_TEMP_INDEX12, .reg = 0x02023000},
{.id = MAC_TEMP_INDEX13, .reg = 0x02023800},
{.id = MAC_TEMP_INDEX14, .reg = 0x02024000},
{.id = MAC_TEMP_INDEX15, .reg = 0x02024800},
},
},
};
static int debuglevel = 0;
module_param(debuglevel, int, S_IRUGO | S_IWUSR);
static int mac_pcie_id = MAC_TYPE_START;
module_param(mac_pcie_id, int, S_IRUGO | S_IWUSR);
#define DBG_DEBUG(fmt, arg...) do { \
if ( debuglevel > DBG_START && debuglevel < DBG_ERROR) { \
printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} else if ( debuglevel >= DBG_ERROR ) { \
printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} else { } \
} while (0)
#define DBG_ERROR(fmt, arg...) do { \
if ( debuglevel > DBG_START) { \
printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \
} \
} while (0)
struct mac_data {
struct i2c_client *client;
struct device *hwmon_dev;
struct mutex update_lock;
u8 data[MAC_SIZE]; /* Register value */
};
static int rg_i2c_read_one_time(struct i2c_client *client, u8 *recv_buf, int size)
{
struct i2c_msg msgs[2];
int ret = 0;
if ((client == NULL) || (recv_buf == NULL)) {
DBG_DEBUG("i2c_client || recv_buf = NULL\r\n");
return -1;
}
memset(msgs, 0, sizeof(msgs));
msgs[0].buf = recv_buf;
msgs[0].len = size;
msgs[0].addr = client->addr;
msgs[0].flags |= I2C_M_RD;
ret = i2c_transfer(client->adapter, msgs, 1);
if (ret < 0) {
return ret;
}
DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d.\n", client->addr, size);
return 0;
}
static int rg_i2c_write_one_time(struct i2c_client *client, u8 *write_buf, int size)
{
struct i2c_msg msgs[2];
int ret = 0;
if ((client == NULL) || (write_buf == NULL)) {
DBG_DEBUG("i2c_client || write_buf = NULL\r\n");
return -1;
}
if ((size <= 0)) {
DBG_DEBUG("size invalid, size %d\n", size);
return -1;
}
memset(msgs, 0, sizeof(msgs));
msgs[0].len = size;
msgs[0].buf = write_buf;
msgs[0].addr = client->addr;
ret = i2c_transfer(client->adapter, msgs, 1);
if (ret < 0) {
return ret;
}
DBG_DEBUG("i2c_transfer, dev_addr 0x%x, size %d\n", client->addr, size);
return 0;
}
static u8 step2_buf1[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00};
static u8 step2_buf2[8] = {0x03, 0x21, 0x04, 0x0c, 0x2c, 0x38, 0x02, 0x00};
static u8 step2_buf3[8] = {0x03, 0x21, 0x04, 0x10, 0x02, 0x00, 0x4a, 0x00};
static u8 step2_buf4[8] = {0x03, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01};
static u8 step2_buf5[4] = {0x03, 0x21, 0x04, 0x08};
static u8 step2_buf6[4] = {0x03, 0x21, 0x04, 0x10};
static int getmac_register(struct i2c_client *client, u32 index, int *reg_value)
{
int i;
int ret = 0;
int value = 0;
unsigned char read_buf[8];
if (index == 0) {
DBG_ERROR("invalid index\n");
return -1;
}
step2_buf3[7] = index & 0xff;
step2_buf3[6] = (index >> 8) & 0xff;
step2_buf3[5] = (index >> 16) & 0xff;
step2_buf3[4] = (index >> 24) & 0xff;
ret = rg_i2c_write_one_time(client, step2_buf1, 8);
if (ret < 0) {
DBG_ERROR("write step2_buf1 failed, ret = %d\n", ret);
}
ret = rg_i2c_write_one_time(client, step2_buf2, 8);
if (ret < 0) {
DBG_ERROR("write step2_buf2 failed, ret = %d\n", ret);
}
ret = rg_i2c_write_one_time(client, step2_buf3, 8);
if (ret < 0) {
DBG_ERROR("write step2_buf3 failed, ret = %d\n", ret);
}
ret = rg_i2c_write_one_time(client, step2_buf4, 8);
if (ret < 0) {
DBG_ERROR("write step2_buf4 failed, ret = %d\n", ret);
}
ret = rg_i2c_write_one_time(client, step2_buf5, 4);
if (ret < 0) {
DBG_ERROR("write step2_buf5 failed, ret = %d\n", ret);
}
ret = rg_i2c_read_one_time(client, read_buf, 4);
if (ret < 0) {
DBG_ERROR("read failed, ret = %d\n", ret);
}
for (i = 0; i < 4; i++) {
DBG_DEBUG("read_buf[%d] = 0x%x \n", i, read_buf[i]);
}
ret = rg_i2c_write_one_time(client, step2_buf6, 4);
if (ret < 0) {
DBG_ERROR("write step2_buf6 failed, ret = %d\n", ret);
}
ret = rg_i2c_read_one_time(client, read_buf, 4);
if (ret < 0) {
DBG_ERROR("read failed, ret = %d\n", ret);
return ret;
}
value = (read_buf[0] << 24)| (read_buf[1] << 16) | (read_buf[2] << 8) | read_buf[3];
*reg_value = value;
return ret;
}
static int mac_calcute(u32 reg, int *temp)
{
int ret = 0;
u32 tmp = 0;
switch(mac_pcie_id) {
case TD3:
case TH3:
tmp = reg & 0x3ff;
*temp = 434100 - (tmp * 535);
break;
case TD4:
case TH4:
case TD4_X9:
case TD4_X9_8:
tmp = reg & 0x7ff;
*temp = (356070 - (tmp * 237));
break;
default:
ret = -1;
DBG_ERROR("read failed, ret = %d\n", ret);
break;
}
if ((*temp / 1000 < -70) || (*temp / 1000 > 200)) {
ret = -1;
DBG_ERROR("mac temp invalid, temp = %d\n", *temp );
}
return ret;
}
static int find_reg_type(int type, int *type_index)
{
int i;
int size;
size = ARRAY_SIZE(mac_temp_reg);
for (i = 0; i < size; i++) {
if (mac_temp_reg[i].mac_type == type) {
*type_index = i;
return 0;
}
}
return -1;
}
static sensor_reg_t * find_reg_offset(int type, int index)
{
int i;
int type_index;
int ret;
ret = find_reg_type(type, &type_index);
if (ret < 0) {
DBG_ERROR("find_reg_type failed, ret = %d\n", ret);
return NULL;
}
for (i = 0; i < MAC_TEMP_NUM; i++) {
if (mac_temp_reg[type_index].sensor_reg[i].id == index) {
return &(mac_temp_reg[type_index].sensor_reg[i]);
}
}
return NULL;
}
static int get_mactemp(struct i2c_client *client, int index, int *temp)
{
int ret;
int reg_value;
if (index == 0) {
DBG_ERROR("invalid index\n");
return -1;
}
ret = getmac_register(client, index, &reg_value);
if (ret < 0) {
DBG_ERROR("getmac_register failed, ret = %d\n", ret);
return ret;
}
DBG_DEBUG("reg_value = 0x%x \n", reg_value);
ret = mac_calcute(reg_value, temp);
if (ret < 0) {
DBG_ERROR("mac_calcute failed, ret = %d\n", ret);
return ret;
}
return 0;
}
static ssize_t show_mac_temp(struct device *dev, struct device_attribute *da, char *buf)
{
struct mac_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
u32 index_value = to_sensor_dev_attr_2(da)->index;
sensor_reg_t *t;
int result = 0;
int temp = -MAC_TEMP_INVALID;
mutex_lock(&data->update_lock);
t = find_reg_offset(mac_pcie_id, index_value);
if (t == NULL) {
temp = -MAC_TEMP_INVALID;
DBG_ERROR("find_reg_offset failed, mac_pcie_id = %d, index_value = %d\n", mac_pcie_id, index_value);
} else {
result = get_mactemp(client, t->reg, &temp);
if (result < 0) {
temp = -MAC_TEMP_INVALID;
DBG_ERROR("get_mactemp failed, ret = %d\n", result);
}
}
mutex_unlock(&data->update_lock);
return snprintf(buf, MAC_SIZE, "%d\n", temp);
}
static ssize_t show_mac_max_temp(struct device *dev, struct device_attribute *da, char *buf)
{
struct mac_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int i;
int result;
int temp = -MAC_TEMP_INVALID;
int type_index;
int tmp;
mutex_lock(&data->update_lock);
result = find_reg_type(mac_pcie_id, &type_index);
if (result < 0) {
DBG_ERROR("find_reg_type failed, ret = %d\n", result);
goto exit;
}
for (i = 0; i < MAC_TEMP_NUM; i++) {
result = get_mactemp(client, mac_temp_reg[type_index].sensor_reg[i].reg, &tmp);
if (result < 0) {
DBG_ERROR("get_mactemp failed, ret = %d\n", result);
tmp = -MAC_TEMP_INVALID;
}
temp = (temp > tmp) ? temp : tmp;
}
exit:
mutex_unlock(&data->update_lock);
return snprintf(buf, MAC_SIZE, "%d\n", temp);
}
static int mac_bsc_init(struct i2c_client *client)
{
int ret;
int reg_value;
int mac_id = 0;
ret = getmac_register(client, MAC_ID_REG, &reg_value);
if (ret < 0) {
DBG_ERROR("getmac_register failed, ret = %d\n", ret);
return ret;
}
DBG_DEBUG("reg_value = 0x%x \n", reg_value);
mac_id = reg_value & 0xffff;
return mac_id;
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX1);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX2);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX3);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX4);
static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX5);
static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX6);
static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX7);
static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX8);
static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX9);
static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX10);
static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX11);
static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX12);
static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX13);
static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX14);
static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, show_mac_temp, NULL, MAC_TEMP_INDEX15);
static SENSOR_DEVICE_ATTR(temp99_input, S_IRUGO, show_mac_max_temp, NULL, 0);
static struct attribute *mac_hwmon_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp5_input.dev_attr.attr,
&sensor_dev_attr_temp6_input.dev_attr.attr,
&sensor_dev_attr_temp7_input.dev_attr.attr,
&sensor_dev_attr_temp8_input.dev_attr.attr,
&sensor_dev_attr_temp9_input.dev_attr.attr,
&sensor_dev_attr_temp10_input.dev_attr.attr,
&sensor_dev_attr_temp11_input.dev_attr.attr,
&sensor_dev_attr_temp12_input.dev_attr.attr,
&sensor_dev_attr_temp13_input.dev_attr.attr,
&sensor_dev_attr_temp14_input.dev_attr.attr,
&sensor_dev_attr_temp15_input.dev_attr.attr,
&sensor_dev_attr_temp99_input.dev_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(mac_hwmon);
static int init_bcs_command(int mac_type) {
int ret;
ret = 0;
switch (mac_type) {
case TD3:
step2_buf2[5] = 0x38;
break;
case TH3:
case TH4:
case TD4:
case TD4_X9:
case TD4_X9_8:
step2_buf2[5] = 0x40;
break;
default:
ret = -1;
break;
}
return ret;
}
static int mac_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct mac_data *data;
int mac_type;
int ret;
mac_type = id->driver_data;
mac_pcie_id = mac_type;
if (init_bcs_command(mac_type) < 0) {
DBG_ERROR("mactype[%x] not support \n", mac_type);
return -1;
};
if (mac_type == TD4) {
ret = mac_bsc_init(client);
if (ret < 0) {
DBG_ERROR("mac_bsc_init failed, ret = %d\n", ret);
return -1;
}
mac_type = ret;
mac_pcie_id = mac_type;
}
DBG_DEBUG("=========mac_probe(%x)===========\n",client->addr);
DBG_DEBUG("mac_type: %x\n", mac_type);
data = devm_kzalloc(&client->dev, sizeof(struct mac_data), GFP_KERNEL);
if (!data) {
return -ENOMEM;
}
data->client = client;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, mac_hwmon_groups);
if (IS_ERR(data->hwmon_dev)) {
return PTR_ERR(data->hwmon_dev);
}
return 0;
}
static int mac_remove(struct i2c_client *client)
{
struct mac_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
return 0;
}
static const struct i2c_device_id mac_id[] = {
{ "rg_mac_bsc_td3", TD3 },
{ "rg_mac_bsc_td4", TD4 },
{ "rg_mac_bsc_th3", TH3 },
{ "rg_mac_bsc_th4", TH4 },
{}
};
MODULE_DEVICE_TABLE(i2c, mac_id);
static struct i2c_driver rg_mac_bsc_driver = {
.driver = {
.name = "rg_mac_bsc",
},
.probe = mac_probe,
.remove = mac_remove,
.id_table = mac_id,
};
module_i2c_driver(rg_mac_bsc_driver);
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");
MODULE_DESCRIPTION("ruijie mac bsc driver");
MODULE_LICENSE("GPL");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,773 @@
/*
* Copyright(C) 2022 Ruijie Network. All rights reserved.
*
* rg_pcie_dev.c
* ko to read/write pcie iomem and ioports through /dev/XXX device
* Original Author: sonic_rd@ruijie.com.cn 2022-09-09
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/uio.h>
#include "rg_pcie_dev.h"
#define PROXY_NAME "rg-pci-dev"
#define MAX_NAME_SIZE (20)
#define MAX_PCIE_NUM (256)
#define PCI_RDWR_MAX_LEN (256)
#define PCIE_BUS_WIDTH_1 (1)
#define PCIE_BUS_WIDTH_2 (2)
#define PCIE_BUS_WIDTH_4 (4)
static int g_pcie_dev_debug = 0;
static int g_pcie_dev_error = 0;
module_param(g_pcie_dev_debug, int, S_IRUGO | S_IWUSR);
module_param(g_pcie_dev_error, int, S_IRUGO | S_IWUSR);
#define PCIE_DEV_DEBUG_VERBOSE(fmt, args...) do { \
if (g_pcie_dev_debug) { \
printk(KERN_INFO "[PCIE_DEV][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
#define PCIE_DEV_DEBUG_ERROR(fmt, args...) do { \
if (g_pcie_dev_error) { \
printk(KERN_ERR "[PCIE_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \
} \
} while (0)
typedef struct firmware_upg_s {
int upg_ctrl_base;
int upg_flash_base;
} firmware_upg_t;
typedef struct rg_pci_dev_s {
const char *name;
uint32_t domain;
uint32_t bus;
uint32_t slot;
uint32_t fn;
uint32_t bar;
void __iomem *pci_mem_base;
uint32_t pci_io_base;
uint32_t bar_len;
uint32_t bar_flag;
uint32_t bus_width;
struct miscdevice misc;
void (*setreg)(struct rg_pci_dev_s *rg_pci_dev, int reg, u32 value);
u32 (*getreg)(struct rg_pci_dev_s *rg_pci_dev, int reg);
firmware_upg_t firmware_upg;
} rg_pci_dev_t;
static rg_pci_dev_t* pcie_dev_arry[MAX_PCIE_NUM];
static void pci_dev_setreg_8(rg_pci_dev_t *rg_pci_dev, int reg, u32 value)
{
u8 w_value;
w_value = (u8)(value & 0xff);
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
writeb(w_value, rg_pci_dev->pci_mem_base + reg);
} else {
outb(w_value, rg_pci_dev->pci_io_base + reg);
}
return;
}
static void pci_dev_setreg_16(rg_pci_dev_t *rg_pci_dev, int reg, u32 value)
{
u16 w_value;
w_value = (u16)(value & 0xffff);
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
writew(w_value, rg_pci_dev->pci_mem_base + reg);
} else {
outw(w_value, rg_pci_dev->pci_io_base + reg);
}
return;
}
static void pci_dev_setreg_32(rg_pci_dev_t *rg_pci_dev, int reg, u32 value)
{
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
writel(value, rg_pci_dev->pci_mem_base + reg);
} else {
outl(value, rg_pci_dev->pci_io_base + reg);
}
return;
}
static inline u32 pci_dev_getreg_8(rg_pci_dev_t *rg_pci_dev, int reg)
{
u32 value;
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
value = readb(rg_pci_dev->pci_mem_base + reg);
} else {
value = inb(rg_pci_dev->pci_io_base + reg);
}
return value;
}
static inline u32 pci_dev_getreg_16(rg_pci_dev_t *rg_pci_dev, int reg)
{
u32 value;
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
value = readw(rg_pci_dev->pci_mem_base + reg);
} else {
value = inw(rg_pci_dev->pci_io_base + reg);
}
return value;
}
static inline u32 pci_dev_getreg_32(rg_pci_dev_t *rg_pci_dev, int reg)
{
u32 value;
if (rg_pci_dev->bar_flag == IORESOURCE_MEM) {
value = readl(rg_pci_dev->pci_mem_base + reg);
} else {
value = inl(rg_pci_dev->pci_io_base + reg);
}
return value;
}
static inline void pci_dev_setreg(rg_pci_dev_t *rg_pci_dev, int reg, u32 value)
{
rg_pci_dev->setreg(rg_pci_dev, reg, value);
}
static inline u32 pci_dev_getreg(rg_pci_dev_t *rg_pci_dev, int reg)
{
return rg_pci_dev->getreg(rg_pci_dev, reg);
}
static int pci_dev_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
rg_pci_dev_t *rg_pci_dev;
PCIE_DEV_DEBUG_VERBOSE("inode: %p, file: %p, minor: %u", inode, file, minor);
if (minor >= MAX_PCIE_NUM) {
PCIE_DEV_DEBUG_ERROR("minor out of range, minor = %d.\n", minor);
return -ENODEV;
}
rg_pci_dev = pcie_dev_arry[minor];
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("rg_pci_dev is NULL, open failed, minor = %d\n", minor);
return -ENODEV;
}
file->private_data = rg_pci_dev;
return 0;
}
static int pci_dev_release(struct inode *inode, struct file *file)
{
file->private_data = NULL;
return 0;
}
static int pci_dev_read_tmp(rg_pci_dev_t *rg_pci_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int width, i, j;
u32 val;
if (offset > rg_pci_dev->bar_len) {
PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, rg_pci_dev->bar_len);
return 0;
}
width = rg_pci_dev->bus_width;
if (offset % width) {
PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
if (count > rg_pci_dev->bar_len - offset) {
PCIE_DEV_DEBUG_VERBOSE("read count out of range. input len:%lu, read len:%u.\n",
count, rg_pci_dev->bar_len - offset);
count = rg_pci_dev->bar_len - offset;
}
for (i = 0; i < count; i += width) {
val = pci_dev_getreg(rg_pci_dev, offset + i);
for (j = 0; (j < width) && (i + j < count); j++) {
buf[i + j] = (val >> (8 * j)) & 0xff;
}
}
return count;
}
static ssize_t pci_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
rg_pci_dev_t *rg_pci_dev;
int ret, read_len;
u8 buf_tmp[PCI_RDWR_MAX_LEN];
rg_pci_dev = file->private_data;
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("rg_pci_dev is NULL, read failed.\n");
return -EINVAL;
}
if (count == 0) {
PCIE_DEV_DEBUG_ERROR("Invalid params, read count is 0.n");
return -EINVAL;
}
if (count > sizeof(buf_tmp)) {
PCIE_DEV_DEBUG_VERBOSE("read conut %lu exceed max %lu.\n", count, sizeof(buf_tmp));
count = sizeof(buf_tmp);
}
memset(buf_tmp, 0, sizeof(buf_tmp));
read_len = pci_dev_read_tmp(rg_pci_dev, *offset, buf_tmp, count);
if (read_len < 0) {
PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len);
return read_len;
}
if (access_ok(buf, read_len)) {
PCIE_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
if (copy_to_user(buf, buf_tmp, read_len)) {
PCIE_DEV_DEBUG_ERROR("copy_to_user failed.\n");
return -EFAULT;
}
} else {
PCIE_DEV_DEBUG_VERBOSE("kernel space read, buf: %p, offset: %lld, read conut %lu.\n",
buf, *offset, count);
memcpy(buf, buf_tmp, read_len);
}
*offset += read_len;
ret = read_len;
return ret;
}
static ssize_t pci_dev_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
int ret;
PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, to->count, iocb->ki_pos);
ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos);
return ret;
}
static int pci_dev_write_tmp(rg_pci_dev_t *rg_pci_dev, uint32_t offset, uint8_t *buf, size_t count)
{
int width, i, j;
u32 val;
if (offset > rg_pci_dev->bar_len) {
PCIE_DEV_DEBUG_VERBOSE("offset:0x%x, bar len:0x%x, EOF.\n", offset, rg_pci_dev->bar_len);
return 0;
}
width = rg_pci_dev->bus_width;
if (offset % width) {
PCIE_DEV_DEBUG_ERROR("pci bus width:%d, offset:0x%x, read size %lu invalid.\n",
width, offset, count);
return -EINVAL;
}
if (count > rg_pci_dev->bar_len - offset) {
PCIE_DEV_DEBUG_VERBOSE("write count out of range. input len:%lu, write len:%u.\n",
count, rg_pci_dev->bar_len - offset);
count = rg_pci_dev->bar_len - offset;
}
for (i = 0; i < count; i += width) {
val = 0;
for (j = 0; (j < width) && (i + j < count); j++) {
val |= buf[i + j] << (8 * j);
}
pci_dev_setreg(rg_pci_dev, i + offset, val);
}
return count;
}
static ssize_t pci_dev_write(struct file *file, const char __user *buf, size_t count,
loff_t *offset)
{
rg_pci_dev_t *rg_pci_dev;
u8 buf_tmp[PCI_RDWR_MAX_LEN];
int write_len;
rg_pci_dev = file->private_data;
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("rg_pci_dev is NULL, write failed.\n");
return -EINVAL;
}
if (count == 0) {
PCIE_DEV_DEBUG_ERROR("Invalid params, write count is 0.\n");
return -EINVAL;
}
if (count > sizeof(buf_tmp)) {
PCIE_DEV_DEBUG_VERBOSE("write conut %lu exceed max %lu.\n", count, sizeof(buf_tmp));
count = sizeof(buf_tmp);
}
memset(buf_tmp, 0, sizeof(buf_tmp));
if (access_ok(buf, count)) {
PCIE_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
if (copy_from_user(buf_tmp, buf, count)) {
PCIE_DEV_DEBUG_ERROR("copy_from_user failed.\n");
return -EFAULT;
}
} else {
PCIE_DEV_DEBUG_VERBOSE("kernel space write, buf: %p, offset: %lld, write conut %lu.\n",
buf, *offset, count);
memcpy(buf_tmp, buf, count);
}
write_len = pci_dev_write_tmp(rg_pci_dev, *offset, buf_tmp, count);
if (write_len < 0) {
PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len);
return write_len;
}
*offset += write_len;
return write_len;
}
static ssize_t pci_dev_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
int ret;
PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_iter, file: %p, count: %lu, offset: %lld\n",
iocb->ki_filp, from->count, iocb->ki_pos);
ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos);
return ret;
}
static loff_t pci_dev_llseek(struct file *file, loff_t offset, int origin)
{
loff_t ret = 0;
rg_pci_dev_t *rg_pci_dev;
rg_pci_dev = file->private_data;
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("rg_pci_dev is NULL, llseek failed.\n");
return -EINVAL;
}
switch (origin) {
case SEEK_SET:
if (offset < 0) {
PCIE_DEV_DEBUG_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset);
ret = -EINVAL;
break;
}
if (offset > rg_pci_dev->bar_len) {
PCIE_DEV_DEBUG_ERROR("SEEK_SET out of range, offset:%lld, bar len:0x%x.\n",
offset, rg_pci_dev->bar_len);
ret = - EINVAL;
break;
}
file->f_pos = offset;
ret = file->f_pos;
break;
case SEEK_CUR:
if (((file->f_pos + offset) > rg_pci_dev->bar_len) || ((file->f_pos + offset) < 0)) {
PCIE_DEV_DEBUG_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld, bar len:0x%x.\n",
file->f_pos, offset, rg_pci_dev->bar_len);
ret = - EINVAL;
break;
}
file->f_pos += offset;
ret = file->f_pos;
break;
default:
PCIE_DEV_DEBUG_ERROR("unsupport llseek type:%d.\n", origin);
ret = -EINVAL;
break;
}
return ret;
}
static long pci_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
rg_pci_dev_t *rg_pci_dev;
void __user *argp;
firmware_upg_t *firmware_upg;
int upg_ctrl_base;
int upg_flash_base;
PCIE_DEV_DEBUG_VERBOSE("ioctl, cmd=0x%02x, arg=0x%02lx\n",cmd, arg);
rg_pci_dev = file->private_data;
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("rg_pci_dev is NULL, ioctl failed.\n");
return -EINVAL;
}
firmware_upg = &rg_pci_dev->firmware_upg;
argp = (void __user *)arg;
switch (cmd) {
case GET_FPGA_UPG_CTL_BASE:
if (firmware_upg->upg_ctrl_base < 0) {
PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_ctrl_base\n");
return -EFAULT;
} else {
upg_ctrl_base = firmware_upg->upg_ctrl_base;
if (copy_to_user(argp, &upg_ctrl_base, sizeof(upg_ctrl_base))) {
PCIE_DEV_DEBUG_ERROR("upg_ctrl_base copy_from_user failed\n");
return -EFAULT;
}
}
break;
case GET_FPGA_UPG_FLASH_BASE:
if (firmware_upg->upg_flash_base < 0) {
PCIE_DEV_DEBUG_ERROR("dts not adaptive upg_flash_base\n");
return -EFAULT;
} else {
upg_flash_base = firmware_upg->upg_flash_base;
if (copy_to_user(argp, &upg_flash_base, sizeof(upg_flash_base))) {
PCIE_DEV_DEBUG_ERROR("upg_flash_base copy_from_user failed\n");
return -EFAULT;
}
}
break;
default:
PCIE_DEV_DEBUG_ERROR("command unsupported \n");
return -ENOTTY;
}
return 0;
}
static const struct file_operations pcie_dev_fops = {
.owner = THIS_MODULE,
.llseek = pci_dev_llseek,
.read_iter = pci_dev_read_iter,
.write_iter = pci_dev_write_iter,
.unlocked_ioctl = pci_dev_ioctl,
.open = pci_dev_open,
.release = pci_dev_release,
};
static rg_pci_dev_t *dev_match(const char *path)
{
rg_pci_dev_t *rg_pci_dev;
char dev_name[MAX_NAME_SIZE];
int i;
for (i = 0; i < MAX_PCIE_NUM; i++) {
if (pcie_dev_arry[i] == NULL) {
continue;
}
rg_pci_dev = pcie_dev_arry[i];
snprintf(dev_name, MAX_NAME_SIZE,"/dev/%s", rg_pci_dev->name);
if (!strcmp(path, dev_name)) {
PCIE_DEV_DEBUG_VERBOSE("get dev_name = %s, minor = %d\n", dev_name, i);
return rg_pci_dev;
}
}
return NULL;
}
int pcie_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
rg_pci_dev_t *rg_pci_dev;
int read_len;
if (path == NULL) {
PCIE_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if (buf == NULL) {
PCIE_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
rg_pci_dev = dev_match(path);
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path);
return -EINVAL;
}
read_len = pci_dev_read_tmp(rg_pci_dev, offset, buf, count);
if (read_len < 0) {
PCIE_DEV_DEBUG_ERROR("pci_dev_read_tmp failed, ret:%d.\n", read_len);
}
return read_len;
}
EXPORT_SYMBOL(pcie_device_func_read);
int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count)
{
rg_pci_dev_t *rg_pci_dev;
int write_len;
if (path == NULL) {
PCIE_DEV_DEBUG_ERROR("path NULL");
return -EINVAL;
}
if (buf == NULL) {
PCIE_DEV_DEBUG_ERROR("buf NULL");
return -EINVAL;
}
rg_pci_dev = dev_match(path);
if (rg_pci_dev == NULL) {
PCIE_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path);
return -EINVAL;
}
write_len = pci_dev_write_tmp(rg_pci_dev, offset, buf, count);
if (write_len < 0) {
PCIE_DEV_DEBUG_ERROR("pci_dev_write_tmp failed, ret:%d.\n", write_len);
}
return write_len;
}
EXPORT_SYMBOL(pcie_device_func_write);
static int pci_setup_bars(rg_pci_dev_t *rg_pci_dev, struct pci_dev *dev)
{
int ret;
uint32_t addr, len, flags;
ret = 0;
addr = pci_resource_start(dev, rg_pci_dev->bar);
len = pci_resource_len(dev, rg_pci_dev->bar);
if (addr == 0 || len == 0) {
PCIE_DEV_DEBUG_ERROR("get bar addr failed. bar:%d, addr:0x%x, len:0x%x.\n",
rg_pci_dev->bar, addr, len);
return -EFAULT;
}
rg_pci_dev->bar_len = len;
flags = pci_resource_flags(dev, rg_pci_dev->bar);
PCIE_DEV_DEBUG_VERBOSE("bar:%d, flag:0x%08x, phys addr:0x%x, len:0x%x\n",
rg_pci_dev->bar, flags, addr, len);
if (flags & IORESOURCE_MEM) {
rg_pci_dev->bar_flag = IORESOURCE_MEM;
rg_pci_dev->pci_mem_base = ioremap(addr, len);
PCIE_DEV_DEBUG_VERBOSE("pci mem base:%p.\n", rg_pci_dev->pci_mem_base);
} else if (flags & IORESOURCE_IO) {
rg_pci_dev->bar_flag = IORESOURCE_IO;
rg_pci_dev->pci_io_base = addr;
PCIE_DEV_DEBUG_VERBOSE("pci io base:0x%x.\n", rg_pci_dev->pci_io_base);
} else {
PCIE_DEV_DEBUG_ERROR("unknow pci bar flag:0x%08x.\n", flags);
ret = -EINVAL;
}
return ret;
}
static int pci_dev_probe(struct platform_device *pdev)
{
int ret, devfn;
rg_pci_dev_t *rg_pci_dev;
struct pci_dev *pci_dev;
struct miscdevice *misc;
firmware_upg_t *firmware_upg;
pci_dev_device_t *pci_dev_device;
rg_pci_dev = devm_kzalloc(&pdev->dev, sizeof(rg_pci_dev_t), GFP_KERNEL);
if (!rg_pci_dev) {
dev_err(&pdev->dev, "devm_kzalloc failed.\n");
ret = -ENOMEM;
return ret;
}
firmware_upg = &rg_pci_dev->firmware_upg;
if (pdev->dev.of_node) {
ret = 0;
ret += of_property_read_string(pdev->dev.of_node, "pci_dev_name", &rg_pci_dev->name);
ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &rg_pci_dev->domain);
ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &rg_pci_dev->bus);
ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &rg_pci_dev->slot);
ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &rg_pci_dev->fn);
ret += of_property_read_u32(pdev->dev.of_node, "pci_bar", &rg_pci_dev->bar);
ret += of_property_read_u32(pdev->dev.of_node, "bus_width", &rg_pci_dev->bus_width);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get dts config, ret:%d.\n", ret);
return -ENXIO;
}
ret = 0;
ret += of_property_read_u32(pdev->dev.of_node, "upg_ctrl_base", &firmware_upg->upg_ctrl_base);
ret += of_property_read_u32(pdev->dev.of_node, "upg_flash_base", &firmware_upg->upg_flash_base);
if (ret != 0) {
PCIE_DEV_DEBUG_VERBOSE("dts don't adaptive fpga upg related, ret:%d.\n", ret);
firmware_upg->upg_ctrl_base = -1;
firmware_upg->upg_flash_base = -1;
} else {
PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n",
firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base);
}
} else {
if (pdev->dev.platform_data == NULL) {
dev_err(&pdev->dev, "Failed to get platform data config.\n");
return -ENXIO;
}
pci_dev_device = pdev->dev.platform_data;
rg_pci_dev->name = pci_dev_device->pci_dev_name;
rg_pci_dev->domain = pci_dev_device->pci_domain;
rg_pci_dev->bus = pci_dev_device->pci_bus;
rg_pci_dev->slot = pci_dev_device->pci_slot;
rg_pci_dev->fn = pci_dev_device->pci_fn;
rg_pci_dev->bar = pci_dev_device->pci_bar;
rg_pci_dev->bus_width = pci_dev_device->bus_width;
firmware_upg->upg_ctrl_base = pci_dev_device->upg_ctrl_base;
firmware_upg->upg_flash_base = pci_dev_device->upg_flash_base;
PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n",
firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base);
}
PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d.\n",
rg_pci_dev->name, rg_pci_dev->domain, rg_pci_dev->bus, rg_pci_dev->slot, rg_pci_dev->fn,
rg_pci_dev->bar, rg_pci_dev->bus_width);
devfn = PCI_DEVFN(rg_pci_dev->slot, rg_pci_dev->fn);
pci_dev = pci_get_domain_bus_and_slot(rg_pci_dev->domain, rg_pci_dev->bus, devfn);
if (pci_dev == NULL) {
dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n",
rg_pci_dev->domain, rg_pci_dev->bus, devfn);
return -ENXIO;
}
ret = pci_setup_bars(rg_pci_dev, pci_dev);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to get pci bar address.\n");
return ret;
}
if (!rg_pci_dev->setreg || !rg_pci_dev->getreg) {
switch (rg_pci_dev->bus_width) {
case 1:
rg_pci_dev->setreg = pci_dev_setreg_8;
rg_pci_dev->getreg = pci_dev_getreg_8;
break;
case 2:
rg_pci_dev->setreg = pci_dev_setreg_16;
rg_pci_dev->getreg = pci_dev_getreg_16;
break;
case 4:
rg_pci_dev->setreg = pci_dev_setreg_32;
rg_pci_dev->getreg = pci_dev_getreg_32;
break;
default:
dev_err(&pdev->dev, "Error: unsupported I/O width (%d).\n", rg_pci_dev->bus_width);
ret = -EINVAL;
goto io_unmap;
}
}
misc = &rg_pci_dev->misc;
misc->minor = MISC_DYNAMIC_MINOR;
misc->name = rg_pci_dev->name;
misc->fops = &pcie_dev_fops;
misc->mode = 0666;
if (misc_register(misc) != 0) {
dev_err(&pdev->dev, "Failed to register %s device.\n", misc->name);
ret = -ENXIO;
goto io_unmap;
}
if (misc->minor >= MAX_PCIE_NUM) {
dev_err(&pdev->dev, "Error: device minor[%d] more than max pcie num[%d].\n",
misc->minor, MAX_PCIE_NUM);
misc_deregister(misc);
ret = -EINVAL;
goto io_unmap;
}
pcie_dev_arry[misc->minor] = rg_pci_dev;
dev_info(&pdev->dev, "%04x:%02x:%02x.%d[bar%d: %s]: register %s device with minor:%d success.\n",
rg_pci_dev->domain, rg_pci_dev->bus, rg_pci_dev->slot, rg_pci_dev->fn, rg_pci_dev->bar,
rg_pci_dev->bar_flag == IORESOURCE_MEM ? "IORESOURCE_MEM" : "IORESOURCE_IO",
misc->name, misc->minor );
return 0;
io_unmap:
if (rg_pci_dev->pci_mem_base) {
iounmap(rg_pci_dev->pci_mem_base);
}
return ret;
}
static int pci_dev_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < MAX_PCIE_NUM ; i++) {
if (pcie_dev_arry[i] != NULL) {
if (pcie_dev_arry[i]->pci_mem_base) {
iounmap(pcie_dev_arry[i]->pci_mem_base);
}
misc_deregister(&pcie_dev_arry[i]->misc);
pcie_dev_arry[i] = NULL;
}
}
return 0;
}
static struct of_device_id pci_dev_match[] = {
{
.compatible = "ruijie,rg-pci-dev",
},
{},
};
MODULE_DEVICE_TABLE(of, pci_dev_match);
static struct platform_driver rg_pci_dev_driver = {
.probe = pci_dev_probe,
.remove = pci_dev_remove,
.driver = {
.owner = THIS_MODULE,
.name = PROXY_NAME,
.of_match_table = pci_dev_match,
},
};
static int __init rg_pci_dev_init(void)
{
return platform_driver_register(&rg_pci_dev_driver);
}
static void __exit rg_pci_dev_exit(void)
{
platform_driver_unregister(&rg_pci_dev_driver);
}
module_init(rg_pci_dev_init);
module_exit(rg_pci_dev_exit);
MODULE_DESCRIPTION("pcie device driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");

View File

@@ -0,0 +1,23 @@
#ifndef __RG_PCIE_DEV_H__
#define __RG_PCIE_DEV_H__
#define UPG_TYPE 'U'
#define GET_FPGA_UPG_CTL_BASE _IOR(UPG_TYPE, 0, int)
#define GET_FPGA_UPG_FLASH_BASE _IOR(UPG_TYPE, 1, int)
#define PCI_DEV_NAME_MAX_LEN (64)
typedef struct pci_dev_device_s {
char pci_dev_name[PCI_DEV_NAME_MAX_LEN];
int pci_domain;
int pci_bus;
int pci_slot;
int pci_fn;
int pci_bar;
int bus_width;
int upg_ctrl_base;
int upg_flash_base;
int device_flag;
} pci_dev_device_t;
#endif

View File

@@ -0,0 +1,20 @@
pes_parent_dir:=$(shell pwd)/$(lastword $(MAKEFILE_LIST))
pes_parent_dir:=$(shell dirname $(pes_parent_dir))
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "build") print $$9}')
INC = -I./inc
all : CHECK $(SUBDIRS)
CHECK :
@echo $(pes_parent_dir)
$(SUBDIRS):ECHO
#@echo $@
make -C $@
ECHO:
@echo $(SUBDIRS)
.PHONY : clean
clean :
-rm -rf $(SYSFS_OUT_PUT)

View File

@@ -0,0 +1,31 @@
PWD = $(shell pwd)
EXTRA_CFLAGS:= -I$(M)/include
EXTRA_CFLAGS+= -Wall
SUBDIR_CFG = cfg
rg_plat_dfd-objs := dfd_module.o dfd_fan_driver.o \
dfd_syseeprom_driver.o \
dfd_cpld_driver.o \
dfd_led_driver.o \
dfd_slot_driver.o \
dfd_sensors_driver.o \
dfd_psu_driver.o \
dfd_sff_driver.o \
dfd_sfpbase.o \
$(SUBDIR_CFG)/dfd_cfg.o \
$(SUBDIR_CFG)/dfd_cfg_adapter.o \
$(SUBDIR_CFG)/dfd_cfg_file.o \
$(SUBDIR_CFG)/dfd_cfg_info.o \
$(SUBDIR_CFG)/dfd_cfg_listnode.o \
$(SUBDIR_CFG)/dfd_frueeprom.o \
$(SUBDIR_CFG)/dfd_tlveeprom.o \
obj-m := rg_plat_dfd.o
all:
$(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules
@if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi
cp -p $(PWD)/*.ko $(module_out_put_dir)
clean:
rm -f $(PWD)/*.o $(PWD)/$(SUBDIR_CFG)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/$(SUBDIR_CFG)/.*.cmd $(PWD)/*.mod
rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order
rm -rf $(PWD)/.tmp_versions

View File

@@ -0,0 +1,815 @@
/*
* Copyright(C) 2001-2015 Ruijie Network. All rights reserved.
*/
#include <linux/list.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include "../include/dfd_module.h"
#include "../include/dfd_cfg_file.h"
#include "../include/dfd_cfg_listnode.h"
#include "../include/dfd_cfg_info.h"
#include "../include/dfd_cfg_adapter.h"
#include "../include/dfd_cfg.h"
#ifdef DFD_CFG_ITEM
#undef DFD_CFG_ITEM
#endif
#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _name,
static char *dfd_cfg_item_name[] = {
DFD_CFG_ITEM_ALL
};
#ifdef DFD_CFG_ITEM
#undef DFD_CFG_ITEM
#endif
#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) {_index_min, _index_max},
static index_range_t dfd_cfg_item_index_range[] = {
DFD_CFG_ITEM_ALL
};
static lnode_root_t dfd_ko_cfg_list_root;
static void dfd_ko_cfg_del_space_lf_cr(char *str)
{
int i, j;
int len;
len = strlen(str);
for (i = 0; i < len; i++) {
if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ') {
for (j = i; j < len - 1; j++) {
str[j] = str[j + 1];
}
str[j] = '\0';
len--;
i--;
}
}
}
static int dfd_ko_cfg_get_value_from_char(char *value_str, int32_t *value, int line_num)
{
int value_tmp = 0;
if (strlen(value_str) == 0) {
DBG_DEBUG(DBG_WARN, "line%d: value str is empty\n", line_num);
*value = DFD_CFG_EMPTY_VALUE;
return 0;
}
if ((strlen(value_str) > 2) && (value_str[0] == '0')
&& (value_str[1] == 'x' || value_str[1] == 'X')) {
value_tmp = (int32_t)simple_strtol(value_str, NULL, 16);
} else {
value_tmp = (int32_t)simple_strtol(value_str, NULL, 10);
}
*value = value_tmp;
return 0;
}
static int dfd_ko_cfg_analyse_index(char *index_str, int *index1, int *index2, int line_num)
{
int rv;
char *index1_begin_char, *index2_begin_char;
if (index_str[0] != '_') {
DBG_DEBUG(DBG_ERROR, "line%d: no '-' between name and index1\n", line_num);
return -1;
}
index1_begin_char = index_str;
rv = dfd_ko_cfg_get_value_from_char(++index1_begin_char, index1, line_num);
if (rv < 0) {
return -1;
}
if (index2 == NULL) {
return 0;
}
index2_begin_char = strchr(index1_begin_char, '_');
if (index2_begin_char == NULL) {
DBG_DEBUG(DBG_ERROR, "line%d: no '-' between index1 and index2\n", line_num);
return -1;
} else {
rv = dfd_ko_cfg_get_value_from_char(++index2_begin_char, index2, line_num);
if (rv < 0) {
return -1;
}
}
return 0;
}
static int dfd_ko_cfg_check_array_index(index_range_t *index_range, int *index1, int *index2,
int line_num)
{
if ((*index1 < 0) || (*index1 > index_range->index1_max)) {
DBG_DEBUG(DBG_ERROR, "line%d: index1[%d] invalid, max=%d\n", line_num, *index1,
index_range->index1_max);
return -1;
}
if (index2 == NULL) {
return 0;
}
if ((*index2 < 0) || (*index2 > index_range->index2_max)) {
DBG_DEBUG(DBG_ERROR, "line%d: index2[%d] invalid, max=%d\n", line_num, *index2,
index_range->index2_max);
return -1;
}
return 0;
}
static int dfd_ko_cfg_get_index(char *index_str, index_range_t *index_range, int *index1,
int *index2, int line_num)
{
int rv;
if (index_range->index2_max == INDEX_NOT_EXIST) {
index2 = NULL;
}
rv = dfd_ko_cfg_analyse_index(index_str, index1, index2, line_num);
if (rv < 0) {
return -1;
}
rv = dfd_ko_cfg_check_array_index(index_range, index1, index2, line_num);
if (rv < 0) {
return -1;
}
return 0;
}
static int dfd_ko_cfg_add_int_item(int key, int value, int line_num)
{
int rv;
int *int_cfg;
int_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key);
if (int_cfg == NULL) {
int_cfg = (int *)kmalloc(sizeof(int), GFP_KERNEL);
if (int_cfg == NULL) {
DBG_DEBUG(DBG_ERROR, "line%d: kmalloc int fail\n", line_num);
return -1;
}
*int_cfg = value;
rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, int_cfg);
if (rv == 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: add int item[%d] success, key=0x%08x\n", line_num, value, key);
} else {
kfree(int_cfg);
int_cfg = NULL;
DBG_DEBUG(DBG_ERROR, "line%d: add int item[%d] fail, key=0x%08x rv=%d \n", line_num, value, key, rv);
return -1;
}
} else {
DBG_DEBUG(DBG_WARN, "line%d: replace int item[%d->%d], key=0x%08x\n", line_num, *int_cfg, value, key);
*int_cfg = value;
}
return 0;
}
static int dfd_ko_cfg_analyse_int_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value,
char *cfg_pre, index_range_t *index_range, int line_num)
{
int rv;
int index1 = 0, index2 = 0;
int value, key;
char *arg_name_tmp;
if (index_range->index1_max != INDEX_NOT_EXIST) {
arg_name_tmp = arg_name + strlen(cfg_pre);
rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num);
if (rv < 0) {
return -1;
}
}
rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num);
if (rv < 0) {
return -1;
}
key = DFD_CFG_KEY(cfg_item_id, index1, index2);
rv = dfd_ko_cfg_add_int_item(key, value, line_num);
if (rv < 0) {
return -1;
}
return 0;
}
static int dfd_ko_cfg_add_str_item(int key, char *str, int line_num)
{
int rv;
char *str_cfg;
str_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key);
if (str_cfg == NULL) {
str_cfg = (char *)kmalloc(DFD_CFG_STR_MAX_LEN, GFP_KERNEL);
if (str_cfg == NULL) {
DBG_DEBUG(DBG_ERROR, "line%d: kmalloc str[%lu] fail\n", line_num, strlen(str));
return -1;
}
memset(str_cfg, 0, DFD_CFG_STR_MAX_LEN);
strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1);
rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg);
if (rv == 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: add string item[%s] success, key=0x%08x\n", line_num, str_cfg, key);
} else {
kfree(str_cfg);
str_cfg = NULL;
DBG_DEBUG(DBG_ERROR, "line%d: add string item[%s] fail, key=0x%08x rv=%d \n", line_num, str_cfg, key, rv);
return -1;
}
} else {
DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08x\n", line_num, str_cfg, str, key);
memset(str_cfg, 0, DFD_CFG_STR_MAX_LEN);
strncpy(str_cfg, str, DFD_CFG_STR_MAX_LEN - 1);
}
return 0;
}
static int dfd_ko_cfg_analyse_str_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, char *arg_value,
char *cfg_pre, index_range_t *index_range, int line_num)
{
int rv;
int index1 = 0, index2 = 0;
int btree_key;
char *arg_name_tmp;
if (index_range->index1_max != INDEX_NOT_EXIST) {
arg_name_tmp = arg_name + strlen(cfg_pre);
rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num);
if (rv < 0) {
return -1;
}
}
if (strlen(arg_value) >= DFD_CFG_STR_MAX_LEN) {
DBG_DEBUG(DBG_ERROR, "line%d: string item[%s] is too long \n", line_num, arg_value);
return -1;
}
btree_key = DFD_CFG_KEY(cfg_item_id, index1, index2);
rv = dfd_ko_cfg_add_str_item(btree_key, arg_value, line_num);
if (rv < 0) {
return -1;
}
return 0;
}
static int dfd_ko_cfg_get_i2c_dev_member(char *member_str, dfd_i2c_dev_mem_t *member, int line_num)
{
dfd_i2c_dev_mem_t mem_index;
for (mem_index = DFD_I2C_DEV_MEM_BUS; mem_index < DFD_I2C_DEV_MEM_END; mem_index++) {
if (memcmp(member_str, g_dfd_i2c_dev_mem_str[mem_index],
strlen(g_dfd_i2c_dev_mem_str[mem_index])) == 0) {
*member = mem_index;
return 0;
}
}
DBG_DEBUG(DBG_ERROR, "line%d: i2c dev member[%s] invalid\n", line_num, member_str);
return -1;
}
static void dfd_ko_cfg_set_i2c_dev_mem_value(dfd_i2c_dev_t *i2c_dev, dfd_i2c_dev_mem_t member,
int value)
{
switch (member) {
case DFD_I2C_DEV_MEM_BUS:
i2c_dev->bus = value;
break;
case DFD_I2C_DEV_MEM_ADDR:
i2c_dev->addr = value;
break;
default:
break;
}
}
static int dfd_ko_cfg_add_i2c_dev_item(int key, dfd_i2c_dev_mem_t member, int value, int line_num)
{
int rv;
dfd_i2c_dev_t *i2c_dev_cfg;
i2c_dev_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key);
if (i2c_dev_cfg == NULL) {
i2c_dev_cfg = (dfd_i2c_dev_t *)kmalloc(sizeof(dfd_i2c_dev_t), GFP_KERNEL);
if (i2c_dev_cfg == NULL) {
DBG_DEBUG(DBG_ERROR, "line%d: kmalloc i2c_dev fail\n", line_num);
return -1;
}
memset(i2c_dev_cfg, 0, sizeof(dfd_i2c_dev_t));
dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value);
rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, i2c_dev_cfg);
if (rv == 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: add i2c_dev item[%s=%d] success, key=0x%08x\n", line_num,
g_dfd_i2c_dev_mem_str[member], value, key);
} else {
kfree(i2c_dev_cfg);
i2c_dev_cfg = NULL;
DBG_DEBUG(DBG_ERROR, "line%d: add i2c_dev item[%s=%d] fail, key=0x%08x rv=%d\n", line_num,
g_dfd_i2c_dev_mem_str[member], value, key, rv);
return -1;
}
} else {
DBG_DEBUG(DBG_VERBOSE, "line%d: replace i2c_dev item[%s=%d], key=0x%08x\n", line_num,
g_dfd_i2c_dev_mem_str[member], value, key);
dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value);
}
return 0;
}
static int dfd_ko_cfg_analyse_i2c_dev_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name,
char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num)
{
int rv;
int index1 = 0, index2 = 0;
int value, key;
char *arg_name_tmp;
dfd_i2c_dev_mem_t member;
arg_name_tmp = arg_name + strlen(cfg_pre);
rv = dfd_ko_cfg_get_i2c_dev_member(arg_name_tmp, &member, line_num);
if (rv < 0) {
return -1;
}
if (index_range->index1_max != INDEX_NOT_EXIST) {
arg_name_tmp += strlen(g_dfd_i2c_dev_mem_str[member]);
rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num);
if (rv < 0) {
return -1;
}
}
rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num);
if (rv < 0) {
return -1;
}
key = DFD_CFG_KEY(cfg_item_id, index1, index2);
rv = dfd_ko_cfg_add_i2c_dev_item(key, member, value, line_num);
if (rv < 0) {
return -1;
}
return 0;
}
static int dfd_ko_cfg_get_enum_value_by_str(char *enum_val_str[], int enum_val_end, char *buf)
{
int i;
int enum_val;
enum_val = DFD_CFG_INVALID_VALUE;
for (i = 0; i < enum_val_end; i++) {
if (memcmp(buf, enum_val_str[i], strlen(enum_val_str[i])) == 0) {
enum_val = i;
break;
}
}
return enum_val;
}
static int dfd_ko_cfg_get_info_ctrl_member(char *member_str, info_ctrl_mem_t *member, int line_num)
{
info_ctrl_mem_t mem_index;
for (mem_index = INFO_CTRL_MEM_MODE; mem_index < INFO_CTRL_MEM_END; mem_index++) {
if (memcmp(member_str, g_info_ctrl_mem_str[mem_index],
strlen(g_info_ctrl_mem_str[mem_index])) == 0) {
*member = mem_index;
return 0;
}
}
DBG_DEBUG(DBG_ERROR, "line%d: info ctrl member[%s] invalid\n", line_num, member_str);
return -1;
}
static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl_mem_t member,
char *buf_val, int line_num)
{
switch (member) {
case INFO_CTRL_MEM_MODE:
info_ctrl->mode = dfd_ko_cfg_get_enum_value_by_str(g_info_ctrl_mode_str, INFO_CTRL_MODE_END, buf_val);;
break;
case INFO_CTRL_MEM_INT_CONS:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_cons), line_num);
break;
case INFO_CTRL_MEM_SRC:
info_ctrl->src = dfd_ko_cfg_get_enum_value_by_str(g_info_src_str, INFO_SRC_END, buf_val);
break;
case INFO_CTRL_MEM_FRMT:
info_ctrl->frmt = dfd_ko_cfg_get_enum_value_by_str(g_info_frmt_str, INFO_FRMT_END, buf_val);
break;
case INFO_CTRL_MEM_POLA:
info_ctrl->pola = dfd_ko_cfg_get_enum_value_by_str(g_info_pola_str, INFO_POLA_END, buf_val);
break;
case INFO_CTRL_MEM_FPATH:
memset(info_ctrl->fpath, 0, sizeof(info_ctrl->fpath));
strncpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath) - 1);
break;
case INFO_CTRL_MEM_ADDR:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num);
break;
case INFO_CTRL_MEM_LEN:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->len), line_num);
break;
case INFO_CTRL_MEM_BIT_OFFSET:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->bit_offset), line_num);
break;
case INFO_CTRL_MEM_STR_CONS:
memset(info_ctrl->str_cons, 0, sizeof(info_ctrl->str_cons));
strncpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons) - 1);
break;
case INFO_CTRL_MEM_INT_EXTRA1:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num);
break;
case INFO_CTRL_MEM_INT_EXTRA2:
dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra2), line_num);
break;
default:
break;
}
}
static int dfd_ko_cfg_add_info_ctrl_item(int key, info_ctrl_mem_t member, char *buf_val,
int line_num)
{
int rv;
info_ctrl_t *info_ctrl_cfg;
info_ctrl_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key);
if (info_ctrl_cfg == NULL) {
info_ctrl_cfg = (info_ctrl_t *)kmalloc(sizeof(info_ctrl_t), GFP_KERNEL);
if (info_ctrl_cfg == NULL) {
DBG_DEBUG(DBG_ERROR, "line%d: kmalloc info_ctrl fail\n", line_num);
return -1;
}
memset(info_ctrl_cfg, 0, sizeof(info_ctrl_t));
dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num);
rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, info_ctrl_cfg);
if (rv == 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: add info_ctrl item[%s=%s] success, key=0x%08x\n", line_num,
g_info_ctrl_mem_str[member], buf_val, key);
} else {
kfree(info_ctrl_cfg);
info_ctrl_cfg = NULL;
DBG_DEBUG(DBG_ERROR, "line%d: add info_ctrl item[%s=%s] fail, key=0x%08x rv=%d\n", line_num,
g_info_ctrl_mem_str[member], buf_val, key, rv);
return -1;
}
} else {
DBG_DEBUG(DBG_VERBOSE, "line%d: replace info_ctrl item[%s=%s], key=0x%08x\n", line_num,
g_info_ctrl_mem_str[member], buf_val, key);
dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num);
}
return 0;
}
static int dfd_ko_cfg_analyse_info_ctrl_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name,
char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num)
{
int rv;
int index1 = 0, index2 = 0;
int key;
char *arg_name_tmp;
info_ctrl_mem_t member;
arg_name_tmp = arg_name + strlen(cfg_pre);
rv = dfd_ko_cfg_get_info_ctrl_member(arg_name_tmp, &member, line_num);
if (rv < 0) {
return -1;
}
if (index_range->index1_max != INDEX_NOT_EXIST) {
arg_name_tmp += strlen(g_info_ctrl_mem_str[member]);
rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num);
if (rv < 0) {
return -1;
}
}
key = DFD_CFG_KEY(cfg_item_id, index1, index2);
rv = dfd_ko_cfg_add_info_ctrl_item(key, member, arg_value, line_num);
if (rv < 0) {
return -1;
}
return 0;
}
static int dfd_ko_cfg_analyse_config(char *arg_name, char*arg_value, int line_num)
{
int i, rv = 0;
int cfg_item_num;
cfg_item_num = sizeof(dfd_cfg_item_name) / sizeof(dfd_cfg_item_name[0]);
for (i = 0; i < cfg_item_num; i++) {
if (memcmp(arg_name, dfd_cfg_item_name[i], strlen(dfd_cfg_item_name[i])) == 0){
if (DFD_CFG_ITEM_IS_INT(i)) {
rv = dfd_ko_cfg_analyse_int_item(i, arg_name, arg_value, dfd_cfg_item_name[i],
&(dfd_cfg_item_index_range[i]), line_num);
} else if (DFD_CFG_ITEM_IS_STRING(i)) {
rv = dfd_ko_cfg_analyse_str_item(i, arg_name, arg_value, dfd_cfg_item_name[i],
&(dfd_cfg_item_index_range[i]), line_num);
} else if (DFD_CFG_ITEM_IS_I2C_DEV(i)) {
rv = dfd_ko_cfg_analyse_i2c_dev_item(i, arg_name, arg_value, dfd_cfg_item_name[i],
&(dfd_cfg_item_index_range[i]), line_num);
} else if (DFD_CFG_ITEM_IS_INFO_CTRL(i)) {
rv = dfd_ko_cfg_analyse_info_ctrl_item(i, arg_name, arg_value, dfd_cfg_item_name[i],
&(dfd_cfg_item_index_range[i]), line_num);
} else {
rv = -1;
}
break;
}
}
return rv;
}
static int dfd_ko_cfg_cut_config_line(char *config_line, char *arg_name, char *arg_value)
{
int i, j = 0, k = 0;
int len, name_value_flag = 0;
len = strlen(config_line);
for (i = 0; i < len; i++) {
if (config_line[i] == '=') {
name_value_flag = 1;
continue;
}
if (name_value_flag == 0) {
arg_name[j++] = config_line[i];
} else {
arg_value[k++] = config_line[i];
}
}
if (name_value_flag == 0) {
return -1;
} else {
return 0;
}
}
static int dfd_ko_cfg_analyse_config_line(char *config_line, int line_num)
{
int rv;
char arg_name[DFD_CFG_NAME_MAX_LEN] = {0};
char arg_value[DFD_CFG_VALUE_MAX_LEN] = {0};
dfd_ko_cfg_del_space_lf_cr(config_line);
if (strlen(config_line) == 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: space line\n", line_num);
return 0;
}
if (config_line[0] == '#') {
DBG_DEBUG(DBG_VERBOSE, "line%d: comment line[%s]\n", line_num, config_line);
return 0;
}
rv = dfd_ko_cfg_cut_config_line(config_line, arg_name, arg_value);
if (rv < 0) {
DBG_DEBUG(DBG_VERBOSE, "line%d: [%s]no '=' between name and value\n", line_num, config_line);
return -1;
}
DBG_DEBUG(DBG_VERBOSE, "line%d: config_line[%s] name[%s] value[%s]\n", line_num, config_line, arg_name, arg_value);
return dfd_ko_cfg_analyse_config(arg_name, arg_value, line_num);
}
static int dfd_ko_cfg_analyse_config_file(char *fpath)
{
int rv;
int line_num = 1;
kfile_ctrl_t kfile_ctrl;
char config_line[DFD_CFG_CMDLINE_MAX_LEN] = {0};
rv = kfile_open(fpath, &kfile_ctrl);
if (rv != KFILE_RV_OK) {
DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv);
return -1;
}
while(kfile_gets(config_line, sizeof(config_line), &kfile_ctrl) > 0){
rv = dfd_ko_cfg_analyse_config_line(config_line, line_num++);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "!!!!file[%s] config line[%d %s] analyse fail\n", fpath, line_num - 1,
config_line);
break;
}
(void)memset(config_line, 0, sizeof(config_line));
}
kfile_close(&kfile_ctrl);
return rv;
}
void *dfd_ko_cfg_get_item(int key)
{
return lnode_find_node(&dfd_ko_cfg_list_root, key);
}
static void dfd_ko_cfg_print_item(int key, const void *cfg)
{
int item_id;
dfd_i2c_dev_t *i2c_dev;
info_ctrl_t *info_ctrl;
if (cfg == NULL) {
DBG_DEBUG(DBG_ERROR, "input arguments error\n");
return;
}
printk(KERN_INFO "**************************\n");
printk(KERN_INFO "key=0x%08x\n", key);
item_id = DFD_CFG_ITEM_ID(key);
if (DFD_CFG_ITEM_IS_INT(item_id)) {
printk(KERN_INFO "int=%d\n", *((int *)cfg));
} else if (DFD_CFG_ITEM_IS_I2C_DEV(item_id)) {
i2c_dev = (dfd_i2c_dev_t *)cfg;
printk(KERN_INFO ".bus=0x%02x\n", i2c_dev->bus);
printk(KERN_INFO ".addr=0x%02x\n", i2c_dev->addr);
} else if (DFD_CFG_ITEM_IS_INFO_CTRL(item_id)) {
info_ctrl = (info_ctrl_t *)cfg;
printk(KERN_INFO ".mode=%s\n", g_info_ctrl_mode_str[info_ctrl->mode]);
printk(KERN_INFO ".int_cons=%d\n", info_ctrl->int_cons);
printk(KERN_INFO ".src=%s\n", g_info_src_str[info_ctrl->src]);
printk(KERN_INFO ".frmt=%s\n", g_info_frmt_str[info_ctrl->frmt]);
printk(KERN_INFO ".pola=%s\n", g_info_pola_str[info_ctrl->pola]);
printk(KERN_INFO ".fpath=%s\n", info_ctrl->fpath);
printk(KERN_INFO ".addr=0x%02x\n", info_ctrl->addr);
printk(KERN_INFO ".len=%d\n", info_ctrl->len);
printk(KERN_INFO ".bit_offset=%d\n", info_ctrl->bit_offset);
} else {
printk(KERN_INFO "item[%d] error!\n", item_id);
}
}
void dfd_ko_cfg_show_item(int key)
{
void *cfg;
cfg = lnode_find_node(&dfd_ko_cfg_list_root, key);
if (cfg == 0) {
printk(KERN_INFO "item[0x%08x] not exist\n", key);
return;
}
dfd_ko_cfg_print_item(key, cfg);
}
static int dfd_get_my_dev_type_by_file(void)
{
struct file *fp;
loff_t pos;
int card_type;
char buf[DFD_PID_BUF_LEN];
int ret;
fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0);
if (IS_ERR(fp)) {
DBG_DEBUG(DBG_VERBOSE, "open file fail!\n");
return -1;
}
memset(buf, 0, DFD_PID_BUF_LEN);
pos = 0;
ret = kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos);
if (ret < 0) {
DBG_DEBUG(DBG_VERBOSE, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n",
DFD_PUB_CARDTYPE_FILE, DFD_PRODUCT_ID_LENGTH + 1, ret);
filp_close(fp, NULL);
return -1;
}
card_type = simple_strtoul(buf, NULL, 10);
DBG_DEBUG(DBG_VERBOSE, "card_type 0x%x.\n", card_type);
filp_close(fp, NULL);
return card_type;
}
static int drv_get_my_dev_type(void)
{
static int type = -1;
if (type > 0) {
return type;
}
type = dfd_get_my_dev_type_by_file();
DBG_DEBUG(DBG_VERBOSE, "ko board type %d\n", type);
return type;
}
static int dfd_ko_cfg_init(void)
{
int rv;
int card_type;
char file_name[32] = {0};
char fpath[128] = {0};
kfile_ctrl_t kfile_ctrl;
rv = lnode_init_root(&dfd_ko_cfg_list_root);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "init list root fail, rv=%d\n", rv);
return -1;
}
card_type = drv_get_my_dev_type();
if (card_type > 0) {
snprintf(fpath, sizeof(fpath), "%s0x%x", DFD_KO_CFG_FILE_DIR, card_type);
rv = kfile_open(fpath, &kfile_ctrl);
if (rv != KFILE_RV_OK) {
DBG_DEBUG(DBG_VERBOSE, "open config file[%s] fail, rv=%d, maybe not exist\n",
fpath, rv);
rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl);
if (rv != KFILE_RV_OK) {
DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME,
rv);
return -1;
}
DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME);
} else {
DBG_DEBUG(DBG_VERBOSE, "get config file from: %s, success.\n", fpath);
}
} else {
DBG_DEBUG(DBG_VERBOSE, "get board id failed, try to get config file from: %s\n",
DFD_KO_CFG_FILE_NAME);
rv = kfile_open(DFD_KO_CFG_FILE_NAME, &kfile_ctrl);
if (rv != KFILE_RV_OK) {
DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", DFD_KO_CFG_FILE_NAME, rv);
return -1;
}
DBG_DEBUG(DBG_ERROR, "get config file from: %s, success.\n", DFD_KO_CFG_FILE_NAME);
}
while (kfile_gets(file_name, sizeof(file_name), &kfile_ctrl) > 0) {
dfd_ko_cfg_del_space_lf_cr(file_name);
memset(fpath, 0, sizeof(fpath));
snprintf(fpath, sizeof(fpath), "%s%s.cfg", DFD_KO_CFG_FILE_DIR, file_name);
DBG_DEBUG(DBG_VERBOSE, ">>>>start parsing config file[%s]\n", fpath);
rv = dfd_ko_cfg_analyse_config_file(fpath);
if (rv < 0) {
break;
}
}
kfile_close(&kfile_ctrl);
return 0;
}
int32_t dfd_dev_cfg_init(void)
{
return dfd_ko_cfg_init();
}
void dfd_dev_cfg_exit(void)
{
lnode_free_list(&dfd_ko_cfg_list_root);
return;
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright(C) 2015 Ruijie Network. All rights reserved.
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/unistd.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include "../include/dfd_module.h"
#include "../include/dfd_cfg_file.h"
#include "../include/dfd_cfg.h"
#include "../include/dfd_cfg_adapter.h"
char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END] = {
".bus",
".addr",
};
static dfd_i2c_dev_t* dfd_ko_get_cpld_i2c_dev(int sub_slot, int cpld_id)
{
int key;
dfd_i2c_dev_t *i2c_dev;
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_I2C_DEV, sub_slot, cpld_id);
i2c_dev = dfd_ko_cfg_get_item(key);
if (i2c_dev == NULL) {
DBG_DEBUG(DBG_ERROR, "get cpld[%d] i2c dev config fail, key=0x%08x\n", cpld_id, key);
return NULL;
}
return i2c_dev;
}
static int32_t dfd_ko_i2c_smbus_transfer(int read_write, int bus, int addr, int offset, uint8_t *buf, uint32_t size)
{
int rv;
struct i2c_adapter *i2c_adap;
union i2c_smbus_data data;
i2c_adap = i2c_get_adapter(bus);
if (i2c_adap == NULL) {
DBG_DEBUG(DBG_ERROR, "get i2c bus[%d] adapter fail\n", bus);
return -DFD_RV_DEV_FAIL;
}
if (read_write == I2C_SMBUS_WRITE) {
data.byte = *buf;
} else {
data.byte = 0;
}
rv = i2c_smbus_xfer(i2c_adap, addr, 0, read_write, offset, I2C_SMBUS_BYTE_DATA, &data);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer fail, rv=%d\n",
bus, addr, offset, size, read_write, rv);
rv = -DFD_RV_DEV_FAIL;
} else {
DBG_DEBUG(DBG_VERBOSE, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer success\n",
bus, addr, offset, size, read_write);
rv = DFD_RV_OK;
}
if (read_write == I2C_SMBUS_READ) {
if (rv == DFD_RV_OK) {
*buf = data.byte;
} else {
*buf = 0;
}
}
i2c_put_adapter(i2c_adap);
return rv;
}
static int32_t dfd_ko_i2c_read_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size)
{
int i, rv;
for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) {
rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_READ, bus, addr, offset, buf, size);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "[%d]cpld read[offset=0x%x] fail, rv %d\n", i, addr, rv);
msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP);
} else {
DBG_DEBUG(DBG_VERBOSE, "[%d]cpld read[offset=0x%x] success, value=0x%x\n",
i, addr, *buf);
break;
}
}
return rv;
}
static int32_t dfd_ko_i2c_write_data(int bus, int addr, int offset, uint8_t data, uint32_t size)
{
int i, rv;
for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) {
rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_WRITE, bus, addr, offset, &data, size);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "[%d]cpld write[offset=0x%x] fail, rv=%d\n", i, addr, rv);
msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP);
} else {
DBG_DEBUG(DBG_VERBOSE, "[%d]cpld write[offset=0x%x, data=%d] success\n", i, addr, data);
break;
}
}
return rv;
}
static int32_t dfd_ko_cpld_i2c_read(int32_t addr, uint8_t *buf)
{
int rv;
int sub_slot, cpld_id, cpld_addr;
dfd_i2c_dev_t *i2c_dev;
if (buf == NULL) {
DBG_DEBUG(DBG_ERROR, "input arguments error\n");
return -DFD_RV_INDEX_INVALID;
}
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
cpld_addr = DFD_KO_CPLD_GET_INDEX(addr);
i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id);
if (i2c_dev == NULL) {
return -DFD_RV_DEV_NOTSUPPORT;
}
rv = dfd_ko_i2c_read_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, buf, sizeof(uint8_t));
return rv;
}
static int32_t dfd_ko_cpld_i2c_write(int32_t addr, uint8_t data)
{
int rv;
int sub_slot, cpld_id, cpld_addr;
dfd_i2c_dev_t *i2c_dev;
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
cpld_addr = DFD_KO_CPLD_GET_INDEX(addr);
i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id);
if (i2c_dev == NULL) {
return -DFD_RV_DEV_NOTSUPPORT;
}
rv = dfd_ko_i2c_write_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, data, sizeof(uint8_t));
return rv;
}
static int32_t dfd_ko_cpld_io_read(int32_t addr, uint8_t *buf)
{
int cpld_id, sub_slot, offset;
int key;
int *tmp;
uint16_t io_port;
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
offset = DFD_KO_CPLD_GET_INDEX(addr);
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id);
tmp = dfd_ko_cfg_get_item(key);
if (tmp == NULL) {
DBG_DEBUG(DBG_ERROR,"get cpld io base config fail, key=0x%08x\n", key);
return -1;
}
io_port = (u16)(*tmp) + offset;
*buf = inb(io_port);
DBG_DEBUG(DBG_VERBOSE, "read cpld io port addr 0x%x, data 0x%x\n", io_port, *buf);
return DFD_RV_OK;
}
static int32_t dfd_ko_cpld_io_write(int32_t addr, uint8_t data)
{
int cpld_id, sub_slot, offset;
int key;
int *tmp;
uint16_t io_port;
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
offset = DFD_KO_CPLD_GET_INDEX(addr);
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id);
tmp = dfd_ko_cfg_get_item(key);
if (tmp == NULL) {
DBG_DEBUG(DBG_ERROR, "get cpld io base config fail, key=0x%08x\n", key);
return -1;
}
io_port = (u16)(*tmp) + offset;
DBG_DEBUG(DBG_VERBOSE, "write cpld io port addr 0x%x, data 0x%x\n", io_port, data);
outb(data, (u16)io_port);
return DFD_RV_OK;
}
static int dfd_cfg_get_cpld_mode(int sub_slot, int cpld_id, int *mode)
{
int key;
char *name;
if (mode == NULL) {
DBG_DEBUG(DBG_ERROR, "input arguments error\n");
return -DFD_RV_TYPE_ERR;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_MODE, sub_slot, cpld_id);
name = dfd_ko_cfg_get_item(key);
if (name == NULL) {
DBG_DEBUG(DBG_ERROR, "get cpld[%d] mode info ctrl fail, key=0x%08x\n", cpld_id, key);
return -DFD_RV_NODE_FAIL;
}
DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode_name %s.\n", cpld_id, name);
if (!strncmp(name, DFD_KO_CPLD_MODE_I2C_STRING, strlen(DFD_KO_CPLD_MODE_I2C_STRING))) {
*mode = DFD_CPLD_MODE_I2C;
} else if (!strncmp(name, DFD_KO_CPLD_MODE_LPC_STRING, strlen(DFD_KO_CPLD_MODE_LPC_STRING))) {
*mode = DFD_CPLD_MODE_LPC;
} else {
*mode = DFD_CPLD_MODE_I2C;
}
DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode %d.\n", cpld_id, *mode);
return 0;
}
int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf)
{
int ret;
int sub_slot, cpld_id;
int cpld_mode;
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode);
if (ret) {
DBG_DEBUG(DBG_WARN, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default i2c mode.\n", sub_slot, cpld_id);
cpld_mode = DFD_CPLD_MODE_I2C;
}
if (cpld_mode == DFD_CPLD_MODE_I2C) {
ret = dfd_ko_cpld_i2c_read(addr, buf);
} else if (cpld_mode == DFD_CPLD_MODE_LPC) {
ret = dfd_ko_cpld_io_read(addr, buf);
} else {
DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode);
ret = -DFD_RV_DEV_NOTSUPPORT;
}
DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, *buf, ret);
return ret;
}
int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val)
{
int ret;
int sub_slot, cpld_id, cpld_mode;
sub_slot = DFD_KO_CPLD_GET_SLOT(addr);
cpld_id = DFD_KO_CPLD_GET_ID(addr);
ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode);
if (ret) {
DBG_DEBUG(DBG_ERROR, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default local_bus mode.\n", sub_slot, cpld_id);
cpld_mode = DFD_CPLD_MODE_I2C;
}
if (cpld_mode == DFD_CPLD_MODE_I2C) {
ret = dfd_ko_cpld_i2c_write(addr, val);
} else if (cpld_mode == DFD_CPLD_MODE_LPC) {
ret = dfd_ko_cpld_io_write(addr, val);
} else {
DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode);
ret = -DFD_RV_DEV_NOTSUPPORT;
}
DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, val, ret);
return ret;
}
int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size)
{
int i, rv;
for (i = 0; i < size; i++) {
rv = dfd_ko_i2c_read_data(bus, addr, offset, &buf[i], sizeof(uint8_t));
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n",
bus, addr, offset, rv);
return rv;
}
offset++;
}
return size;
}
int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size)
{
int i, rv;
for (i = 0; i < size; i++) {
rv = dfd_ko_i2c_write_data(bus, addr, offset, buf[i], sizeof(uint8_t));
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_write[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n",
bus, addr, offset, rv);
return rv;
}
offset++;
}
return size;
}
int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes)
{
int32_t ret;
struct file *filp;
loff_t pos;
if ((fpath == NULL) || (val == NULL) || (addr < 0) || (read_bytes < 0)) {
DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d read_bytes=%d\n", addr, read_bytes);
return -DFD_RV_INDEX_INVALID;
}
filp = filp_open(fpath, O_RDONLY, 0);
if (IS_ERR(filp)){
DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath);
return -DFD_RV_DEV_FAIL;
}
pos = addr;
ret = kernel_read(filp, val, read_bytes, &pos);
if (ret < 0) {
DBG_DEBUG(DBG_ERROR, "kernel_read failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, read_bytes, ret);
ret = -DFD_RV_DEV_FAIL;
}
filp_close(filp, NULL);
return ret;
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright(C) 2001-2015s Ruijie Network. All rights reserved.
*/
#include <asm/unistd.h>
#include <linux/uaccess.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "../include/dfd_cfg_file.h"
#include "../include/dfd_module.h"
struct getdents_callback {
struct dir_context ctx;
const char *obj_name;
char *match_name;
int dir_len;
int found;
};
int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl)
{
int ret;
struct file *filp;
loff_t pos;
if ((fname == NULL) || (kfile_ctrl == NULL)) {
return KFILE_RV_INPUT_ERR;
}
filp = filp_open(fname, O_RDONLY, 0);
if (IS_ERR(filp)){
return KFILE_RV_OPEN_FAIL;
}
kfile_ctrl->size = filp->f_inode->i_size;
kfile_ctrl->buf = kmalloc(kfile_ctrl->size, GFP_KERNEL);
if (kfile_ctrl->buf == NULL) {
ret = KFILE_RV_MALLOC_FAIL;
goto close_fp;
}
memset(kfile_ctrl->buf, 0, kfile_ctrl->size);
pos = 0;
ret = kernel_read(filp, kfile_ctrl->buf, kfile_ctrl->size, &pos);
if (ret < 0) {
ret = KFILE_RV_RD_FAIL;
goto free_buf;
}
kfile_ctrl->pos = 0;
ret = KFILE_RV_OK;
goto close_fp;
free_buf:
kfree(kfile_ctrl->buf);
kfile_ctrl->buf = NULL;
close_fp:
filp_close(filp, NULL);
return ret;
}
void kfile_close(kfile_ctrl_t *kfile_ctrl)
{
if (kfile_ctrl == NULL) {
return;
}
kfile_ctrl->size = 0;
kfile_ctrl->pos = 0;
if (kfile_ctrl->buf) {
kfree(kfile_ctrl->buf);
kfile_ctrl->buf = NULL;
}
}
int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl)
{
int i;
int has_cr = 0;
if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL)
|| (kfile_ctrl->size <= 0)) {
return KFILE_RV_INPUT_ERR;
}
memset(buf, 0, buf_size);
for (i = 0; i < buf_size; i++) {
if (kfile_ctrl->pos >= kfile_ctrl->size) {
break;
}
if (has_cr) {
break;
}
if (IS_CR(kfile_ctrl->buf[kfile_ctrl->pos])) {
has_cr = 1;
}
buf[i] = kfile_ctrl->buf[kfile_ctrl->pos];
kfile_ctrl->pos++;
}
return i;
}
int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl)
{
int i;
if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL)
|| (kfile_ctrl->size <= 0)) {
return KFILE_RV_INPUT_ERR;
}
if ((addr < 0) || (addr >= kfile_ctrl->size)) {
return KFILE_RV_ADDR_ERR;
}
memset(buf, 0, buf_size);
kfile_ctrl->pos = addr;
for (i = 0; i < buf_size; i++) {
if (kfile_ctrl->pos >= kfile_ctrl->size) {
break;
}
buf[i] = kfile_ctrl->buf[kfile_ctrl->pos];
kfile_ctrl->pos++;
}
return i;
}
static int kfile_filldir_one(struct dir_context *ctx, const char * name, int len,
loff_t pos, u64 ino, unsigned int d_type)
{
struct getdents_callback *buf ;
int result;
buf = container_of(ctx, struct getdents_callback, ctx);
result = 0;
if (strncmp(buf->obj_name, name, strlen(buf->obj_name)) == 0) {
if (buf->dir_len < len) {
DBG_DEBUG(DBG_ERROR, "match ok. dir name:%s, but buf_len %d small than dir len %d.\n",
name, buf->dir_len, len);
buf->found = 0;
return -1;
}
memset(buf->match_name, 0 , buf->dir_len);
memcpy(buf->match_name, name, len);
buf->found = 1;
result = -1;
}
return result;
}
int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len)
{
int ret;
struct file *dir;
struct getdents_callback buffer = {
.ctx.actor = kfile_filldir_one,
};
if(!dir_path || !obj_name || !match_name) {
DBG_DEBUG(DBG_ERROR, "params error. \n");
return KFILE_RV_INPUT_ERR;
}
buffer.obj_name = obj_name;
buffer.match_name = match_name;
buffer.dir_len = len;
buffer.found = 0;
dir = filp_open(dir_path, O_RDONLY, 0);
if (IS_ERR(dir)) {
DBG_DEBUG(DBG_ERROR, "filp_open error, dir path:%s\n", dir_path);
return KFILE_RV_OPEN_FAIL;
}
ret = iterate_dir(dir, &buffer.ctx);
if (buffer.found) {
DBG_DEBUG(DBG_VERBOSE, "match ok, dir name:%s\n", match_name);
filp_close(dir, NULL);
return DFD_RV_OK;
}
filp_close(dir, NULL);
return -DFD_RV_NODE_FAIL;
}
#if 0
int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size)
{
int ret = KFILE_RV_OK;
struct file *filp;
mm_segment_t old_fs;
int wlen;
if ((fpath == NULL) || (buf == NULL) || (buf_size <= 0)) {
return KFILE_RV_INPUT_ERR;
}
if (addr < 0) {
return KFILE_RV_ADDR_ERR;
}
filp = filp_open(fpath, O_RDWR, 0);
if (IS_ERR(filp)){
return KFILE_RV_OPEN_FAIL;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
filp->f_op->llseek(filp,0,0);
filp->f_pos = addr;
wlen = filp->f_op->write(filp, buf, buf_size, &(filp->f_pos));
if (wlen < 0) {
ret = KFILE_RV_WR_FAIL;
}
filp->f_op->llseek(filp,0,0);
set_fs(old_fs);
filp_close(filp, NULL);
return ret;
}
#endif

View File

@@ -0,0 +1,590 @@
/*
* Copyright(C) 2013 Ruijie Network. All rights reserved.
*/
#include <linux/string.h>
#include <linux/types.h>
#include <linux/slab.h>
#include "../include/dfd_module.h"
#include "../include/dfd_cfg_adapter.h"
#include "../include/dfd_cfg.h"
#include "../include/dfd_cfg_info.h"
#include "../include/dfd_cfg_file.h"
#define DFD_HWMON_NAME "hwmon"
#define DFD_GET_CPLD_VOLATGE_CODE_VALUE(value) ((value >> 4)& 0xfff)
#define DFD_GET_CPLD_VOLATGE_REAL_VALUE(code_val, k) ((code_val * 16 * 33 * k) / ((65536 - 5000) * 10))
char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = {
".mode",
".int_cons",
".src",
".frmt",
".pola",
".fpath",
".addr",
".len",
".bit_offset",
".str_cons",
".int_extra1",
".int_extra2",
};
char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END] = {
"none",
"config",
"constant",
"tlv",
"str_constant",
};
char *g_info_src_str[INFO_SRC_END] = {
"none",
"cpld",
"fpga",
"other_i2c",
"file",
};
char *g_info_frmt_str[INFO_FRMT_END] = {
"none",
"bit",
"byte",
"num_bytes",
"num_str",
"num_buf",
"buf",
};
char *g_info_pola_str[INFO_POLA_END] = {
"none",
"positive",
"negative",
};
static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val)
{
int i, rv;
for (i = 0; i < read_bytes; i++) {
rv = dfd_ko_cpld_read(addr, &(val[i]));
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from cpld fail, reading_byte=%d rv=%d\n",
addr, read_bytes, i, rv);
return rv;
}
addr++;
}
return read_bytes;
}
static int dfd_write_info_to_cpld(int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask)
{
int rv;
uint8_t val_tmp;
if (bit_mask != 0xff) {
rv = dfd_ko_cpld_read(addr, &val_tmp);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "read original info[addr=0x%x] from cpld fail, rv=%d\n", addr, rv);
return -1;
}
val_tmp = (val_tmp & (~bit_mask)) | (val[0] & bit_mask);
} else {
val_tmp = val[0];
}
rv = dfd_ko_cpld_write(addr, val_tmp);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "write info[addr=0x%x val=0x%x] to cpld fail, rv=%d\n", addr, val_tmp, rv);
return -1;
}
return 0;
}
static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_bytes, uint8_t *val)
{
int rv = 0;
switch (src) {
case INFO_SRC_CPLD:
rv = dfd_read_info_from_cpld(addr, read_bytes, val);
break;
case INFO_SRC_FPGA:
rv = -1;
DBG_DEBUG(DBG_ERROR, "not support read info from fpga\n");
break;
case INFO_SRC_OTHER_I2C:
rv = -1;
DBG_DEBUG(DBG_ERROR, "not support read info from other i2c\n");
break;
case INFO_SRC_FILE:
rv = dfd_ko_read_file(fpath, addr, val, read_bytes);
break;
default:
rv = -1;
DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src);
break;
}
return rv;
}
static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask)
{
int rv = 0;
switch (src) {
case INFO_SRC_CPLD:
rv = dfd_write_info_to_cpld(addr, write_bytes, val, bit_mask);
break;
case INFO_SRC_FPGA:
rv = -1;
DBG_DEBUG(DBG_ERROR, "not support write info to fpga\n");
break;
case INFO_SRC_OTHER_I2C:
rv = -1;
DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n");
break;
case INFO_SRC_FILE:
rv = -1;
DBG_DEBUG(DBG_ERROR, "not support write info to file\n");
break;
default:
rv = -1;
DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src);
break;
}
return rv;
}
int dfd_info_get_int(int key, int *ret, info_num_buf_to_value_f pfun)
{
int i, rv;
int read_bytes, readed_bytes, int_tmp;
uint8_t byte_tmp, val[INFO_INT_MAX_LEN + 1] = {0};
info_ctrl_t *info_ctrl;
if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (ret == NULL)) {
DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key);
return -DFD_RV_INDEX_INVALID;
}
info_ctrl = dfd_ko_cfg_get_item(key);
if (info_ctrl == NULL) {
DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
if (info_ctrl->mode == INFO_CTRL_MODE_CONS) {
*ret = info_ctrl->int_cons;
return DFD_RV_OK;
} else if (info_ctrl->mode == INFO_CTRL_MODE_TLV) {
return INFO_CTRL_MODE_TLV;
}
if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) {
if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n",
key, info_ctrl->bit_offset);
return -DFD_RV_TYPE_ERR;
}
read_bytes = 1;
} else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt) || IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)
|| IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) {
if (!INFO_INT_LEN_VALAID(info_ctrl->len)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len);
return -DFD_RV_TYPE_ERR;
}
read_bytes = info_ctrl->len;
} else {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] info format[%d] error\n", key, info_ctrl->frmt);
return -DFD_RV_TYPE_ERR;
}
readed_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, read_bytes, &(val[0]));
if (readed_bytes <= 0) {
DBG_DEBUG(DBG_ERROR, "read int info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x read_bytes=%d] fail, rv=%d\n",
key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath,
info_ctrl->addr, read_bytes, readed_bytes);
return -DFD_RV_DEV_FAIL;
}
if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) {
if (info_ctrl->pola == INFO_POLA_NEGA) {
val[0] = ~val[0];
}
byte_tmp = (val[0] >> info_ctrl->bit_offset) & (~(0xff << info_ctrl->len));
if (pfun) {
rv = pfun(&byte_tmp, sizeof(byte_tmp), &int_tmp);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit process fail, rv=%d\n", key, rv);
return rv;
}
} else {
int_tmp = (int)byte_tmp;
}
} else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) {
int_tmp = 0;
for (i = 0; i < info_ctrl->len; i++) {
if (info_ctrl->pola == INFO_POLA_NEGA) {
int_tmp |= val[info_ctrl->len - i - 1];
} else {
int_tmp |= val[i];
}
if (i != (info_ctrl->len - 1)) {
int_tmp <<= 8;
}
}
} else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) {
val[readed_bytes] = '\0';
int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10);
} else {
if (pfun == NULL) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process function is null\n", key);
return -DFD_RV_INDEX_INVALID;
}
rv = pfun(val, readed_bytes, &int_tmp);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] number buf process fail, rv=%d\n", key, rv);
return rv;
}
}
*ret = int_tmp;
DBG_DEBUG(DBG_VERBOSE, "read int info[key=0x%08x src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d] success, ret=%d\n",
key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola],
info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, *ret);
return DFD_RV_OK;
}
int dfd_info_get_buf(int key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun)
{
int rv;
int read_bytes, buf_real_len;
uint8_t buf_tmp[INFO_BUF_MAX_LEN];
info_ctrl_t *info_ctrl;
if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (buf == NULL)) {
DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key);
return -DFD_RV_INDEX_INVALID;
}
info_ctrl = dfd_ko_cfg_get_item(key);
if (info_ctrl == NULL) {
DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
if (info_ctrl->mode != INFO_CTRL_MODE_CFG) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] invalid\n", key, info_ctrl->mode);
return -DFD_RV_TYPE_ERR;
}
if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len)
|| (buf_len <= info_ctrl->len)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format=%d or len=%d invlaid, buf_len=%d\n",
key, info_ctrl->frmt, info_ctrl->len, buf_len);
return -DFD_RV_TYPE_ERR;
}
read_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, buf_tmp);
if (read_bytes <= 0) {
DBG_DEBUG(DBG_ERROR, "read buf info[key=0x%08x src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n",
key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath,
info_ctrl->addr, info_ctrl->len, read_bytes);
return -DFD_RV_DEV_FAIL;
}
if (pfun) {
buf_real_len = buf_len;
rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] buf process fail, rv=%d\n", key, rv);
return -DFD_RV_DEV_NOTSUPPORT;
}
} else {
buf_real_len = read_bytes;
memcpy(buf, buf_tmp, read_bytes);
}
return buf_real_len;
}
static int dfd_2key_info_get_buf(info_ctrl_t *info_ctrl, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun)
{
int rv;
int read_bytes, buf_real_len;
uint8_t buf_tmp[INFO_BUF_MAX_LEN];
char temp_fpath[INFO_FPATH_MAX_LEN];
if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len)
|| (buf_len <= info_ctrl->len)) {
DBG_DEBUG(DBG_ERROR, "key_path info ctrl format=%d or len=%d invlaid, buf_len=%d\n",
info_ctrl->frmt, info_ctrl->len, buf_len);
return -DFD_RV_TYPE_ERR;
}
memset(buf_tmp, 0 , sizeof(buf_tmp));
rv = kfile_iterate_dir(info_ctrl->fpath, DFD_HWMON_NAME, buf_tmp, INFO_BUF_MAX_LEN);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "dir patch:%s ,can find name %s dir \n",
info_ctrl->fpath, DFD_HWMON_NAME);
return -DFD_RV_NO_NODE;
}
memset(temp_fpath, 0 , sizeof(temp_fpath));
snprintf(temp_fpath, sizeof(temp_fpath), "%s%s/%s",
info_ctrl->fpath, buf_tmp, info_ctrl->str_cons);
DBG_DEBUG(DBG_VERBOSE, "match ok path = %s \n", temp_fpath);
memset(buf_tmp, 0, sizeof(buf_tmp));
read_bytes = dfd_read_info(info_ctrl->src, temp_fpath, info_ctrl->addr, info_ctrl->len, buf_tmp);
if (read_bytes <= 0) {
DBG_DEBUG(DBG_ERROR, "read buf info[src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n",
g_info_src_str[info_ctrl->src], g_info_src_str[info_ctrl->frmt], temp_fpath,
info_ctrl->addr, info_ctrl->len, read_bytes);
return -DFD_RV_DEV_FAIL;
}
if (pfun) {
buf_real_len = buf_len;
rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "info ctrl buf process fail, rv=%d\n", rv);
return -DFD_RV_DEV_NOTSUPPORT;
}
} else {
buf_real_len = read_bytes;
memcpy(buf, buf_tmp, buf_real_len);
}
return buf_real_len;
}
int dfd_info_set_int(int key, int val)
{
int rv;
int write_bytes;
uint8_t byte_tmp, bit_mask;
info_ctrl_t *info_ctrl;
if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key))) {
DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08x\n", key);
return -DFD_RV_INDEX_INVALID;
}
info_ctrl = dfd_ko_cfg_get_item(key);
if (info_ctrl == NULL) {
DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
if (info_ctrl->mode != INFO_CTRL_MODE_CFG) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] mode[%d] warnning\n", key, info_ctrl->mode);
return -DFD_RV_TYPE_ERR;
}
if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) {
if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] bit_offsest[%d] invalid\n",
key, info_ctrl->bit_offset);
return -DFD_RV_TYPE_ERR;
}
write_bytes = 1;
byte_tmp = (uint8_t)(val & 0xff);
byte_tmp <<= info_ctrl->bit_offset;
if (info_ctrl->pola == INFO_POLA_NEGA) {
byte_tmp = ~byte_tmp;
}
bit_mask = (~(0xff << info_ctrl->len)) << info_ctrl->bit_offset;
} else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) {
if (!INFO_INT_LEN_VALAID(info_ctrl->len)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len);
return -DFD_RV_TYPE_ERR;
}
write_bytes = 1;
byte_tmp = (uint8_t)(val & 0xff);
bit_mask = 0xff;
} else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) {
DBG_DEBUG(DBG_ERROR, "not support str int set\n");
return -1;
} else if (IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) {
if (!INFO_INT_LEN_VALAID(info_ctrl->len)) {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] len[%d] invalid\n", key, info_ctrl->len);
return -DFD_RV_TYPE_ERR;
}
write_bytes = 1;
byte_tmp = (uint8_t)(val & 0xff);
bit_mask = 0xff;
} else {
DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08x] format[%d] error\n", key, info_ctrl->frmt);
return -DFD_RV_TYPE_ERR;
}
rv = dfd_write_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes,
&byte_tmp, bit_mask);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "write int info[src=%s frmt=%s fpath=%s addr=0x%x len=%d val=%d] fail, rv=%d\n",
g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath,
info_ctrl->addr, info_ctrl->len, val, rv);
return -DFD_RV_DEV_FAIL;
}
DBG_DEBUG(DBG_VERBOSE, "write int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d val=%d] success\n",
g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola],
info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, val);
return DFD_RV_OK;
}
static int dfd_info_get_cpld_voltage(int key, int *value)
{
int rv, addr_tmp;
int vol_ref_tmp, vol_ref;
int vol_curr_tmp, vol_curr;
info_ctrl_t *info_ctrl;
info_ctrl = dfd_ko_cfg_get_item(key);
if (info_ctrl == NULL) {
DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
rv = dfd_info_get_int(key, &vol_curr_tmp, NULL);
if(rv < 0) {
DBG_DEBUG(DBG_ERROR, "get cpld current voltage error, addr:0x%x, rv =%d\n", info_ctrl->addr, rv);
return rv;
}
vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_curr_tmp);
if(info_ctrl->addr == info_ctrl->int_extra1) {
vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE(vol_curr_tmp, info_ctrl->int_extra2);
} else {
addr_tmp = info_ctrl->addr;
info_ctrl->addr = info_ctrl->int_extra1;
rv = dfd_info_get_int(key, &vol_ref_tmp, NULL);
info_ctrl->addr = addr_tmp;
if(rv < 0) {
DBG_DEBUG(DBG_ERROR, "get cpld reference voltage error, addr:0x%x rv:%d\n", info_ctrl->addr, rv);
return rv;
}
vol_ref = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_ref_tmp);
vol_curr = (vol_curr_tmp * info_ctrl->int_extra2) / vol_ref;
}
*value = vol_curr;
return DFD_RV_OK;
}
static int dfd_info_get_sensor_value(int key, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun)
{
int rv, buf_real_len;
int value;
uint8_t buf_tmp[INFO_BUF_MAX_LEN];
info_ctrl_t *info_ctrl;
info_ctrl = dfd_ko_cfg_get_item(key);
if (info_ctrl == NULL) {
DBG_DEBUG(DBG_ERROR, "get info ctrl fail, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
if ( DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) {
rv = dfd_info_get_cpld_voltage(key, &value);
if(rv < 0) {
DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08x, rv:%d\n", key, rv);
return -DFD_RV_DEV_NOTSUPPORT;
}
DBG_DEBUG(DBG_VERBOSE, "get cpld voltage ok, value:%d\n", value);
memset(buf_tmp, 0 ,sizeof(buf_tmp));
snprintf(buf_tmp, sizeof(buf_tmp), "%d\n", value);
buf_real_len = strlen(buf_tmp);
if(buf_len <= buf_real_len) {
DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len);
return -DFD_RV_DEV_FAIL;
}
if (pfun) {
buf_real_len = buf_len;
rv = pfun(buf_tmp, strlen(buf_tmp), buf, &buf_real_len, info_ctrl);
if (rv < 0) {
DBG_DEBUG(DBG_ERROR, "deal date error.org value:%s, buf_len:%d, rv=%d\n",
buf_tmp, buf_len, rv);
return -DFD_RV_DEV_NOTSUPPORT;
}
} else {
memcpy(buf, buf_tmp, buf_real_len);
}
return buf_real_len;
}
DBG_DEBUG(DBG_ERROR, "not support mode. key:0x%08x\n", key);
return -DFD_RV_MODE_NOTSUPPORT;
}
int dfd_info_get_sensor(uint32_t key, char *buf, int buf_len, info_hwmon_buf_f pfun)
{
info_ctrl_t *key_info_ctrl;
int rv;
if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) ||
(buf == NULL) || buf_len <= 0) {
DBG_DEBUG(DBG_ERROR, "input arguments error, key_path=0x%08x, buf_len:%d.\n",
key, buf_len);
return -DFD_RV_INVALID_VALUE;
}
key_info_ctrl = dfd_ko_cfg_get_item(key);
if (key_info_ctrl == NULL) {
DBG_DEBUG(DBG_ERROR, "key_path info error, key=0x%08x\n", key);
return -DFD_RV_DEV_NOTSUPPORT;
}
memset(buf, 0 , buf_len);
if (key_info_ctrl->mode == INFO_CTRL_MODE_SRT_CONS) {
snprintf(buf, buf_len, "%s\n", key_info_ctrl->str_cons);
DBG_DEBUG(DBG_VERBOSE, "get sensor value through string config, key=0x%08x, value:%s\n", key, buf);
return strlen(buf);
}
if (key_info_ctrl->mode == INFO_CTRL_MODE_CFG && key_info_ctrl->src == INFO_SRC_FILE) {
DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon, key:0x%08x\n", key);
rv = dfd_2key_info_get_buf(key_info_ctrl, buf, buf_len, pfun);
if (rv < 0) {
DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon failed, key:0x%08x, rv:%d\n", key, rv);
}
return rv;
}
rv = dfd_info_get_sensor_value(key, buf, buf_len, pfun);
if( rv < 0) {
DBG_DEBUG(DBG_ERROR, "get sensor value failed, key=0x%08x, rv:%d.\n", key, rv);
}
return rv;
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright(C) 2001-2015 Ruijie Network. All rights reserved.
*/
#include <linux/list.h>
#include <linux/slab.h>
#include "../include/dfd_cfg_listnode.h"
void *lnode_find_node(lnode_root_t *root, int key)
{
lnode_node_t *lnode;
if (root == NULL){
return NULL;
}
list_for_each_entry(lnode, &(root->root), lst) {
if (lnode->key == key) {
return lnode->data;
}
}
return NULL;
}
int lnode_insert_node(lnode_root_t *root, int key, void *data)
{
lnode_node_t *lnode;
void *data_tmp;
if ((root == NULL) || (data == NULL)) {
return LNODE_RV_INPUT_ERR;
}
data_tmp = lnode_find_node(root, key);
if (data_tmp != NULL) {
return LNODE_RV_NODE_EXIST;
}
lnode = kmalloc(sizeof(lnode_node_t), GFP_KERNEL);
if (lnode == NULL) {
return LNODE_RV_NOMEM;
}
lnode->key = key;
lnode->data = data;
list_add_tail(&(lnode->lst), &(root->root));
return LNODE_RV_OK;
}
int lnode_init_root(lnode_root_t *root)
{
if (root == NULL) {
return LNODE_RV_INPUT_ERR;
}
INIT_LIST_HEAD(&(root->root));
return LNODE_RV_OK;
}
void lnode_free_list(lnode_root_t *root)
{
lnode_node_t *lnode, *lnode_next;
if (root == NULL){
return ;
}
list_for_each_entry_safe(lnode, lnode_next, &(root->root), lst) {
if ( lnode->data ) {
kfree(lnode->data);
lnode->data = NULL;
lnode->key = 0;
}
list_del(&lnode->lst);
kfree(lnode);
lnode = NULL;
}
return ;
}

View File

@@ -0,0 +1,496 @@
/*
* Copyright(C) 2001-2012 Ruijie Network. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include "../include/dfd_frueeprom.h"
#include "../include/dfd_cfg_adapter.h"
#include "../include/dfd_module.h"
#include "../../rg_dev_sysfs/include/rg_sysfs_common.h"
int g_dfd_fru_dbg_level = 0;
module_param(g_dfd_fru_dbg_level, int, S_IRUGO | S_IWUSR);
/**
* Takes the pointer to stream of bytes and length
* and returns the 8 bit checksum
* This algo is per IPMI V2.0 spec
*/
static unsigned char ipmi_calculate_crc(const unsigned char *data, size_t len)
{
char crc = 0;
size_t byte = 0;
for(byte = 0; byte < len; byte++)
{
crc += *data++;
}
return(-crc);
}
/* Validates the data for crc and mandatory fields */
static int ipmi_verify_fru_data(const uint8_t *data, const size_t len)
{
uint8_t checksum = 0;
int rc = -DFD_RV_TYPE_ERR;
/* Validate for first byte to always have a value of [1] */
if(data[0] != IPMI_FRU_HDR_BYTE_ZERO)
{
DBG_FRU_DEBUG(DBG_ERROR, "Invalid entry:[%d] in byte-0\n",data[0]);
return rc;
} else {
DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Validated [0x%X] in entry_1 of fru_data\n",data[0]);
}
/* See if the calculated CRC matches with the embedded one.
* CRC to be calculated on all except the last one that is CRC itself.*/
checksum = ipmi_calculate_crc(data, len - 1);
if(checksum != data[len-1])
{
DBG_FRU_DEBUG(DBG_ERROR, "Checksum mismatch."
" Calculated:[0x%X], Embedded:[0x%X]\n",
checksum, data[len - 1]);
return rc;
} else {
DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Checksum matches:[0x%X]\n",checksum);
}
return 0;
}
/* private method to parse type/length */
static int ipmi_parse_type_length (const void *areabuf,
unsigned int areabuflen,
unsigned int current_area_offset,
uint8_t *number_of_data_bytes,
ipmi_fru_field_t *field)
{
const uint8_t *areabufptr = (const uint8_t*) areabuf;
uint8_t type_length;
uint8_t type_code;
type_length = areabufptr[current_area_offset];
/* ipmi workaround
*
* dell p weredge r610
*
* my reading of the fru spec is that all non-custom fields are
* required to be listed by the vendor. however, on this
* motherboard, some areas list this, indicating that there is
* no more data to be parsed. so now, for "required" fields, i
* check to see if the type-length field is a sentinel before
* calling this function.
*/
type_code = (type_length & IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK) >> IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT;
(*number_of_data_bytes) = type_length & IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK;
/* special case: this shouldn't be a length of 0x01 (see type/length
* byte format in fru information storage definition).
*/
DBG_FRU_DEBUG(DBG_VERBOSE, "areabuflen:%d, current_area_offset:0x%x, type_code:0x%x, number_of_data_bytes:%d\n",
areabuflen, current_area_offset, type_code, *number_of_data_bytes );
if (type_code == IPMI_FRU_TYPE_LENGTH_TYPE_CODE_LANGUAGE_CODE
&& (*number_of_data_bytes) == 0x01) {
DBG_FRU_DEBUG(DBG_ERROR, "fru type length error.value:0x%x\n", type_length);
return (-1);
}
if ((current_area_offset + 1 + (*number_of_data_bytes)) > areabuflen) {
DBG_FRU_DEBUG(DBG_ERROR, "buf length error. current_area_offset:0x%x, need length:%d, total length:0x%x\n",
current_area_offset, *number_of_data_bytes, areabuflen );
return (-1);
}
if (field) {
memset (field->type_length_field, '\0', IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX);
memcpy (field->type_length_field, &areabufptr[current_area_offset + 1], *number_of_data_bytes);
DBG_FRU_DEBUG(DBG_VERBOSE, "fru parse ok. value:%s\n", field->type_length_field);
field->type_length_field_length = *number_of_data_bytes;
}
return (0);
}
static int ipmi_fru_product_info_area(const void *areabuf,
unsigned int areabuflen, ipmi_product_info_t *ipmi_product_info)
{
const uint8_t *areabufptr = (const uint8_t*) areabuf;
unsigned int area_offset = 2;
uint8_t number_of_data_bytes;
int rv;
ipmi_fru_field_t **ipmi_fru_field_point;
int ipmi_fru_field_len, i;
if (!areabuf || !areabuflen || !ipmi_product_info) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n");
return -DFD_RV_INVALID_VALUE;
}
/* Verify the crc and size */
rv = ipmi_verify_fru_data(areabuf, areabuflen);
if(rv < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n");
return rv;
}
ipmi_fru_field_len = (sizeof(ipmi_product_info_t) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *));
if (ipmi_product_info->language_code) {
(*ipmi_product_info->language_code) = areabufptr[area_offset];
}
area_offset++;
ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_product_info + sizeof(uint8_t *));
for(i = 0; i < ipmi_fru_field_len; i++) {
if (*ipmi_fru_field_point) {
memset(*ipmi_fru_field_point, '\0', sizeof(ipmi_fru_field_t));
}
if ((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) || (area_offset == areabuflen - 1)) {
rv = 0;
break;
}
rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point);
if (rv < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv);
break;
}
area_offset += 1; /* type/length byte */
area_offset += number_of_data_bytes;
ipmi_fru_field_point++;
}
return (rv);
}
static int ipmi_fru_board_info_area(const void *areabuf,
unsigned int areabuflen, ipmi_board_info_t *ipmi_board_info)
{
const uint8_t *areabufptr = (const uint8_t*) areabuf;
unsigned int area_offset = 2;
uint8_t number_of_data_bytes;
int rv;
ipmi_fru_field_t **ipmi_fru_field_point;
int ipmi_fru_field_len, i;
if (!areabuf || !areabuflen || !ipmi_board_info) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n");
return -DFD_RV_INVALID_VALUE;
}
/* Verify the crc and size */
rv = ipmi_verify_fru_data(areabuf, areabuflen);
if(rv < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n");
return rv;
}
ipmi_fru_field_len = (sizeof(ipmi_board_info_t) - sizeof(uint8_t *) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *));
if (ipmi_board_info->language_code) {
(*ipmi_board_info->language_code) = areabufptr[area_offset];
}
area_offset++;
if (ipmi_board_info->mfg_time) {
memcpy(ipmi_board_info->mfg_time, &areabufptr[area_offset], IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH);
}
area_offset += IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH;
ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_board_info + sizeof(uint8_t *) + sizeof(uint8_t *));
for(i = 0; i < ipmi_fru_field_len; i++) {
if (*ipmi_fru_field_point) {
memset(*ipmi_fru_field_point, '\0', sizeof(ipmi_fru_field_t));
}
if ((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) || (area_offset == areabuflen - 1)) {
rv = 0;
break;
}
rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point);
if (rv < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv);
break;
}
area_offset += 1; /* type/length byte */
area_offset += number_of_data_bytes;
ipmi_fru_field_point++;
}
return (rv);
}
/**
* Validates the fru data per ipmi common header constructs.
* Returns with updated common_hdr and also file_size
*/
static int ipmi_validate_common_hdr(const uint8_t *fru_data, const size_t data_len)
{
int rc = -1;
uint8_t common_hdr[sizeof(fru_common_header_t)] = {0};
if(data_len >= sizeof(common_hdr))
{
memcpy(common_hdr, fru_data, sizeof(common_hdr));
}
else
{
DBG_FRU_DEBUG(DBG_ERROR, "Incomplete fru data file. Size:[%zd]\n", data_len);
return rc;
}
/* Verify the crc and size */
rc = ipmi_verify_fru_data(common_hdr, sizeof(common_hdr));
if(rc < 0)
{
DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate common header\n");
return rc;
}
return 0;
}
static int dfd_get_frue2prom_info(int bus, int dev_addr, fru_common_header_t *info)
{
int ret;
uint8_t fru_common_header_info[sizeof(fru_common_header_t)];
if (info == NULL) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n");
return -DFD_RV_INVALID_VALUE;
}
ret = dfd_ko_i2c_read(bus, dev_addr, 0, (uint8_t *)info, sizeof(fru_common_header_t));
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom head info error(bus: %d, addr: 0x%02x).\n", bus, dev_addr);
return ret;
}
memcpy(fru_common_header_info, (uint8_t *)info, sizeof(fru_common_header_t));
if (ipmi_validate_common_hdr(fru_common_header_info, sizeof(fru_common_header_t)) != 0) {
return -DFD_RV_TYPE_ERR;
}
return DFD_RV_OK;
}
static int dfd_set_fru_product_info(ipmi_product_info_t *ipmi_product_info, ipmi_fru_field_t *vpd_info, int type)
{
int ret;
ret = DFD_RV_OK;
if (ipmi_product_info == NULL || vpd_info == NULL) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n");
return -DFD_RV_INVALID_VALUE;
}
memset((uint8_t *)ipmi_product_info, 0, sizeof(ipmi_product_info_t));
switch(type) {
case DFD_DEV_INFO_TYPE_SN:
ipmi_product_info->product_serial_number = vpd_info;
break;
case DFD_DEV_INFO_TYPE_NAME:
ipmi_product_info->product_name = vpd_info;
break;
case DFD_DEV_INFO_TYPE_DEV_TYPE:
ipmi_product_info->product_type_fields = vpd_info;
break;
case DFD_DEV_INFO_TYPE_HW_INFO:
ipmi_product_info->product_version = vpd_info;
break;
case DFD_DEV_INFO_TYPE_PART_NAME:
ipmi_product_info->product_part_model_number = vpd_info;
break;
case DFD_DEV_INFO_TYPE_PART_NUMBER:
ipmi_product_info->product_part_model_number = vpd_info;
break;
default:
ret = -1;
break;
}
return ret;
}
static int dfd_set_fru_board_info(ipmi_board_info_t *ipmi_board_info, ipmi_fru_field_t *vpd_info, int type)
{
int ret;
ret = DFD_RV_OK;
if (ipmi_board_info == NULL || vpd_info == NULL) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n");
return -DFD_RV_INVALID_VALUE;
}
memset((uint8_t *)ipmi_board_info, 0, sizeof(ipmi_board_info_t));
switch(type) {
case DFD_DEV_INFO_TYPE_SN:
ipmi_board_info->board_serial_number = vpd_info;
break;
case DFD_DEV_INFO_TYPE_NAME:
ipmi_board_info->board_product_name = vpd_info;
break;
case DFD_DEV_INFO_TYPE_HW_INFO:
ipmi_board_info->board_custom_fields = vpd_info;
break;
case DFD_DEV_INFO_TYPE_PART_NUMBER:
ipmi_board_info->board_part_number = vpd_info;
break;
default:
ret = -1;
break;
}
return ret;
}
int dfd_get_fru_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len)
{
fru_common_header_t info;
uint8_t *fru_data;
int ret;
uint8_t fru_len;
ipmi_product_info_t ipmi_product_info;
ipmi_fru_field_t vpd_info;
int product_offset;
int fru_len_tmp;
if (buf == NULL || buf_len <= 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n");
return -DFD_RV_INVALID_VALUE;
}
DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n",
bus, dev_addr, type, buf, buf_len);
ret = dfd_get_frue2prom_info(bus, dev_addr, &info);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n",
bus, dev_addr, buf, buf_len);
return ret;
}
product_offset = info.product_offset * IPMI_EIGHT_BYTES;
ret = dfd_ko_i2c_read(bus, dev_addr, product_offset + 1, &fru_len, 1);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n",
bus, dev_addr, info.product_offset);
return -DFD_RV_DEV_FAIL;
}
fru_len_tmp = fru_len * IPMI_EIGHT_BYTES;
fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL);
if (fru_data == NULL) {
DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp);
return -DFD_RV_NO_MEMORY;
}
ret = dfd_ko_i2c_read(bus, dev_addr, product_offset, fru_data, fru_len_tmp);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n");
kfree(fru_data);
return ret;
}
memset((uint8_t *)&vpd_info, 0, sizeof(ipmi_fru_field_t));
ret = dfd_set_fru_product_info(&ipmi_product_info, &vpd_info, type);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type);
kfree(fru_data);
return ret;
}
ret = ipmi_fru_product_info_area(fru_data, fru_len_tmp, &ipmi_product_info);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n");
kfree(fru_data);
return ret;
}
kfree(fru_data);
buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length;
memcpy(buf, (uint8_t *)&vpd_info, buf_len);
return DFD_RV_OK;
}
int dfd_get_fru_board_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len)
{
fru_common_header_t info;
uint8_t *fru_data;
int ret;
uint8_t fru_len;
ipmi_board_info_t ipmi_board_info;
ipmi_fru_field_t vpd_info;
int board_offset;
int fru_len_tmp;
if (buf == NULL || buf_len <= 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n");
return -DFD_RV_INVALID_VALUE;
}
DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n",
bus, dev_addr, type, buf, buf_len);
ret = dfd_get_frue2prom_info(bus, dev_addr, &info);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n",
bus, dev_addr, buf, buf_len);
return ret;
}
board_offset = info.board_offset * IPMI_EIGHT_BYTES;
ret = dfd_ko_i2c_read(bus, dev_addr, board_offset + 1, &fru_len, 1);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n",
bus, dev_addr, info.board_offset);
return -DFD_RV_DEV_FAIL;
}
fru_len_tmp = fru_len * IPMI_EIGHT_BYTES;
fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL);
if (fru_data == NULL) {
DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp);
return -DFD_RV_NO_MEMORY;
}
ret = dfd_ko_i2c_read(bus, dev_addr, board_offset, fru_data, fru_len_tmp);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n");
kfree(fru_data);
return ret;
}
memset((uint8_t *)&vpd_info, 0, sizeof(ipmi_fru_field_t));
ret = dfd_set_fru_board_info(&ipmi_board_info, &vpd_info, type);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type);
kfree(fru_data);
return ret;
}
ret = ipmi_fru_board_info_area(fru_data, fru_len_tmp, &ipmi_board_info);
if (ret < 0) {
DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n");
kfree(fru_data);
return ret;
}
kfree(fru_data);
buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length;
memcpy(buf, (uint8_t *)&vpd_info, buf_len);
return DFD_RV_OK;
}

View File

@@ -0,0 +1,474 @@
/*
* Copyright (C) 2003-2014 FreeIPMI Core Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*****************************************************************************\
* Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC.
* Copyright (C) 2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Albert Chu <chu11@llnl.gov>
* UCRL-CODE-232183
*
* This file is part of Ipmi-fru, a tool used for retrieving
* motherboard field replaceable unit (FRU) information. For details,
* see http://www.llnl.gov/linux/.
*
* Ipmi-fru is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* Ipmi-fru is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Ipmi-fru. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/
#include <linux/module.h>
#include "../include/dfd_tlveeprom.h"
#include "../include/dfd_module.h"
#include "../../rg_dev_sysfs/include/rg_sysfs_common.h"
/* using in is_valid_tlvinfo_header */
static uint32_t g_eeprom_size;
/*
* List of TLV codes and names.
*/
static const struct tlv_code_desc tlv_code_list[] = {
{ TLV_CODE_PRODUCT_NAME , "Product Name"},
{ TLV_CODE_PART_NUMBER , "Part Number"},
{ TLV_CODE_SERIAL_NUMBER , "Serial Number"},
{ TLV_CODE_MAC_BASE , "Base MAC Address"},
{ TLV_CODE_MANUF_DATE , "Manufacture Date"},
{ TLV_CODE_DEVICE_VERSION , "Device Version"},
{ TLV_CODE_LABEL_REVISION , "Label Revision"},
{ TLV_CODE_PLATFORM_NAME , "Platform Name"},
{ TLV_CODE_ONIE_VERSION , "ONIE Version"},
{ TLV_CODE_MAC_SIZE , "MAC Addresses"},
{ TLV_CODE_MANUF_NAME , "Manufacturer"},
{ TLV_CODE_MANUF_COUNTRY , "Country Code"},
{ TLV_CODE_VENDOR_NAME , "Vendor Name"},
{ TLV_CODE_DIAG_VERSION , "Diag Version"},
{ TLV_CODE_SERVICE_TAG , "Service Tag"},
{ TLV_CODE_VENDOR_EXT , "Vendor Extension"},
{ TLV_CODE_CRC_32 , "CRC-32"},
};
#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0]))
const unsigned long g_crc_table[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len)
{
unsigned i;
if (len < 1)
return 0xffffffff;
for (i = 0; i != len; ++i)
{
crc = g_crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
}
crc = crc ^ 0xffffffff;
return crc;
}
/*
* is_valid_tlv
*
* Perform basic sanity checks on a TLV field. The TLV is pointed to
* by the parameter provided.
* 1. The type code is not reserved (0x00 or 0xFF)
*/
static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv)
{
return ((tlv->type != 0x00) && (tlv->type != 0xFF));
}
/*
* is_valid_tlvinfo_header
*
* Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM
* data pointed to by the parameter:
* 1. First 8 bytes contain null-terminated ASCII string "TlvInfo"
* 2. Version byte is 1
* 3. Total length bytes contain value which is less than or equal
* to the allowed maximum (2048-11)
*
*/
static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr)
{
int max_size = g_eeprom_size;
return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) &&
(hdr->version == TLV_INFO_VERSION) &&
(be16_to_cpu(hdr->totallen) <= max_size) );
}
/*
* decode_tlv_value
*
* Decode a single TLV value into a string.
* The validity of EEPROM contents and the TLV field have been verified
* prior to calling this function.
*/
static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value)
{
int i;
char *value;
uint32_t length;
value = (char *)decode_value->value;
switch (tlv->type) {
case TLV_CODE_PRODUCT_NAME:
case TLV_CODE_PART_NUMBER:
case TLV_CODE_SERIAL_NUMBER:
case TLV_CODE_MANUF_DATE:
case TLV_CODE_LABEL_REVISION:
case TLV_CODE_PLATFORM_NAME:
case TLV_CODE_ONIE_VERSION:
case TLV_CODE_MANUF_NAME:
case TLV_CODE_MANUF_COUNTRY:
case TLV_CODE_VENDOR_NAME:
case TLV_CODE_DIAG_VERSION:
case TLV_CODE_SERVICE_TAG:
memcpy(value, tlv->value, tlv->length);
value[tlv->length] = 0;
length = tlv->length;
break;
case TLV_CODE_MAC_BASE:
length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X",
tlv->value[0], tlv->value[1], tlv->value[2],
tlv->value[3], tlv->value[4], tlv->value[5]);
break;
case TLV_CODE_DEVICE_VERSION:
length = sprintf(value, "%u", tlv->value[0]);
break;
case TLV_CODE_MAC_SIZE:
length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]);
break;
case TLV_CODE_VENDOR_EXT:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s %02X", value, tlv->value[i]);
}
break;
case TLV_CODE_CRC_32:
length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0],
tlv->value[1], tlv->value[2], tlv->value[3]);
break;
default:
value[0] = 0;
length = 0;
for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) {
length += sprintf(value, "%s 0x%02X", value, tlv->value[i]);
}
break;
}
decode_value->length = length;
}
/*
* is_checksum_valid
*
* Validate the checksum in the provided TlvInfo EEPROM data. First,
* verify that the TlvInfo header is valid, then make sure the last
* TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data
* and compare it to the value stored in the EEPROM CRC-32 TLV.
*/
static bool is_checksum_valid(uint8_t *eeprom)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_crc;
unsigned int calc_crc;
unsigned int stored_crc;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
/* Is the eeprom header valid? */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
return false;
}
/* Is the last TLV a CRC? */
eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)];
if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) {
return false;
}
/* Calculate the checksum */
calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) +
be16_to_cpu(eeprom_hdr->totallen) - 4);
stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) |
(eeprom_crc->value[2] << 8) | eeprom_crc->value[3]);
return (calc_crc == stored_crc);
}
/*
* tlvinfo_find_tlv
*
* This function finds the TLV with the supplied code in the EERPOM.
* An offset from the beginning of the EEPROM is returned in the
* eeprom_index parameter if the TLV is found.
*/
static bool tlvinfo_find_tlv(uint8_t *eeprom, uint8_t tcode, int *eeprom_index)
{
tlvinfo_header_t *eeprom_hdr;
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
/* Search through the TLVs, looking for the first one which matches the
* supplied type code. */
*eeprom_index = sizeof(tlvinfo_header_t);
eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen);
while (*eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index];
if (!is_valid_tlv(eeprom_tlv)) {
return false;
}
if (eeprom_tlv->type == tcode) {
return true;
}
*eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
return false;
}
/*
* tlvinfo_decode_tlv
*
* This function finds the TLV with the supplied code in the EERPOM
* and decodes the value into the buffer provided.
*/
static bool tlvinfo_decode_tlv(uint8_t *eeprom, uint8_t tcode, tlv_decode_value_t *decode_value)
{
int eeprom_index;
tlvinfo_tlv_t *eeprom_tlv;
/* Find the TLV and then decode it */
if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) {
eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index];
decode_tlv_value(eeprom_tlv, decode_value);
return true;
}
return false;
}
/*
* parse_tlv_eeprom
*
* parse the EEPROM into memory, if it hasn't already been read.
*/
int parse_tlv_eeprom(uint8_t *eeprom, uint32_t size)
{
unsigned int i;
bool ret;
tlvinfo_header_t *eeprom_hdr;
tlv_decode_value_t decode_value;
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
g_eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n");
return -1;
}
for (i = 0; i < TLV_CODE_NUM; i++) {
memset((void *)&decode_value, 0, sizeof(tlv_decode_value_t));
ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value);
if (!ret) {
DBG_DEBUG(DBG_ERROR, "No found type: %s\n", tlv_code_list[i].m_name);
continue;
}
DBG_DEBUG(DBG_VERBOSE, "i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code,
decode_value.value);
for (j = 0; j < decode_value.length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG(DBG_VERBOSE, "\n");
}
DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value.value[j]);
}
DBG_DEBUG(DBG_VERBOSE, "\n\n");
}
return 0;
}
static int dfd_parse_tlv_eeprom(uint8_t *eeprom, uint32_t size, uint8_t main_type, tlv_decode_value_t *decode_value)
{
bool ret;
tlvinfo_header_t *eeprom_hdr;
int j;
eeprom_hdr = (tlvinfo_header_t *) eeprom;
g_eeprom_size = size; /* eeprom real size */
if (!is_valid_tlvinfo_header(eeprom_hdr)) {
DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n");
return -1;
}
if (!is_checksum_valid(eeprom)) {
DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n");
return -1;
}
ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value);
if (!ret) {
DBG_DEBUG(DBG_ERROR, "No found type: %d\n", main_type);
return -1;
}
DBG_DEBUG(DBG_VERBOSE, "Found type: %d, value: %s\n", main_type,decode_value->value);
for (j = 0; j < decode_value->length; j++) {
if ((j % 16) == 0) {
DBG_DEBUG(DBG_VERBOSE, "\n");
}
DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value->value[j]);
}
DBG_DEBUG(DBG_VERBOSE, "\n\n");
return 0;
}
#if 0
static int tlvinfo_find_rg_ext_tlv(tlv_decode_value_t *ext_tlv_value, uint8_t ext_type,
uint8_t *buf, uint32_t *buf_len)
{
tlvinfo_tlv_t *eeprom_tlv;
int eeprom_end, eeprom_index;
/* Search through the TLVs, looking for the first one which matches the
* supplied type code.*/
DBG_DEBUG(DBG_VERBOSE, "ext_tlv_value->length: %d.\n", ext_tlv_value->length);
for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) {
if ((eeprom_index % 16) == 0) {
DBG_DEBUG(DBG_VERBOSE, "\n");
}
DBG_DEBUG(DBG_VERBOSE, "%02x ", ext_tlv_value->value[eeprom_index]);
}
DBG_DEBUG(DBG_VERBOSE, "\n");
eeprom_index = 0;
eeprom_end = ext_tlv_value->length;
while (eeprom_index < eeprom_end) {
eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]);
if (!is_valid_tlv(eeprom_tlv)) {
DBG_DEBUG(DBG_ERROR, "tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type);
return -1;
}
DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length);
if (eeprom_tlv->type == ext_type) {
if (*buf_len >= eeprom_tlv->length) {
memcpy(buf, eeprom_tlv->value, eeprom_tlv->length);
DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length);
*buf_len = eeprom_tlv->length;
return 0;
}
DBG_DEBUG(DBG_VERBOSE, "buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length);
return -1;
}
eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length;
}
DBG_DEBUG(DBG_VERBOSE, "ext_type %d: tlv is not found.\n", ext_type);
return -1;
}
#endif
int dfd_tlvinfo_get_e2prom_info(uint8_t *eeprom, uint32_t size, dfd_tlv_type_t *tlv_type, uint8_t* buf, uint32_t *buf_len)
{
tlv_decode_value_t decode_value;
int ret;
if (eeprom == NULL || tlv_type == NULL || buf == NULL) {
DBG_DEBUG(DBG_ERROR, "Input para invalid.\n");
return -1;
}
memset((void *)&decode_value, 0, sizeof(tlv_decode_value_t));
ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value);
if (ret) {
DBG_DEBUG(DBG_ERROR, "dfd_parse_tlv_eeprom failed ret %d.\n", ret);
return ret;
}
if (*buf_len >= decode_value.length) {
memcpy(buf, decode_value.value, decode_value.length);
*buf_len = decode_value.length;
return 0;
}
DBG_DEBUG(DBG_ERROR, "buf_len %d small than info_len %d.\n", *buf_len, decode_value.length);
return -1;
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright(C) 2001-2012 Ruijie Network. All rights reserved.
*/
#include <linux/module.h>
#include "./include/dfd_module.h"
#include "./include/dfd_cfg.h"
#include "./include/dfd_cfg_adapter.h"
#include "./include/dfd_cfg_info.h"
#include "./include/dfd_frueeprom.h"
int g_dfd_cpld_dbg_level = 0;
module_param(g_dfd_cpld_dbg_level, int, S_IRUGO | S_IWUSR);
ssize_t dfd_get_cpld_name(unsigned int cpld_index, char *buf)
{
int key;
char *cpld_name;
if (buf == NULL) {
DBG_CPLD_DEBUG(DBG_ERROR, "param error. buf is NULL.cpld index:%d", cpld_index);
return -DFD_RV_INVALID_VALUE;
}
memset(buf, 0, PAGE_SIZE);
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_NAME, cpld_index, 0);
cpld_name = dfd_ko_cfg_get_item(key);
if (cpld_name == NULL) {
DBG_CPLD_DEBUG(DBG_ERROR, "cpld name config error, key=0x%08x\n", key);
return -DFD_RV_NODE_FAIL;
}
DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_name);
snprintf(buf, PAGE_SIZE, "%s\n", cpld_name);
return strlen(buf);
}
ssize_t dfd_get_cpld_type(unsigned int cpld_index, char *buf)
{
int key;
char *cpld_type;
if (buf == NULL) {
DBG_CPLD_DEBUG(DBG_ERROR, "param error. buf is NULL.cpld index:%d\n", cpld_index);
return -DFD_RV_INVALID_VALUE;
}
memset(buf, 0, PAGE_SIZE);
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TYPE, cpld_index, 0);
cpld_type = dfd_ko_cfg_get_item(key);
if (cpld_type == NULL) {
DBG_CPLD_DEBUG(DBG_ERROR, "cpld type config error, key=0x%08x\n", key);
return -DFD_RV_NODE_FAIL;
}
DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_type);
snprintf(buf, PAGE_SIZE, "%s\n", cpld_type);
return strlen(buf);
}
ssize_t dfd_get_cpld_version(unsigned int cpld_index, char *buf)
{
int key, rv;
uint32_t value;
if (buf == NULL) {
DBG_CPLD_DEBUG(DBG_ERROR, "param error. buf is NULL.");
return -DFD_RV_INVALID_VALUE;
}
memset(buf, 0, PAGE_SIZE);
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_VERSION, cpld_index, 0);
rv = dfd_info_get_int(key, &value, NULL);
if (rv < 0) {
DBG_CPLD_DEBUG(DBG_ERROR, "cpld version config error, key=0x%08x\n", key);
return -DFD_RV_NODE_FAIL;
}
DBG_CPLD_DEBUG(DBG_VERBOSE, "%x\n", value);
snprintf(buf, PAGE_SIZE, "%08x\n", value);
return strlen(buf);
}
int dfd_set_cpld_testreg(unsigned int cpld_index, int value)
{
int key, ret;
if (value < 0 || value > 0xff) {
DBG_CPLD_DEBUG(DBG_ERROR, "can not set cpld test register value = 0x%02x.\n", value);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, cpld_index, 0);
ret = dfd_info_set_int(key, value);
if (ret < 0) {
DBG_CPLD_DEBUG(DBG_ERROR, "set cpld test register error, key:0x%x,ret:%d\n",key, ret);
return ret;
}
return DFD_RV_OK;
}
int dfd_get_cpld_testreg(unsigned int cpld_index, int *value)
{
int key, ret;
key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, cpld_index, 0);
ret = dfd_info_get_int(key, value, NULL);
if (ret < 0) {
DBG_CPLD_DEBUG(DBG_ERROR, "get cpld test register error, key:0x%x,ret:%d\n",key, ret);
return ret;
}
return DFD_RV_OK;
}

View File

@@ -0,0 +1,487 @@
/*
* Copyright(C) 2001-2012 Ruijie Network. All rights reserved.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include "./include/dfd_module.h"
#include "./include/dfd_cfg.h"
#include "./include/dfd_cfg_adapter.h"
#include "./include/dfd_cfg_info.h"
#include "./include/dfd_frueeprom.h"
#include "../rg_dev_sysfs/include/rg_sysfs_common.h"
#define DFD_FAN_EEPROM_MODE_TLV_STRING "tlv"
#define DFD_FAN_EEPROM_MODE_FRU_STRING "fru"
#define FAN_SIZE (256)
typedef enum fan_status_e {
FAN_ABSENT = 0,
FAN_OK = 1,
FAN_NOT_OK = 2,
} fan_status_t;
typedef enum fan_present_status_e {
ABSENT = 0,
PRESENT = 1,
} fan_present_status_t;
typedef enum fan_motor_status_e {
MOTOR_STALL = 0,
MOTOR_ROLL = 1,
} fan_motor_status_t;
typedef enum fan_eeprom_mode_e {
FAN_EEPROM_MODE_TLV, /* TLV */
FAN_EEPROM_MODE_FRU, /*FRU*/
} fan_eeprom_mode_t;
typedef struct dfd_dev_head_info_s {
uint8_t ver;
uint8_t flag;
uint8_t hw_ver;
uint8_t type;
int16_t tlv_len;
} dfd_dev_head_info_t;
typedef struct dfd_dev_tlv_info_s {
uint8_t type;
uint8_t len;
uint8_t data[0];
} dfd_dev_tlv_info_t;
typedef enum fan_direction_e {
FRONT_TO_BACK = 0,
BACK_TO_FRONT = 1,
FAN_DIRECTION_END = 2,
} fan_direction_t;
int g_dfd_fan_dbg_level = 0;
module_param(g_dfd_fan_dbg_level, int, S_IRUGO | S_IWUSR);
static int dfd_get_fan_eeprom_mode(void)
{
int key, mode;
char *name;
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_E2_MODE, 0, 0);
name = dfd_ko_cfg_get_item(key);
if (name == NULL) {
DFD_FAN_DEBUG(DBG_WARN, "get fan eeprom mode fail, key=0x%08x\n", key);
return FAN_EEPROM_MODE_TLV;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode_name %s.\n", name);
if (!strncmp(name, DFD_FAN_EEPROM_MODE_TLV_STRING, strlen(DFD_FAN_EEPROM_MODE_TLV_STRING))) {
mode = FAN_EEPROM_MODE_TLV;
} else if (!strncmp(name, DFD_FAN_EEPROM_MODE_FRU_STRING, strlen(DFD_FAN_EEPROM_MODE_FRU_STRING))) {
mode = FAN_EEPROM_MODE_FRU;
} else {
mode = FAN_EEPROM_MODE_TLV;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode %d.\n", mode);
return mode;
}
static int dfd_fan_tlv_eeprom_read(int bus, int addr, uint8_t cmd, char *buf)
{
dfd_dev_head_info_t info;
char tmp_tlv_len[sizeof(uint16_t)];
char *tlv_data;
dfd_dev_tlv_info_t *tlv;
int buf_len;
int rv, match_flag;
if (buf == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL\n");
return -DFD_RV_INVALID_VALUE;
}
rv = dfd_ko_i2c_read(bus, addr, 0, (uint8_t *)&info, sizeof(dfd_dev_head_info_t));
if (rv < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan may not present.\n");
return -DFD_RV_DEV_NOTSUPPORT;
}
memcpy(tmp_tlv_len, (uint8_t *)&info.tlv_len, sizeof(uint16_t));
info.tlv_len = (tmp_tlv_len[0] << 8) + tmp_tlv_len[1];
if ((info.tlv_len <= 0 ) || (info.tlv_len > 0xFF)) {
DFD_FAN_DEBUG(DBG_ERROR, "fan maybe not set mac.\n");
return -DFD_RV_TYPE_ERR;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "info.tlv_len:%d\n", info.tlv_len);
tlv_data = (uint8_t *)kmalloc(info.tlv_len, GFP_KERNEL);
if (tlv_data == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "tlv_data kmalloc failed \n");
return -DFD_RV_NO_MEMORY;
}
memset(tlv_data, 0, info.tlv_len);
rv = dfd_ko_i2c_read(bus, addr, sizeof(dfd_dev_head_info_t), tlv_data, info.tlv_len);
if (rv < 0) {
DFD_FAN_DEBUG(DBG_ERROR,"fan eeprom read failed\n");
kfree(tlv_data);
return -DFD_RV_DEV_NOTSUPPORT;
}
buf_len = FAN_SIZE - 1;
match_flag = 0;
for(tlv = (dfd_dev_tlv_info_t *)tlv_data; (ulong)tlv < (ulong)tlv_data + info.tlv_len;) {
DFD_FAN_DEBUG(DBG_VERBOSE, "tlv: %p, tlv->type: 0x%x, tlv->len: 0x%x info->tlv_len: 0x%x\n",
tlv, tlv->type, tlv->len, info.tlv_len);
if (tlv->type == cmd && tlv->len <= buf_len ) {
DFD_FAN_DEBUG(DBG_VERBOSE, "find tlv data, copy...\n");
memcpy(buf, (uint8_t *)tlv->data, tlv->len);
buf_len = (uint32_t)tlv->len;
match_flag = 1;
break;
}
tlv = (dfd_dev_tlv_info_t *)((uint8_t* )tlv + sizeof(dfd_dev_tlv_info_t) + tlv->len);
}
kfree(tlv_data);
if (match_flag == 0) {
DFD_FAN_DEBUG(DBG_ERROR,"can't find fan tlv date. bus:%d, addr:0x%02x, tlv type:%d.\n", bus, addr, cmd);
return -DFD_RV_TYPE_ERR;
}
return buf_len;
}
int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index)
{
int key, ret;
int status;
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_ROLL_STATUS, fan_index, motor_index);
ret = dfd_info_get_int(key, &status, NULL);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan:%d,motor:%d\n",
fan_index, motor_index);
return ret;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u motor%u get fan roll status success, status:%d.\n",
fan_index, motor_index, status);
return status;
}
int dfd_get_fan_present_status(unsigned int fan_index)
{
int key, ret;
int status;
key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, RG_MAIN_DEV_FAN, fan_index);
ret = dfd_info_get_int(key, &status, NULL);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan%u get present status error, key:0x%x\n", fan_index, key);
return ret;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan%u get present status success, status:%d.\n", fan_index, status);
return status;
}
int dfd_get_fan_status(unsigned int fan_index)
{
int motor_num, motor_index, status, errcnt;
status = dfd_get_fan_present_status(fan_index);
if(status != PRESENT ) {
DFD_FAN_DEBUG(DBG_ERROR, "fan index:%d, status:%d\n",fan_index, status);
return status;
}
motor_num = dfd_get_dev_number(RG_MAIN_DEV_FAN, RG_MINOR_DEV_MOTOR);
if(motor_num <= 0 ) {
DFD_FAN_DEBUG(DBG_ERROR, "get motor number error:%d\n",motor_num);
return -DFD_RV_DEV_FAIL;
}
errcnt = 0;
for(motor_index = 0; motor_index < motor_num; motor_index++) {
status = dfd_get_fan_roll_status(fan_index, motor_index);
if(status < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan index:%d, motor index:%d, status:%d\n",
fan_index, motor_index, status);
return status;
}
if(status != MOTOR_ROLL) {
DFD_FAN_DEBUG(DBG_ERROR,
"stall:fan index:%d, motor index:%d, status:%d\n",fan_index, motor_index, status);
errcnt++;
}
}
if (errcnt > 0) {
return FAN_NOT_OK;
}
return FAN_OK;
}
ssize_t dfd_get_fan_status_str(unsigned int fan_index, char *buf)
{
int ret;
if(buf == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "params error.fan_index:%d.",fan_index);
return -DFD_RV_INVALID_VALUE;
}
ret = dfd_get_fan_status(fan_index);
if(ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan status error,ret:%d, fan_index:%d\n", ret, fan_index);
return ret;
}
memset(buf, 0, PAGE_SIZE);
return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", ret);
}
ssize_t dfd_get_fan_info(unsigned int fan_index, uint8_t cmd, char *buf)
{
int key, rv, eeprom_mode;
char fan_buf[FAN_SIZE];
dfd_i2c_dev_t *i2c_dev;
if (buf == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index:%d, cmd:0x%x.\n", fan_index, cmd);
return -DFD_RV_INVALID_VALUE;
}
memset(buf, 0, PAGE_SIZE);
memset(fan_buf, 0, FAN_SIZE);
key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, RG_MAIN_DEV_FAN, fan_index);
i2c_dev = dfd_ko_cfg_get_item(key);
if (i2c_dev == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "fan i2c dev config error, key=0x%08x\n", key);
return -DFD_RV_NODE_FAIL;
}
eeprom_mode = dfd_get_fan_eeprom_mode();
if(eeprom_mode == FAN_EEPROM_MODE_TLV) {
rv = dfd_fan_tlv_eeprom_read(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf);
} else {
rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE);
}
if (rv < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan eeprom read failed");
return -DFD_RV_DEV_FAIL;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "%s\n", fan_buf);
snprintf(buf, FAN_SIZE, "%s\n", fan_buf);
return strlen(buf);
}
ssize_t dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed)
{
int key, ret, speed_tmp;
if (speed == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED, fan_index, motor_index);
ret = dfd_info_get_int(key, &speed_tmp, NULL);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan speed error, key:0x%x,ret:%d\n",key, ret);
return ret;
}
if (speed_tmp == 0 || speed_tmp == 0xffff) {
*speed = 0;
} else {
*speed = 15000000 / speed_tmp;
}
return DFD_RV_OK;
}
int dfd_set_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int level)
{
int key, ret;
if (level < 0 || level > 0xff) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can not set fan speed level: %d.\n",
fan_index, motor_index, level);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index);
ret = dfd_info_set_int(key, level);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan level 0x%02x error, key:0x%x,ret:%d\n",
fan_index, motor_index, level, key, ret);
return ret;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan speed level 0x%02x success.\n",
fan_index, motor_index, level);
return DFD_RV_OK;
}
int dfd_set_fan_pwm(unsigned int fan_index, unsigned int motor_index, int pwm)
{
int ret, data;
if (pwm < 0 || pwm > 100) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, can't set pwm: %d.\n",
fan_index, motor_index, pwm);
return -DFD_RV_INVALID_VALUE;
}
data = pwm * 255 / 100;
ret = dfd_set_fan_speed_level(fan_index, motor_index, data);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, set fan ratio:%d error, ret:%d\n",
fan_index, motor_index, data, ret);
return ret;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, set fan ratio %d success.\n",
fan_index, motor_index, data);
return DFD_RV_OK;
}
int dfd_get_fan_speed_level(unsigned int fan_index, unsigned int motor_index, int *level)
{
int key, ret, speed_level;
if (level == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, motor_index);
ret = dfd_info_get_int(key, &speed_level, NULL);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan speed level error, key:0x%x,ret:%d\n",
fan_index, motor_index, key, ret);
return ret;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan speed level success, value:0x%02x.\n",
fan_index, motor_index, speed_level);
*level = speed_level;
return DFD_RV_OK;
}
int dfd_get_fan_pwm(unsigned int fan_index, unsigned int motor_index, int *pwm)
{
int ret, level;
if (pwm == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
ret = dfd_get_fan_speed_level(fan_index, motor_index, &level);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "fan:%u, motor:%u, get fan pwm error, ret:%d\n",
fan_index, motor_index, ret);
return ret;
}
if ((level * 100) % 255 > 0) {
*pwm = level * 100 / 255 + 1;
} else {
*pwm = level * 100 / 255;
}
DFD_FAN_DEBUG(DBG_VERBOSE, "fan:%u, motor:%u, get fan pwm success, value:%d.\n",
fan_index, motor_index, *pwm);
return DFD_RV_OK;
}
int dfd_get_fan_speed_tolerance(unsigned int fan_index, unsigned int motor_index, int *value)
{
int key;
int *p_fan_speed_tolerance;
if (value == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED_TOLERANCE, fan_index, motor_index);
p_fan_speed_tolerance = dfd_ko_cfg_get_item(key);
if (p_fan_speed_tolerance == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan speed tolerance failed, key:0x%x\n",key);
return -DFD_RV_DEV_NOTSUPPORT;
}
*value = *p_fan_speed_tolerance;
DFD_FAN_DEBUG(DBG_VERBOSE, "get fan speed tolerance ok, key:0x%x, value:%d\n",key, *value);
return DFD_RV_OK;
}
int dfd_get_fan_speed_target(unsigned int fan_index, unsigned int motor_index, int *value)
{
int key;
int *p_fan_speed_target;
if (value == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED_TARGET, fan_index, motor_index);
p_fan_speed_target = dfd_ko_cfg_get_item(key);
if (p_fan_speed_target == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan speed target failed, key:0x%x\n",key);
return -DFD_RV_DEV_NOTSUPPORT;
}
*value = *p_fan_speed_target;
DFD_FAN_DEBUG(DBG_VERBOSE, "get fan speed target ok, key:0x%x, value:%d\n",key, *value);
return DFD_RV_OK;
}
int dfd_get_fan_direction(unsigned int fan_index, unsigned int motor_index, int *value)
{
int key;
int *p_fan_direction;
if (value == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_DIRECTION, fan_index, motor_index);
p_fan_direction = dfd_ko_cfg_get_item(key);
if (p_fan_direction == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan direction failed, key:0x%x\n",key);
return -DFD_RV_DEV_NOTSUPPORT;
}
*value = *p_fan_direction;
DFD_FAN_DEBUG(DBG_VERBOSE, "get fan direction ok, key:0x%x, value:%d\n",key, *value);
return DFD_RV_OK;
}
ssize_t dfd_get_fan_direction_str(unsigned int fan_index, unsigned int motor_index, char *buf)
{
int ret, value;
if (buf == NULL) {
DFD_FAN_DEBUG(DBG_ERROR, "param error. buf is NULL. fan index:%d, motor index:%d.\n",
fan_index, motor_index);
return -DFD_RV_INVALID_VALUE;
}
ret = dfd_get_fan_direction(fan_index, motor_index, &value);
if (ret < 0) {
DFD_FAN_DEBUG(DBG_ERROR, "get fan direction string failed, ret:%d, fan_index:%d, motor_index:%d\n",
ret, fan_index, motor_index);
return ret;
}
memset(buf, 0, PAGE_SIZE);
return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", value);
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright(C) 2001-2012 Ruijie Network. All rights reserved.
*/
#include <linux/module.h>
#include "./include/dfd_module.h"
#include "./include/dfd_cfg.h"
#include "./include/dfd_cfg_info.h"
#include "./include/dfd_cfg_adapter.h"
#define LED_STATUS_MEM (9)
int g_dfd_sysled_dbg_level = 0;
module_param(g_dfd_sysled_dbg_level, int, S_IRUGO | S_IWUSR);
typedef enum dfd_led_status_e {
DFD_LED_DARK = 0,
DFD_LED_GREEN = 1,
DFD_LED_YELLOW = 2,
DFD_LED_RED = 3,
DFD_LED_GREEN_FLASH = 4,
DFD_LED_YELLOW_FLASH = 5,
DFD_LED_RED_FLASH = 6,
DFD_LED_BLUE = 7,
DFD_LED_END = 8,
} dfd_led_status_t;
static int g_dfd_rg_led_status[LED_STATUS_MEM] = {
DFD_LED_DARK,
DFD_LED_RED_FLASH,
DFD_LED_RED,
DFD_LED_GREEN_FLASH,
DFD_LED_GREEN,
DFD_LED_YELLOW_FLASH,
DFD_LED_YELLOW,
DFD_LED_DARK,
DFD_LED_BLUE,
};
static int dfd_get_led_status_value(uint16_t led_id, uint8_t led_index, int *value)
{
int key, ori_value, ret, value_tmp;
int *p_decode_value;
key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS, led_id, led_index);
ret = dfd_info_get_int(key, &ori_value, NULL);
if (ret < 0) {
DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error, key:0x%x,ret:%d\n", key, ret);
return ret;
}
key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS_DECODE, led_id, ori_value);
p_decode_value = dfd_ko_cfg_get_item(key);
if (p_decode_value == NULL) {
DFD_FAN_DEBUG(DBG_VERBOSE, "led id:%d index:%d, status needn't decode.value:0x%x\n", led_id, led_index, ori_value);
value_tmp = ori_value;
} else {
DFD_FAN_DEBUG(DBG_VERBOSE, "led id:%d index:%d,, ori_value:0x%x,decode value:0x%x\n", led_id, led_index, ori_value, *p_decode_value);
value_tmp = *p_decode_value;
}
if(value_tmp >=0 && value_tmp < LED_STATUS_MEM) {
*value = g_dfd_rg_led_status[value_tmp];
return DFD_RV_OK;
}
return -DFD_RV_INVALID_VALUE;
}
ssize_t dfd_get_led_status(uint16_t led_id, uint8_t led_index, char *buf)
{
int ret, led_value;
if(buf == NULL) {
DBG_SYSLED_DEBUG(DBG_ERROR, "param error, buf is NULL. led_id:%d, led_index:%d\n",
led_id, led_index);
return -DFD_RV_INVALID_VALUE;
}
ret = dfd_get_led_status_value(led_id, led_index, &led_value);
if(ret < 0) {
DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error,ret:%d, led_id:%d, led_index:%d\n", ret, led_id, led_index);
return ret;
}
memset(buf, 0 , PAGE_SIZE);
return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", led_value);
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright(C) 2001-2012 Ruijie Network. All rights reserved.
*/
#include <linux/module.h>
#include "../rg_dev_sysfs/include/rg_sysfs_common.h"
#include "./include/dfd_module.h"
#include "./include/dfd_cfg.h"
#include "./include/dfd_fan_driver.h"
#include "./include/dfd_syseeprom_driver.h"
#include "./include/dfd_cpld_driver.h"
#include "./include/dfd_led_driver.h"
#include "./include/dfd_slot_driver.h"
#include "./include/dfd_sensors_driver.h"
#include "./include/dfd_psu_driver.h"
#include "./include/dfd_sff_driver.h"
typedef enum dfd_dev_init_fail_s {
DFD_KO_INIT_CPLD_FAIL = 1,
DFD_KO_INIT_FPGA_FAIL = 2,
DFD_KO_INIT_IRQ_FAIL = 3,
DFD_KO_INIT_CFG_FAIL = 4,
DFD_KO_INIT_DATA_FAIL = 5,
} dfd_dev_init_fail_t;
int g_dfd_dbg_level = 0;
char *g_status_mem_str[STATUS_MEM_END] = {
"ABSENT",
"OK",
"NOT OK",
};
int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id)
{
int key,dev_num;
int *p_dev_num;
key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, main_dev_id, minor_dev_id);
p_dev_num = dfd_ko_cfg_get_item(key);
if (p_dev_num == NULL) {
DBG_DEBUG(DBG_ERROR, "get device number failed, key:0x%x\n",key);
return -DFD_RV_DEV_NOTSUPPORT;
}
dev_num = *p_dev_num;
DBG_DEBUG(DBG_VERBOSE, "get device number ok, number:%d\n",dev_num);
return dev_num;
}
static struct switch_drivers_t switch_drivers= {
.get_dev_number = dfd_get_dev_number,
/* fan */
.get_fan_status = dfd_get_fan_status,
.get_fan_info = dfd_get_fan_info,
.get_fan_speed = dfd_get_fan_speed,
.get_fan_pwm = dfd_get_fan_pwm,
.set_fan_pwm = dfd_set_fan_pwm,
.get_fan_speed_tolerance = dfd_get_fan_speed_tolerance,
.get_fan_speed_target = dfd_get_fan_speed_target,
.get_fan_direction = dfd_get_fan_direction,
.get_fan_status_str = dfd_get_fan_status_str,
.get_fan_direction_str = dfd_get_fan_direction_str,
.get_fan_present_status = dfd_get_fan_present_status,
.get_fan_roll_status = dfd_get_fan_roll_status,
.get_fan_speed_level = dfd_get_fan_speed_level,
.set_fan_speed_level = dfd_set_fan_speed_level,
/* syseeprom */
.get_syseeprom_info = dfd_get_syseeprom_info,
/* cpld */
.get_cpld_name = dfd_get_cpld_name,
.get_cpld_type = dfd_get_cpld_type,
.get_cpld_version = dfd_get_cpld_version,
.get_cpld_testreg = dfd_get_cpld_testreg,
.set_cpld_testreg = dfd_set_cpld_testreg,
/* led */
.get_led_status = dfd_get_led_status,
/* slot */
.get_slot_status_str = dfd_get_slot_status_str,
.get_slot_info = dfd_get_slot_info,
/* sensors */
.get_temp_info = dfd_get_temp_info,
.get_voltage_info = dfd_get_voltage_info,
/* psu */
.get_psu_info = dfd_get_psu_info,
.get_psu_status_str = dfd_get_psu_status_str,
.get_psu_sensor_info = dfd_get_psu_sensor_info,
.get_psu_present_status = dfd_get_psu_present_status,
.get_psu_output_status = dfd_get_psu_output_status,
.get_psu_alert_status = dfd_get_psu_alert_status,
/* sff */
.get_sff_id = dfd_get_sff_id,
.set_sff_cpld_info = dfd_set_sff_cpld_info,
.get_sff_cpld_info = dfd_get_sff_cpld_info,
.get_sff_eeprom_info = dfd_get_sff_eeprom_info,
.get_sff_dir_name = dfd_get_sff_dir_name,
.get_sff_polling_size = dfd_get_sff_polling_size,
.get_sff_polling_data = dfd_get_sff_polling_data,
};
struct switch_drivers_t * dfd_plat_driver_get(void) {
return &switch_drivers;
}
static int32_t __init dfd_dev_init(void)
{
int ret;
DBG_DEBUG(DBG_VERBOSE, "Enter.\n");
ret = dfd_dev_cfg_init();
if (ret != 0) {
DBG_DEBUG(DBG_ERROR, "dfd_dev_cfg_init failed ret %d.\n", ret);
ret = -DFD_KO_INIT_CFG_FAIL;
return ret;
}
DBG_DEBUG(DBG_VERBOSE, "success.\n");
return 0;
}
static void __exit dfd_dev_exit(void)
{
DBG_DEBUG(DBG_VERBOSE, "dfd_dev_exit.\n");
dfd_dev_cfg_exit();
return ;
}
module_init(dfd_dev_init);
module_exit(dfd_dev_exit);
module_param(g_dfd_dbg_level, int, S_IRUGO | S_IWUSR);
EXPORT_SYMBOL(dfd_plat_driver_get);
MODULE_AUTHOR("sonic_rd <sonic_rd@ruijie.com.cn>");
MODULE_LICENSE("GPL");

Some files were not shown because too many files have changed in this diff Show More