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