[devices]: add the delta ag9064 platform (#1435)

* add the ag9064 platform

Signed-off-by: hans <hans.tseng@deltaww.com>
This commit is contained in:
hans-tseng 2018-03-01 18:14:26 +08:00 committed by lguohan
parent 33d5a9cfd6
commit 837e964854
28 changed files with 7128 additions and 1 deletions

View File

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

View File

@ -0,0 +1 @@
SAI_INIT_CONFIG_FILE=/etc/bcm/th2-ag9064-64x100G.config.bcm

View File

@ -0,0 +1,2 @@
CONSOLE_PORT=0x3f8
CONSOLE_SPEED=115200

View File

@ -0,0 +1,63 @@
led 0 stop
led 0 prog \
02 00 60 E0 02 A0 60 E2 86 ED 02 00 60 E1 2E E0 \
32 08 97 02 00 0E 05 60 E3 2E E0 32 00 32 01 B7 \
97 02 00 0E 00 12 E7 FE E1 50 86 E0 86 E1 06 E1 \
D2 04 74 19 16 E7 61 EB 06 E3 12 05 67 92 06 E3 \
12 04 67 92 06 E3 12 03 67 92 16 E9 61 EB 06 E5 \
12 03 67 92 02 02 60 EC 02 00 60 E1 77 66 02 01 \
60 EC 02 00 60 E1 12 E7 FE E1 05 60 EB 12 E3 FE \
E1 05 16 EC 67 92 86 E1 06 E1 D2 04 74 66 06 EC \
D2 02 70 5E 06 E2 F2 04 60 E2 06 E0 D2 40 74 0A \
3A C0 09 75 A9 06 EB D2 00 70 A5 16 ED 99 99 1A \
00 71 A5 77 A9 32 0F 87 57 32 0E 87 57 00 00 00
led 0 auto on
led 0 start
led 1 stop
led 1 prog \
02 00 60 E0 02 A0 60 E2 86 ED 02 00 60 E1 2E E0 \
32 08 97 02 00 0E 05 60 E3 2E E0 32 00 32 01 B7 \
97 02 00 0E 00 12 E7 FE E1 50 86 E0 86 E1 06 E1 \
D2 04 74 19 16 E7 61 EB 06 E3 12 05 67 92 06 E3 \
12 04 67 92 06 E3 12 03 67 92 16 E9 61 EB 06 E5 \
12 03 67 92 02 02 60 EC 02 00 60 E1 77 66 02 01 \
60 EC 02 00 60 E1 12 E7 FE E1 05 60 EB 12 E3 FE \
E1 05 16 EC 67 92 86 E1 06 E1 D2 04 74 66 06 EC \
D2 02 70 5E 06 E2 F2 04 60 E2 06 E0 D2 40 74 0A \
3A C0 09 75 A9 06 EB D2 00 70 A5 16 ED 99 99 1A \
00 71 A5 77 A9 32 0F 87 57 32 0E 87 57 00 00 00
led 1 auto on
led 1 start
led 2 stop
led 2 prog \
02 00 60 E0 02 A0 60 E2 86 ED 02 00 60 E1 2E E0 \
32 08 97 02 00 0E 05 60 E3 2E E0 32 00 32 01 B7 \
97 02 00 0E 00 12 E7 FE E1 50 86 E0 86 E1 06 E1 \
D2 04 74 19 16 E7 61 EB 06 E3 12 05 67 92 06 E3 \
12 04 67 92 06 E3 12 03 67 92 16 E9 61 EB 06 E5 \
12 03 67 92 02 02 60 EC 02 00 60 E1 77 66 02 01 \
60 EC 02 00 60 E1 12 E7 FE E1 05 60 EB 12 E3 FE \
E1 05 16 EC 67 92 86 E1 06 E1 D2 04 74 66 06 EC \
D2 02 70 5E 06 E2 F2 04 60 E2 06 E0 D2 40 74 0A \
3A C0 09 75 A9 06 EB D2 00 70 A5 16 ED 99 99 1A \
00 71 A5 77 A9 32 0F 87 57 32 0E 87 57 00 00 00
led 2 auto on
led 2 start
led 3 stop
led 3 prog \
02 00 60 E0 02 A0 60 E2 86 ED 02 00 60 E1 2E E0 \
32 08 97 02 00 0E 05 60 E3 2E E0 32 00 32 01 B7 \
97 02 00 0E 00 12 E7 FE E1 50 86 E0 86 E1 06 E1 \
D2 04 74 19 16 E7 61 EB 06 E3 12 05 67 92 06 E3 \
12 04 67 92 06 E3 12 03 67 92 16 E9 61 EB 06 E5 \
12 03 67 92 02 02 60 EC 02 00 60 E1 77 66 02 01 \
60 EC 02 00 60 E1 12 E7 FE E1 05 60 EB 12 E3 FE \
E1 05 16 EC 67 92 86 E1 06 E1 D2 04 74 66 06 EC \
D2 02 70 5E 06 E2 F2 04 60 E2 06 E0 D2 40 74 0A \
3A C0 09 75 A9 06 EB D2 00 70 A5 16 ED 99 99 1A \
00 71 A5 77 A9 32 0F 87 57 32 0E 87 57 00 00 00
led 3 auto on
led 3 start

View File

@ -0,0 +1,848 @@
<DeviceMiniGraph xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="Microsoft.Search.Autopilot.Evolution">
<CpgDec>
<IsisRouters xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
<PeeringSessions>
</PeeringSessions>
<Routers xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
</Routers>
</CpgDec>
<DpgDec>
<DeviceDataPlaneInfo>
<IPSecTunnels/>
<LoopbackIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:LoopbackIPInterface>
<Name>HostIP</Name>
<AttachTo>Loopback0</AttachTo>
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.Evolution">
<b:IPPrefix>10.1.0.32/32</b:IPPrefix>
</a:Prefix>
<a:PrefixStr>10.1.0.32/32</a:PrefixStr>
</a:LoopbackIPInterface>
</LoopbackIPInterfaces>
<ManagementIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
</ManagementIPInterfaces>
<MplsInterfaces/>
<MplsTeInterfaces/>
<RsvpInterfaces/>
<Hostname>sonic</Hostname>
<PortChannelInterfaces/>
<VlanInterfaces/>
<IPInterfaces>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet1/1</AttachTo>
<Prefix>10.0.0.0/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet2/1</AttachTo>
<Prefix>10.0.0.2/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet3/1</AttachTo>
<Prefix>10.0.0.4/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet4/1</AttachTo>
<Prefix>10.0.0.6/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet5/1</AttachTo>
<Prefix>10.0.0.8/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet6/1</AttachTo>
<Prefix>10.0.0.10/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet7/1</AttachTo>
<Prefix>10.0.0.12/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet8/1</AttachTo>
<Prefix>10.0.0.14/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet9/1</AttachTo>
<Prefix>10.0.0.16/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet10/1</AttachTo>
<Prefix>10.0.0.18/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet11/1</AttachTo>
<Prefix>10.0.0.20/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet12/1</AttachTo>
<Prefix>10.0.0.22/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet13/1</AttachTo>
<Prefix>10.0.0.24/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet14/1</AttachTo>
<Prefix>10.0.0.26/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet15/1</AttachTo>
<Prefix>10.0.0.28/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet16/1</AttachTo>
<Prefix>10.0.0.30/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet17/1</AttachTo>
<Prefix>10.0.0.32/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet18/1</AttachTo>
<Prefix>10.0.0.34/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet19/1</AttachTo>
<Prefix>10.0.0.36/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet20/1</AttachTo>
<Prefix>10.0.0.38/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet21/1</AttachTo>
<Prefix>10.0.0.40/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet22/1</AttachTo>
<Prefix>10.0.0.42/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet23/1</AttachTo>
<Prefix>10.0.0.44/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet24/1</AttachTo>
<Prefix>10.0.0.46/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet25/1</AttachTo>
<Prefix>10.0.0.48/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet26/1</AttachTo>
<Prefix>10.0.0.50/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet27/1</AttachTo>
<Prefix>10.0.0.52/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet28/1</AttachTo>
<Prefix>10.0.0.54/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet29/1</AttachTo>
<Prefix>10.0.0.56/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet30/1</AttachTo>
<Prefix>10.0.0.58/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet31/1</AttachTo>
<Prefix>10.0.0.60/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet32/1</AttachTo>
<Prefix>10.0.0.62/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet33/1</AttachTo>
<Prefix>10.0.0.64/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet34/1</AttachTo>
<Prefix>10.0.0.66/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet35/1</AttachTo>
<Prefix>10.0.0.68/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet36/1</AttachTo>
<Prefix>10.0.0.70/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet37/1</AttachTo>
<Prefix>10.0.0.72/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet38/1</AttachTo>
<Prefix>10.0.0.74/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet39/1</AttachTo>
<Prefix>10.0.0.76/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet40/1</AttachTo>
<Prefix>10.0.0.78/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet41/1</AttachTo>
<Prefix>10.0.0.80/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet42/1</AttachTo>
<Prefix>10.0.0.82/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet43/1</AttachTo>
<Prefix>10.0.0.84/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet44/1</AttachTo>
<Prefix>10.0.0.86/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet45/1</AttachTo>
<Prefix>10.0.0.88/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet46/1</AttachTo>
<Prefix>10.0.0.90/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet47/1</AttachTo>
<Prefix>10.0.0.92/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet48/1</AttachTo>
<Prefix>10.0.0.94/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet49/1</AttachTo>
<Prefix>10.0.0.96/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet50/1</AttachTo>
<Prefix>10.0.0.98/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet51/1</AttachTo>
<Prefix>10.0.0.100/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet52/1</AttachTo>
<Prefix>10.0.0.102/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet53/1</AttachTo>
<Prefix>10.0.0.104/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet54/1</AttachTo>
<Prefix>10.0.0.106/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet55/1</AttachTo>
<Prefix>10.0.0.108/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet56/1</AttachTo>
<Prefix>10.0.0.110/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet57/1</AttachTo>
<Prefix>10.0.0.112/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet58/1</AttachTo>
<Prefix>10.0.0.114/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet59/1</AttachTo>
<Prefix>10.0.0.116/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet60/1</AttachTo>
<Prefix>10.0.0.118/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet61/1</AttachTo>
<Prefix>10.0.0.120/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet62/1</AttachTo>
<Prefix>10.0.0.122/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet63/1</AttachTo>
<Prefix>10.0.0.124/31</Prefix>
</IPInterface>
<IPInterface>
<Name i:Name="true"/>
<AttachTo>Ethernet64/1</AttachTo>
<Prefix>10.0.0.126/31</Prefix>
</IPInterface>
</IPInterfaces>
<DataAcls/>
<AclInterfaces/>
<DownstreamSummaries/>
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</DeviceDataPlaneInfo>
</DpgDec>
<PngDec>
<DeviceInterfaceLinks>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet1/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet1/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet2/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet2/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet3/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet3/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet4/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet4/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet5/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet5/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet6/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet6/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet7/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet7/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet8/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet8/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet9/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet9/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet10/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet10/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet11/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet11/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet12/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet12/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet13/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet13/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet14/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet14/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet15/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet15/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet16/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet16/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet17/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet17/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet18/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet18/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet19/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet19/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet20/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet20/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet21/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet21/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet22/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet22/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet23/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet23/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet24/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet24/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet25/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet25/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet26/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet26/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet27/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet27/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet28/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet28/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet29/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet29/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet30/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet30/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet31/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet31/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet32/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet32/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet33/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet33/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet34/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet34/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet35/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet35/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet36/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet36/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet37/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet37/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet38/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet38/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet39/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet39/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet40/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet40/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet41/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet41/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet42/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet42/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet43/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet43/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet44/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet44/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet45/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet45/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet46/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet46/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet47/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet47/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet48/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet48/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet49/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet49/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet50/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet50/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet51/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet51/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet52/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet52/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet53/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet53/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet54/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet54/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet55/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet55/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet56/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet56/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet57/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet57/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet58/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet58/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet59/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet59/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet60/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet60/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet61/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet61/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet62/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet62/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet63/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet63/1</StartPort>
</DeviceLinkBase>
<DeviceLinkBase>
<ElementType>DeviceInterfaceLink</ElementType>
<EndDevice>sonic-target</EndDevice>
<EndPort>Ethernet64/1</EndPort>
<StartDevice>sonic</StartDevice>
<StartPort>Ethernet64/1</StartPort>
</DeviceLinkBase>
</DeviceInterfaceLinks>
<Devices>
<Device i:type="LeafRouter">
<Hostname>sonic</Hostname>
<HwSku>Delta-ag9064</HwSku>
</Device>
</Devices>
</PngDec>
<MetadataDeclaration>
<Devices xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:DeviceMetadata>
<a:Name>sonic</a:Name>
<a:Properties>
<a:DeviceProperty>
<a:Name>DhcpResources</a:Name>
<a:Reference i:nil="true"/>
<a:Value></a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>NtpResources</a:Name>
<a:Reference i:nil="true"/>
<a:Value>0.debian.pool.ntp.org;1.debian.pool.ntp.org;2.debian.pool.ntp.org;3.debian.pool.ntp.org</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>SyslogResources</a:Name>
<a:Reference i:nil="true"/>
<a:Value></a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>ErspanDestinationIpv4</a:Name>
<a:Reference i:nil="true"/>
<a:Value>2.2.2.2</a:Value>
</a:DeviceProperty>
</a:Properties>
</a:DeviceMetadata>
</Devices>
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</MetadataDeclaration>
<Hostname>sonic</Hostname>
<HwSku>Delta-ag9064</HwSku>
</DeviceMiniGraph>

View File

@ -0,0 +1,32 @@
#!/usr/bin/env python
#############################################################################
# Mellanox
#
# Platform and model specific eeprom subclass, inherits from the base class,
# and provides the followings:
# - the eeprom format definition
# - specific encoder/decoder if there is special need
#############################################################################
try:
import exceptions
import binascii
import time
import optparse
import warnings
import os
import sys
from sonic_eeprom import eeprom_base
from sonic_eeprom import eeprom_tlvinfo
import subprocess
except ImportError, e:
raise ImportError (str(e) + "- required module not found")
class board(eeprom_tlvinfo.TlvInfoDecoder):
_TLV_INFO_MAX_LEN = 256
def __init__(self, name, path, cpld_root, ro):
self.eeprom_path = "/sys/devices/pci0000:00/0000:00:1f.3/i2c-0/0-0056/eeprom"
super(board, self).__init__(self.eeprom_path, 0, '', True)

View File

@ -0,0 +1,175 @@
# sfputil.py
#
# Platform-specific SFP transceiver interface for SONiC
#
try:
import time
from sonic_sfp.sfputilbase import SfpUtilBase
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))
class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""
PORT_START = 0
PORT_END = 63
PORTS_IN_BLOCK = 64
EEPROM_OFFSET = 20
_port_to_eeprom_mapping = {}
@property
def port_start(self):
return self.PORT_START
@property
def port_end(self):
return self.PORT_END
@property
def qsfp_ports(self):
return range(0, self.PORTS_IN_BLOCK + 1)
@property
def port_to_eeprom_mapping(self):
return self._port_to_eeprom_mapping
def __init__(self):
eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-0050/eeprom"
for x in range(0, self.port_end + 1):
self._port_to_eeprom_mapping[x] = eeprom_path.format(x + self.EEPROM_OFFSET)
SfpUtilBase.__init__(self)
def get_presence(self, port_num):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False
try:
reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_present")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = reg_file.readline().rstrip()
# content is a string containing the hex representation of the register
reg_value = int(content, 16)
# Mask off the bit corresponding to our port
mask = (1 << port_num)
# ModPrsL is active low
if reg_value & mask == 0:
return True
return False
def get_low_power_mode(self, port_num):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False
try:
reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_lpmode")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
content = reg_file.readline().rstrip()
# content is a string containing the hex representation of the register
reg_value = int(content, 16)
# Mask off the bit corresponding to our port
mask = (1 << port_num)
# LPMode is active high
if reg_value & mask == 0:
return False
return True
def set_low_power_mode(self, port_num, lpmode):
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False
try:
reg_file = open("/sys/devices/platform/delta-ag9064-cpld.0/qsfp_lpmode", "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = reg_file.readline().rstrip()
# content is a string containing the hex representation of the register
reg_value = int(content, 16)
# Mask off the bit corresponding to our port
mask = (1 << port_num)
# LPMode is active high; set or clear the bit accordingly
if lpmode is True:
reg_value = reg_value | mask
else:
reg_value = reg_value & ~mask
# Convert our register value back to a hex string and write back
content = hex(reg_value)
reg_file.seek(0)
reg_file.write(content)
reg_file.close()
return True
def reset(self, port_num):
QSFP_RESET_REGISTER_DEVICE_FILE = "/sys/devices/platform/delta-ag9064-cpld.0/qsfp_reset"
# Check for invalid port_num
if port_num < self.port_start or port_num > self.port_end:
return False
try:
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "r+")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
content = reg_file.readline().rstrip()
# File content is a string containing the hex representation of the register
reg_value = int(content, 16)
# Mask off the bit corresponding to our port
mask = (1 << port_num)
# ResetL is active low
reg_value = reg_value & ~mask
# Convert our register value back to a hex string and write back
reg_file.seek(0)
reg_file.write(hex(reg_value))
reg_file.close()
# Sleep 1 second to allow it to settle
time.sleep(1)
# Flip the bit back high and write back to the register to take port out of reset
try:
reg_file = open(QSFP_RESET_REGISTER_DEVICE_FILE, "w")
except IOError as e:
print "Error: unable to open file: %s" % str(e)
return False
reg_value = reg_value | mask
reg_file.seek(0)
reg_file.write(hex(reg_value))
reg_file.close()
return True

