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