[net PATCH 2/2] net: dsa: qca8k: fix ethtool autocast mib for big-endian systems

From: Christian Marangi
Date: Mon Oct 10 2022 - 13:17:37 EST


The switch sends autocast mib in little-endian. This is problematic for
big-endian system as the values needs to be converted.

Fix this by converting each mib value to cpu byte order.

Fixes: 5c957c7ca78c ("net: dsa: qca8k: add support for mib autocast in Ethernet packet")
Tested-by: Pawel Dembicki <paweldembicki@xxxxxxxxx>
Tested-by: Lech Perczak <lech.perczak@xxxxxxxxx>
Signed-off-by: Christian Marangi <ansuelsmth@xxxxxxxxx>
---
drivers/net/dsa/qca/qca8k-8xxx.c | 20 ++++++++------------
include/linux/dsa/tag_qca.h | 2 +-
2 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index 4bb9b7eac68b..e3e89ce479c6 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -1518,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
struct qca8k_priv *priv = ds->priv;
const struct qca8k_mib_desc *mib;
struct mib_ethhdr *mib_ethhdr;
- int i, mib_len, offset = 0;
- u64 *data;
+ __le32 *data2;
u8 port;
+ int i;

mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
mib_eth_data = &priv->mib_eth_data;
@@ -1532,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
if (port != mib_eth_data->req_port)
goto exit;

- data = mib_eth_data->data;
+ data2 = (__le32 *)skb->data;

for (i = 0; i < priv->info->mib_count; i++) {
mib = &ar8327_mib[i];

/* First 3 mib are present in the skb head */
if (i < 3) {
- data[i] = mib_ethhdr->data[i];
+ mib_eth_data->data[i] = le32_to_cpu(mib_ethhdr->data[i]);
continue;
}

- mib_len = sizeof(uint32_t);
-
/* Some mib are 64 bit wide */
if (mib->size == 2)
- mib_len = sizeof(uint64_t);
-
- /* Copy the mib value from packet to the */
- memcpy(data + i, skb->data + offset, mib_len);
+ mib_eth_data->data[i] = le64_to_cpu(*(__le64 *)data2);
+ else
+ mib_eth_data->data[i] = le32_to_cpu(*data2);

- /* Set the offset for the next mib */
- offset += mib_len;
+ data2 += mib->size;
}

exit:
diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h
index 0e176da1e43f..b1b5720d89a5 100644
--- a/include/linux/dsa/tag_qca.h
+++ b/include/linux/dsa/tag_qca.h
@@ -73,7 +73,7 @@ enum mdio_cmd {
};

struct mib_ethhdr {
- u32 data[3]; /* first 3 mib counter */
+ __le32 data[3]; /* first 3 mib counter */
__be16 hdr; /* qca hdr */
} __packed;

--
2.37.2