[RFC net-next v2 4/5] net: phy: nxp-c45-tja11xx: add MACsec statistics

Radu Pirea (NXP OSS)
2023-08-24T09:16:58Z

Add MACsec statistics callbacks.
The statistic registers must be set to 0 if the SC/SA is
deleted to read relevant values next time when the SC/SA is used.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
drivers/net/phy/nxp-c45-tja11xx-macsec.c | 416 ++++++++++++++++++++++-
1 file changed, 415 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx-macsec.c b/drivers/net/phy/nxp-c45-tja11xx-macsec.c
index 1567865b8de4..edfdd2540d39 100644
--- a/drivers/net/phy/nxp-c45-tja11xx-macsec.c
+++ b/drivers/net/phy/nxp-c45-tja11xx-macsec.c
@@ -140,6 +140,33 @@
#define ADAPTER_EN BIT(6)
#define MACSEC_EN BIT(5)

+#define MACSEC_INOV1HS 0x0140
+#define MACSEC_INOV2HS 0x0144
+#define MACSEC_INOD1HS 0x0148
+#define MACSEC_INOD2HS 0x014C
+#define MACSEC_RXSCIPUS 0x0150
+#define MACSEC_RXSCIPDS 0x0154
+#define MACSEC_RXSCIPLS 0x0158
+#define MACSEC_RXAN0INUSS 0x0160
+#define MACSEC_RXAN0IPUSS 0x0170
+#define MACSEC_RXSAAIPOS 0x0194
+#define MACSEC_RXSAAIPIS 0x01B0
+#define MACSEC_RXSAAIPNVS 0x01B4
+#define MACSEC_RXSABIPOS 0x01D4
+#define MACSEC_RXSABIPIS 0x01F0
+#define MACSEC_RXSABIPNVS 0x01F4
+#define MACSEC_OPUS 0x021C
+#define MACSEC_OPTLS 0x022C
+#define MACSEC_OOE1HS 0x0248
+#define MACSEC_OOE2HS 0x024C
+#define MACSEC_TXSAAOPPS 0x028C
+#define MACSEC_TXSAAOPES 0x0290
+#define MACSEC_TXSABOPPS 0x02CC
+#define MACSEC_TXSABOPES 0x02D0
+#define MACSEC_INPWTS 0x0630
+#define MACSEC_INPBTS 0x0638
+#define MACSEC_IPSNFS 0x063C
+
struct nxp_c45_rx_sc {
struct macsec_rx_sc *rx_sc;
struct macsec_rx_sa *rx_sa_a;
@@ -148,6 +175,7 @@ struct nxp_c45_rx_sc {

struct nxp_c45_tx_sa {
struct macsec_tx_sa *tx_sa;
+ struct macsec_tx_sa_stats stats;
u8 key[MACSEC_MAX_KEY_LEN];
u8 salt[MACSEC_SALT_LEN];
u8 an;
@@ -787,6 +815,113 @@ static int nxp_c45_disable_rxsa_key(struct phy_device *phydev, bool key_a)
return 0;
}

+static void nxp_c45_clear_dev_stats(struct phy_device *phydev,
+ struct nxp_c45_secy *phy_secy)
+{
+ nxp_c45_macsec_write(phydev, MACSEC_OPUS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_OPTLS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_OOE1HS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_OOE2HS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSAAOPES, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSABOPES, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSAAOPPS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSABOPPS, 0);
+
+ if (phy_secy->rx_sc) {
+ nxp_c45_macsec_write(phydev, MACSEC_INPBTS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_INPWTS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_IPSNFS, 0);
+ }
+}
+
+static void nxp_c45_clear_rx_sc_stats(struct phy_device *phydev)
+{
+ int i;
+
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPIS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPNVS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPOS, 0);
+
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPIS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPNVS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPOS, 0);
+
+ nxp_c45_macsec_write(phydev, MACSEC_INOD1HS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_INOD2HS, 0);
+
+ nxp_c45_macsec_write(phydev, MACSEC_INOV1HS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_INOV2HS, 0);
+
+ nxp_c45_macsec_write(phydev, MACSEC_RXSCIPDS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSCIPLS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSCIPUS, 0);
+
+ for (i = 0; i < MACSEC_NUM_AN; i++)
+ nxp_c45_macsec_write(phydev, MACSEC_RXAN0INUSS + i * 4, 0);
+
+ for (i = 0; i < MACSEC_NUM_AN; i++)
+ nxp_c45_macsec_write(phydev, MACSEC_RXAN0IPUSS + i * 4, 0);
+}
+
+static void nxp_c45_tx_sa_stats_read(struct phy_device *phydev,
+ struct nxp_c45_tx_sa *tx_sa,
+ struct macsec_tx_sa_stats *stats)
+{
+ u32 reg = 0;
+
+ if (tx_sa->is_key_a) {
+ nxp_c45_macsec_read(phydev, MACSEC_TXSAAOPES, &reg);
+ stats->OutPktsEncrypted = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_TXSAAOPPS, &reg);
+ stats->OutPktsProtected = reg;
+ } else {
+ nxp_c45_macsec_read(phydev, MACSEC_TXSABOPES, &reg);
+ stats->OutPktsEncrypted = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_TXSABOPPS, &reg);
+ stats->OutPktsProtected = reg;
+ }
+}
+
+static void nxp_c45_tx_sa_stats_clear(struct phy_device *phydev,
+ struct nxp_c45_tx_sa *tx_sa)
+{
+ if (tx_sa->is_key_a) {
+ nxp_c45_macsec_write(phydev, MACSEC_TXSAAOPES, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSAAOPPS, 0);
+ } else {
+ nxp_c45_macsec_write(phydev, MACSEC_TXSABOPES, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_TXSABOPPS, 0);
+ }
+}
+
+static void nxp_c45_tx_sa_stats_backup(struct phy_device *phydev,
+ struct nxp_c45_tx_sa *tx_sa)
+{
+ struct macsec_tx_sa_stats stats;
+
+ nxp_c45_tx_sa_stats_read(phydev, tx_sa, &stats);
+ tx_sa->stats.OutPktsEncrypted += stats.OutPktsEncrypted;
+ tx_sa->stats.OutPktsProtected += stats.OutPktsProtected;
+ nxp_c45_tx_sa_stats_clear(phydev, tx_sa);
+}
+
+static void nxp_c45_clear_rx_sa_stats(struct phy_device *phydev,
+ u8 an, bool is_key_a)
+{
+ if (is_key_a) {
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPIS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPNVS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSAAIPOS, 0);
+ } else {
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPIS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPNVS, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXSABIPOS, 0);
+ }
+
+ nxp_c45_macsec_write(phydev, MACSEC_RXAN0INUSS + an * 4, 0);
+ nxp_c45_macsec_write(phydev, MACSEC_RXAN0IPUSS + an * 4, 0);
+}
+
static int nxp_c45_rx_sc_del(struct phy_device *phydev,
struct nxp_c45_rx_sc *rx_sc)
{
@@ -801,6 +936,8 @@ static int nxp_c45_rx_sc_del(struct phy_device *phydev,
if (rx_sc->rx_sa_b)
nxp_c45_disable_rxsa_key(phydev, false);

+ nxp_c45_clear_rx_sc_stats(phydev);
+
return 0;
}

@@ -961,6 +1098,7 @@ static int nxp_c45_mdo_upd_secy(struct macsec_context *ctx)
if (old_tx_sa) {
old_tx_sa->is_enabled = false;
nxp_c45_txsa_get_pn(phydev, old_tx_sa);
+ nxp_c45_tx_sa_stats_backup(phydev, old_tx_sa);
}
}