View File

@ -0,0 +1,14 @@
# libsensors configuration file for DCS-7060CX-32S
# ------------------------------------------------
#
bus "i2c-1" "i2c-1-mux (chan_id 1)"
# tmp75-i2c-1-4d CPU below side thermal sensor.
chip "tmp75-i2c-1-4d"
label temp1 "CPU below side thermal sensor"
set temp1_max 60
set temp1_max_hyst 55

View File

@ -21,6 +21,7 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \
$(INVENTEC_D7054Q28B_PLATFORM_MODULE) \
$(CEL_DX010_PLATFORM_MODULE) \
$(DELTA_AG9032V1_PLATFORM_MODULE) \
$(DELTA_AG9064_PLATFORM_MODULE) \
$(QUANTA_IX1B_32X_PLATFORM_MODULE) \
$(MITAC_LY1200_32X_PLATFORM_MODULE)
$(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_IMAGES)

View File

@ -1,8 +1,10 @@
# Delta AG9032v1 Platform modules
DELTA_AG9032V1_PLATFORM_MODULE_VERSION = 1.1
DELTA_AG9064_PLATFORM_MODULE_VERSION = 1.1
export DELTA_AG9032V1_PLATFORM_MODULE_VERSION
export DELTA_AG9064_PLATFORM_MODULE_VERSION
DELTA_AG9032V1_PLATFORM_MODULE = platform-modules-ag9032v1_$(DELTA_AG9032V1_PLATFORM_MODULE_VERSION)_amd64.deb
$(DELTA_AG9032V1_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-delta
@ -10,3 +12,7 @@ $(DELTA_AG9032V1_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_CO
$(DELTA_AG9032V1_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9032v1-r0
SONIC_DPKG_DEBS += $(DELTA_AG9032V1_PLATFORM_MODULE)
DELTA_AG9064_PLATFORM_MODULE = platform-modules-ag9064_$(DELTA_AG9064_PLATFORM_MODULE_VERSION)_amd64.deb
$(DELTA_AG9064_PLATFORM_MODULE)_PLATFORM = x86_64-delta_ag9064-r0
$(eval $(call add_extra_package,$(DELTA_AG9032V1_PLATFORM_MODULE),$(DELTA_AG9064_PLATFORM_MODULE)))

View File

@ -0,0 +1,13 @@
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
i2c-i801
i2c-isch
i2c-ismt
i2c-dev
i2c-mux
i2c-smbus
i2c-mux-gpio
i2c-mux-pca954x

View File

@ -0,0 +1,4 @@
obj-m += delta_ag9064_platform.o
obj-m += i2c-mei.o
i2c-mei-objs := i2c-mei_io.o i2c-mei_main.o i2c-mei_rw.o

View File

@ -0,0 +1,255 @@
/*
*
* Intel Management Engine Interface (Intel MEI) Linux driver
* Copyright (c) 2003-2012, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _MEI_CLIENT_H_
#define _MEI_CLIENT_H_
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/poll.h>
#include <linux/mei.h>
#include "mei_dev.h"
/*
* reference counting base function
*/
void mei_me_cl_init(struct mei_me_client *me_cl);
void mei_me_cl_put(struct mei_me_client *me_cl);
struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl);
void mei_me_cl_add(struct mei_device *dev, struct mei_me_client *me_cl);
void mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl);
struct mei_me_client *mei_me_cl_by_uuid(struct mei_device *dev,
const uuid_le *uuid);
struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev,
const uuid_le *uuid, u8 client_id);
void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid);
void mei_me_cl_rm_by_uuid_id(struct mei_device *dev,
const uuid_le *uuid, u8 id);
void mei_me_cl_rm_all(struct mei_device *dev);
/**
* mei_me_cl_is_active - check whether me client is active in the fw
*
* @me_cl: me client
*
* Return: true if the me client is active in the firmware
*/
static inline bool mei_me_cl_is_active(const struct mei_me_client *me_cl)
{
return !list_empty_careful(&me_cl->list);
}
/**
* mei_me_cl_uuid - return me client protocol name (uuid)
*
* @me_cl: me client
*
* Return: me client protocol name
*/
static inline const uuid_le *mei_me_cl_uuid(const struct mei_me_client *me_cl)
{
return &me_cl->props.protocol_name;
}
/**
* mei_me_cl_ver - return me client protocol version
*
* @me_cl: me client
*
* Return: me client protocol version
*/
static inline u8 mei_me_cl_ver(const struct mei_me_client *me_cl)
{
return me_cl->props.protocol_version;
}
/*
* MEI IO Functions
*/
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
struct file *fp);
void mei_io_cb_free(struct mei_cl_cb *priv_cb);
int mei_io_cb_alloc_buf(struct mei_cl_cb *cb, size_t length);
/**
* mei_io_list_init - Sets up a queue list.
*
* @list: An instance cl callback structure
*/
static inline void mei_io_list_init(struct mei_cl_cb *list)
{
INIT_LIST_HEAD(&list->list);
}
void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl);
/*
* MEI Host Client Functions
*/
struct mei_cl *mei_cl_allocate(struct mei_device *dev);
void mei_cl_init(struct mei_cl *cl, struct mei_device *dev);
int mei_cl_link(struct mei_cl *cl, int id);
int mei_cl_unlink(struct mei_cl *cl);
struct mei_cl *mei_cl_alloc_linked(struct mei_device *dev, int id);
struct mei_cl_cb *mei_cl_read_cb(const struct mei_cl *cl,
const struct file *fp);
void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp);
struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
enum mei_cb_file_ops type, struct file *fp);
int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp);
int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
/*
* MEI input output function prototype
*/
/**
* mei_cl_is_connected - host client is connected
*
* @cl: host client
*
* Return: true if the host client is connected
*/
static inline bool mei_cl_is_connected(struct mei_cl *cl)
{
return cl->state == MEI_FILE_CONNECTED;
}
/**
* mei_cl_me_id - me client id
*
* @cl: host client
*
* Return: me client id or 0 if client is not connected
*/
static inline u8 mei_cl_me_id(const struct mei_cl *cl)
{
return cl->me_cl ? cl->me_cl->client_id : 0;
}
/**
* mei_cl_mtu - maximal message that client can send and receive
*
* @cl: host client
*
* Return: mtu
*/
static inline size_t mei_cl_mtu(const struct mei_cl *cl)
{
return cl->me_cl->props.max_msg_length;
}
/**
* mei_cl_is_fixed_address - check whether the me client uses fixed address
*
* @cl: host client
*
* Return: true if the client is connected and it has fixed me address
*/
static inline bool mei_cl_is_fixed_address(const struct mei_cl *cl)
{
return cl->me_cl && cl->me_cl->props.fixed_address;
}
/**
* mei_cl_is_single_recv_buf- check whether the me client
* uses single receiving buffer
*
* @cl: host client
*
* Return: true if single_recv_buf == 1; 0 otherwise
*/
static inline bool mei_cl_is_single_recv_buf(const struct mei_cl *cl)
{
return cl->me_cl->props.single_recv_buf;
}
/**
* mei_cl_uuid - client's uuid
*
* @cl: host client
*
* Return: return uuid of connected me client
*/
static inline const uuid_le *mei_cl_uuid(const struct mei_cl *cl)
{
return mei_me_cl_uuid(cl->me_cl);
}
/**
* mei_cl_host_addr - client's host address
*
* @cl: host client
*
* Return: 0 for fixed address client, host address for dynamic client
*/
static inline u8 mei_cl_host_addr(const struct mei_cl *cl)
{
return mei_cl_is_fixed_address(cl) ? 0 : cl->host_client_id;
}
int mei_cl_disconnect(struct mei_cl *cl);
void mei_cl_set_disconnected(struct mei_cl *cl);
int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl,
struct file *file);
int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp);
int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
struct mei_cl_cb *cmpl_list);
int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
void mei_host_client_init(struct work_struct *work);
u8 mei_cl_notify_fop2req(enum mei_cb_file_ops fop);
enum mei_cb_file_ops mei_cl_notify_req2fop(u8 request);
int mei_cl_notify_request(struct mei_cl *cl, struct file *file, u8 request);
int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
int mei_cl_notify_get(struct mei_cl *cl, bool block, bool *notify_ev);
void mei_cl_notify(struct mei_cl *cl);
void mei_cl_all_disconnect(struct mei_device *dev);
void mei_cl_all_wakeup(struct mei_device *dev);
void mei_cl_all_write_clear(struct mei_device *dev);
#define MEI_CL_FMT "cl:host=%02d me=%02d "
#define MEI_CL_PRM(cl) (cl)->host_client_id, mei_cl_me_id(cl)
#define cl_dbg(dev, cl, format, arg...) \
dev_dbg((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
#define cl_err(dev, cl, format, arg...) \
dev_err((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
#endif /* _MEI_CLIENT_H_ */

View File

@ -0,0 +1,62 @@
/*
*
* Intel Management Engine Interface (Intel MEI) Linux driver
* Copyright (c) 2003-2012, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _MEI_HBM_H_
#define _MEI_HBM_H_
struct mei_device;
struct mei_msg_hdr;
struct mei_cl;
/**
* enum mei_hbm_state - host bus message protocol state
*
* @MEI_HBM_IDLE : protocol not started
* @MEI_HBM_STARTING : start request message was sent
* @MEI_HBM_ENUM_CLIENTS : enumeration request was sent
* @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties
* @MEI_HBM_STARTED : enumeration was completed
* @MEI_HBM_STOPPED : stopping exchange
*/
enum mei_hbm_state {
MEI_HBM_IDLE = 0,
MEI_HBM_STARTING,
MEI_HBM_ENUM_CLIENTS,
MEI_HBM_CLIENT_PROPERTIES,
MEI_HBM_STARTED,
MEI_HBM_STOPPED,
};
const char *mei_hbm_state_str(enum mei_hbm_state state);
int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr);
void mei_hbm_idle(struct mei_device *dev);
void mei_hbm_reset(struct mei_device *dev);
int mei_hbm_start_req(struct mei_device *dev);
int mei_hbm_start_wait(struct mei_device *dev);
int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl);
int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
bool mei_hbm_version_is_supported(struct mei_device *dev);
int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd);
void mei_hbm_pg_resume(struct mei_device *dev);
int mei_hbm_cl_notify_req(struct mei_device *dev,
struct mei_cl *cl, u8 request);
#endif /* _MEI_HBM_H_ */

View File

@ -0,0 +1,426 @@
/*
*
* Intel Management Engine Interface (Intel MEI) Linux driver
* Copyright (c) 2003-2012, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _MEI_HW_TYPES_H_
#define _MEI_HW_TYPES_H_
#include <linux/uuid.h>
/*
* Timeouts in Seconds
*/
#define MEI_HW_READY_TIMEOUT 2 /* Timeout on ready message */
#define MEI_CONNECT_TIMEOUT 3 /* HPS: at least 2 seconds */
#define MEI_CL_CONNECT_TIMEOUT 15 /* HPS: Client Connect Timeout */
#define MEI_CLIENTS_INIT_TIMEOUT 15 /* HPS: Clients Enumeration Timeout */
#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */
#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */
#define MEI_PGI_TIMEOUT 1 /* PG Isolation time response 1 sec */
#define MEI_D0I3_TIMEOUT 5 /* D0i3 set/unset max response time */
#define MEI_HBM_TIMEOUT 1 /* 1 second */
/*
* MEI Version
*/
#define HBM_MINOR_VERSION 0
#define HBM_MAJOR_VERSION 2
/*
* MEI version with PGI support
*/
#define HBM_MINOR_VERSION_PGI 1
#define HBM_MAJOR_VERSION_PGI 1
/*
* MEI version with Dynamic clients support
*/
#define HBM_MINOR_VERSION_DC 0
#define HBM_MAJOR_VERSION_DC 2
/*
* MEI version with disconnect on connection timeout support
*/
#define HBM_MINOR_VERSION_DOT 0
#define HBM_MAJOR_VERSION_DOT 2
/*
* MEI version with notifcation support
*/
#define HBM_MINOR_VERSION_EV 0
#define HBM_MAJOR_VERSION_EV 2
/* Host bus message command opcode */
#define MEI_HBM_CMD_OP_MSK 0x7f
/* Host bus message command RESPONSE */
#define MEI_HBM_CMD_RES_MSK 0x80
/*
* MEI Bus Message Command IDs
*/
#define HOST_START_REQ_CMD 0x01
#define HOST_START_RES_CMD 0x81
#define HOST_STOP_REQ_CMD 0x02
#define HOST_STOP_RES_CMD 0x82
#define ME_STOP_REQ_CMD 0x03
#define HOST_ENUM_REQ_CMD 0x04
#define HOST_ENUM_RES_CMD 0x84
#define HOST_CLIENT_PROPERTIES_REQ_CMD 0x05
#define HOST_CLIENT_PROPERTIES_RES_CMD 0x85
#define CLIENT_CONNECT_REQ_CMD 0x06
#define CLIENT_CONNECT_RES_CMD 0x86
#define CLIENT_DISCONNECT_REQ_CMD 0x07
#define CLIENT_DISCONNECT_RES_CMD 0x87
#define MEI_FLOW_CONTROL_CMD 0x08
#define MEI_PG_ISOLATION_ENTRY_REQ_CMD 0x0a
#define MEI_PG_ISOLATION_ENTRY_RES_CMD 0x8a
#define MEI_PG_ISOLATION_EXIT_REQ_CMD 0x0b
#define MEI_PG_ISOLATION_EXIT_RES_CMD 0x8b
#define MEI_HBM_ADD_CLIENT_REQ_CMD 0x0f
#define MEI_HBM_ADD_CLIENT_RES_CMD 0x8f
#define MEI_HBM_NOTIFY_REQ_CMD 0x10
#define MEI_HBM_NOTIFY_RES_CMD 0x90
#define MEI_HBM_NOTIFICATION_CMD 0x11
/*
* MEI Stop Reason
* used by hbm_host_stop_request.reason
*/
enum mei_stop_reason_types {
DRIVER_STOP_REQUEST = 0x00,
DEVICE_D1_ENTRY = 0x01,
DEVICE_D2_ENTRY = 0x02,
DEVICE_D3_ENTRY = 0x03,
SYSTEM_S1_ENTRY = 0x04,
SYSTEM_S2_ENTRY = 0x05,
SYSTEM_S3_ENTRY = 0x06,
SYSTEM_S4_ENTRY = 0x07,
SYSTEM_S5_ENTRY = 0x08
};
/**
* enum mei_hbm_status - mei host bus messages return values
*
* @MEI_HBMS_SUCCESS : status success
* @MEI_HBMS_CLIENT_NOT_FOUND : client not found
* @MEI_HBMS_ALREADY_EXISTS : connection already established
* @MEI_HBMS_REJECTED : connection is rejected
* @MEI_HBMS_INVALID_PARAMETER : invalid parameter
* @MEI_HBMS_NOT_ALLOWED : operation not allowed
* @MEI_HBMS_ALREADY_STARTED : system is already started
* @MEI_HBMS_NOT_STARTED : system not started
*
* @MEI_HBMS_MAX : sentinel
*/
enum mei_hbm_status {
MEI_HBMS_SUCCESS = 0,
MEI_HBMS_CLIENT_NOT_FOUND = 1,
MEI_HBMS_ALREADY_EXISTS = 2,
MEI_HBMS_REJECTED = 3,
MEI_HBMS_INVALID_PARAMETER = 4,
MEI_HBMS_NOT_ALLOWED = 5,
MEI_HBMS_ALREADY_STARTED = 6,
MEI_HBMS_NOT_STARTED = 7,
MEI_HBMS_MAX
};
/*
* Client Connect Status
* used by hbm_client_connect_response.status
*/
enum mei_cl_connect_status {
MEI_CL_CONN_SUCCESS = MEI_HBMS_SUCCESS,
MEI_CL_CONN_NOT_FOUND = MEI_HBMS_CLIENT_NOT_FOUND,
MEI_CL_CONN_ALREADY_STARTED = MEI_HBMS_ALREADY_EXISTS,
MEI_CL_CONN_OUT_OF_RESOURCES = MEI_HBMS_REJECTED,
MEI_CL_CONN_MESSAGE_SMALL = MEI_HBMS_INVALID_PARAMETER,
MEI_CL_CONN_NOT_ALLOWED = MEI_HBMS_NOT_ALLOWED,
};
/*
* Client Disconnect Status
*/
enum mei_cl_disconnect_status {
MEI_CL_DISCONN_SUCCESS = MEI_HBMS_SUCCESS
};
/*
* MEI BUS Interface Section
*/
struct mei_msg_hdr {
u32 me_addr:8;
u32 host_addr:8;
u32 length:9;
u32 reserved:5;
u32 internal:1;
u32 msg_complete:1;
} __packed;
struct mei_bus_message {
u8 hbm_cmd;
u8 data[0];
} __packed;
/**
* struct hbm_cl_cmd - client specific host bus command
* CONNECT, DISCONNECT, and FlOW CONTROL
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: address of the client in the driver
* @data: generic data
*/
struct mei_hbm_cl_cmd {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 data;
};
struct hbm_version {
u8 minor_version;
u8 major_version;
} __packed;
struct hbm_host_version_request {
u8 hbm_cmd;
u8 reserved;
struct hbm_version host_version;
} __packed;
struct hbm_host_version_response {
u8 hbm_cmd;
u8 host_version_supported;
struct hbm_version me_max_version;
} __packed;
struct hbm_host_stop_request {
u8 hbm_cmd;
u8 reason;
u8 reserved[2];
} __packed;
struct hbm_host_stop_response {
u8 hbm_cmd;
u8 reserved[3];
} __packed;
struct hbm_me_stop_request {
u8 hbm_cmd;
u8 reason;
u8 reserved[2];
} __packed;
/**
* struct hbm_host_enum_request - enumeration request from host to fw
*
* @hbm_cmd: bus message command header
* @allow_add: allow dynamic clients add HBM version >= 2.0
* @reserved: reserved
*/
struct hbm_host_enum_request {
u8 hbm_cmd;
u8 allow_add;
u8 reserved[2];
} __packed;
struct hbm_host_enum_response {
u8 hbm_cmd;
u8 reserved[3];
u8 valid_addresses[32];
} __packed;
struct mei_client_properties {
uuid_le protocol_name;
u8 protocol_version;
u8 max_number_of_connections;
u8 fixed_address;
u8 single_recv_buf;
u32 max_msg_length;
} __packed;
struct hbm_props_request {
u8 hbm_cmd;
u8 me_addr;
u8 reserved[2];
} __packed;
struct hbm_props_response {
u8 hbm_cmd;
u8 me_addr;
u8 status;
u8 reserved[1];
struct mei_client_properties client_properties;
} __packed;
/**
* struct hbm_add_client_request - request to add a client
* might be sent by fw after enumeration has already completed
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @reserved: reserved
* @client_properties: client properties
*/
struct hbm_add_client_request {
u8 hbm_cmd;
u8 me_addr;
u8 reserved[2];
struct mei_client_properties client_properties;
} __packed;
/**
* struct hbm_add_client_response - response to add a client
* sent by the host to report client addition status to fw
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @status: if HBMS_SUCCESS then the client can now accept connections.
* @reserved: reserved
*/
struct hbm_add_client_response {
u8 hbm_cmd;
u8 me_addr;
u8 status;
u8 reserved[1];
} __packed;
/**
* struct hbm_power_gate - power gate request/response
*
* @hbm_cmd: bus message command header
* @reserved: reserved
*/
struct hbm_power_gate {
u8 hbm_cmd;
u8 reserved[3];
} __packed;
/**
* struct hbm_client_connect_request - connect/disconnect request
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: address of the client in the driver
* @reserved: reserved
*/
struct hbm_client_connect_request {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 reserved;
} __packed;
/**
* struct hbm_client_connect_response - connect/disconnect response
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: address of the client in the driver
* @status: status of the request
*/
struct hbm_client_connect_response {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 status;
} __packed;
#define MEI_FC_MESSAGE_RESERVED_LENGTH 5
struct hbm_flow_control {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH];
} __packed;
#define MEI_HBM_NOTIFICATION_START 1
#define MEI_HBM_NOTIFICATION_STOP 0
/**
* struct hbm_notification_request - start/stop notification request
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: address of the client in the driver
* @start: start = 1 or stop = 0 asynchronous notifications
*/
struct hbm_notification_request {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 start;
} __packed;
/**
* struct hbm_notification_response - start/stop notification response
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: - address of the client in the driver
* @status: (mei_hbm_status) response status for the request
* - MEI_HBMS_SUCCESS: successful stop/start
* - MEI_HBMS_CLIENT_NOT_FOUND: if the connection could not be found.
* - MEI_HBMS_ALREADY_STARTED: for start requests for a previously
* started notification.
* - MEI_HBMS_NOT_STARTED: for stop request for a connected client for whom
* asynchronous notifications are currently disabled.
*
* @start: start = 1 or stop = 0 asynchronous notifications
* @reserved: reserved
*/
struct hbm_notification_response {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 status;
u8 start;
u8 reserved[3];
} __packed;
/**
* struct hbm_notification - notification event
*
* @hbm_cmd: bus message command header
* @me_addr: address of the client in ME
* @host_addr: address of the client in the driver
* @reserved: reserved for alignment
*/
struct hbm_notification {
u8 hbm_cmd;
u8 me_addr;
u8 host_addr;
u8 reserved[1];
} __packed;
#endif

