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
192  - This does not work since there may be n different fault LEDs as per
193    [Spec](#background-and-references)
194  - Also this is basically lying to ourselves and making it difficult for other
195    sw to get any meaningful info about LEDs from dbus anymore.
196
197- Allow Priority "Off" for LED config.
198
199  - This only solves the issue for very simple configurations.
200  - Individual LED priorities are hard to think about when multiple LEDs form an
201    indicator
202
203- Allow the mixed use of group and individual led priority
204
205  - This will require considering more edge cases arising from the mixed use.
206  - Not aware of a use-case which would benefit from mixed use.
207
208- Allow each LED to configure the priority of groups it represents, instead of
209  just one state.
210
211  - e.g. "Priority": ["enclosure_identify", "fault", "power"]
212  - This config would have to be repeated on each instance of an LED
213  - Or assumed that the first instance defines it?
214  - Would need to check for equality of all these priority lists for an LED
215  - This does not solve the problem of a group being represented incompletely
216    - For example it is possible for 2 LEDs belonging to the same group to
217      prioritize these groups differently in their priority list.
218
219- Allow configuring an "indicator" that's comprised of multiple LEDs and then
220  just define states for that indicator.
221
222  - Need to translate these states to groups anyways to be compatible with the
223    existing internal data structures
224  - Handle the case of member LEDs of that indicator also being members of other
225    groups
226  - This is basically the same as group priorities but with additional overhead
227    in config parsing
228
229- Only display the group that was last asserted, in case of conflicting groups
230  - This is undesirable since there are groups which are more important to
231    display
232
233## Impacts
234
235Need to
236
237- extend docs on how to configure LED group priority
238- implement the LED group priority
239- write unit tests for LED group priority
240- perhaps change some configs to use this new feature
241  - this is optional as the change is backwards-compatible
242
243There should be no impact on d-bus except if we choose to expose the led group
244priority.
245
246### Organizational
247
248- Does this repository require a new repository?
249  - No
250- Who will be the initial maintainer(s) of this repository?
251- Which repositories are expected to be modified to execute this design?
252  - phosphor-led-manager
253  - optionally openbmc to upgrade existing configs
254- Make a list, and add listed repository maintainers to the gerrit review.
255
256## Testing
257
258How will this be tested? How will this feature impact CI testing?
259
260The feature can easily be unit-tested.
261