@@ -979,6 +1117,7 @@ static int nxp_c45_mdo_del_secy(struct macsec_context *ctx)
struct nxp_c45_phy *priv = phydev->priv;
struct nxp_c45_secy *phy_secy;
u32 reg;
+ int i;

phydev_dbg(phydev, "delete secy SCI %llu\n", ctx->secy->sci);

@@ -990,11 +1129,16 @@ static int nxp_c45_mdo_del_secy(struct macsec_context *ctx)
nxp_c45_mdo_dev_stop(ctx);
nxp_c45_tx_sa_disable(phydev, phy_secy);
nxp_c45_tx_sc_clear(phy_secy);
+ nxp_c45_clear_dev_stats(phydev, phy_secy);
if (phy_secy->rx_sc) {
nxp_c45_rx_sc_del(phydev, phy_secy->rx_sc);
kfree(phy_secy->rx_sc);
}

+ for (i = 0; i < ARRAY_SIZE(phy_secy->tx_sa); i++)
+ if (phy_secy->tx_sa[i] && phy_secy->tx_sa[i]->is_enabled)
+ nxp_c45_tx_sa_stats_clear(phydev, phy_secy->tx_sa[i]);
+
if (phy_interrupt_is_valid(phydev)) {
nxp_c45_macsec_read(phydev, MACSEC_EVER, &reg);
reg &= ~TX_SC_BIT(phy_secy->secy_id);
@@ -1188,6 +1332,7 @@ static int nxp_c45_mdo_del_rxsa(struct macsec_context *ctx)
phydev_dbg(phydev, "delete RX SA A %u %s\n",
an, rx_sa->active ? "enabled" : "disabled");
nxp_c45_disable_rxsa_key(phydev, true);
+ nxp_c45_clear_rx_sa_stats(phydev, an, true);
rx_sc->rx_sa_a = NULL;
return 0;
}
@@ -1196,6 +1341,7 @@ static int nxp_c45_mdo_del_rxsa(struct macsec_context *ctx)
phydev_dbg(phydev, "delete RX SA B %u %s\n",
an, rx_sa->active ? "enabled" : "disabled");
nxp_c45_disable_rxsa_key(phydev, false);
+ nxp_c45_clear_rx_sa_stats(phydev, an, false);
rx_sc->rx_sa_b = NULL;
return 0;
}
@@ -1323,8 +1469,10 @@ static int nxp_c45_mdo_del_txsa(struct macsec_context *ctx)

