1## GPIO-based Cable Presence Detection
2
3Author: Chu Lin (linchuyuan@google.com)
4
5Created: 2021-07-29
6
7## Problem Description
8
9The intent of this new daemon design is to report GPIO-based cable presence
10status. IPMI currently doesn't support grouping discrete values and it could at
11most support 255 sensor IDs. On a systems with 25 cables, and 255 sensor IDs,
12taking up one sensor per slot would use 10% of the available space, and be a
13huge waste. Therefore, we need a solution to pack multiple presence states into
14less SDR IDs.
15
16## Background and References
17
181. https://www.intel.com/content/www/us/en/products/docs/servers/ipmi/ipmi-second-gen-interface-spec-v2-rev1-1.html
192. https://www.dmtf.org/sites/default/files/Redfish_Cable_Management_Proposal_WIP_04-2021.pdf
20
21## Requirements
22
231. The openbmc IPMI interface should support exposing cable presence states.
242. The OpenBMC dbus interface should be compatible with redfish
25
26## Proposed Design
27
28Inventory.Item.Cable will be introduced as a new dbus interface for querying
29cable objects. We will also need to introduce a new dbus daemon to collect
30Presence states. This new daemon will resIDe in openbmc/dbus-sensors. Its
31runtime configuration will be provIDed by EntityManager during startup. A
32proposed config file looks like the following:
33
34```
35{
36  "Exposes": [
37    {
38      "Name": "cable0",
39      "GpioLine": "osfp0",
40      "Polarity": "active_low",
41      "Type": "GPIOCableSensing",
42      "FaultLedGroup": [
43        "attention"
44      ]
45    },
46    {
47      "Name": "cable1",
48      "GpioLine": "osfp1",
49      "Polarity": "active_high",
50      "Type": "GPIOCableSensing",
51      "FaultLedGroup": [
52        "attention"
53      ]
54    }
55  ]
56}
57```
58
59The `Name` attribute is a unique name for each object from the config file. The
60`GpioLine` is the gpio line label from the device tree. The `Polarity` should
61tell the daemon whether it needs to revert the GPIO signal. Each entry from the
62config would get translated into one object on the dbus. In addition, the daemon
63polls the gpio presence signal for these objects in an interval of 10 seconds.
64When the cable is not properly seated, the daemon will assert on the
65corresponding fault led group. This should cause the corresponding led to blink
66or to turn on base on how phosphor-led-manager is configured. No action is taken
67if FaultLedGroup is empty.
68
69On the IPMI sIDe, the presence states will be grouped into fewer SDR IDs in
70order to save SDR IDs for ipmi. Given the following example,
71
72```
73└─/xyz
74  └─/xyz/openbmc_project
75    └─/xyz/openbmc_project/inventory
76      └─/xyz/openbmc_project/inventory/item
77        └─/xyz/openbmc_project/inventory/item/cable0
78        └─/xyz/openbmc_project/inventory/item/cable1
79```
80
81In this example, we have both cable0 and cable1 and we expect to group them
82together. The grouping handler first removes all the trailing index from the SDR
83name. In this case, the SDR name is cable0 and cable1. After that, both cable0
84and cable1 become cable. Therefore, objects with the same name after removing
85the trailing index indicates that they need to be grouped. After grouping, the
86new SDR name is cable[0-1]. The SDR name implies that this SDR has the presence
87state for cable0 and cable1. Meanwhile, the bit position for cable0 is 0 and the
88bit position for cable1 is 1. In the case of having more than 14 presence
89states, the group handler will automatically jump to use a new SDR. For example,
90if there are 20 cable indexed from 0 to 19, we shall see two SDRs. One is
91cable0-13. One is cable[14-19]. If the object path is not indexed by the user,
92it will take one SDR ID.
93
94```
95ipmitool sdr list event
96# /xyz/openbmc_project/inventory/item/cdfp0 to
97# /xyz/openbmc_project/inventory/item/cdfp3
98cdfp[0-3]        | Event-Only        | ns
99# /xyz/openbmc_project/inventory/item/osfp0 and
100# /xyz/openbmc_project/inventory/item/osfp1
101osfp[0-1]        | Event-Only        | ns
102```
103
104On the other hand, if the object name from the config file is not indexed. For
105example, `/xyz/openbmc_project/inventory/item/cable`. The group handler will not
106try to group it with anything and use 1 SDR ID for its presence state. See the
107following for an example output.
108
109```
110ipmitool sdr list event
111cdfp[0-3]        | Event-Only        | ns
112# /xyz/openbmc_project/inventory/item/osfp
113osfp             | Event-Only        | ns
114osfp[1-2]        | Event-Only        | ns
115```
116
117During the fetch operation, once the ipmi daemon receives the client request. It
118forwards the request to the dynamic ipmi commands. In the get method, the range
119string is extracted from the tailing square bracket. The original dbus path can
120be reconstructed given the index. Then, the SDR assertion value can be
121constructed after collecting the OperationalStatus from the dbus from each
122individual dbus objects.
123
124The design is also compatible with the Redfish daemon. Redfish can call the
125GetSubTree method to list all the instances under the cable interface. In
126addition, Redfish doesn't have a limit of 256 SDR IDs. Therefore, no need to
127implement grouping mechanism. It should work out of the box.
128
129## Alternatives Considered
130
131- Explore the option of reporting the presence state via type12 record instead
132  of discrete sensors. The challenge here is that type12 record also has a limit
133  of 255 IDs. Meanwhile, it doesn't support stacking multiple presence states in
134  one ID.
135
136- We could also let the user define how to group different cables from config
137  file. However, this requires users to have a deep understanding of how ipmid
138  works. It is better if the ipmi daemon just takes care of this.
139
140- Instead of having a sleep-poll mechanism, it is better to have a event
141  listener on the gpio signals. However, the gpio_event_wait api requires all
142  the lines to come from the same chip. See
143  https://github.com/brgl/libgpiod/blob/cc23ef61f66d5a9055b0e9fbdcfe6744c8a637ae/lib/core.c#L993
144  We could spawn threads to listen to each chips but I don't think we should
145  increase the complexity of such a simple daemon.
146
147- The polling interval is 10 seconds. Is this too long/short for some other
148  projects? For now, let's make it a compiler option.
149
150- IPMI name string can only be 16 characters. Using square brackets would take
151  away 2 chars. However, using square brackets gives a better indication for the
152  start of the index string. Hence, the index string will be enclosed by square
153  bracket.
154
155## Testing
156
157Testing can be accomplished via automated or manual testing to verify that:
158
159- The presence state that is reported by GpioCableSevice is matching the result
160  from linux gpioget command.
161
162- Given the SDR name from `ipmitool sdr list event`, say cable[0-1], make sure
163  the zeroth bit is matching the presence state of object
164  `/xyz/openbmc_project/inventory/item/cable0` on the dbus and the first bit is
165  matching the state of object `/xyz/openbmc_project/inventory/item/cable`.
166
167- Unindex items from the config should have its own SDR ID. For example,
168  `/xyz/openbmc_project/inventory/item/cable` should not be grouped to another
169  group. Meanwhile, only the zero bit is used to report the presence state.
170
171- The state of the cable presence need to change with 10 seconds once a cable is
172  plug or unplug from the system.
173