View File

@ -0,0 +1,636 @@
#include "i2c-mei_rw.h"
/* ========== IoLibGcc.c ========= */
/**
Reads an 8-bit I/O port.
Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned.
This function must guarantee that all I/O read and write operations are
serialized.
If 8-bit I/O port operations are not supported, then ASSERT().
@param Port The I/O port to read.
@return The value read.
**/
//__inline__
UINT8
IoRead8 (
IN UINTN Port
)
{
UINT8 Data;
__asm__ __volatile__ ("inb %w1,%b0" : "=a" (Data) : "d" ((UINT16)Port));
return Data;
}
/**
Writes an 8-bit I/O port.
Writes the 8-bit I/O port specified by Port with the value specified by Value
and returns Value. This function must guarantee that all I/O read and write
operations are serialized.
If 8-bit I/O port operations are not supported, then ASSERT().
@param Port The I/O port to write.
@param Value The value to write to the I/O port.
@return The value written the I/O port.
**/
//__inline__
UINT8
IoWrite8 (
IN UINTN Port,
IN UINT8 Value
)
{
__asm__ __volatile__ ("outb %b0,%w1" : : "a" (Value), "d" ((UINT16)Port));
return Value;;
}
/**
Reads a 16-bit I/O port.
Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned.
This function must guarantee that all I/O read and write operations are
serialized.
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
@param Port The I/O port to read.
@return The value read.
**/
//__inline__
UINT16
IoRead16 (
IN UINTN Port
)
{
UINT16 Data;
if((Port & 1) != 0)
printk("Failed\n");
__asm__ __volatile__ ("inw %w1,%w0" : "=a" (Data) : "d" ((UINT16)Port));
return Data;
}
/**
Writes a 16-bit I/O port.
Writes the 16-bit I/O port specified by Port with the value specified by Value
and returns Value. This function must guarantee that all I/O read and write
operations are serialized.
If 16-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 16-bit boundary, then ASSERT().
@param Port The I/O port to write.
@param Value The value to write to the I/O port.
@return The value written the I/O port.
**/
//__inline__
UINT16
IoWrite16 (
IN UINTN Port,
IN UINT16 Value
)
{
if((Port & 1) != 0)
printk("Failed\n");
__asm__ __volatile__ ("outw %w0,%w1" : : "a" (Value), "d" ((UINT16)Port));
return Value;;
}
/**
Reads a 32-bit I/O port.
Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned.
This function must guarantee that all I/O read and write operations are
serialized.
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
@param Port The I/O port to read.
@return The value read.
**/
//__inline__
UINT32
IoRead32 (
IN UINTN Port
)
{
UINT32 Data;
if((Port & 3) != 0)
printk("Failed\n");
__asm__ __volatile__ ("inl %w1,%0" : "=a" (Data) : "d" ((UINT16)Port));
return Data;
}
/**
Writes a 32-bit I/O port.
Writes the 32-bit I/O port specified by Port with the value specified by Value
and returns Value. This function must guarantee that all I/O read and write
operations are serialized.
If 32-bit I/O port operations are not supported, then ASSERT().
If Port is not aligned on a 32-bit boundary, then ASSERT().
@param Port The I/O port to write.
@param Value The value to write to the I/O port.
@return The value written the I/O port.
**/
//__inline__
UINT32
IoWrite32 (
IN UINTN Port,
IN UINT32 Value
)
{
if((Port & 3) != 0)
printk("Failed\n");
__asm__ __volatile__ ("outl %0,%w1" : : "a" (Value), "d" ((UINT16)Port));
return Value;
}
/* ========== GccInline.c ========= */
/**
Enables CPU interrupts.
Enables CPU interrupts.
**/
VOID
EnableInterrupts (
VOID
)
{
__asm__ __volatile__ ("sti"::: "memory");
}
/**
Disables CPU interrupts.
Disables CPU interrupts.
**/
VOID
DisableInterrupts (
VOID
)
{
__asm__ __volatile__ ("cli"::: "memory");
}
/**
Reads the current value of the EFLAGS register.
Reads and returns the current value of the EFLAGS register. This function is
only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
64-bit value on X64.
@return EFLAGS on IA-32 or RFLAGS on X64.
**/
UINTN
AsmReadEflags (
VOID
)
{
UINTN Eflags;
__asm__ __volatile__ (
"pushfq \n\t"
"pop %0 "
: "=r" (Eflags) // %0
);
return Eflags;
}
/* ========== X86GetInterruptState.c ========= */
/**
Retrieves the current CPU interrupt state.
Returns TRUE is interrupts are currently enabled. Otherwise
returns FALSE.
@retval TRUE CPU interrupts are enabled.
@retval FALSE CPU interrupts are disabled.
**/
BOOLEAN
GetInterruptState (
VOID
)
{
IA32_EFLAGS32 EFlags;
EFlags.UintN = AsmReadEflags ();
return (BOOLEAN)(1 == EFlags.Bits.IF);
}
/* ========== Cpu.c ========= */
/**
Disables CPU interrupts and returns the interrupt state prior to the disable
operation.
@retval TRUE CPU interrupts were enabled on entry to this call.
@retval FALSE CPU interrupts were disabled on entry to this call.
**/
BOOLEAN
SaveAndDisableInterrupts (
VOID
)
{
BOOLEAN InterruptState;
InterruptState = GetInterruptState ();
DisableInterrupts ();
return InterruptState;
}
/**
Set the current CPU interrupt state.
Sets the current CPU interrupt state to the state specified by
InterruptState. If InterruptState is TRUE, then interrupts are enabled. If
InterruptState is FALSE, then interrupts are disabled. InterruptState is
returned.
@param InterruptState TRUE if interrupts should be enabled. FALSE if
interrupts should be disabled.
@return InterruptState
**/
BOOLEAN
SetInterruptState (
IN BOOLEAN InterruptState
)
{
if (InterruptState) {
EnableInterrupts ();
} else {
DisableInterrupts ();
}
return InterruptState;
}
/* ========== pciLib.c ========= */
//
// Declare I/O Ports used to perform PCI Confguration Cycles
//
#define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
#define PCI_CONFIGURATION_DATA_PORT 0xCFC
/**
Convert a PCI Library address to PCI CF8 formatted address.
Declare macro to convert PCI Library address to PCI CF8 formatted address.
Bit fields of PCI Library and CF8 formatted address is as follows:
PCI Library formatted address CF8 Formatted Address
============================= ======================
Bits 00..11 Register Bits 00..07 Register
Bits 12..14 Function Bits 08..10 Function
Bits 15..19 Device Bits 11..15 Device
Bits 20..27 Bus Bits 16..23 Bus
Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
Bits 31..31 Must be 1
@param A The address to convert.
@retval The coverted address.
**/
#define PCI_TO_CF8_ADDRESS(A) \
((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
/**
Reads an 8-bit PCI configuration register.
Reads and returns the 8-bit PCI configuration register specified by Address.
This function must guarantee that all PCI read and write operations are
serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@return The read value from the PCI configuration register.
**/
UINT8
PciCf8Read8 (
IN UINTN Address
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT8 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/**
Writes an 8-bit PCI configuration register.
Writes the 8-bit PCI configuration register specified by Address with the
value specified by Value. Value is returned. This function must guarantee
that all PCI read and write operations are serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@param Value The value to write.
@return The value written to the PCI configuration register.
**/
UINT8
PciCf8Write8 (
IN UINTN Address,
IN UINT8 Value
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT8 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoWrite8 (
PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
Value
);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/**
Reads a 16-bit PCI configuration register.
Reads and returns the 16-bit PCI configuration register specified by Address.
This function must guarantee that all PCI read and write operations are
serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@return The read value from the PCI configuration register.
**/
UINT16
PciCf8Read16 (
IN UINTN Address
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT16 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/**
Writes a 16-bit PCI configuration register.
Writes the 16-bit PCI configuration register specified by Address with the
value specified by Value. Value is returned. This function must guarantee
that all PCI read and write operations are serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If Address is not aligned on a 16-bit boundary, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@param Value The value to write.
@return The value written to the PCI configuration register.
**/
UINT16
PciCf8Write16 (
IN UINTN Address,
IN UINT16 Value
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT16 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoWrite16 (
PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
Value
);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/**
Reads a 32-bit PCI configuration register.
Reads and returns the 32-bit PCI configuration register specified by Address.
This function must guarantee that all PCI read and write operations are
serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@return The read value from the PCI configuration register.
**/
UINT32
PciCf8Read32 (
IN UINTN Address
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT32 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/**
Writes a 32-bit PCI configuration register.
Writes the 32-bit PCI configuration register specified by Address with the
value specified by Value. Value is returned. This function must guarantee
that all PCI read and write operations are serialized.
If Address > 0x0FFFFFFF, then ASSERT().
If Address is not aligned on a 32-bit boundary, then ASSERT().
If the register specified by Address >= 0x100, then ASSERT().
@param Address The address that encodes the PCI Bus, Device, Function and
Register.
@param Value The value to write.
@return The value written to the PCI configuration register.
**/
UINT32
PciCf8Write32 (
IN UINTN Address,
IN UINT32 Value
)
{
BOOLEAN InterruptState;
UINT32 AddressPort;
UINT32 Result;
InterruptState = SaveAndDisableInterrupts ();
AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
Result = IoWrite32 (
PCI_CONFIGURATION_DATA_PORT,
Value
);
IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
SetInterruptState (InterruptState);
return Result;
}
/* ========== Other ========= */
// UINT8 PciRead8(UINT64 addr)
// {
// printf("[%s] addr: %8X.\n", __func__, addr);
// return 0x01;
// }
// UINT8 PciWrite8(UINT64 addr, UINT8 data)
// {
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
// return 0x02;
// }
// UINT16 PciRead16(UINT64 addr)
// {
// printf("[%s] addr: %8X.\n", __func__, addr);
// return 0x03;
// }
// UINT16 PciWrite16(UINT64 addr, UINT8 data)
// {
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
// return 0x04;
// }
// UINT32 PciRead32(UINT64 addr)
// {
// printf("[%s] addr: %8X.\n", __func__, addr);
// return 0x05;
// }
// UINT32 PciWrite32(UINT64 addr, UINT8 data)
// {
// printf("[%s] addr: %8X data: %2X.\n", __func__, addr, data);
// return 0x06;
// }
UINT8 PciRead8(UINT64 addr)
{
return PciCf8Read8 (addr);
}
UINT8 PciWrite8(UINT64 addr, UINT8 data)
{
return PciCf8Write8 (addr, data);
}
UINT16 PciRead16(UINT64 addr)
{
return PciCf8Read16 (addr);
}
UINT16 PciWrite16(UINT64 addr, UINT8 data)
{
return PciCf8Write16 (addr, data);
}
UINT32 PciRead32(UINT64 addr)
{
return PciCf8Read32 (addr);
}
UINT32 PciWrite32(UINT64 addr, UINT8 data)
{
return PciCf8Write32 (addr, data);
}

View File

@ -0,0 +1,46 @@
#include "i2c-mei_type.h"
/* ========== PciLib.h ========= */
/**
Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an
address that can be passed to the PCI Library functions.
@param Bus PCI Bus number. Range 0..255.
@param Device PCI Device number. Range 0..31.
@param Function PCI Function number. Range 0..7.
@param Register PCI Register number. Range 0..255 for PCI. Range 0..4095
for PCI Express.
@return The encoded PCI address.
**/
#define PCI_LIB_ADDRESS(Bus,Device,Function,Register) \
(((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))
/* ========== Qubbing ========= */
UINT8 PciRead8(UINT64 addr);
UINT8 PciWrite8(UINT64 addr, UINT8 data);
UINT16 PciRead16(UINT64 addr);
UINT16 PciWrite16(UINT64 addr, UINT8 data);
UINT32 PciRead32(UINT64 addr);
UINT32 PciWrite32(UINT64 addr, UINT8 data);
void I2C_Set(UINT8 smbus, UINT8 daddr, INT32 reg, UINT8 *data, UINT8 dlen);
void I2C_Read(UINT8 smbus, UINT8 daddr, INT32 reg, UINT8 dlen);
void VersionRead(void);
void I2C_Probe(void);

View File

@ -0,0 +1,578 @@
/*
* MEI-I2C driver
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "mei_dev.h"
#include "client.h"
#include "i2c-mei_rw.h"
#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
defined CONFIG_DMI
#include <linux/gpio.h>
#include <linux/i2c-mux-gpio.h>
#endif
/* PCI Address Constants */
#define SMBBAR 0
#define SMBPCICTL 0x004
#define SMBPCISTS 0x006
#define SMBHSTCFG 0x040
#define TCOBASE 0x050
#define TCOCTL 0x054
/* Other settings */
#define MAX_RETRIES 400
/* I801 command constants */
#define I801_QUICK 0x00
#define I801_BYTE 0x04
#define I801_BYTE_DATA 0x08
#define I801_WORD_DATA 0x0C
#define I801_PROC_CALL 0x10 /* unimplemented */
#define I801_BLOCK_DATA 0x14
#define I801_I2C_BLOCK_DATA 0x18 /* ICH5 and later */
#define HECI_PEC_FLAG 0x80
#define PCI_DEVICE_ID_INTEL_LPT_H 0x8C3A /* Lynx Point H */
struct mei_i2c_mux_config {
char *gpio_chip;
unsigned values[3];
int n_values;
unsigned classes[3];
unsigned gpios[2]; /* Relative to gpio_chip->base */
int n_gpios;
};
#define FEATURE_SMBUS_PEC (1 << 0)
#define FEATURE_BLOCK_BUFFER (1 << 1)
#define FEATURE_BLOCK_PROC (1 << 2)
#define FEATURE_I2C_BLOCK_READ (1 << 3)
#define FEATURE_IRQ (1 << 4)
/* Not really a feature, but it's convenient to handle it as such */
#define FEATURE_IDF (1 << 15)
#define FEATURE_TCO (1 << 16)
static const char *mei_i2c_feature_names[] = {
"SMBus PEC",
"Block buffer",
"Block process call",
"I2C block read",
"Interrupt",
};
static unsigned int disable_features;
module_param(disable_features, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n"
"\t\t 0x01 disable SMBus PEC\n"
"\t\t 0x02 disable the block buffer\n"
"\t\t 0x08 disable the I2C block read functionality\n"
"\t\t 0x10 don't use interrupts ");
/*MEI SMB Sensor Bus (when MEI_FLAG_SMB_DEV_ADD_FMAT_EXT)*/
#define MEI_SMB_BUS_SMBUS 0x0
#define MEI_SMB_BUS_SMLINK0 0x1
#define MEI_SMB_BUS_SMLINK1 0x2
#define MEI_SMB_BUS_SMLINK2 0x3
#define MEI_SMB_BUS_SMLINK3 0x4
#define MEI_SMB_BUS_SMLINK4 0x5
struct mei_smb_priv{
struct i2c_adapter adapter;
unsigned long smba;
unsigned char original_hstcfg;
struct pci_dev *pci_dev;
unsigned int features;
unsigned char sensorbus;
/* isr processing */
wait_queue_head_t waitq;
u8 status;
/* Command state used by isr for byte-by-byte block transactions */
u8 cmd;
bool is_read;
int count;
int len;
u8 *data;
};
struct mei_i2c_data_ext{
char Cmd;
char Flag;
char Sensor_Bus;
char Psu_Addr;
char Mux_Addr;
char Mux_Channel;
char Mux_Conf;
char Reserved;
char W_Length;
char R_Length;
char PMbus_data[21];
};
struct mei_msg{
struct mei_msg_hdr hdr;
struct mei_i2c_data_ext data;
};
#define DEBUG_MSG 0
static int mei_TxRx(u8 sensor_bus, u16 addr, u8 command, char read_write, int size, union i2c_smbus_data * data, int pec)
{
struct mei_msg_hdr mei_hdr;
int rets;
unsigned char * recv_buf;
int retry = 0;
int len = 0;
int i = 0;
struct mei_msg * msg;
unsigned char blen;
UINT32 timeout, dwTimeout;
HECI_DEVICE sHeciDev;
recv_buf = kmalloc(sizeof(unsigned char) * (32), GFP_KERNEL);
msg = kmalloc(sizeof(struct mei_msg), GFP_KERNEL);
dwTimeout = 2000000 / HECI_TIMEOUT_UNIT;
sHeciDev.Bus = HECI_BUS;
sHeciDev.Dev = HECI_DEV;
sHeciDev.Fun = HECI_FUN;
sHeciDev.Hidm = HECI_HIDM_MSI;
sHeciDev.Mbar = HECI_MBAR_DEFAULT;
HeciInit(&sHeciDev, &dwTimeout);
msg->data.Cmd = 0x0A;
if(read_write){
if(size == I2C_SMBUS_WORD_DATA){
msg->data.Flag = 0x56;
msg->data.W_Length = 1;
msg->data.R_Length = 2;
}
else if(size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_QUICK){
msg->data.Flag = 0x52;
msg->data.W_Length = 1;
msg->data.R_Length = 1;
}else if(size == I2C_SMBUS_BYTE){
msg->data.Flag = 0x50;
msg->data.W_Length = 0;
msg->data.R_Length = 1;
}else if(size == I2C_SMBUS_BLOCK_DATA){
msg->data.Flag = 0x5A;
msg->data.W_Length = 1;
}
}
else{
if(size == I2C_SMBUS_WORD_DATA){
msg->data.Flag = 0x58;
msg->data.W_Length = 3;
}
else if(size == I2C_SMBUS_BYTE_DATA){
msg->data.Flag = 0x54;
msg->data.W_Length = 2;
}
else if((size == I2C_SMBUS_BYTE) || (size == I2C_SMBUS_QUICK)){
msg->data.Flag = 0x50;
msg->data.W_Length = 1;
}else if(size == I2C_SMBUS_BLOCK_DATA){
msg->data.Flag = 0x5C;
msg->data.W_Length = data->block[0];
}
msg->data.R_Length = 0x0;
if(data !=NULL){
if(size == I2C_SMBUS_WORD_DATA){
msg->data.PMbus_data[1] = data->word & 0xff;
msg->data.PMbus_data[2] = (data->word & 0xff00) >> 8;
}else if(size == I2C_SMBUS_BYTE_DATA){
msg->data.PMbus_data[1] = data->byte;
}else if(size == I2C_SMBUS_BLOCK_DATA){
for (i = 0; i < msg->data.W_Length; i++)
msg->data.PMbus_data[i+1] = data->block[i+1];
}
}else{
msg->data.PMbus_data[1] = 0;
}
}
if (pec == 1)
msg->data.Flag |= HECI_PEC_FLAG;
msg->data.Sensor_Bus = sensor_bus;
msg->data.Psu_Addr =(char) addr << 1;
msg->data.Mux_Addr = 0x0;
msg->data.Mux_Channel = 0x0;
msg->data.Mux_Conf = 0x0;
msg->data.Reserved = 0x0;
msg->data.PMbus_data[0] = command;
msg->hdr.host_addr = 0;//mei_cl_host_addr(cl);
msg->hdr.me_addr = 0x20;
msg->hdr.reserved = 0;
msg->hdr.msg_complete = 0;
msg->hdr.internal = 0; //cb->internal;
msg->hdr.length = 10 + msg->data.W_Length;
msg->hdr.msg_complete = 1;
#if (DEBUG_MSG)
printk("Cmd : 0x%02x , Flag : 0x%02x , Sensor_Bus : 0x%02x , Psu_Addr : 0x%02x\n" , msg->data.Cmd, msg->data.Flag, msg->data.Sensor_Bus, msg->data.Psu_Addr);
printk("Mux_Addr : 0x%02x , Mux_Channel : 0x%02x , Mux_Conf : 0x%02x , W_Length : 0x%02x\n" , msg->data.Mux_Addr, msg->data.Mux_Channel, msg->data.Mux_Conf, msg->data.W_Length);
printk("R_Length : 0x%02x , PMbus_data[0] : 0x%02x , size : 0x%x\n" , msg->data.R_Length, msg->data.PMbus_data[0], size);
if(!read_write){
if(size == I2C_SMBUS_BLOCK_DATA){
for (i = 0; i < msg->data.W_Length; i++){
printk("PMbus_data[%d] : 0x%02x , ", i, msg->data.PMbus_data[i]);
}
printk("\n");
}else{
printk("PMbus_data[1] : 0x%02x , PMbus_data[2] : 0x%02x\n", msg->data.PMbus_data[1], msg->data.PMbus_data[2]);
}
}
#endif
retry = 3;
while(retry){
timeout = HECI_SEND_TIMEOUT / HECI_TIMEOUT_UNIT;
rets = HeciMsgSend(&sHeciDev, &timeout, (HECI_MSG_HEADER *)msg);
if (rets != 0){
printk("HeciMsgSend ret: %d\n",rets);
retry --;
continue;
}else{
break;
}
}
if(read_write)
{
if(size == I2C_SMBUS_WORD_DATA){
blen = 8;
HeciMsgRecv(&sHeciDev, &timeout, (HECI_MSG_HEADER *)recv_buf, &blen);
}
else if(size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE){
blen = 7;
HeciMsgRecv(&sHeciDev, &timeout, (HECI_MSG_HEADER *)recv_buf, &blen);
}
#if (DEBUG_MSG)
if(size == I2C_SMBUS_BLOCK_DATA){
printk("recv_len %d hdr: 0x%02x%02x%02x%02x\n", blen, recv_buf[3], recv_buf[2], recv_buf[1], recv_buf[0]);
for (i = 0; i < blen ; i++){
printk("0x%02x , ", recv_buf[4 + i]);
}
printk("\n");
}else{
printk("recv_len %d recv: 0x%02x%02x%02x%02x\n0x%02x , 0x%02x , 0x%02x, 0x%02x \n", blen, recv_buf[3], recv_buf[2], recv_buf[1], recv_buf[0], recv_buf[4], recv_buf[5], recv_buf[6], recv_buf[7]);
}
#endif
if(data !=NULL){
if(size == I2C_SMBUS_WORD_DATA){
data->word = ((recv_buf[7] << 8) & 0xff00) | (recv_buf[6] & 0xff);
}
else if(size == I2C_SMBUS_BYTE_DATA){
data->byte = recv_buf[6] & 0xff;
}
else if(size == I2C_SMBUS_BLOCK_DATA){
for (i = 0; i < blen; i++){
data->block[i] = recv_buf[6+i] & 0xff;
}
}
}
}
else
{
blen = 6;
HeciMsgRecv(&sHeciDev, &timeout, (HECI_MSG_HEADER *)recv_buf, &blen);
#if (DEBUG_MSG)
printk("recv: 0x%02x%02x%02x%02x , 0x%02x , 0x%02x \n", recv_buf[3], recv_buf[2], recv_buf[1], recv_buf[0], recv_buf[4], recv_buf[5]);
#endif
}
rets = recv_buf[5];
kfree(recv_buf);
kfree(msg);
if(rets)
return -1;
else
return 0;
}
/* Return negative errno on error. */
static s32 mei_i2c_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data)
{
int hwpec;
int block = 0;
int ret = 0, xact = 0;
int pec = 0;
char byte = 0;
struct mei_smb_priv *priv = i2c_get_adapdata(adap);
if (flags & I2C_CLIENT_PEC)
pec = 1;
switch (size) {
case I2C_SMBUS_QUICK:
command = 0;
read_write = 1;
ret = mei_TxRx(priv->sensorbus, addr, command, read_write, size, NULL, pec);
xact = I801_QUICK;
break;
case I2C_SMBUS_BYTE:
if (read_write == I2C_SMBUS_READ)
command = 0;
ret = mei_TxRx(priv->sensorbus, addr, command, read_write, size, data, pec);
xact = I801_BYTE;
break;
case I2C_SMBUS_BYTE_DATA:
ret = mei_TxRx(priv->sensorbus, addr, command, read_write, size, data, pec);
xact = I801_BYTE_DATA;
break;
case I2C_SMBUS_WORD_DATA:
ret = mei_TxRx(priv->sensorbus, addr, command, read_write, size, data, pec);
xact = I801_WORD_DATA;
break;
case I2C_SMBUS_BLOCK_DATA:
ret = mei_TxRx(priv->sensorbus, addr, command, read_write, size, data, pec);
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
printk("I2C_SMBUS_I2C_BLOCK_DATA unsupported!!%d\n",size);
break;
default:
dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
size);
return -EOPNOTSUPP;
}
if (ret)
return ret;
return 0;
}
static u32 mei_i2c_func(struct i2c_adapter *adapter)
{
struct mei_smb_priv *priv = i2c_get_adapdata(adapter);
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA ;
}
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = mei_i2c_access,
.functionality = mei_i2c_func,
};
static const struct pci_device_id mei_i2c_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LPT_H) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, mei_i2c_ids);
/* richard + priv_table */
struct mei_smb_priv_table {
struct mei_smb_priv *priv_tbl[MEI_SMB_BUS_SMLINK4];
int count;
};
static int mei_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
unsigned char temp;
int err, i;
struct mei_smb_priv *priv_sml_0, *priv_sml_1, *priv_sml_2, *priv_sml_3, *priv_sml_4, *priv_smb;
//richard + priv_table
struct mei_smb_priv_table *priv_table;
priv_table = kzalloc(sizeof(*priv_table), GFP_KERNEL);
if(!priv_table)
return -ENOMEM;
priv_sml_0= kzalloc(sizeof(struct mei_smb_priv), GFP_KERNEL);
if (!priv_sml_0)
return -ENOMEM;
i2c_set_adapdata(&priv_sml_0->adapter, priv_sml_0);
priv_sml_0->adapter.owner = THIS_MODULE;
priv_sml_0->adapter.algo = &smbus_algorithm;
priv_sml_0->adapter.dev.parent = &pdev->dev;
priv_sml_0->adapter.retries = 3;
priv_sml_0->sensorbus = MEI_SMB_BUS_SMLINK0;
priv_sml_0->pci_dev = pdev;
priv_sml_1 = kzalloc(sizeof(*priv_sml_1), GFP_KERNEL);
if (!priv_sml_1)
return -ENOMEM;
i2c_set_adapdata(&priv_sml_1->adapter, priv_sml_1);
priv_sml_1->adapter.owner = THIS_MODULE;
priv_sml_1->adapter.algo = &smbus_algorithm;
priv_sml_1->adapter.dev.parent = &pdev->dev;
priv_sml_1->adapter.retries = 3;
priv_sml_1->sensorbus = MEI_SMB_BUS_SMLINK1;
priv_sml_1->pci_dev = pdev;
priv_sml_2 = kzalloc(sizeof(*priv_sml_2), GFP_KERNEL);
if (!priv_sml_2)
return -ENOMEM;
i2c_set_adapdata(&priv_sml_2->adapter, priv_sml_2);
priv_sml_2->adapter.owner = THIS_MODULE;
priv_sml_2->adapter.algo = &smbus_algorithm;
priv_sml_2->adapter.dev.parent = &pdev->dev;
priv_sml_2->adapter.retries = 3;
priv_sml_2->sensorbus = MEI_SMB_BUS_SMLINK2;
priv_sml_2->pci_dev = pdev;
priv_sml_3 = kzalloc(sizeof(*priv_sml_3), GFP_KERNEL);
if (!priv_sml_3)
return -ENOMEM;
i2c_set_adapdata(&priv_sml_3->adapter, priv_sml_3);
priv_sml_3->adapter.owner = THIS_MODULE;
priv_sml_3->adapter.algo = &smbus_algorithm;
priv_sml_3->adapter.dev.parent = &pdev->dev;
priv_sml_3->adapter.retries = 3;
priv_sml_3->sensorbus = MEI_SMB_BUS_SMLINK3;
priv_sml_3->pci_dev = pdev;
priv_sml_4 = kzalloc(sizeof(*priv_sml_4), GFP_KERNEL);
if (!priv_sml_4)
return -ENOMEM;
i2c_set_adapdata(&priv_sml_4->adapter, priv_sml_4);
priv_sml_4->adapter.owner = THIS_MODULE;
priv_sml_4->adapter.algo = &smbus_algorithm;
priv_sml_4->adapter.dev.parent = &pdev->dev;
priv_sml_4->adapter.retries = 3;
priv_sml_4->sensorbus = MEI_SMB_BUS_SMLINK4;
priv_sml_4->pci_dev = pdev;
printk("mei_i2c_probe 0x%x 0x%x\n", pdev->device, pdev->dev.id);
snprintf(priv_sml_0->adapter.name, sizeof(priv_sml_0->adapter.name),
"ME-SMLINK0");
err = i2c_add_adapter(&priv_sml_0->adapter);
printk("i2c nr : %d \n", priv_sml_0->adapter.nr);
if (err) {
dev_err(&pdev->dev, "Failed to add SMBus adapter ME-SMLINK0\n");
return err;
}
snprintf(priv_sml_1->adapter.name, sizeof(priv_sml_1->adapter.name),
"ME-SMLINK1");
err = i2c_add_adapter(&priv_sml_1->adapter);
if (err) {
dev_err(&pdev->dev, "Failed to add SMBus adapter ME-SMLINK1\n");
return err;
}
snprintf(priv_sml_2->adapter.name, sizeof(priv_sml_2->adapter.name),
"ME-SMLINK2");
err = i2c_add_adapter(&priv_sml_2->adapter);
if (err) {
dev_err(&pdev->dev, "Failed to add SMBus adapter ME-SMLINK2\n");
return err;
}
snprintf(priv_sml_3->adapter.name, sizeof(priv_sml_3->adapter.name),
"ME-SMLINK3");
err = i2c_add_adapter(&priv_sml_3->adapter);
if (err) {
dev_err(&pdev->dev, "Failed to add SMBus adapter ME-SMLINK3\n");
return err;
}
snprintf(priv_sml_4->adapter.name, sizeof(priv_sml_4->adapter.name),
"ME-SMLINK4");
err = i2c_add_adapter(&priv_sml_4->adapter);
if (err) {
dev_err(&pdev->dev, "Failed to add SMBus adapter ME-SMLINK4\n");
return err;
}
priv_table->count = 0;
priv_table->priv_tbl[priv_table->count++] = priv_sml_0;
priv_table->priv_tbl[priv_table->count++] = priv_sml_1;
priv_table->priv_tbl[priv_table->count++] = priv_sml_2;
priv_table->priv_tbl[priv_table->count++] = priv_sml_3;
priv_table->priv_tbl[priv_table->count++] = priv_sml_4;
pci_set_drvdata(pdev, priv_table);
return 0;
}
static void mei_i2c_remove(struct pci_dev *dev)
{
struct mei_smb_priv *priv = pci_get_drvdata(dev);
// richard + priv_table
struct mei_smb_priv_table *priv_table = pci_get_drvdata(dev);
int i;
for(i=0; i<priv_table->count; i++) {
i2c_del_adapter(&priv_table->priv_tbl[i]->adapter);
}
pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
/*
* do not call pci_disable_device(dev) since it can cause hard hangs on
* some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010)
*/
}
#define mei_i2c_suspend NULL
#define mei_i2c_resume NULL
static struct pci_driver mei_i2c_driver = {
.name = "mei_i2c",
.id_table = mei_i2c_ids,
.probe = mei_i2c_probe,
.remove = mei_i2c_remove,
.suspend = mei_i2c_suspend,
.resume = mei_i2c_resume,
};
static int __init mei_i2c_init(void)
{
int ret = 16;
u32 status = 0;
struct pci_dev *pdev = NULL;
struct mei_device *dev;
struct pci_driver *pci_drv;
return pci_register_driver(&mei_i2c_driver);
}
static void __exit mei_i2c_exit(void)
{
pci_unregister_driver(&mei_i2c_driver);
}
MODULE_AUTHOR("Delta Networks, Inc.");
MODULE_DESCRIPTION("MEI SMBus driver");
MODULE_LICENSE("GPL");
module_init(mei_i2c_init);
module_exit(mei_i2c_exit);

View File

@ -0,0 +1,591 @@
#include "i2c-mei_rw.h"
#define MicroSecondDelay(time) udelay(time)
/****** Parameter *****/
/****** Struct *****/
typedef struct
{
volatile UINT32 CB_WW; // Circular Buffer Write Window
volatile UINT32 H_CSR; // Host Control and Status Register
volatile UINT32 CB_RW; // Circular Buffer Read Window
volatile UINT32 ME_CSR; // ME Control and Status Register (read only)
} HECI_MBAR_REGS;
typedef union
{
UINT32 DWord;
struct
{
UINT32 H_IE : 1, // 0 - Interrupt Enable ME
H_IS : 1, // 1 - Interrupt Status ME
H_IG : 1, // 2 - Interrupt Generate
H_RDY : 1, // 3 - Ready
H_RST : 1, // 4 - Reset
Reserved: 3, // 5~7
H_CBRP : 8, // 8~15 - CB Read Pointer
H_CBWP : 8, // 16~23 - CB Write Pointer
H_CBD : 8; // 24~31 - Circular Buffer Depth
} Bits;
} HECI_HOST_CSR;
// HECI_MBAR_REGS::ME_CSR - ME Control and Status Register
typedef union
{
UINT32 DWord;
struct
{
UINT32 ME_IE : 1, // 0 - Interrupt Enable (Host Read Access)
ME_IS : 1, // 1 - Interrupt Status (Host Read Access)
ME_IG : 1, // 2 - Interrupt Generate (Host Read Access)
ME_RDY : 1, // 3 - Ready (Host Read Access)
ME_RST : 1, // 4 - Reset (Host Read Access)
Reserved: 3, // 5~7
ME_CBRP : 8, // 8~15 - CB Read Pointer (Host Read Access)
ME_CBWP : 8, // 16~23 - CB Write Pointer (Host Read Access)
ME_CBD : 8; // 24~31 - Circular Buffer Depth (Host Read Access)
} Bits;
} HECI_ME_CSR;
/****** Function *****/
VOID* HeciMbarRead(IN HECI_DEVICE *pThis);
VOID HeciTrace(IN HECI_DEVICE*, IN CHAR8*, IN HECI_MSG_HEADER*, IN INT32);
EFI_STATUS HeciInit ( HECI_DEVICE *pThis,
UINT32 *pTimeout)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 Timeout = 0;
HECI_HOST_CSR sHCsr;
HECI_ME_CSR sMeCsr;
HECI_MBAR_REGS *pMbarRegs;
VOID *pAddrPoint;
if (pThis == NULL || (pThis->Mbar & 0xF) != 0 || pThis->Hidm > HECI_HIDM_LAST)
{
printk("Heci Init Failed");
return EFI_INVALID_PARAMETER;
}
if (pTimeout != NULL)
{
Timeout = *pTimeout;
}
// HECI vendor and device information away
pThis->PciCfg = PCI_LIB_ADDRESS(pThis->Bus, pThis->Dev, pThis->Fun, 0);
pThis->Vid = PciRead16(pThis->PciCfg + HECI_REG_VENDORID);
pThis->Did = PciRead16(pThis->PciCfg + HECI_REG_DEVICEID);
if (pThis->Vid != 0x8086)
{
printk("[HECI] Init failed, PCI device %d/%d/%d not valid HECI (%2X-%2X)\n",
pThis->Bus, pThis->Dev, pThis->Fun, pThis->Vid, pThis->Did);
return EFI_DEVICE_ERROR;
}
// Check MBAR,
pAddrPoint = HeciMbarRead(pThis);
pMbarRegs = (HECI_MBAR_REGS*)ioremap_nocache(pAddrPoint, 0x1000);
if (pMbarRegs == NULL)
{
printk("[HECI-%d] Init failed (device disabled)\n", pThis->Fun);
printk("Check MBAR Failed");
Status = EFI_DEVICE_ERROR;
goto GO_FAIL;
}
// Set HECI interrupt delivery mode.
sHCsr.DWord = pMbarRegs->H_CSR;
sHCsr.Bits.H_IE = 0;
pMbarRegs->H_CSR = sHCsr.DWord;
PciWrite8(pThis->PciCfg + HECI_REG_HIDM, pThis->Hidm);
// Check HECI was free
sMeCsr.DWord = pMbarRegs->ME_CSR;
if (!sMeCsr.Bits.ME_RDY)
{
Status = HecClearQue(pThis, &Timeout);
}
else
{
if (!sHCsr.Bits.H_RDY)
{
sHCsr.Bits.H_IG = 1;
sHCsr.Bits.H_RDY = 1;
sHCsr.Bits.H_RST = 0;
pMbarRegs->H_CSR = sHCsr.DWord;
}
pThis->HMtu = sHCsr.Bits.H_CBD * sizeof(UINT32) - sizeof(HECI_MSG_HEADER);
pThis->MeMtu = sMeCsr.Bits.ME_CBD * sizeof(UINT32) - sizeof(HECI_MSG_HEADER);
}
GO_FAIL:
if (pTimeout != NULL)
{
*pTimeout = Timeout;
}
pThis->Mefs1.DWord = HeciPciReadMefs1();
iounmap((VOID *)pMbarRegs);
return Status;
}
EFI_STATUS HecClearQue ( HECI_DEVICE *pThis,
UINT32 *pTimeout)
{
EFI_STATUS Status;
UINT32 Timeout = 0;
HECI_HOST_CSR sHCsr;
HECI_ME_CSR sMeCsr;
HECI_MBAR_REGS *pMbarRegs;
VOID *pAddrPoint;
if (pThis == NULL)
{
printk("Failed");
return EFI_INVALID_PARAMETER;
}
// Check for HECI availability on PCI
pAddrPoint = HeciMbarRead(pThis);
pMbarRegs = (HECI_MBAR_REGS*)ioremap_nocache(pAddrPoint, 0x1000);
printk("pMbarRegs: %x\n", pMbarRegs);
if (pMbarRegs == NULL)
{
printk("[HECI-%d] Reset failed (device disabled)\n", pThis->Fun);
printk("Failed");
return EFI_DEVICE_ERROR;
}
if (pTimeout != NULL)
{
Timeout = *pTimeout;
}
printk("[HECI-%d] Resetting HECI interface (CSR %X/%X)\n",
pThis->Fun, pMbarRegs->H_CSR, pMbarRegs->ME_CSR);
sHCsr.DWord = pMbarRegs->H_CSR;
if (!sHCsr.Bits.H_RST)
{
sHCsr.Bits.H_RST = 1;
sHCsr.Bits.H_IG = 1;
pMbarRegs->H_CSR = sHCsr.DWord;
}
// Wait for H_RDY cleared to make sure that the reset started.
while (1)
{
sHCsr.DWord = pMbarRegs->H_CSR;
if (!sHCsr.Bits.H_RDY)
{
break;
}
if (Timeout == 0)
{
printk("[HECI-%d] Reset failed (timeout)(CSR %X/%X)\n",
pThis->Fun, pMbarRegs->H_CSR, pMbarRegs->ME_CSR);
Status = EFI_TIMEOUT;
goto GO_FAIL;
}
MicroSecondDelay(HECI_TIMEOUT_UNIT);
Timeout--;
}
// Wait for ME to perform reset and signal it is ready.
while (1)
{
sMeCsr.DWord = pMbarRegs->ME_CSR;
if (sMeCsr.Bits.ME_RDY)
{
break;
}
if (Timeout == 0)
{
printk("[HECI-%d] Reset failed (timeout)(CSR %X/%X)\n",
pThis->Fun, pMbarRegs->H_CSR, pMbarRegs->ME_CSR);
Status = EFI_TIMEOUT;
goto GO_FAIL;
}
MicroSecondDelay(HECI_TIMEOUT_UNIT);
Timeout--;
}
// ME side is ready, signal host side is ready too.
sHCsr.DWord = pMbarRegs->H_CSR;
sHCsr.Bits.H_RST = 0;
sHCsr.Bits.H_RDY = 1;
sHCsr.Bits.H_IG = 1;
pMbarRegs->H_CSR = sHCsr.DWord;
// Update MTU, ME could change it during reset.
pThis->HMtu = sHCsr.Bits.H_CBD * sizeof(UINT32) - sizeof(HECI_MSG_HEADER);
pThis->MeMtu = sMeCsr.Bits.ME_CBD * sizeof(UINT32) - sizeof(HECI_MSG_HEADER);
Status = EFI_SUCCESS;
GO_FAIL:
if (pTimeout != NULL)
{
*pTimeout = Timeout;
}
pThis->Mefs1.DWord = HeciPciReadMefs1();
iounmap((VOID *)pMbarRegs);
return Status;
}
EFI_STATUS HeciMsgRecv ( HECI_DEVICE *pThis,
UINT32 *pTimeout,
HECI_MSG_HEADER *pMsgBuf,
UINT32 *pBufLen )
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 Timeout = 0;
UINT32 DWord, dwDataReads, dwBufLen;
UINT8 bFilledSlots, bMsgLen = 0;
HECI_HOST_CSR sHCsr;
HECI_ME_CSR sMeCsr;
HECI_MBAR_REGS *pMbarRegs;
VOID *pAddrPoint;
if (pThis == NULL || pMsgBuf == NULL ||
pBufLen == NULL || *pBufLen < sizeof(HECI_MSG_HEADER))
{
printk("Heci MsgRecv Failed\n");
return EFI_INVALID_PARAMETER;
}
// Check for HECI availability on PCI
pAddrPoint = HeciMbarRead(pThis);
pMbarRegs = (HECI_MBAR_REGS*)ioremap_nocache(pAddrPoint, 0x1000);
if (pMbarRegs == NULL)
{
printk("[HECI-%d] Receive failed (device disabled)\n", pThis->Fun);
printk("pMbarRegs Failed\n");
return EFI_DEVICE_ERROR;
}
if (pTimeout != NULL)
{
Timeout = *pTimeout;
}
// read from queue.
dwBufLen = *pBufLen;
*pBufLen = dwDataReads = 0;
while (1)
{
sHCsr.DWord = pMbarRegs->H_CSR;
sMeCsr.DWord = pMbarRegs->ME_CSR;
bFilledSlots = (UINT8)((INT8)sMeCsr.Bits.ME_CBWP - (INT8)sMeCsr.Bits.ME_CBRP);
// Is it ready ?
if (!sMeCsr.Bits.ME_RDY || !sHCsr.Bits.H_RDY || bFilledSlots > sHCsr.Bits.H_CBD)
{
Status = HecClearQue(pThis, &Timeout);
if (EFI_ERROR(Status))
{
goto GO_FAIL;
}
continue;
}
// Read queue
while (bFilledSlots-- > 0)
{
DWord = pMbarRegs->CB_RW;
if (*pBufLen < dwBufLen)
{
if (dwDataReads < dwBufLen / sizeof(UINT32))
{
((UINT32*)pMsgBuf)[dwDataReads] = DWord;
*pBufLen += sizeof(UINT32);
}
else
{
switch (dwBufLen % sizeof(UINT32))
{
case 3: ((UINT8*)pMsgBuf)[*pBufLen + 2] = (UINT8)(DWord >> 16);
case 2: ((UINT8*)pMsgBuf)[*pBufLen + 1] = (UINT8)(DWord >> 8);
case 1: ((UINT8*)pMsgBuf)[*pBufLen + 0] = (UINT8)DWord;
}
*pBufLen += dwBufLen % sizeof(UINT32);
}
}
else
{
printk("[HECI-%d] Message 0x%08X exceeds buffer size (%dB)\n",
pThis->Fun, pMsgBuf[0].DWord, dwBufLen);
}
dwDataReads++;
// Read message length.
if (bMsgLen == 0)
{
bMsgLen = (UINT8)((pMsgBuf[0].Bits.Length + sizeof(UINT32) - 1) / sizeof(UINT32));
bMsgLen++; // One more double word for message header
//
// Sanity check. If message length exceeds queue length this is
// not valid header. We are out of synch, let's reset the queue.
//
if (bMsgLen > sMeCsr.Bits.ME_CBD)
{
printk("[HECI-%d] 0x%08X does not seem to be msg header, reseting...\n",
pThis->Fun, pMsgBuf[0].DWord);
Status = HecClearQue(pThis, &Timeout);
if (EFI_ERROR(Status))
{
goto GO_FAIL;
}
*pBufLen = dwDataReads = bMsgLen = 0;
break; // while (bFilledSlots)
}
}
// If message is complete set interrupt to ME to let it know that next
// message can be sent and exit.
if (dwDataReads >= bMsgLen)
{
sMeCsr.DWord = pMbarRegs->ME_CSR;
sHCsr.DWord = pMbarRegs->H_CSR;
if (!sMeCsr.Bits.ME_RDY)
{
HecClearQue(pThis, &Timeout);
Status = EFI_ABORTED;
}
else
{
HeciTrace(pThis, " Got msg: ", pMsgBuf, *pBufLen);
sHCsr.Bits.H_IG = 1;
pMbarRegs->H_CSR = sHCsr.DWord;
}
goto GO_FAIL;
}
}
if (Timeout == 0)
{
printk("[HECI-%d] Receive failed (timeout)\n", pThis->Fun);
Status = EFI_TIMEOUT;
goto GO_FAIL;
}
MicroSecondDelay(HECI_TIMEOUT_UNIT);
Timeout--;
}
GO_FAIL:
if (pTimeout != NULL)
{
*pTimeout = Timeout;
}
pThis->Mefs1.DWord = HeciPciReadMefs1();
iounmap((VOID *)pMbarRegs);
return Status;
}
EFI_STATUS HeciMsgSend ( HECI_DEVICE *pThis,
UINT32 *pTimeout,
HECI_MSG_HEADER *pMessage)
{
EFI_STATUS Status;
UINT32 Timeout = 0;
UINT8 bEmptySlots;
UINT8 i, bMsgLen;
HECI_HOST_CSR sHCsr;
HECI_ME_CSR sMeCsr;
HECI_MBAR_REGS *pMbarRegs;
VOID *pAddrPoint;
if (pThis == NULL || pMessage == NULL)
{
printk("HeciMsgSend Failed\n");
return EFI_INVALID_PARAMETER;
}
HeciTrace(pThis, "Send msg: ", pMessage, sizeof(HECI_MSG_HEADER) + pMessage->Bits.Length);
// Check for HECI availability
pAddrPoint = HeciMbarRead(pThis);
pMbarRegs = (HECI_MBAR_REGS*)ioremap_nocache(pAddrPoint, 0x1000);
if (pMbarRegs == NULL)
{
printk("[HECI-%d] Send failed (device disabled)\n", pThis->Fun);
printk("Failed\n");
return EFI_DEVICE_ERROR;
}
if (pTimeout != NULL)
{
Timeout = *pTimeout;
}
bMsgLen = (UINT8)((pMessage->Bits.Length + sizeof(UINT32) - 1) / sizeof(UINT32));
bMsgLen++; //message header
while (1)
{
sHCsr.DWord = pMbarRegs->H_CSR;
sMeCsr.DWord = pMbarRegs->ME_CSR;
// If message is more than queue length go fail.
if (bMsgLen > sHCsr.Bits.H_CBD)
{
printk("[HECI-%d] Send failed (msg %d B, queue %d B only)\n",
pThis->Fun, pMessage->Bits.Length, sHCsr.Bits.H_CBD * sizeof(UINT32));
Status = EFI_BAD_BUFFER_SIZE;
goto GO_FAIL;
}
bEmptySlots = (UINT8)sHCsr.Bits.H_CBD -
(UINT8)((INT8)sHCsr.Bits.H_CBWP - (INT8)sHCsr.Bits.H_CBRP);
// Is it ready ?
if (!sMeCsr.Bits.ME_RDY || !sHCsr.Bits.H_RDY || bEmptySlots > sHCsr.Bits.H_CBD)
{
Status = HecClearQue(pThis, &Timeout);
if (EFI_ERROR(Status))
{
goto GO_FAIL;
}
continue;
}
if (bMsgLen <= bEmptySlots)
{
for (i = 0; i < bMsgLen; i++)
{
pMbarRegs->CB_WW = ((UINT32*)pMessage)[i];
}
sMeCsr.DWord = pMbarRegs->ME_CSR;
if (!sMeCsr.Bits.ME_RDY)
{
printk("[HECI-%d] Queue has been reset while sending\n", pThis->Fun);
continue;
}
sHCsr.DWord = pMbarRegs->H_CSR;
sHCsr.Bits.H_IS = 0;
sHCsr.Bits.H_IG = 1;
pMbarRegs->H_CSR = sHCsr.DWord;
Status = EFI_SUCCESS;
goto GO_FAIL;
}
if (Timeout == 0)
{
printk("[HECI-%d] Send failed (timeout)\n", pThis->Fun);
Status = EFI_TIMEOUT;
goto GO_FAIL;
}
MicroSecondDelay(HECI_TIMEOUT_UNIT);
Timeout--;
}
GO_FAIL:
if (pTimeout != NULL)
{
*pTimeout = Timeout;
}
pThis->Mefs1.DWord = HeciPciReadMefs1();
iounmap((VOID *)pMbarRegs);
return Status;
}
VOID *HeciMbarRead(HECI_DEVICE *pThis)
{
VOID *start;
UINT16 Cmd;
union
{
UINT64 QWord;
struct
{
UINT32 DWordL;
UINT32 DWordH;
} Bits;
} Mbar;
//
// Read MBAR.
Mbar.QWord = 0;
Mbar.Bits.DWordL = PciRead32(pThis->PciCfg + HECI_REG_MBAR);
if (Mbar.Bits.DWordL == 0xFFFFFFFF)
{
printk("[HECI-%d] Device disabled\n", pThis->Fun);
Mbar.Bits.DWordL = 0;
goto GO_FAIL;
}
if (Mbar.Bits.DWordL & 0x4) // if 64-bit address add the upper half
{
Mbar.Bits.DWordH = PciRead32(pThis->PciCfg + HECI_REG_MBAR + 4);
}
Mbar.Bits.DWordL &= 0xFFFFFFF0;
if (Mbar.QWord == 0)
{
if (pThis->Mbar == 0)
{
printk("[HECI-%d] MBAR not programmed\n", pThis->Fun);
goto GO_FAIL;
}
else
{
Mbar.QWord = pThis->Mbar;
printk("[HECI-%d] MBAR not programmed, using default 0x%08X%08X\n",
pThis->Fun, Mbar.Bits.DWordH, Mbar.Bits.DWordL);
// Programm the MBAR, set the 64-bit support bit regardless of the size
// of the address currently used.
PciWrite32(pThis->PciCfg + HECI_REG_MBAR + 4, Mbar.Bits.DWordH);
PciWrite32(pThis->PciCfg + HECI_REG_MBAR, Mbar.Bits.DWordL | 4);
}
}
else
{
pThis->Mbar = Mbar.QWord;
}
// Enable the MBAR
Cmd = PciRead16(pThis->PciCfg + HECI_REG_COMMAND);
if (!(Cmd & HECI_CMD_MSE))
{
PciWrite16(pThis->PciCfg + HECI_REG_COMMAND, Cmd | HECI_CMD_BME | HECI_CMD_MSE);
}
GO_FAIL:
return (VOID*)(INTN)Mbar.QWord;
}
VOID HeciTrace( HECI_DEVICE *pThis,
CHAR8 *pPrefix,
HECI_MSG_HEADER *pMsg,
INT32 MsgLen)
{
#if 0 /// Trace Enable or Disable
if (MsgLen > 4)
{
UINT32 dwLineBreak = 0;
UINT32 dwIndex = 0;
UINT8 *pMsgBody = (UINT8*)&pMsg[1];
MsgLen -= 4;
while (MsgLen-- > 0)
{
if (dwLineBreak == 0)
printk("%02x: ", (dwIndex & 0xF0));
printk("%02x ", pMsgBody[dwIndex++]);
dwLineBreak++;
if (dwLineBreak == 16)
{
printk("\n");
dwLineBreak = 0;
}
if (dwLineBreak == 8)
{
printk("-");
}
}
printk("\n");
}
#endif
}

