@PigLover 's
reference document is exceedingly useful, however it's not fully accurate on one point. This supplemental information (below) may help others who are new to manually controlling Supermicro motherboard fan speeds.
1. The description of fan speed step zones is partially incorrect and needs a bit of clarification, IMHO.
"You can also set the PWM duty cycle for each of the fan zones. PWM values are set 64 steps using hex values from 00-FF (ox00 to 0x64). 0x00 is minimum speed, 0x64 is full speed, and 0x32 is 50%, etc."
There are in fact 100 intervals, not 64. Those are hexadecimal values (base-16), and therefore 0x00 - 0x64 is equivalent to 0 - 100 decimal (base-10). In other words, 0x00 - 0x64 (hex) is a range of 100 (decimal) steps, where each step = 1% in fan speed change.
10x = 16
20x = 32
etc.
64x = 100
I don't know what happens if you plug in a value of 0x65 or higher. Out-of-range behavior is likely dependent how any given BMC controller handles such data. Some ignore values out of range and some roll the value over (e.g. 0x65 becomes 0x00).
--------------
2. The information above is
true for certain Supermicro motherboards, but not all of them.
The 0x00 - 0x64 step utilization mentioned above works on Supermicro generation
X10 and
X11 motherboards. The hex value is directly correlated to decimal percentage equivalents, which is nice for humans as it makes it easier for us to do the math.
In short, X10 and X11 mobos use a literal percentage expression. But, what if you have a Supermicro
X9 motherboard?
On X9 boards, you have to convert an 8-bit hexadecimal range (0-FF) into its corresponding decimal range (0-255), and then break that into increments of 1/100 to find the equivalent decimal percentage us humans are used to, expressed as its equivalent hex range.
In order to set your fan speed correctly, you must convert from a 100-point with increments of 1, as a decimal scale, to a 256-point scale divided by increments of 1/100. In other words, you must think of 0-100% stepping along a scale of 0 - 255 ( x00 - xFF ).
For X9 boards you must treat it like a scale, where you are pegging a percentage to the corresponding value along the scale. In human-readable decimal terms, we are talking about a 0 - 100 integer scale (percentage) cross-referenced to an 8-bit hexadecimal scale (00 - FF).
Examples:
00 decimal =0x00 hexadecimal
10 decimal = 0x1A hex (10% of FF or 255 = 25.5 rounded = 26)
25% = 0x40 (25% of 255 is 63.75 = rounded to 64 decimal or x40 hex { 4 x 16 + 0 = 64 decimal }
50% = 0x7F
75% = 0xBF (75% of 255 = 191.25 = rounded to 191 decimal = { 11 x 16 + 15 = 191 decimal }
100% = 0xFF
Basically,
for X9 boards you have to convert your desired percentage value from decimal to hexadecimal, while at the same time mapping a decimal value (percentage) to an 8-bit hexadecimal scale equivalent. This is because while 0x00 = 0%, since 0xFF = 100%, it means in order to determine how to set your power percentage for any given fan zone, the formula is:
(( percentage / 100 ) * 255 )
or
(( percentage * 255 ) / 100 )
You then convert the value to hexadecimal. For example, 50% = 0x7F: 7F = 128 = 50% of 256
Note: It's normally good practice to use lowercase letters when expressing hex values in code. They are written in uppercase in this post to make it easier to read. Also, the "0x" preceding each hex value clarifies the value following the "0x" is hexadecimal and not decimal. Not every operating system or programming language supports that syntax, but many do.
--------------
3. FYI: Raw fan speed IPMI commands are different for Supermicro X9 vs. X10/X11 boards:
X9: ipmitool raw 0x30 0x91 0x5A 0x03 "zone" "duty"
X10/X11: ipmitool raw 0x30 0x70 0x66 0x01 "zone" "duty"
where "zone" = 0x00 or 0x01
where "duty" = 0x00 --> 0xFF or 0x00 --> 0x64 depending on mobo gen, as explained above