nxp_c45_select_secy(phydev, phy_secy->secy_id);

- if (tx_sa->is_enabled)
+ if (tx_sa->is_enabled) {
nxp_c45_update_key_status(phydev, tx_sa);
+ nxp_c45_tx_sa_stats_clear(phydev, tx_sa);
+ }

phy_secy->tx_sa[sa] = NULL;
kfree(tx_sa);
@@ -1332,6 +1480,267 @@ static int nxp_c45_mdo_del_txsa(struct macsec_context *ctx)
return 0;
}

+static int nxp_c45_mdo_get_dev_stats(struct macsec_context *ctx)
+{
+ struct phy_device *phydev = ctx->phydev;
+ struct nxp_c45_phy *priv = phydev->priv;
+ struct macsec_dev_stats *dev_stats;
+ struct nxp_c45_secy *phy_secy;
+ u32 reg = 0;
+
+ phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
+ if (IS_ERR(phy_secy))
+ return PTR_ERR(phy_secy);
+
+ dev_stats = ctx->stats.dev_stats;
+ nxp_c45_select_secy(phydev, phy_secy->secy_id);
+
+ nxp_c45_macsec_read(phydev, MACSEC_OPUS, &reg);
+ dev_stats->OutPktsUntagged = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_OPTLS, &reg);
+ dev_stats->OutPktsTooLong = reg;
+
+ dev_stats->InPktsUntagged = 0;
+ dev_stats->InPktsNoTag = 0;
+ dev_stats->InPktsBadTag = 0;
+ dev_stats->InPktsUnknownSCI = 0;
+ dev_stats->InPktsNoSCI = 0;
+
+ if (phy_secy->rx_sc) {
+ nxp_c45_macsec_read(phydev, MACSEC_INPBTS, &reg);
+ dev_stats->InPktsBadTag = reg;
+
+ nxp_c45_macsec_read(phydev, MACSEC_INPWTS, &reg);
+ if (phy_secy->secy->validate_frames == MACSEC_VALIDATE_STRICT)
+ dev_stats->InPktsNoTag += reg;
+ else
+ dev_stats->InPktsUntagged += reg;
+
+ nxp_c45_macsec_read(phydev, MACSEC_IPSNFS, &reg);
+ if (phy_secy->secy->validate_frames == MACSEC_VALIDATE_STRICT)
+ dev_stats->InPktsNoSCI += reg;
+ else
+ dev_stats->InPktsUnknownSCI += reg;
+ }
+
+ /* Always 0. */
+ dev_stats->InPktsOverrun = 0;
+
+ return 0;
+}
+
+static int nxp_c45_mdo_get_tx_sc_stats(struct macsec_context *ctx)
+{
+ struct phy_device *phydev = ctx->phydev;
+ struct nxp_c45_phy *priv = phydev->priv;
+ struct macsec_tx_sc_stats *tx_sc_stats;
+ struct macsec_tx_sa_stats tx_sa_stats;
+ struct nxp_c45_secy *phy_secy;
+ struct nxp_c45_tx_sa *tx_sa;
+ u32 reg = 0;
+ u64 stat;
+ int i;
+
+ phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
+ if (IS_ERR(phy_secy))
+ return PTR_ERR(phy_secy);
+
+ tx_sc_stats = ctx->stats.tx_sc_stats;
+ nxp_c45_select_secy(phydev, phy_secy->secy_id);
+
+ nxp_c45_macsec_read(phydev, MACSEC_OOE1HS, &reg);
+ stat = (u64)reg << 32;
+ nxp_c45_macsec_read(phydev, MACSEC_OOE2HS, &reg);
+ stat |= reg;
+ if (ctx->secy->tx_sc.encrypt)
+ tx_sc_stats->OutOctetsEncrypted = stat;
+ else
+ tx_sc_stats->OutOctetsEncrypted = 0;
+
+ if (ctx->secy->protect_frames)
+ tx_sc_stats->OutOctetsProtected = stat;
+ else
+ tx_sc_stats->OutOctetsProtected = 0;
+
+ tx_sc_stats->OutPktsEncrypted = 0;
+ tx_sc_stats->OutPktsProtected = 0;
+
+ for (i = 0; i < ARRAY_SIZE(phy_secy->tx_sa); i++) {
+ tx_sa = phy_secy->tx_sa[i];
+ if (!tx_sa)
+ continue;
+
+ if (tx_sa->is_enabled) {
+ nxp_c45_tx_sa_stats_read(phydev, tx_sa, &tx_sa_stats);
+ tx_sc_stats->OutPktsEncrypted +=
+ tx_sa_stats.OutPktsEncrypted;
+ tx_sc_stats->OutPktsProtected +=
+ tx_sa_stats.OutPktsProtected;
+ continue;
+ }
+
+ tx_sc_stats->OutPktsEncrypted += tx_sa->stats.OutPktsEncrypted;
+ tx_sc_stats->OutPktsProtected += tx_sa->stats.OutPktsProtected;
+ }
+
+ return 0;
+}
+
+static int nxp_c45_mdo_get_tx_sa_stats(struct macsec_context *ctx)
+{
+ struct phy_device *phydev = ctx->phydev;
+ struct nxp_c45_phy *priv = phydev->priv;
+ struct macsec_tx_sa_stats *tx_sa_stats;
+ struct nxp_c45_secy *phy_secy;
+ struct nxp_c45_tx_sa *tx_sa;
+
+ phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
+ if (IS_ERR(phy_secy))
+ return PTR_ERR(phy_secy);
+
+ tx_sa = phy_secy->tx_sa[ctx->sa.assoc_num];
+ if (!tx_sa)
+ return -EINVAL;
+
+ tx_sa_stats = ctx->stats.tx_sa_stats;
+
+ if (!tx_sa->is_enabled) {
+ tx_sa_stats->OutPktsEncrypted = tx_sa->stats.OutPktsEncrypted;
+ tx_sa_stats->OutPktsProtected = tx_sa->stats.OutPktsProtected;
+ return 0;
+ }
+
+ nxp_c45_select_secy(phydev, phy_secy->secy_id);
+ nxp_c45_tx_sa_stats_read(phydev, tx_sa, tx_sa_stats);
+
+ return 0;
+}
+
+static int nxp_c45_mdo_get_rx_sc_stats(struct macsec_context *ctx)
+{
+ struct phy_device *phydev = ctx->phydev;
+ struct nxp_c45_phy *priv = phydev->priv;
+ struct macsec_rx_sc_stats *rx_sc_stats;
+ struct nxp_c45_secy *phy_secy;
+ struct nxp_c45_rx_sc *rx_sc;
+ u32 reg = 0;
+ int i;
+
+ phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
+ if (IS_ERR(phy_secy))
+ return PTR_ERR(phy_secy);
+
+ rx_sc = phy_secy->rx_sc;
+ if (rx_sc->rx_sc != ctx->rx_sc)
+ return -EINVAL;
+
+ rx_sc_stats = ctx->stats.rx_sc_stats;
+ nxp_c45_select_secy(phydev, phy_secy->secy_id);
+
+ rx_sc_stats->InPktsInvalid = 0;
+ rx_sc_stats->InPktsNotValid = 0;
+ rx_sc_stats->InPktsOK = 0;
+
+ if (rx_sc->rx_sa_a) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPIS, &reg);
+ rx_sc_stats->InPktsInvalid += reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPNVS, &reg);
+ rx_sc_stats->InPktsNotValid += reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPOS, &reg);
+ rx_sc_stats->InPktsOK += reg;
+ }
+
+ if (rx_sc->rx_sa_b) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPIS, &reg);
+ rx_sc_stats->InPktsInvalid += reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPNVS, &reg);
+ rx_sc_stats->InPktsNotValid += reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPOS, &reg);
+ rx_sc_stats->InPktsOK += reg;
+ }
+
+ ctx->stats.rx_sa_stats->InPktsNotUsingSA = 0;
+ for (i = 0; i < MACSEC_NUM_AN; i++) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXAN0INUSS + i * 4, &reg);
+ rx_sc_stats->InPktsNotUsingSA += reg;
+ }
+
+ ctx->stats.rx_sa_stats->InPktsUnusedSA = 0;
+ for (i = 0; i < MACSEC_NUM_AN; i++) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXAN0IPUSS + i * 4, &reg);
+ rx_sc_stats->InPktsUnusedSA += reg;
+ }
+
+ nxp_c45_macsec_read(phydev, MACSEC_INOD1HS, &reg);
+ rx_sc_stats->InOctetsDecrypted = (u64)reg << 32;
+ nxp_c45_macsec_read(phydev, MACSEC_INOD2HS, &reg);
+ rx_sc_stats->InOctetsDecrypted |= reg;
+
+ nxp_c45_macsec_read(phydev, MACSEC_INOV1HS, &reg);
+ rx_sc_stats->InOctetsValidated = (u64)reg << 32;
+ nxp_c45_macsec_read(phydev, MACSEC_INOV2HS, &reg);
+ rx_sc_stats->InOctetsValidated |= reg;
+
+ nxp_c45_macsec_read(phydev, MACSEC_RXSCIPDS, &reg);
+ rx_sc_stats->InPktsDelayed = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSCIPLS, &reg);
+ rx_sc_stats->InPktsLate = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSCIPUS, &reg);
+ rx_sc_stats->InPktsUnchecked = reg;
+
+ return 0;
+}
+
+static int nxp_c45_mdo_get_rx_sa_stats(struct macsec_context *ctx)
+{
+ struct phy_device *phydev = ctx->phydev;
+ struct nxp_c45_phy *priv = phydev->priv;
+ struct macsec_rx_sa_stats *rx_sa_stats;
+ struct nxp_c45_secy *phy_secy;
+ struct nxp_c45_rx_sc *rx_sc;
+ u8 an = ctx->sa.assoc_num;
+ u32 reg = 0;
+
+ phy_secy = nxp_c45_find_secy(&priv->macsec->secy_list, ctx->secy->sci);
+ if (IS_ERR(phy_secy))
+ return PTR_ERR(phy_secy);
+
+ rx_sc = phy_secy->rx_sc;
+ if (rx_sc->rx_sc != ctx->sa.rx_sa->sc)
+ return -EINVAL;
+
+ if (!rx_sc->rx_sa_a && !rx_sc->rx_sa_b)
+ return -EINVAL;
+
+ rx_sa_stats = ctx->stats.rx_sa_stats;
+ nxp_c45_select_secy(phydev, phy_secy->secy_id);
+
+ if (rx_sc->rx_sa_a == ctx->sa.rx_sa) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPIS, &reg);
+ rx_sa_stats->InPktsInvalid = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPNVS, &reg);
+ rx_sa_stats->InPktsNotValid = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSAAIPOS, &reg);
+ rx_sa_stats->InPktsOK = reg;
+ }
+
+ if (rx_sc->rx_sa_b == ctx->sa.rx_sa) {
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPIS, &reg);
+ rx_sa_stats->InPktsInvalid = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPNVS, &reg);
+ rx_sa_stats->InPktsNotValid = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXSABIPOS, &reg);
+ rx_sa_stats->InPktsOK = reg;
+ }
+
+ nxp_c45_macsec_read(phydev, MACSEC_RXAN0INUSS + an * 4, &reg);
+ rx_sa_stats->InPktsNotUsingSA = reg;
+ nxp_c45_macsec_read(phydev, MACSEC_RXAN0IPUSS + an * 4, &reg);
+ rx_sa_stats->InPktsUnusedSA = reg;
+
+ return 0;
+}
+
static const struct macsec_ops nxp_c45_macsec_ops = {
.mdo_dev_open = nxp_c45_mdo_dev_open,
.mdo_dev_stop = nxp_c45_mdo_dev_stop,
@@ -1347,6 +1756,11 @@ static const struct macsec_ops nxp_c45_macsec_ops = {
.mdo_add_txsa = nxp_c45_mdo_add_txsa,
.mdo_upd_txsa = nxp_c45_mdo_upd_txsa,
.mdo_del_txsa = nxp_c45_mdo_del_txsa,
+ .mdo_get_dev_stats = nxp_c45_mdo_get_dev_stats,
+ .mdo_get_tx_sc_stats = nxp_c45_mdo_get_tx_sc_stats,
+ .mdo_get_tx_sa_stats = nxp_c45_mdo_get_tx_sa_stats,
+ .mdo_get_rx_sc_stats = nxp_c45_mdo_get_rx_sc_stats,
+ .mdo_get_rx_sa_stats = nxp_c45_mdo_get_rx_sa_stats,
};

int nxp_c45_macsec_probe(struct phy_device *phydev)
--
2.34.1