View File

@ -0,0 +1,143 @@
#include "i2c-mei_io.h"
/****** Parameter *****/
#define HECI_READ_TIMEOUT 12500000 // 12.5sec
#define HECI_SEND_TIMEOUT 12500000 // 12.5sec
#define HECI_TIMEOUT_UNIT 10
// HECI functions location
#define HECI_BUS 0
#define HECI_DEV 22
#define HECI_FUN 0
// HECI register
#define HECI_REG_VENDORID 0x00
#define HECI_REG_DEVICEID 0x02
#define HECI_REG_COMMAND 0x04
#define HECI_REG_REVID 0x08
#define HECI_REG_MBAR 0x10
#define HECI_REG_IRQ 0x3C
#define HECI_REG_HIDM 0xA0
#define HECI_REG_HFS 0x40
#define HECI_REG_MISC_SHDW 0x44
#define HECI_REG_GS_SHDW 0x48
#define HECI_REG_H_GS 0x4C
#define HECI_REG_GS_SHDW2 0x60
#define HECI_REG_GS_SHDW3 0x64
#define HECI_REG_GS_SHDW4 0x68
#define HECI_REG_GS_SHDW5 0x6C
#define HECI_REG_H_GS2 0x70
#define HECI_REG_H_GS3 0x74
#define HECI_REG_MEFS1 HECI_REG_HFS
#define HECI_REG_MEFS2 HECI_REG_GS_SHDW
#define HECI_MBAR_DEFAULT 0xFEDB0000
// HECI Interrupt Delivery Mode to be set in HECI_REG_HIDM.
#define HECI_HIDM_MSI 0
#define HECI_HIDM_SCI 1
#define HECI_HIDM_SMI 2
#define HECI_HIDM_LAST HECI_HIDM_SMI
// HECI command register bits
#define HECI_CMD_BME 0x04 // Bus master enable
#define HECI_CMD_MSE 0x02 // Memory space enable
/****** Struct *****/
typedef union
{
UINT32 DWord;
struct
{
UINT32 MeAddress : 8, // Addressee on ME side
HostAddress: 8, // Addressee on host siede, zero for BIOS
Length : 9, // Number of bytes following the header
Reserved : 6,
MsgComplete: 1; // Whether this is last fragment of a message
} Bits;
} HECI_MSG_HEADER;
// ME Firmware Status 1 register basics. offset:40h
typedef union
{
UINT32 DWord;
struct
{
UINT32 CurrentState : 4, // 0~3 Current ME firmware state
Reserved_5 : 5, // 4~8
InitComplete : 1, // 9 ME firmware finished initialization
Reserved_10 : 2, // 10~11
ErrorCode : 4, // 12~15 If set means fatal error
OperatingMode: 4, // 16~19 Current ME operating mode
Reserved_20 : 5, // 20~24
MsgAckData : 3, // 25~27 MSG ACK Data specific for acknowledged BIOS message
MsgAck : 4; // 28~31 Acknowledge for register based BIOS message
} Bits;
} HECI_MEFS1;
typedef struct
{
UINT8 Bus; // PCI bus
UINT8 Dev; // PCI device
UINT8 Fun; // PCI function number
UINTN PciCfg;
UINT16 Vid; // Device ID
UINT16 Did; // Vendor ID
UINT8 Hidm; // interrupt mode
UINT64 Mbar;
UINT32 HMtu; // Max transfer unit configured by ME minus header
UINT32 MeMtu; // Max transfer unit configured by ME minus header
HECI_MEFS1 Mefs1; // ME Firmware Status at recent operation
} HECI_DEVICE;
/****** Function *****/
/**
* @param pThis Pointer to HECI device structure
* @param pTimeout On input timeout in ms, on exit time left
*/
EFI_STATUS HeciInit ( HECI_DEVICE *pThis,
UINT32 *pTimeout);
/**
* @param pThis Pointer to HECI device structure
* @param pTimeout On input timeout in ms, on exit time left
*/
EFI_STATUS HecClearQue ( HECI_DEVICE *pThis,
UINT32 *pTimeout);
/**
* @param pThis Pointer to HECI device structure
* @param pTimeout On input timeout in ms, on exit time left
* @param pMsgBuf Buffer for the received message
* @param pBufLen On input buffer size, on exit message, in bytes
*/
EFI_STATUS HeciMsgRecv ( HECI_DEVICE *pThis,
UINT32 *pTimeout,
HECI_MSG_HEADER *pMsgBuf,
UINT32 *pBufLen );
/**
* @param pThis Pointer to HECI device structure
* @param pTimeout On input timeout in ms, on exit time left
* @param pMessage The header of the message to send
*/
EFI_STATUS HeciMsgSend ( HECI_DEVICE *pThis,
UINT32 *pTimeout,
HECI_MSG_HEADER *pMessage);
#define HeciPciReadMefs1() PciRead32(PCI_LIB_ADDRESS(HECI_BUS, HECI_DEV, HECI_FUN, HECI_REG_MEFS1))

