The external calibration coefficients of the RX power are big-endian
floats in page A2h. They are read by casting the byte buffer
to a 32-bit pointer, which is an unaligned access if the buffer
is not 4-byte aligned.

The telemetry command always decodes a buffer from calloc(),
but an application may pass any buffer once the decoders are exposed.

Read the value with memcpy() and convert it with rte_be_to_cpu_32().

Signed-off-by: Roman Khromenok <[email protected]>
---
v3: new patch

 lib/ethdev/sff_8472.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/ethdev/sff_8472.c b/lib/ethdev/sff_8472.c
index f58eba9d2d..cdb6ef1f7e 100644
--- a/lib/ethdev/sff_8472.c
+++ b/lib/ethdev/sff_8472.c
@@ -4,6 +4,9 @@
  */
 
 #include <stdio.h>
+#include <string.h>
+
+#include <rte_byteorder.h>
 
 #include "sff_common.h"
 
@@ -126,7 +129,7 @@ static struct sff_8472_aw_flags {
 
 /* RXPWR(x) are IEEE-754 floating point numbers in big-endian format */
 #define A2_OFFSET_TO_RXPWRx(offset) \
-       (befloattoh((const uint32_t *)(data + SFF_A2_BASE + (offset))))
+       (befloattoh(data + SFF_A2_BASE + (offset)))
 
 /*
  * 2-byte internal temperature conversions:
@@ -169,14 +172,17 @@ static void sff_8472_dom_parse(const uint8_t *data, 
struct sff_diags *sd)
 }
 
 /* Converts to a float from a big-endian 4-byte source buffer. */
-static float befloattoh(const uint32_t *source)
+static float befloattoh(const uint8_t *source)
 {
        union {
                uint32_t src;
                float dst;
        } converter;
+       rte_be32_t be;
 
-       converter.src = ntohl(*source);
+       /* the source may be unaligned */
+       memcpy(&be, source, sizeof(be));
+       converter.src = rte_be_to_cpu_32(be);
        return converter.dst;
 }
 
-- 
2.47.3

Reply via email to