xref: /openbmc/docs/designs/ocp-led-policy-support.md (revision ba560cc31297caddfc157c540ae9e6d760d630e5)
1# OCP LED Policy Support
2
3Author: Alexander Hansen
4[alexander.hansen@9elements.com](mailto:alexander.hansen@9elements.com)
5
6Other contributors: None
7
8Created: July 22, 2024
9
10## Problem Description
11
12OpenBMC must support the [OCP LED Policy](#background-and-references). Currently
13there are some problematic cases in which the Policy is not supported by
14existing services like phosphor-led-manager.
15
16### Example ([Spec](#background-and-references) 6.2. System General Status)
17
18#### Defined states
19
20| STS (blue) | FAULT (amber) | NAME                                            |
21| ---------- | ------------- | ----------------------------------------------- |
22| 1          | 0             | "All OK"                                        |
23| 0          | 1             | "Module missing / fault"                        |
24| 1          | 1             | LED Priority (cannot represent the fault state) |
25
26#### Example sequence
27
28| STS | FAULT | action        |
29| --- | ----- | ------------- |
30| 0   | 0     | initial state |
31| 1   | 0     | assert ok     |
32| 1   | 1     | assert fault  |
33| 1   | 1     | final state   |
34
35When for example both of these groups are asserted, the change in LED state will
36be determined by the LED priority. The result is not allowed in the state
37diagram in [Spec](#background-and-references).
38
39In this trivial example we can fix it by just assigning Priority "Off" to the
40led-blue. But that's not possible at the time of writing (commit
41[bdbfcde](https://github.com/openbmc/phosphor-led-manager/commit/bdbfcde10520fc841b44d1e777c353a698b774ff)).
42
43There are other examples with more LEDs where that alone will not fix the issue.
44
45### Example ([Spec](#background-and-references) 6.4 PSU Status)
46
47Here we pretend that LED Priority "Off" is allowed and discover that it will not
48be sufficient to fix the issue.
49
50#### Defined states
51
52| AC OK (blue) | FAULT (amber) | LOW V (amber) | BACK UP (amber) | State                     |
53| ------------ | ------------- | ------------- | --------------- | ------------------------- |
54| 1            | 0             | 0             | 0               | "AC OK"                   |
55| 0            | 1             | 0             | 0               | "AC Fault"                |
56| 0            | 1             | 1             | 0               | "AC Under Voltage"        |
57| 0            | 0             | 0             | 1               | "Backup due to AC Outage" |
58
59#### LED Priority
60
61| AC OK (blue) | FAULT (amber) | LOW V (amber) | BACK UP (amber) | State                     |
62| ------------ | ------------- | ------------- | --------------- | ------------------------- |
63| 0            | 0             | 0             | 1               | "Backup due to AC Outage" |
64
65#### Example Sequence
66
67| AC OK (blue) | FAULT (amber) | LOW V (amber) | BACK UP (amber) | State                        |
68| ------------ | ------------- | ------------- | --------------- | ---------------------------- |
69| 0            | 0             | 0             | 1               | LED Priority (for reference) |
70| 0            | 0             | 0             | 0               | initial state                |
71| 1            | 0             | 0             | 0               | assert "AC OK"               |
72| 0            | 0             | 0             | 0               | assert "AC Fault"            |
73| 0            | 0             | 0             | 0               | final state                  |
74
75The final state is undefined according to [Spec](#background-and-references)
766.4.
77
78The different possible LED priorities do not matter here, since "Backup due to
79AC Outage" could very well be the highest priority state. And choosing any other
80LED Priority will prevent it from being applied completely when any other state
81is asserted simultaneously.
82
83By now it becomes clear that what's needed is a way to define priorities in
84terms of groups and not single LEDs.
85
86## Background and References
87
88- [OCP Panel Indicator Specification rev1.0 (pdf)](http://files.opencompute.org/oc/public.php?service=files&t=65c02b1c6d59188351357cfb232cbfaa&download)
89- [OCP Panel Indicator Specification rev1.0 (presentation)](https://www.opencompute.org/files/OCP18-EngWorkshop-Indicator-Specification-Proposal.pdf)
90
91Quick summary of what's important for us here:
92
93### Permitted Indicator Colors
94
95- Blue
96- Amber
97- Combined Blue/Amber in tight spaces
98
99### Permitted Indicator States
100
101- OFF
102- ON
103- BLINK (500ms on, 500ms off)
104
105### Permitted Indicator Count on Component
106
107- 1 blue LED
108- 1 to n amber LED to communicate multiple fault conditions OR
109- 1 blue/amber LED
110
111## Requirements
112
113- Ability to prioritize the different LED Groups and thus possible indicator
114  states.
115- An Indicator should not be in an inconsistent state. It can display the states
116  as per the [Spec](#background-and-references)
117- Other services cannot be trusted to keep the assertion of the LED groups in a
118  consistent state. The indicator state must be consistent even when conflicting
119  LED groups are asserted.
120
121## Proposed Design
122
123Extend the concept of "Priority" to groups in phosphor-led-manager. The group
124priority will be an integer value. A larger number means higher priority for
125that group. This allows users to have configurations like:
126
1271. OK
1282. Fault 1
1293. Fault 2
1304. Locate
131
132with locating and fault states having higher priorities. The LEDs would always
133be in a consistent state. The change can be done in a backwards-compatible way.
134
135### Configuration example
136
137```json
138{
139  "leds": [
140    {
141      "group": "enclosure_identify",
142      "Priority": 2,
143      "members": [
144        {
145          "Name": "sys_id",
146          "Action": "Blink"
147        },
148        {
149          "Name": "rear_id",
150          "Action": "Blink"
151        }
152      ]
153    },
154    {
155      "group": "fault",
156      "Priority": 1,
157      "members": [
158        {
159          "Name": "sys_id",
160          "Action": "On"
161        },
162        {
163          "Name": "fault",
164          "Action": "On"
165        }
166      ]
167    },
168    {
169      "group": "unrelated",
170      "members": [
171        {
172          "Name": "rear_id",
173          "Action": "On"
174        }
175      ]
176    }
177  ]
178}
179```
180
181### Mixed Use
182
183The group priority and led priority can be mutually exclusive in configuration
184to prevent any issues arising from mixed use. So the existing configs continue
185to work with individual LED Priority and when a group priority is assigned, we
186assume the user wants to use that for configuration.
187
188## Alternatives Considered
189
190- Extend phosphor-led-sysfs to expose 2 LEDs (blue/amber) as a single LED.
191  - This does not work since there may be n different fault LEDs as per
192    [Spec](#background-and-references)
193  - Also this is basically lying to ourselves and making it difficult for other
194    sw to get any meaningful info about LEDs from dbus anymore.
195
196- Allow Priority "Off" for LED config.
197  - This only solves the issue for very simple configurations.
198  - Individual LED priorities are hard to think about when multiple LEDs form an
199    indicator
200
201- Allow the mixed use of group and individual led priority
202  - This will require considering more edge cases arising from the mixed use.
203  - Not aware of a use-case which would benefit from mixed use.
204
205- Allow each LED to configure the priority of groups it represents, instead of
206  just one state.
207  - e.g. "Priority": ["enclosure_identify", "fault", "power"]
208  - This config would have to be repeated on each instance of an LED
209  - Or assumed that the first instance defines it?
210  - Would need to check for equality of all these priority lists for an LED
211  - This does not solve the problem of a group being represented incompletely
212    - For example it is possible for 2 LEDs belonging to the same group to
213      prioritize these groups differently in their priority list.
214
215- Allow configuring an "indicator" that's comprised of multiple LEDs and then
216  just define states for that indicator.
217  - Need to translate these states to groups anyways to be compatible with the
218    existing internal data structures
219  - Handle the case of member LEDs of that indicator also being members of other
220    groups
221  - This is basically the same as group priorities but with additional overhead
222    in config parsing
223
224- Only display the group that was last asserted, in case of conflicting groups
225  - This is undesirable since there are groups which are more important to
226    display
227
228## Impacts
229
230Need to
231
232- extend docs on how to configure LED group priority
233- implement the LED group priority
234- write unit tests for LED group priority
235- perhaps change some configs to use this new feature
236  - this is optional as the change is backwards-compatible
237
238There should be no impact on d-bus except if we choose to expose the led group
239priority.
240
241### Organizational
242
243- Does this repository require a new repository?
244  - No
245- Who will be the initial maintainer(s) of this repository?
246- Which repositories are expected to be modified to execute this design?
247  - phosphor-led-manager
248  - optionally openbmc to upgrade existing configs
249- Make a list, and add listed repository maintainers to the gerrit review.
250
251## Testing
252
253How will this be tested? How will this feature impact CI testing?
254
255The feature can easily be unit-tested.
256