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 "FaultLedGroup": [ 40 "attention" 41 ] 42 }, 43 { 44 "Name": "cable1", 45 "GpioLine": "osfp1", 46 "Polarity": "active_high", 47 "Type": "GPIOCableSensing", 48 "FaultLedGroup": [ 49 "attention" 50 ] 51 } 52 ] 53} 54``` 55The `Name` attribute is a unique name for each object from the config file. 56The `GpioLine` is the gpio line label from the device tree. The `Polarity` 57should tell the daemon whether it needs to revert the GPIO signal. Each entry 58from the config would get translated into one object on the dbus. In addition, 59the daemon polls the gpio presence signal for these objects in an interval of 6010 seconds. When the cable is not properly seated, the daemon will assert on 61the corresponding fault led group. This should cause the corresponding led to 62blink or to turn on base on how phosphor-led-manager is configured. No action 63is taken if FaultLedGroup is empty. 64 65On the IPMI sIDe, the presence states will be grouped into fewer SDR IDs in 66order to save SDR IDs for ipmi. Given the following example, 67``` 68└─/xyz 69 └─/xyz/openbmc_project 70 └─/xyz/openbmc_project/inventory 71 └─/xyz/openbmc_project/inventory/item 72 └─/xyz/openbmc_project/inventory/item/cable0 73 └─/xyz/openbmc_project/inventory/item/cable1 74``` 75In this example, we have both cable0 and cable1 and we expect to group them 76together. The grouping handler first removes all the trailing index from the 77SDR name. In this case, the SDR name is cable0 and cable1. After that, both 78cable0 and cable1 become cable. Therefore, objects with the same name after 79removing the trailing index indicates that they need to be grouped. After 80grouping, the new SDR name is cable[0-1]. The SDR name implies that this SDR 81has the presence state for cable0 and cable1. Meanwhile, the bit position 82for cable0 is 0 and the bit position for cable1 is 1. In the case of having 83more than 14 presence states, the group handler will automatically jump to use 84a new SDR. For example, if there are 20 cable indexed from 0 to 19, we 85shall see two SDRs. One is cable0-13. One is cable[14-19]. If the object path 86is not indexed by the user, it will take one SDR ID. 87``` 88ipmitool sdr list event 89# /xyz/openbmc_project/inventory/item/cdfp0 to 90# /xyz/openbmc_project/inventory/item/cdfp3 91cdfp[0-3] | Event-Only | ns 92# /xyz/openbmc_project/inventory/item/osfp0 and 93# /xyz/openbmc_project/inventory/item/osfp1 94osfp[0-1] | Event-Only | ns 95``` 96 97On the other hand, if the object name from the config file is not indexed. For 98exmaple, `/xyz/openbmc_project/inventory/item/cable`. The group handler will not 99try to group it with anything and use 1 SDR ID for its presence state. 100See the following for an example output. 101``` 102ipmitool sdr list event 103cdfp[0-3] | Event-Only | ns 104# /xyz/openbmc_project/inventory/item/osfp 105osfp | Event-Only | ns 106osfp[1-2] | Event-Only | ns 107``` 108During the fetch operation, once the ipmi daemon receives the client request. It 109forwards the request to the dynamic ipmi commands. In the get method, the range 110string is extracted from the tailing square bracket. The original dbus path can 111be reconstructed given the index. Then, the SDR assertion value can be 112constructed after collecting the OperationalStatus from the dbus from each 113individual dbus objects. 114 115The design is also compatible with the Redfish daemon. Redfish can call the 116GetSubTree method to list all the instances under the cable interface. In 117addition, Redfish doesn't have a limit of 256 SDR IDs. Therefore, no need to 118implement grouping mechanism. It should work out of the box. 119 120## Alternatives Considered 121 122* Explore the option of reporting the presence state via type12 record instead 123 of discrete sensors. The challenge here is that type12 record also has a limit 124 of 255 IDs. Meanwhile, it doesn't support stacking multiple presence states in 125 one ID. 126 127* We could also let the user define how to group different cables from config 128 file. However, this requires users to have a deep understanding of how ipmid 129 works. It is better if the ipmi daemon just takes care of this. 130 131* Instead of having a sleep-poll mechanism, it is better to have a event 132 listener on the gpio signals. However, the gpio_event_wait api requires all 133 the lines to come from the same chip. See 134 https://github.com/brgl/libgpiod/blob/cc23ef61f66d5a9055b0e9fbdcfe6744c8a637ae/lib/core.c#L993 135 We could spawn threads to listen to each chips but I don't think we should 136 increase the complexity of such a simple daemon. 137 138* The polling interval is 10 seconds. Is this too long/short for some other 139 projects? For now, let's make it a compiler option. 140 141* IPMI name string can only be 16 characters. Using square brackets would take 142 away 2 chars. However, using square brackets gives a better indication for the 143 start of the index string. Hence, the index string will be enclosed by square 144 bracket. 145 146 147## Testing 148Testing can be accomplished via automated or manual testing to verify that: 149 150* The presence state that is reported by GpioCableSevice is matching the result 151 from linux gpioget command. 152 153* Given the SDR name from `ipmitool sdr list event`, say cable[0-1], make sure 154 the zeroth bit is matching the presence state of object 155 `/xyz/openbmc_project/inventory/item/cable0` on the dbus and the first bit is 156 matching the state of object `/xyz/openbmc_project/inventory/item/cable`. 157 158* Unindex items from the config should have its own SDR ID. For example, 159 `/xyz/openbmc_project/inventory/item/cable` should not be grouped to another 160 group. Meanwhile, only the zero bit is used to report the presence state. 161 162* The state of the cable presence need to change with 10 seconds once a cable is 163 plug or unplug from the system. 164