Skip to content

Commit

Permalink
fix(sfp): fix rx power conversion
Browse files Browse the repository at this point in the history
closes sonic-net#449

Signed-off-by: Wataru Ishida <wataru.ishid@gmail.com>
  • Loading branch information
ishidawataru committed Jun 28, 2024
1 parent 8e673d5 commit f3db323
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 50 deletions.
67 changes: 17 additions & 50 deletions sonic_platform_base/sonic_sfp/sff8472.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,7 @@
from __future__ import print_function

try:
import fcntl
import struct
import sys
import time
import os
import getopt
import types
from math import log10
from .sff8024 import type_of_transceiver # Dot module supports both Python 2 and Python 3 using explicit relative import methods
from .sff8024 import type_abbrv_name # Dot module supports both Python 2 and Python 3 using explicit relative import methods
from .sffbase import sffbase # Dot module supports both Python 2 and Python 3 using explicit relative import methods
Expand Down Expand Up @@ -828,49 +821,23 @@ def calc_rx_power(self, eeprom_data, offset, size):

# External Calibration

# RX_PWR(uW) = RX_PWR_4 * RX_PWR_AD +
# RX_PWR_3 * RX_PWR_AD +
# RX_PWR_2 * RX_PWR_AD +
# RX_PWR_1 * RX_PWR_AD +
# RX_PWR(0)
off = self.dom_ext_calibration_constants['RX_PWR_4']['offset']
rx_pwr_byte3 = int(eeprom_data[off], 16)
rx_pwr_byte2 = int(eeprom_data[off + 1], 16)
rx_pwr_byte1 = int(eeprom_data[off + 2], 16)
rx_pwr_byte0 = int(eeprom_data[off + 3], 16)
rx_pwr_4 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff)

off = self.dom_ext_calibration_constants['RX_PWR_3']['offset']
rx_pwr_byte3 = int(eeprom_data[off], 16)
rx_pwr_byte2 = int(eeprom_data[off + 1], 16)
rx_pwr_byte1 = int(eeprom_data[off + 2], 16)
rx_pwr_byte0 = int(eeprom_data[off + 3], 16)
rx_pwr_3 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff)

off = self.dom_ext_calibration_constants['RX_PWR_2']['offset']
rx_pwr_byte3 = int(eeprom_data[off], 16)
rx_pwr_byte2 = int(eeprom_data[off + 1], 16)
rx_pwr_byte1 = int(eeprom_data[off + 2], 16)
rx_pwr_byte0 = int(eeprom_data[off + 3], 16)
rx_pwr_2 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff)

off = self.dom_ext_calibration_constants['RX_PWR_1']['offset']
rx_pwr_byte3 = int(eeprom_data[off], 16)
rx_pwr_byte2 = int(eeprom_data[off + 1], 16)
rx_pwr_byte1 = int(eeprom_data[off + 2], 16)
rx_pwr_byte0 = int(eeprom_data[off + 3], 16)
rx_pwr_1 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff)

off = self.dom_ext_calibration_constants['RX_PWR_0']['offset']
rx_pwr_byte3 = int(eeprom_data[off], 16)
rx_pwr_byte2 = int(eeprom_data[off + 1], 16)
rx_pwr_byte1 = int(eeprom_data[off + 2], 16)
rx_pwr_byte0 = int(eeprom_data[off + 3], 16)
rx_pwr_0 = (rx_pwr_byte3 << 24) | (rx_pwr_byte2 << 16) | (rx_pwr_byte1 << 8) | (rx_pwr_byte0 & 0xff)

rx_pwr = (rx_pwr_4 * result) + (rx_pwr_3 * result) + (rx_pwr_2 * result) + (rx_pwr_1 * result) + rx_pwr_0

result = float(result * 0.0001)
# SFF-8472 Rev 12.4 section 9.3 5)
# Rx_PWR (uW) = Rx_PWR(4) * Rx_PWR_ADe4 (16 bit unsigned integer) +
# Rx_PWR(3) * Rx_PWR_ADe3 (16 bit unsigned integer) +
# Rx_PWR(2) * Rx_PWR_ADe2 (16 bit unsigned integer) +
# Rx_PWR(1) * Rx_PWR_AD (16 bit unsigned integer) +
# Rx_PWR(0)
rx_pwr_ad = result
result = 0
for i in range(0, 5):
field_name = f'RX_PWR_{i}'
rx_pwr = self.dom_ext_calibration_constants[field_name]
off = rx_pwr['offset']
size = rx_pwr['size']
coeff = self.float_from_bytes(eeprom_data[off:off+size])
result += coeff * rx_pwr_ad ** i

result = result * 0.0001 # uW to mW
#print(indent, name, " : ", power_in_dbm_str(result))
retval = self.power_in_dbm_str(result)
else:
Expand Down
4 changes: 4 additions & 0 deletions sonic_platform_base/sonic_sfp/sffbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ def twos_comp(self, num, bits):
except Exception:
return 0

def float_from_bytes(b):
"""Convert IEEE 754 single precision float from bytes."""
return struct.unpack('!f', b)[0]

def mw_to_dbm(self, mW):
if mW == 0:
return float("-inf")
Expand Down

0 comments on commit f3db323

Please sign in to comment.