View File

@ -0,0 +1,448 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/delay.h>
#ifdef EFIAPI
#define EFIAPI
#endif
//
// Assume standard AARCH64 alignment.
//
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned int UINT32;
typedef int INT32;
typedef unsigned short UINT16;
typedef unsigned short CHAR16;
typedef short INT16;
typedef unsigned char BOOLEAN;
typedef unsigned char UINT8;
typedef char CHAR8;
typedef signed char INT8;
///
/// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef UINT64 UINTN;
///
/// Signed value of native width. (4 bytes on supported 32-bit processor instructions,
/// 8 bytes on supported 64-bit processor instructions)
///
typedef INT64 INTN;
/* ========== ProcessBind.h ========= */
///
/// A value of native width with the highest bit set.
///
#define MAX_BIT 0x8000000000000000ULL
/* ========== Base.h ========= */
//
// Modifiers to abstract standard types to aid in debug of problems
//
///
/// Datum is read-only.
///
#define CONST const
///
/// Datum is scoped to the current file or function.
///
#define STATIC static
///
/// Undeclared type.
///
#define VOID void
//
// Modifiers for Data Types used to self document code.
// This concept is borrowed for UEFI specification.
//
///
/// Datum is passed to the function.
///
#define IN
///
/// Datum is returned from the function.
///
#define OUT
///
/// Passing the datum to the function is optional, and a NULL
/// is passed if the value is not supplied.
///
#define OPTIONAL
//
// UEFI specification claims 1 and 0. We are concerned about the
// complier portability so we did it this way.
//
///
/// Boolean true value. UEFI Specification defines this value to be 1,
/// but this form is more portable.
///
#define TRUE ((BOOLEAN)(1==1))
///
/// Boolean false value. UEFI Specification defines this value to be 0,
/// but this form is more portable.
///
#define FALSE ((BOOLEAN)(0==1))
///
/// NULL pointer (VOID *)
///
#define NULL ((VOID *) 0)
//
// Status codes common to all execution phases
//
typedef UINTN RETURN_STATUS;
/**
Produces a RETURN_STATUS code with the highest bit set.
@param StatusCode The status code value to convert into a warning code.
StatusCode must be in the range 0x00000000..0x7FFFFFFF.
@return The value specified by StatusCode with the highest bit set.
**/
#define ENCODE_ERROR(StatusCode) ((RETURN_STATUS)(MAX_BIT | (StatusCode)))
/**
Produces a RETURN_STATUS code with the highest bit clear.
@param StatusCode The status code value to convert into a warning code.
StatusCode must be in the range 0x00000000..0x7FFFFFFF.
@return The value specified by StatusCode with the highest bit clear.
**/
#define ENCODE_WARNING(StatusCode) ((RETURN_STATUS)(StatusCode))
/**
Returns TRUE if a specified RETURN_STATUS code is an error code.
This function returns TRUE if StatusCode has the high bit set. Otherwise, FALSE is returned.
@param StatusCode The status code value to evaluate.
@retval TRUE The high bit of StatusCode is set.
@retval FALSE The high bit of StatusCode is clear.
**/
#define RETURN_ERROR(StatusCode) (((INTN)(RETURN_STATUS)(StatusCode)) < 0)
///
/// The operation completed successfully.
///
#define RETURN_SUCCESS 0
///
/// The image failed to load.
///
#define RETURN_LOAD_ERROR ENCODE_ERROR (1)
///
/// The parameter was incorrect.
///
#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2)
///
/// The operation is not supported.
///
#define RETURN_UNSUPPORTED ENCODE_ERROR (3)
///
/// The buffer was not the proper size for the request.
///
#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4)
///
/// The buffer was not large enough to hold the requested data.
/// The required buffer size is returned in the appropriate
/// parameter when this error occurs.
///
#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5)
///
/// There is no data pending upon return.
///
#define RETURN_NOT_READY ENCODE_ERROR (6)
///
/// The physical device reported an error while attempting the
/// operation.
///
#define RETURN_DEVICE_ERROR ENCODE_ERROR (7)
///
/// The device can not be written to.
///
#define RETURN_WRITE_PROTECTED ENCODE_ERROR (8)
///
/// The resource has run out.
///
#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9)
///
/// An inconsistency was detected on the file system causing the
/// operation to fail.
///
#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10)
///
/// There is no more space on the file system.
///
#define RETURN_VOLUME_FULL ENCODE_ERROR (11)
///
/// The device does not contain any medium to perform the
/// operation.
///
#define RETURN_NO_MEDIA ENCODE_ERROR (12)
///
/// The medium in the device has changed since the last
/// access.
///
#define RETURN_MEDIA_CHANGED ENCODE_ERROR (13)
///
/// The item was not found.
///
#define RETURN_NOT_FOUND ENCODE_ERROR (14)
///
/// Access was denied.
///
#define RETURN_ACCESS_DENIED ENCODE_ERROR (15)
///
/// The server was not found or did not respond to the request.
///
#define RETURN_NO_RESPONSE ENCODE_ERROR (16)
///
/// A mapping to the device does not exist.
///
#define RETURN_NO_MAPPING ENCODE_ERROR (17)
///
/// A timeout time expired.
///
#define RETURN_TIMEOUT ENCODE_ERROR (18)
///
/// The protocol has not been started.
///
#define RETURN_NOT_STARTED ENCODE_ERROR (19)
///
/// The protocol has already been started.
///
#define RETURN_ALREADY_STARTED ENCODE_ERROR (20)
///
/// The operation was aborted.
///
#define RETURN_ABORTED ENCODE_ERROR (21)
///
/// An ICMP error occurred during the network operation.
///
#define RETURN_ICMP_ERROR ENCODE_ERROR (22)
///
/// A TFTP error occurred during the network operation.
///
#define RETURN_TFTP_ERROR ENCODE_ERROR (23)
///
/// A protocol error occurred during the network operation.
///
#define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24)
///
/// A function encountered an internal version that was
/// incompatible with a version requested by the caller.
///
#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25)
///
/// The function was not performed due to a security violation.
///
#define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26)
///
/// A CRC error was detected.
///
#define RETURN_CRC_ERROR ENCODE_ERROR (27)
///
/// The beginning or end of media was reached.
///
#define RETURN_END_OF_MEDIA ENCODE_ERROR (28)
///
/// The end of the file was reached.
///
#define RETURN_END_OF_FILE ENCODE_ERROR (31)
///
/// The language specified was invalid.
///
#define RETURN_INVALID_LANGUAGE ENCODE_ERROR (32)
///
/// The security status of the data is unknown or compromised
/// and the data must be updated or replaced to restore a valid
/// security status.
///
#define RETURN_COMPROMISED_DATA ENCODE_ERROR (33)
///
/// The string contained one or more characters that
/// the device could not render and were skipped.
///
#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1)
///
/// The handle was closed, but the file was not deleted.
///
#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2)
///
/// The handle was closed, but the data to the file was not
/// flushed properly.
///
#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3)
///
/// The resulting buffer was too small, and the data was
/// truncated to the buffer size.
///
#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4)
///
/// The data has not been updated within the timeframe set by
/// local policy for this type of data.
///
#define RETURN_WARN_STALE_DATA ENCODE_WARNING (5)
/* ========== UefiBaseType.h ========= */
///
/// Function return status for EFI API.
///
typedef RETURN_STATUS EFI_STATUS;
///
/// Enumeration of EFI_STATUS.
///@{
#define EFI_SUCCESS RETURN_SUCCESS
#define EFI_LOAD_ERROR RETURN_LOAD_ERROR
#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER
#define EFI_UNSUPPORTED RETURN_UNSUPPORTED
#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE
#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL
#define EFI_NOT_READY RETURN_NOT_READY
#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR
#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED
#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES
#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED
#define EFI_VOLUME_FULL RETURN_VOLUME_FULL
#define EFI_NO_MEDIA RETURN_NO_MEDIA
#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED
#define EFI_NOT_FOUND RETURN_NOT_FOUND
#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED
#define EFI_NO_RESPONSE RETURN_NO_RESPONSE
#define EFI_NO_MAPPING RETURN_NO_MAPPING
#define EFI_TIMEOUT RETURN_TIMEOUT
#define EFI_NOT_STARTED RETURN_NOT_STARTED
#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED
#define EFI_ABORTED RETURN_ABORTED
#define EFI_ICMP_ERROR RETURN_ICMP_ERROR
#define EFI_TFTP_ERROR RETURN_TFTP_ERROR
#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR
#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION
#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION
#define EFI_CRC_ERROR RETURN_CRC_ERROR
#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA
#define EFI_END_OF_FILE RETURN_END_OF_FILE
#define EFI_INVALID_LANGUAGE RETURN_INVALID_LANGUAGE
#define EFI_COMPROMISED_DATA RETURN_COMPROMISED_DATA
#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH
#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE
#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE
#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL
#define EFI_WARN_STALE_DATA RETURN_WARN_STALE_DATA
///@}
///
/// Define macro to encode the status code.
///
#define EFIERR(_a) ENCODE_ERROR(_a)
#define EFI_ERROR(A) RETURN_ERROR(A)
/* ========== BaseLib.h ========= */
///
/// Byte packed structure for EFLAGS/RFLAGS.
/// 32-bits on IA-32.
/// 64-bits on x64. The upper 32-bits on x64 are reserved.
///
typedef union {
struct {
UINT32 CF:1; ///< Carry Flag.
UINT32 Reserved_0:1; ///< Reserved.
UINT32 PF:1; ///< Parity Flag.
UINT32 Reserved_1:1; ///< Reserved.
UINT32 AF:1; ///< Auxiliary Carry Flag.
UINT32 Reserved_2:1; ///< Reserved.
UINT32 ZF:1; ///< Zero Flag.
UINT32 SF:1; ///< Sign Flag.
UINT32 TF:1; ///< Trap Flag.
UINT32 IF:1; ///< Interrupt Enable Flag.
UINT32 DF:1; ///< Direction Flag.
UINT32 OF:1; ///< Overflow Flag.
UINT32 IOPL:2; ///< I/O Privilege Level.
UINT32 NT:1; ///< Nested Task.
UINT32 Reserved_3:1; ///< Reserved.
UINT32 RF:1; ///< Resume Flag.
UINT32 VM:1; ///< Virtual 8086 Mode.
UINT32 AC:1; ///< Alignment Check.
UINT32 VIF:1; ///< Virtual Interrupt Flag.
UINT32 VIP:1; ///< Virtual Interrupt Pending.
UINT32 ID:1; ///< ID Flag.
UINT32 Reserved_4:10; ///< Reserved.
} Bits;
UINTN UintN;
} IA32_EFLAGS32;

