[devices]: add the delta ag9064 platform (#1435)
* add the ag9064 platform Signed-off-by: hans <hans.tseng@deltaww.com>
This commit is contained in:
parent
33d5a9cfd6
commit
837e964854
@ -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
|
@ -0,0 +1 @@
|
||||
SAI_INIT_CONFIG_FILE=/etc/bcm/th2-ag9064-64x100G.config.bcm
|
2
device/delta/x86_64-delta_ag9064-r0/installer.conf
Normal file
2
device/delta/x86_64-delta_ag9064-r0/installer.conf
Normal file
@ -0,0 +1,2 @@
|
||||
CONSOLE_PORT=0x3f8
|
||||
CONSOLE_SPEED=115200
|
63
device/delta/x86_64-delta_ag9064-r0/led_proc_init.soc
Normal file
63
device/delta/x86_64-delta_ag9064-r0/led_proc_init.soc
Normal 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
|
848
device/delta/x86_64-delta_ag9064-r0/minigraph.xml
Normal file
848
device/delta/x86_64-delta_ag9064-r0/minigraph.xml
Normal 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>
|
32
device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py
Normal file
32
device/delta/x86_64-delta_ag9064-r0/plugins/eeprom.py
Normal 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)
|
175
device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py
Normal file
175
device/delta/x86_64-delta_ag9064-r0/plugins/sfputil.py
Normal 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
|
14
device/delta/x86_64-delta_ag9064-r0/sensors.conf
Normal file
14
device/delta/x86_64-delta_ag9064-r0/sensors.conf
Normal 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
|
||||
|
@ -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)
|
||||
|
@ -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)))
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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_ */
|
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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);
|
@ -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
|
||||
}
|
@ -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))
|
@ -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;
|
@ -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
|
@ -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
|
||||
|
@ -1 +1,2 @@
|
||||
platform-modules-ag9032v1_1.1_amd64.deb main extra
|
||||
platform-modules-ag9064_1.1_amd64.deb main extra
|
||||
|
@ -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
|
@ -0,0 +1 @@
|
||||
ag9064/cfg/ag9064-modules.conf etc/modules-load.d
|
@ -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 $@
|
||||
|
Loading…
Reference in New Issue
Block a user