View File

@ -0,0 +1,832 @@
/*
*
* Intel Management Engine Interface (Intel MEI) Linux driver
* Copyright (c) 2003-2012, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _MEI_DEV_H_
#define _MEI_DEV_H_
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/poll.h>
#include <linux/mei.h>
#include <linux/mei_cl_bus.h>
#include "hw.h"
#include "hbm.h"
/*
* watch dog definition
*/
#define MEI_WD_HDR_SIZE 4
#define MEI_WD_STOP_MSG_SIZE MEI_WD_HDR_SIZE
#define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16)
#define MEI_WD_DEFAULT_TIMEOUT 120 /* seconds */
#define MEI_WD_MIN_TIMEOUT 120 /* seconds */
#define MEI_WD_MAX_TIMEOUT 65535 /* seconds */
#define MEI_WD_STOP_TIMEOUT 10 /* msecs */
#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0)
#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32))
/*
* AMTHI Client UUID
*/
extern const uuid_le mei_amthif_guid;
/*
* Watchdog Client UUID
*/
extern const uuid_le mei_wd_guid;
/*
* Number of Maximum MEI Clients
*/
#define MEI_CLIENTS_MAX 256
/*
* maximum number of consecutive resets
*/
#define MEI_MAX_CONSEC_RESET 3
/*
* Number of File descriptors/handles
* that can be opened to the driver.
*
* Limit to 255: 256 Total Clients
* minus internal client for MEI Bus Messages
*/
#define MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 1)
/*
* Internal Clients Number
*/
#define MEI_HOST_CLIENT_ID_ANY (-1)
#define MEI_HBM_HOST_CLIENT_ID 0 /* not used, just for documentation */
#define MEI_WD_HOST_CLIENT_ID 1
#define MEI_IAMTHIF_HOST_CLIENT_ID 2
/* File state */
enum file_state {
MEI_FILE_INITIALIZING = 0,
MEI_FILE_CONNECTING,
MEI_FILE_CONNECTED,
MEI_FILE_DISCONNECTING,
MEI_FILE_DISCONNECT_REPLY,
MEI_FILE_DISCONNECT_REQUIRED,
MEI_FILE_DISCONNECTED,
};
/* MEI device states */
enum mei_dev_state {
MEI_DEV_INITIALIZING = 0,
MEI_DEV_INIT_CLIENTS,
MEI_DEV_ENABLED,
MEI_DEV_RESETTING,
MEI_DEV_DISABLED,
MEI_DEV_POWER_DOWN,
MEI_DEV_POWER_UP
};
const char *mei_dev_state_str(int state);
enum iamthif_states {
MEI_IAMTHIF_IDLE,
MEI_IAMTHIF_WRITING,
MEI_IAMTHIF_FLOW_CONTROL,
MEI_IAMTHIF_READING,
MEI_IAMTHIF_READ_COMPLETE
};
enum mei_file_transaction_states {
MEI_IDLE,
MEI_WRITING,
MEI_WRITE_COMPLETE,
MEI_FLOW_CONTROL,
MEI_READING,
MEI_READ_COMPLETE
};
enum mei_wd_states {
MEI_WD_IDLE,
MEI_WD_RUNNING,
MEI_WD_STOPPING,
};
/**
* enum mei_cb_file_ops - file operation associated with the callback
* @MEI_FOP_READ: read
* @MEI_FOP_WRITE: write
* @MEI_FOP_CONNECT: connect
* @MEI_FOP_DISCONNECT: disconnect
* @MEI_FOP_DISCONNECT_RSP: disconnect response
* @MEI_FOP_NOTIFY_START: start notification
* @MEI_FOP_NOTIFY_STOP: stop notification
*/
enum mei_cb_file_ops {
MEI_FOP_READ = 0,
MEI_FOP_WRITE,
MEI_FOP_CONNECT,
MEI_FOP_DISCONNECT,
MEI_FOP_DISCONNECT_RSP,
MEI_FOP_NOTIFY_START,
MEI_FOP_NOTIFY_STOP,
};
/*
* Intel MEI message data struct
*/
struct mei_msg_data {
u32 size;
unsigned char *data;
};
/* Maximum number of processed FW status registers */
#define MEI_FW_STATUS_MAX 6
/* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */
#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
/*
* struct mei_fw_status - storage of FW status data
*
* @count: number of actually available elements in array
* @status: FW status registers
*/
struct mei_fw_status {
int count;
u32 status[MEI_FW_STATUS_MAX];
};
/**
* struct mei_me_client - representation of me (fw) client
*
* @list: link in me client list
* @refcnt: struct reference count
* @props: client properties
* @client_id: me client id
* @mei_flow_ctrl_creds: flow control credits
* @connect_count: number connections to this client
* @bus_added: added to bus
*/
struct mei_me_client {
struct list_head list;
struct kref refcnt;
struct mei_client_properties props;
u8 client_id;
u8 mei_flow_ctrl_creds;
u8 connect_count;
u8 bus_added;
};
struct mei_cl;
/**
* struct mei_cl_cb - file operation callback structure
*
* @list: link in callback queue
* @cl: file client who is running this operation
* @fop_type: file operation type
* @buf: buffer for data associated with the callback
* @buf_idx: last read index
* @read_time: last read operation time stamp (iamthif)
* @file_object: pointer to file structure
* @status: io status of the cb
* @internal: communication between driver and FW flag
* @completed: the transfer or reception has completed
*/
struct mei_cl_cb {
struct list_head list;
struct mei_cl *cl;
enum mei_cb_file_ops fop_type;
struct mei_msg_data buf;
unsigned long buf_idx;
unsigned long read_time;
struct file *file_object;
int status;
u32 internal:1;
u32 completed:1;
};
/**
* struct mei_cl - me client host representation
* carried in file->private_data
*
* @link: link in the clients list
* @dev: mei parent device
* @state: file operation state
* @tx_wait: wait queue for tx completion
* @rx_wait: wait queue for rx completion
* @wait: wait queue for management operation
* @ev_wait: notification wait queue
* @ev_async: event async notification
* @status: connection status
* @me_cl: fw client connected
* @host_client_id: host id
* @mei_flow_ctrl_creds: transmit flow credentials
* @timer_count: watchdog timer for operation completion
* @reserved: reserved for alignment
* @notify_en: notification - enabled/disabled
* @notify_ev: pending notification event
* @writing_state: state of the tx
* @rd_pending: pending read credits
* @rd_completed: completed read
*
* @cldev: device on the mei client bus
*/
struct mei_cl {
struct list_head link;
struct mei_device *dev;
enum file_state state;
wait_queue_head_t tx_wait;
wait_queue_head_t rx_wait;
wait_queue_head_t wait;
wait_queue_head_t ev_wait;
struct fasync_struct *ev_async;
int status;
struct mei_me_client *me_cl;
u8 host_client_id;
u8 mei_flow_ctrl_creds;
u8 timer_count;
u8 reserved;
u8 notify_en;
u8 notify_ev;
enum mei_file_transaction_states writing_state;
struct list_head rd_pending;
struct list_head rd_completed;
struct mei_cl_device *cldev;
};
/**
* struct mei_hw_ops - hw specific ops
*
* @host_is_ready : query for host readiness
*
* @hw_is_ready : query if hw is ready
* @hw_reset : reset hw
* @hw_start : start hw after reset
* @hw_config : configure hw
*
* @fw_status : get fw status registers
* @pg_state : power gating state of the device
* @pg_in_transition : is device now in pg transition
* @pg_is_enabled : is power gating enabled
*
* @intr_clear : clear pending interrupts
* @intr_enable : enable interrupts
* @intr_disable : disable interrupts
*
* @hbuf_free_slots : query for write buffer empty slots
* @hbuf_is_ready : query if write buffer is empty
* @hbuf_max_len : query for write buffer max len
*
* @write : write a message to FW
*
* @rdbuf_full_slots : query how many slots are filled
*
* @read_hdr : get first 4 bytes (header)
* @read : read a buffer from the FW
*/
struct mei_hw_ops {
bool (*host_is_ready)(struct mei_device *dev);
bool (*hw_is_ready)(struct mei_device *dev);
int (*hw_reset)(struct mei_device *dev, bool enable);
int (*hw_start)(struct mei_device *dev);
void (*hw_config)(struct mei_device *dev);
int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts);
enum mei_pg_state (*pg_state)(struct mei_device *dev);
bool (*pg_in_transition)(struct mei_device *dev);
bool (*pg_is_enabled)(struct mei_device *dev);
void (*intr_clear)(struct mei_device *dev);
void (*intr_enable)(struct mei_device *dev);
void (*intr_disable)(struct mei_device *dev);
int (*hbuf_free_slots)(struct mei_device *dev);
bool (*hbuf_is_ready)(struct mei_device *dev);
size_t (*hbuf_max_len)(const struct mei_device *dev);
int (*write)(struct mei_device *dev,
struct mei_msg_hdr *hdr,
unsigned char *buf);
int (*rdbuf_full_slots)(struct mei_device *dev);
u32 (*read_hdr)(const struct mei_device *dev);
int (*read)(struct mei_device *dev,
unsigned char *buf, unsigned long len);
};
/* MEI bus API*/
void mei_cl_bus_rescan(struct mei_device *bus);
void mei_cl_bus_dev_fixup(struct mei_cl_device *dev);
ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
bool blocking);
ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
void mei_cl_bus_rx_event(struct mei_cl *cl);
void mei_cl_bus_notify_event(struct mei_cl *cl);
void mei_cl_bus_remove_devices(struct mei_device *bus);
int mei_cl_bus_init(void);
void mei_cl_bus_exit(void);
/**
* enum mei_pg_event - power gating transition events
*
* @MEI_PG_EVENT_IDLE: the driver is not in power gating transition
* @MEI_PG_EVENT_WAIT: the driver is waiting for a pg event to complete
* @MEI_PG_EVENT_RECEIVED: the driver received pg event
* @MEI_PG_EVENT_INTR_WAIT: the driver is waiting for a pg event interrupt
* @MEI_PG_EVENT_INTR_RECEIVED: the driver received pg event interrupt
*/
enum mei_pg_event {
MEI_PG_EVENT_IDLE,
MEI_PG_EVENT_WAIT,
MEI_PG_EVENT_RECEIVED,
MEI_PG_EVENT_INTR_WAIT,
MEI_PG_EVENT_INTR_RECEIVED,
};
/**
* enum mei_pg_state - device internal power gating state
*
* @MEI_PG_OFF: device is not power gated - it is active
* @MEI_PG_ON: device is power gated - it is in lower power state
*/
enum mei_pg_state {
MEI_PG_OFF = 0,
MEI_PG_ON = 1,
};
const char *mei_pg_state_str(enum mei_pg_state state);
/**
* struct mei_device - MEI private device struct
*
* @dev : device on a bus
* @cdev : character device
* @minor : minor number allocated for device
*
* @write_list : write pending list
* @write_waiting_list : write completion list
* @ctrl_wr_list : pending control write list
* @ctrl_rd_list : pending control read list
*
* @file_list : list of opened handles
* @open_handle_count: number of opened handles
*
* @device_lock : big device lock
* @timer_work : MEI timer delayed work (timeouts)
*
* @recvd_hw_ready : hw ready message received flag
*
* @wait_hw_ready : wait queue for receive HW ready message form FW
* @wait_pg : wait queue for receive PG message from FW
* @wait_hbm_start : wait queue for receive HBM start message from FW
* @wait_stop_wd : wait queue for receive WD stop message from FW
*
* @reset_count : number of consecutive resets
* @dev_state : device state
* @hbm_state : state of host bus message protocol
* @init_clients_timer : HBM init handshake timeout
*
* @pg_event : power gating event
* @pg_domain : runtime PM domain
*
* @rd_msg_buf : control messages buffer
* @rd_msg_hdr : read message header storage
*
* @hbuf_depth : depth of hardware host/write buffer is slots
* @hbuf_is_ready : query if the host host/write buffer is ready
* @wr_msg : the buffer for hbm control messages
*
* @version : HBM protocol version in use
* @hbm_f_pg_supported : hbm feature pgi protocol
* @hbm_f_dc_supported : hbm feature dynamic clients
* @hbm_f_dot_supported : hbm feature disconnect on timeout
* @hbm_f_ev_supported : hbm feature event notification
*
* @me_clients_rwsem: rw lock over me_clients list
* @me_clients : list of FW clients
* @me_clients_map : FW clients bit map
* @host_clients_map : host clients id pool
* @me_client_index : last FW client index in enumeration
*
* @allow_fixed_address: allow user space to connect a fixed client
*
* @wd_cl : watchdog client
* @wd_state : watchdog client state
* @wd_pending : watchdog command is pending
* @wd_timeout : watchdog expiration timeout
* @wd_data : watchdog message buffer
*
* @amthif_cmd_list : amthif list for cmd waiting
* @amthif_rd_complete_list : amthif list for reading completed cmd data
* @iamthif_file_object : file for current amthif operation
* @iamthif_cl : amthif host client
* @iamthif_current_cb : amthif current operation callback
* @iamthif_open_count : number of opened amthif connections
* @iamthif_timer : time stamp of current amthif command completion
* @iamthif_stall_timer : timer to detect amthif hang
* @iamthif_state : amthif processor state
* @iamthif_canceled : current amthif command is canceled
*
* @init_work : work item for the device init
* @reset_work : work item for the device reset
*
* @device_list : mei client bus list
* @cl_bus_lock : client bus list lock
*
* @dbgfs_dir : debugfs mei root directory
*
* @ops: : hw specific operations
* @hw : hw specific data
*/
struct mei_device {
struct device *dev;
struct cdev cdev;
int minor;
struct mei_cl_cb write_list;
struct mei_cl_cb write_waiting_list;
struct mei_cl_cb ctrl_wr_list;
struct mei_cl_cb ctrl_rd_list;
struct list_head file_list;
long open_handle_count;
struct mutex device_lock;
struct delayed_work timer_work;
bool recvd_hw_ready;
/*
* waiting queue for receive message from FW
*/
wait_queue_head_t wait_hw_ready;
wait_queue_head_t wait_pg;
wait_queue_head_t wait_hbm_start;
wait_queue_head_t wait_stop_wd;
/*
* mei device states
*/
unsigned long reset_count;
enum mei_dev_state dev_state;
enum mei_hbm_state hbm_state;
u16 init_clients_timer;
/*
* Power Gating support
*/
enum mei_pg_event pg_event;
#ifdef CONFIG_PM
struct dev_pm_domain pg_domain;
#endif /* CONFIG_PM */
unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];
u32 rd_msg_hdr;
/* write buffer */
u8 hbuf_depth;
bool hbuf_is_ready;
/* used for control messages */
struct {
struct mei_msg_hdr hdr;
unsigned char data[128];
} wr_msg;
struct hbm_version version;
unsigned int hbm_f_pg_supported:1;
unsigned int hbm_f_dc_supported:1;
unsigned int hbm_f_dot_supported:1;
unsigned int hbm_f_ev_supported:1;
struct rw_semaphore me_clients_rwsem;
struct list_head me_clients;
DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
unsigned long me_client_index;
bool allow_fixed_address;
struct mei_cl wd_cl;
enum mei_wd_states wd_state;
bool wd_pending;
u16 wd_timeout;
unsigned char wd_data[MEI_WD_START_MSG_SIZE];
/* amthif list for cmd waiting */
struct mei_cl_cb amthif_cmd_list;
/* driver managed amthif list for reading completed amthif cmd data */
struct mei_cl_cb amthif_rd_complete_list;
struct file *iamthif_file_object;
struct mei_cl iamthif_cl;
struct mei_cl_cb *iamthif_current_cb;
long iamthif_open_count;
unsigned long iamthif_timer;
u32 iamthif_stall_timer;
enum iamthif_states iamthif_state;
bool iamthif_canceled;
struct work_struct init_work;
struct work_struct reset_work;
/* List of bus devices */
struct list_head device_list;
struct mutex cl_bus_lock;
#if IS_ENABLED(CONFIG_DEBUG_FS)
struct dentry *dbgfs_dir;
#endif /* CONFIG_DEBUG_FS */
const struct mei_hw_ops *ops;
char hw[0] __aligned(sizeof(void *));
};
static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
{
return msecs_to_jiffies(sec * MSEC_PER_SEC);
}
/**
* mei_data2slots - get slots - number of (dwords) from a message length
* + size of the mei header
*
* @length: size of the messages in bytes
*
* Return: number of slots
*/
static inline u32 mei_data2slots(size_t length)
{
return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
}
/**
* mei_slots2data - get data in slots - bytes from slots
*
* @slots: number of available slots
*
* Return: number of bytes in slots
*/
static inline u32 mei_slots2data(int slots)
{
return slots * 4;
}
/*
* mei init function prototypes
*/
void mei_device_init(struct mei_device *dev,
struct device *device,
const struct mei_hw_ops *hw_ops);
int mei_reset(struct mei_device *dev);
int mei_start(struct mei_device *dev);
int mei_restart(struct mei_device *dev);
void mei_stop(struct mei_device *dev);
void mei_cancel_work(struct mei_device *dev);
/*
* MEI interrupt functions prototype
*/
void mei_timer(struct work_struct *work);
int mei_irq_read_handler(struct mei_device *dev,
struct mei_cl_cb *cmpl_list, s32 *slots);
int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list);
/*
* AMTHIF - AMT Host Interface Functions
*/
void mei_amthif_reset_params(struct mei_device *dev);
int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl);
int mei_amthif_read(struct mei_device *dev, struct file *file,
char __user *ubuf, size_t length, loff_t *offset);
unsigned int mei_amthif_poll(struct mei_device *dev,
struct file *file, poll_table *wait);
int mei_amthif_release(struct mei_device *dev, struct file *file);
struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
struct file *file);
int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb);
int mei_amthif_run_next_cmd(struct mei_device *dev);
int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_cl_cb *cmpl_list);
void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
int mei_amthif_irq_read_msg(struct mei_cl *cl,
struct mei_msg_hdr *mei_hdr,
struct mei_cl_cb *complete_list);
int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
/*
* NFC functions
*/
int mei_nfc_host_init(struct mei_device *dev, struct mei_me_client *me_cl);
void mei_nfc_host_exit(struct mei_device *dev);
/*
* NFC Client UUID
*/
extern const uuid_le mei_nfc_guid;
int mei_wd_send(struct mei_device *dev);
int mei_wd_stop(struct mei_device *dev);
int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl);
/*
* mei_watchdog_register - Registering watchdog interface
* once we got connection to the WD Client
* @dev: mei device
*/
int mei_watchdog_register(struct mei_device *dev);
/*
* mei_watchdog_unregister - Unregistering watchdog interface
* @dev: mei device
*/
void mei_watchdog_unregister(struct mei_device *dev);
/*
* Register Access Function
*/
static inline void mei_hw_config(struct mei_device *dev)
{
dev->ops->hw_config(dev);
}
static inline enum mei_pg_state mei_pg_state(struct mei_device *dev)
{
return dev->ops->pg_state(dev);
}
static inline bool mei_pg_in_transition(struct mei_device *dev)
{
return dev->ops->pg_in_transition(dev);
}
static inline bool mei_pg_is_enabled(struct mei_device *dev)
{
return dev->ops->pg_is_enabled(dev);
}
static inline int mei_hw_reset(struct mei_device *dev, bool enable)
{
return dev->ops->hw_reset(dev, enable);
}
static inline int mei_hw_start(struct mei_device *dev)
{
return dev->ops->hw_start(dev);
}
static inline void mei_clear_interrupts(struct mei_device *dev)
{
dev->ops->intr_clear(dev);
}
static inline void mei_enable_interrupts(struct mei_device *dev)
{
dev->ops->intr_enable(dev);
}
static inline void mei_disable_interrupts(struct mei_device *dev)
{
dev->ops->intr_disable(dev);
}
static inline bool mei_host_is_ready(struct mei_device *dev)
{
return dev->ops->host_is_ready(dev);
}
static inline bool mei_hw_is_ready(struct mei_device *dev)
{
return dev->ops->hw_is_ready(dev);
}
static inline bool mei_hbuf_is_ready(struct mei_device *dev)
{
return dev->ops->hbuf_is_ready(dev);
}
static inline int mei_hbuf_empty_slots(struct mei_device *dev)
{
return dev->ops->hbuf_free_slots(dev);
}
static inline size_t mei_hbuf_max_len(const struct mei_device *dev)
{
return dev->ops->hbuf_max_len(dev);
}
static inline int mei_write_message(struct mei_device *dev,
struct mei_msg_hdr *hdr,
unsigned char *buf)
{
return dev->ops->write(dev, hdr, buf);
}
static inline u32 mei_read_hdr(const struct mei_device *dev)
{
return dev->ops->read_hdr(dev);
}
static inline void mei_read_slots(struct mei_device *dev,
unsigned char *buf, unsigned long len)
{
dev->ops->read(dev, buf, len);
}
static inline int mei_count_full_read_slots(struct mei_device *dev)
{
return dev->ops->rdbuf_full_slots(dev);
}
static inline int mei_fw_status(struct mei_device *dev,
struct mei_fw_status *fw_status)
{
return dev->ops->fw_status(dev, fw_status);
}
bool mei_hbuf_acquire(struct mei_device *dev);
bool mei_write_is_idle(struct mei_device *dev);
#if IS_ENABLED(CONFIG_DEBUG_FS)
int mei_dbgfs_register(struct mei_device *dev, const char *name);
void mei_dbgfs_deregister(struct mei_device *dev);
#else
static inline int mei_dbgfs_register(struct mei_device *dev, const char *name)
{
return 0;
}
static inline void mei_dbgfs_deregister(struct mei_device *dev) {}
#endif /* CONFIG_DEBUG_FS */
int mei_register(struct mei_device *dev, struct device *parent);
void mei_deregister(struct mei_device *dev);
#define MEI_HDR_FMT "hdr:host=%02d me=%02d len=%d internal=%1d comp=%1d"
#define MEI_HDR_PRM(hdr) \
(hdr)->host_addr, (hdr)->me_addr, \
(hdr)->length, (hdr)->internal, (hdr)->msg_complete
ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
/**
* mei_fw_status_str - fetch and convert fw status registers to printable string
*
* @dev: the device structure
* @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
* @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
*
* Return: number of bytes written or < 0 on failure
*/
static inline ssize_t mei_fw_status_str(struct mei_device *dev,
char *buf, size_t len)
{
struct mei_fw_status fw_status;
int ret;
buf[0] = '\0';
ret = mei_fw_status(dev, &fw_status);
if (ret)
return ret;
ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
return ret;
}
#endif

View File

@ -9,3 +9,8 @@ Package: platform-modules-ag9032v1
Architecture: amd64
Depends: linux-image-3.16.0-5-amd64
Description: kernel modules for platform devices such as fan, led, sfp
Package: platform-modules-ag9064
Architecture: amd64
Depends: linux-image-3.16.0-5-amd64
Description: kernel modules for platform devices such as fan, led, sfp

View File

@ -1 +1,2 @@
platform-modules-ag9032v1_1.1_amd64.deb main extra
platform-modules-ag9064_1.1_amd64.deb main extra

View File

@ -0,0 +1,48 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: setup-board
# Required-Start:
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Setup ag9064 board.
### END INIT INFO
case "$1" in
start)
echo -n "Setting up board... "
depmod -a
rmmod i2c-i801
rmmod i2c-ismt
modprobe i2c-dev
modprobe i2c-i801
modprobe i2c-ismt
modprobe i2c-mei
modprobe i2c-mux-pca954x
modprobe at24
modprobe delta_ag9064_platform
/usr/local/bin/ag9064_platform_init.sh
echo "done."
;;
stop)
echo "done."
;;
force-reload|restart)
echo "Not supported"
;;
*)
echo "Usage: /etc/init.d/platform-modules-ag9064.init {start|stop}"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1 @@
ag9064/cfg/ag9064-modules.conf etc/modules-load.d

View File

@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra
KVERSION ?= $(shell uname -r)
KERNEL_SRC := /lib/modules/$(KVERSION)
MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= ag9032v1
MODULE_DIRS:= ag9032v1 ag9064
%:
dh $@