#include "aq_vec.h"
#include "aq_ptp.h"
#include "aq_filters.h"
+#include "aq_macsec.h"
#include <linux/ptp_clock_kernel.h>
"Queue[%d] InErrors",
};
+#if IS_ENABLED(CONFIG_MACSEC)
+static const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
+ "MACSec InCtlPackets",
+ "MACSec InTaggedMissPackets",
+ "MACSec InUntaggedMissPackets",
+ "MACSec InNotagPackets",
+ "MACSec InUntaggedPackets",
+ "MACSec InBadTagPackets",
+ "MACSec InNoSciPackets",
+ "MACSec InUnknownSciPackets",
+ "MACSec InCtrlPortPassPackets",
+ "MACSec InUnctrlPortPassPackets",
+ "MACSec InCtrlPortFailPackets",
+ "MACSec InUnctrlPortFailPackets",
+ "MACSec InTooLongPackets",
+ "MACSec InIgpocCtlPackets",
+ "MACSec InEccErrorPackets",
+ "MACSec InUnctrlHitDropRedir",
+ "MACSec OutCtlPackets",
+ "MACSec OutUnknownSaPackets",
+ "MACSec OutUntaggedPackets",
+ "MACSec OutTooLong",
+ "MACSec OutEccErrorPackets",
+ "MACSec OutUnctrlHitDropRedir",
+};
+
+static const char *aq_macsec_txsc_stat_names[] = {
+ "MACSecTXSC%d ProtectedPkts",
+ "MACSecTXSC%d EncryptedPkts",
+ "MACSecTXSC%d ProtectedOctets",
+ "MACSecTXSC%d EncryptedOctets",
+};
+
+static const char *aq_macsec_txsa_stat_names[] = {
+ "MACSecTXSC%dSA%d HitDropRedirect",
+ "MACSecTXSC%dSA%d Protected2Pkts",
+ "MACSecTXSC%dSA%d ProtectedPkts",
+ "MACSecTXSC%dSA%d EncryptedPkts",
+};
+
+static const char *aq_macsec_rxsa_stat_names[] = {
+ "MACSecRXSC%dSA%d UntaggedHitPkts",
+ "MACSecRXSC%dSA%d CtrlHitDrpRedir",
+ "MACSecRXSC%dSA%d NotUsingSa",
+ "MACSecRXSC%dSA%d UnusedSa",
+ "MACSecRXSC%dSA%d NotValidPkts",
+ "MACSecRXSC%dSA%d InvalidPkts",
+ "MACSecRXSC%dSA%d OkPkts",
+ "MACSecRXSC%dSA%d LatePkts",
+ "MACSecRXSC%dSA%d DelayedPkts",
+ "MACSecRXSC%dSA%d UncheckedPkts",
+ "MACSecRXSC%dSA%d ValidatedOctets",
+ "MACSecRXSC%dSA%d DecryptedOctets",
+};
+#endif
+
static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
"DMASystemLoopback",
"PKTSystemLoopback",
"PHYExternalLoopback",
};
+static u32 aq_ethtool_n_stats(struct net_device *ndev)
+{
+ struct aq_nic_s *nic = netdev_priv(ndev);
+ struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
+ u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
+ ARRAY_SIZE(aq_ethtool_queue_stat_names) * cfg->vecs;
+
+#if IS_ENABLED(CONFIG_MACSEC)
+ if (nic->macsec_cfg) {
+ n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
+ ARRAY_SIZE(aq_macsec_txsc_stat_names) *
+ aq_macsec_tx_sc_cnt(nic) +
+ ARRAY_SIZE(aq_macsec_txsa_stat_names) *
+ aq_macsec_tx_sa_cnt(nic) +
+ ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
+ aq_macsec_rx_sa_cnt(nic);
+ }
+#endif
+
+ return n_stats;
+}
+
static void aq_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *stats, u64 *data)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
- struct aq_nic_cfg_s *cfg;
- cfg = aq_nic_get_cfg(aq_nic);
-
- memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
- ARRAY_SIZE(aq_ethtool_queue_stat_names) *
- cfg->vecs) * sizeof(u64));
- aq_nic_get_stats(aq_nic, data);
+ memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
+ data = aq_nic_get_stats(aq_nic, data);
+#if IS_ENABLED(CONFIG_MACSEC)
+ data = aq_macsec_get_stats(aq_nic, data);
+#endif
}
static void aq_ethtool_get_drvinfo(struct net_device *ndev,
{
struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
struct aq_nic_s *aq_nic = netdev_priv(ndev);
- struct aq_nic_cfg_s *cfg;
u32 firmware_version;
u32 regs_count;
- cfg = aq_nic_get_cfg(aq_nic);
firmware_version = aq_nic_get_fw_version(aq_nic);
regs_count = aq_nic_get_regs_count(aq_nic);
strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
sizeof(drvinfo->bus_info));
- drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
- cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
+ drvinfo->n_stats = aq_ethtool_n_stats(ndev);
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = regs_count;
drvinfo->eedump_len = 0;
struct aq_nic_cfg_s *cfg;
u8 *p = data;
int i, si;
+#if IS_ENABLED(CONFIG_MACSEC)
+ int sa;
+#endif
cfg = aq_nic_get_cfg(aq_nic);
p += ETH_GSTRING_LEN;
}
}
+#if IS_ENABLED(CONFIG_MACSEC)
+ if (!aq_nic->macsec_cfg)
+ break;
+
+ memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
+ p = p + sizeof(aq_macsec_stat_names);
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ struct aq_macsec_txsc *aq_txsc;
+
+ if (!(test_bit(i, &aq_nic->macsec_cfg->txsc_idx_busy)))
+ continue;
+
+ for (si = 0;
+ si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
+ si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_macsec_txsc_stat_names[si], i);
+ p += ETH_GSTRING_LEN;
+ }
+ aq_txsc = &aq_nic->macsec_cfg->aq_txsc[i];
+ for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
+ if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
+ continue;
+ for (si = 0;
+ si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
+ si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_macsec_txsa_stat_names[si],
+ i, sa);
+ p += ETH_GSTRING_LEN;
+ }
+ }
+ }
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ struct aq_macsec_rxsc *aq_rxsc;
+
+ if (!(test_bit(i, &aq_nic->macsec_cfg->rxsc_idx_busy)))
+ continue;
+
+ aq_rxsc = &aq_nic->macsec_cfg->aq_rxsc[i];
+ for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
+ if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
+ continue;
+ for (si = 0;
+ si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
+ si++) {
+ snprintf(p, ETH_GSTRING_LEN,
+ aq_macsec_rxsa_stat_names[si],
+ i, sa);
+ p += ETH_GSTRING_LEN;
+ }
+ }
+ }
+#endif
break;
case ETH_SS_PRIV_FLAGS:
memcpy(p, aq_ethtool_priv_flag_names,
static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
{
- struct aq_nic_s *aq_nic = netdev_priv(ndev);
- struct aq_nic_cfg_s *cfg;
int ret = 0;
- cfg = aq_nic_get_cfg(aq_nic);
-
switch (stringset) {
case ETH_SS_STATS:
- ret = ARRAY_SIZE(aq_ethtool_stat_names) +
- cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
+ ret = aq_ethtool_n_stats(ndev);
break;
case ETH_SS_PRIV_FLAGS:
ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
}
}
+#define STATS_2x32_TO_64(stat_field) \
+ (((u64)stat_field[1] << 32) | stat_field[0])
+
+static int aq_get_macsec_common_stats(struct aq_hw_s *hw,
+ struct aq_macsec_common_stats *stats)
+{
+ struct aq_mss_ingress_common_counters ingress_counters;
+ struct aq_mss_egress_common_counters egress_counters;
+ int ret;
+
+ /* MACSEC counters */
+ ret = aq_mss_get_ingress_common_counters(hw, &ingress_counters);
+ if (unlikely(ret))
+ return ret;
+
+ stats->in.ctl_pkts = STATS_2x32_TO_64(ingress_counters.ctl_pkts);
+ stats->in.tagged_miss_pkts =
+ STATS_2x32_TO_64(ingress_counters.tagged_miss_pkts);
+ stats->in.untagged_miss_pkts =
+ STATS_2x32_TO_64(ingress_counters.untagged_miss_pkts);
+ stats->in.notag_pkts = STATS_2x32_TO_64(ingress_counters.notag_pkts);
+ stats->in.untagged_pkts =
+ STATS_2x32_TO_64(ingress_counters.untagged_pkts);
+ stats->in.bad_tag_pkts =
+ STATS_2x32_TO_64(ingress_counters.bad_tag_pkts);
+ stats->in.no_sci_pkts = STATS_2x32_TO_64(ingress_counters.no_sci_pkts);
+ stats->in.unknown_sci_pkts =
+ STATS_2x32_TO_64(ingress_counters.unknown_sci_pkts);
+ stats->in.ctrl_prt_pass_pkts =
+ STATS_2x32_TO_64(ingress_counters.ctrl_prt_pass_pkts);
+ stats->in.unctrl_prt_pass_pkts =
+ STATS_2x32_TO_64(ingress_counters.unctrl_prt_pass_pkts);
+ stats->in.ctrl_prt_fail_pkts =
+ STATS_2x32_TO_64(ingress_counters.ctrl_prt_fail_pkts);
+ stats->in.unctrl_prt_fail_pkts =
+ STATS_2x32_TO_64(ingress_counters.unctrl_prt_fail_pkts);
+ stats->in.too_long_pkts =
+ STATS_2x32_TO_64(ingress_counters.too_long_pkts);
+ stats->in.igpoc_ctl_pkts =
+ STATS_2x32_TO_64(ingress_counters.igpoc_ctl_pkts);
+ stats->in.ecc_error_pkts =
+ STATS_2x32_TO_64(ingress_counters.ecc_error_pkts);
+ stats->in.unctrl_hit_drop_redir =
+ STATS_2x32_TO_64(ingress_counters.unctrl_hit_drop_redir);
+
+ ret = aq_mss_get_egress_common_counters(hw, &egress_counters);
+ if (unlikely(ret))
+ return ret;
+ stats->out.ctl_pkts = STATS_2x32_TO_64(egress_counters.ctl_pkt);
+ stats->out.unknown_sa_pkts =
+ STATS_2x32_TO_64(egress_counters.unknown_sa_pkts);
+ stats->out.untagged_pkts =
+ STATS_2x32_TO_64(egress_counters.untagged_pkts);
+ stats->out.too_long = STATS_2x32_TO_64(egress_counters.too_long);
+ stats->out.ecc_error_pkts =
+ STATS_2x32_TO_64(egress_counters.ecc_error_pkts);
+ stats->out.unctrl_hit_drop_redir =
+ STATS_2x32_TO_64(egress_counters.unctrl_hit_drop_redir);
+
+ return 0;
+}
+
+static int aq_get_rxsa_stats(struct aq_hw_s *hw, const int sa_idx,
+ struct aq_macsec_rx_sa_stats *stats)
+{
+ struct aq_mss_ingress_sa_counters i_sa_counters;
+ int ret;
+
+ ret = aq_mss_get_ingress_sa_counters(hw, &i_sa_counters, sa_idx);
+ if (unlikely(ret))
+ return ret;
+
+ stats->untagged_hit_pkts =
+ STATS_2x32_TO_64(i_sa_counters.untagged_hit_pkts);
+ stats->ctrl_hit_drop_redir_pkts =
+ STATS_2x32_TO_64(i_sa_counters.ctrl_hit_drop_redir_pkts);
+ stats->not_using_sa = STATS_2x32_TO_64(i_sa_counters.not_using_sa);
+ stats->unused_sa = STATS_2x32_TO_64(i_sa_counters.unused_sa);
+ stats->not_valid_pkts = STATS_2x32_TO_64(i_sa_counters.not_valid_pkts);
+ stats->invalid_pkts = STATS_2x32_TO_64(i_sa_counters.invalid_pkts);
+ stats->ok_pkts = STATS_2x32_TO_64(i_sa_counters.ok_pkts);
+ stats->late_pkts = STATS_2x32_TO_64(i_sa_counters.late_pkts);
+ stats->delayed_pkts = STATS_2x32_TO_64(i_sa_counters.delayed_pkts);
+ stats->unchecked_pkts = STATS_2x32_TO_64(i_sa_counters.unchecked_pkts);
+ stats->validated_octets =
+ STATS_2x32_TO_64(i_sa_counters.validated_octets);
+ stats->decrypted_octets =
+ STATS_2x32_TO_64(i_sa_counters.decrypted_octets);
+
+ return 0;
+}
+
+static int aq_get_txsa_stats(struct aq_hw_s *hw, const int sa_idx,
+ struct aq_macsec_tx_sa_stats *stats)
+{
+ struct aq_mss_egress_sa_counters e_sa_counters;
+ int ret;
+
+ ret = aq_mss_get_egress_sa_counters(hw, &e_sa_counters, sa_idx);
+ if (unlikely(ret))
+ return ret;
+
+ stats->sa_hit_drop_redirect =
+ STATS_2x32_TO_64(e_sa_counters.sa_hit_drop_redirect);
+ stats->sa_protected2_pkts =
+ STATS_2x32_TO_64(e_sa_counters.sa_protected2_pkts);
+ stats->sa_protected_pkts =
+ STATS_2x32_TO_64(e_sa_counters.sa_protected_pkts);
+ stats->sa_encrypted_pkts =
+ STATS_2x32_TO_64(e_sa_counters.sa_encrypted_pkts);
+
+ return 0;
+}
+
+static int aq_get_txsa_next_pn(struct aq_hw_s *hw, const int sa_idx, u32 *pn)
+{
+ struct aq_mss_egress_sa_record sa_rec;
+ int ret;
+
+ ret = aq_mss_get_egress_sa_record(hw, &sa_rec, sa_idx);
+ if (likely(!ret))
+ *pn = sa_rec.next_pn;
+
+ return ret;
+}
+
+static int aq_get_rxsa_next_pn(struct aq_hw_s *hw, const int sa_idx, u32 *pn)
+{
+ struct aq_mss_ingress_sa_record sa_rec;
+ int ret;
+
+ ret = aq_mss_get_ingress_sa_record(hw, &sa_rec, sa_idx);
+ if (likely(!ret))
+ *pn = (!sa_rec.sat_nextpn) ? sa_rec.next_pn : 0;
+
+ return ret;
+}
+
+static int aq_get_txsc_stats(struct aq_hw_s *hw, const int sc_idx,
+ struct aq_macsec_tx_sc_stats *stats)
+{
+ struct aq_mss_egress_sc_counters e_sc_counters;
+ int ret;
+
+ ret = aq_mss_get_egress_sc_counters(hw, &e_sc_counters, sc_idx);
+ if (unlikely(ret))
+ return ret;
+
+ stats->sc_protected_pkts =
+ STATS_2x32_TO_64(e_sc_counters.sc_protected_pkts);
+ stats->sc_encrypted_pkts =
+ STATS_2x32_TO_64(e_sc_counters.sc_encrypted_pkts);
+ stats->sc_protected_octets =
+ STATS_2x32_TO_64(e_sc_counters.sc_protected_octets);
+ stats->sc_encrypted_octets =
+ STATS_2x32_TO_64(e_sc_counters.sc_encrypted_octets);
+
+ return 0;
+}
+
static int aq_mdo_dev_open(struct macsec_context *ctx)
{
struct aq_nic_s *nic = netdev_priv(ctx->netdev);
return ret;
}
+static int aq_mdo_get_dev_stats(struct macsec_context *ctx)
+{
+ struct aq_nic_s *nic = netdev_priv(ctx->netdev);
+ struct aq_macsec_common_stats *stats = &nic->macsec_cfg->stats;
+ struct aq_hw_s *hw = nic->aq_hw;
+
+ if (ctx->prepare)
+ return 0;
+
+ aq_get_macsec_common_stats(hw, stats);
+
+ ctx->stats.dev_stats->OutPktsUntagged = stats->out.untagged_pkts;
+ ctx->stats.dev_stats->InPktsUntagged = stats->in.untagged_pkts;
+ ctx->stats.dev_stats->OutPktsTooLong = stats->out.too_long;
+ ctx->stats.dev_stats->InPktsNoTag = stats->in.notag_pkts;
+ ctx->stats.dev_stats->InPktsBadTag = stats->in.bad_tag_pkts;
+ ctx->stats.dev_stats->InPktsUnknownSCI = stats->in.unknown_sci_pkts;
+ ctx->stats.dev_stats->InPktsNoSCI = stats->in.no_sci_pkts;
+ ctx->stats.dev_stats->InPktsOverrun = 0;
+
+ return 0;
+}
+
+static int aq_mdo_get_tx_sc_stats(struct macsec_context *ctx)
+{
+ struct aq_nic_s *nic = netdev_priv(ctx->netdev);
+ struct aq_macsec_tx_sc_stats *stats;
+ struct aq_hw_s *hw = nic->aq_hw;
+ struct aq_macsec_txsc *aq_txsc;
+ int txsc_idx;
+
+ txsc_idx = aq_get_txsc_idx_from_secy(nic->macsec_cfg, ctx->secy);
+ if (txsc_idx < 0)
+ return -ENOENT;
+
+ if (ctx->prepare)
+ return 0;
+
+ aq_txsc = &nic->macsec_cfg->aq_txsc[txsc_idx];
+ stats = &aq_txsc->stats;
+ aq_get_txsc_stats(hw, aq_txsc->hw_sc_idx, stats);
+
+ ctx->stats.tx_sc_stats->OutPktsProtected = stats->sc_protected_pkts;
+ ctx->stats.tx_sc_stats->OutPktsEncrypted = stats->sc_encrypted_pkts;
+ ctx->stats.tx_sc_stats->OutOctetsProtected = stats->sc_protected_octets;
+ ctx->stats.tx_sc_stats->OutOctetsEncrypted = stats->sc_encrypted_octets;
+
+ return 0;
+}
+
+static int aq_mdo_get_tx_sa_stats(struct macsec_context *ctx)
+{
+ struct aq_nic_s *nic = netdev_priv(ctx->netdev);
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ struct aq_macsec_tx_sa_stats *stats;
+ struct aq_hw_s *hw = nic->aq_hw;
+ const struct macsec_secy *secy;
+ struct aq_macsec_txsc *aq_txsc;
+ struct macsec_tx_sa *tx_sa;
+ unsigned int sa_idx;
+ int txsc_idx;
+ u32 next_pn;
+ int ret;
+
+ txsc_idx = aq_get_txsc_idx_from_secy(cfg, ctx->secy);
+ if (txsc_idx < 0)
+ return -EINVAL;
+
+ if (ctx->prepare)
+ return 0;
+
+ aq_txsc = &cfg->aq_txsc[txsc_idx];
+ sa_idx = aq_txsc->hw_sc_idx | ctx->sa.assoc_num;
+ stats = &aq_txsc->tx_sa_stats[ctx->sa.assoc_num];
+ ret = aq_get_txsa_stats(hw, sa_idx, stats);
+ if (ret)
+ return ret;
+
+ ctx->stats.tx_sa_stats->OutPktsProtected = stats->sa_protected_pkts;
+ ctx->stats.tx_sa_stats->OutPktsEncrypted = stats->sa_encrypted_pkts;
+
+ secy = aq_txsc->sw_secy;
+ tx_sa = rcu_dereference_bh(secy->tx_sc.sa[ctx->sa.assoc_num]);
+ ret = aq_get_txsa_next_pn(hw, sa_idx, &next_pn);
+ if (ret == 0) {
+ spin_lock_bh(&tx_sa->lock);
+ tx_sa->next_pn = next_pn;
+ spin_unlock_bh(&tx_sa->lock);
+ }
+
+ return ret;
+}
+
+static int aq_mdo_get_rx_sc_stats(struct macsec_context *ctx)
+{
+ struct aq_nic_s *nic = netdev_priv(ctx->netdev);
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ struct aq_macsec_rx_sa_stats *stats;
+ struct aq_hw_s *hw = nic->aq_hw;
+ struct aq_macsec_rxsc *aq_rxsc;
+ unsigned int sa_idx;
+ int rxsc_idx;
+ int ret = 0;
+ int i;
+
+ rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, ctx->rx_sc);
+ if (rxsc_idx < 0)
+ return -ENOENT;
+
+ if (ctx->prepare)
+ return 0;
+
+ aq_rxsc = &cfg->aq_rxsc[rxsc_idx];
+ for (i = 0; i < MACSEC_NUM_AN; i++) {
+ if (!test_bit(i, &aq_rxsc->rx_sa_idx_busy))
+ continue;
+
+ stats = &aq_rxsc->rx_sa_stats[i];
+ sa_idx = aq_rxsc->hw_sc_idx | i;
+ ret = aq_get_rxsa_stats(hw, sa_idx, stats);
+ if (ret)
+ break;
+
+ ctx->stats.rx_sc_stats->InOctetsValidated +=
+ stats->validated_octets;
+ ctx->stats.rx_sc_stats->InOctetsDecrypted +=
+ stats->decrypted_octets;
+ ctx->stats.rx_sc_stats->InPktsUnchecked +=
+ stats->unchecked_pkts;
+ ctx->stats.rx_sc_stats->InPktsDelayed += stats->delayed_pkts;
+ ctx->stats.rx_sc_stats->InPktsOK += stats->ok_pkts;
+ ctx->stats.rx_sc_stats->InPktsInvalid += stats->invalid_pkts;
+ ctx->stats.rx_sc_stats->InPktsLate += stats->late_pkts;
+ ctx->stats.rx_sc_stats->InPktsNotValid += stats->not_valid_pkts;
+ ctx->stats.rx_sc_stats->InPktsNotUsingSA += stats->not_using_sa;
+ ctx->stats.rx_sc_stats->InPktsUnusedSA += stats->unused_sa;
+ }
+
+ return ret;
+}
+
+static int aq_mdo_get_rx_sa_stats(struct macsec_context *ctx)
+{
+ struct aq_nic_s *nic = netdev_priv(ctx->netdev);
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ struct aq_macsec_rx_sa_stats *stats;
+ struct aq_hw_s *hw = nic->aq_hw;
+ struct aq_macsec_rxsc *aq_rxsc;
+ struct macsec_rx_sa *rx_sa;
+ unsigned int sa_idx;
+ int rxsc_idx;
+ u32 next_pn;
+ int ret;
+
+ rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, ctx->rx_sc);
+ if (rxsc_idx < 0)
+ return -EINVAL;
+
+ if (ctx->prepare)
+ return 0;
+
+ aq_rxsc = &cfg->aq_rxsc[rxsc_idx];
+ stats = &aq_rxsc->rx_sa_stats[ctx->sa.assoc_num];
+ sa_idx = aq_rxsc->hw_sc_idx | ctx->sa.assoc_num;
+ ret = aq_get_rxsa_stats(hw, sa_idx, stats);
+ if (ret)
+ return ret;
+
+ ctx->stats.rx_sa_stats->InPktsOK = stats->ok_pkts;
+ ctx->stats.rx_sa_stats->InPktsInvalid = stats->invalid_pkts;
+ ctx->stats.rx_sa_stats->InPktsNotValid = stats->not_valid_pkts;
+ ctx->stats.rx_sa_stats->InPktsNotUsingSA = stats->not_using_sa;
+ ctx->stats.rx_sa_stats->InPktsUnusedSA = stats->unused_sa;
+
+ rx_sa = rcu_dereference_bh(aq_rxsc->sw_rxsc->sa[ctx->sa.assoc_num]);
+ ret = aq_get_rxsa_next_pn(hw, sa_idx, &next_pn);
+ if (ret == 0) {
+ spin_lock_bh(&rx_sa->lock);
+ rx_sa->next_pn = next_pn;
+ spin_unlock_bh(&rx_sa->lock);
+ }
+
+ return ret;
+}
+
static int apply_txsc_cfg(struct aq_nic_s *nic, const int txsc_idx)
{
struct aq_macsec_txsc *aq_txsc = &nic->macsec_cfg->aq_txsc[txsc_idx];
.mdo_add_txsa = aq_mdo_add_txsa,
.mdo_upd_txsa = aq_mdo_upd_txsa,
.mdo_del_txsa = aq_mdo_del_txsa,
+ .mdo_get_dev_stats = aq_mdo_get_dev_stats,
+ .mdo_get_tx_sc_stats = aq_mdo_get_tx_sc_stats,
+ .mdo_get_tx_sa_stats = aq_mdo_get_tx_sa_stats,
+ .mdo_get_rx_sc_stats = aq_mdo_get_rx_sc_stats,
+ .mdo_get_rx_sa_stats = aq_mdo_get_rx_sa_stats,
};
int aq_macsec_init(struct aq_nic_s *nic)
aq_check_txsa_expiration(nic);
rtnl_unlock();
}
+
+int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
+{
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ int i, cnt = 0;
+
+ if (!cfg)
+ return 0;
+
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!test_bit(i, &cfg->rxsc_idx_busy))
+ continue;
+ cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy);
+ }
+
+ return cnt;
+}
+
+int aq_macsec_tx_sc_cnt(struct aq_nic_s *nic)
+{
+ if (!nic->macsec_cfg)
+ return 0;
+
+ return hweight_long(nic->macsec_cfg->txsc_idx_busy);
+}
+
+int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
+{
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ int i, cnt = 0;
+
+ if (!cfg)
+ return 0;
+
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!test_bit(i, &cfg->txsc_idx_busy))
+ continue;
+ cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy);
+ }
+
+ return cnt;
+}
+
+static int aq_macsec_update_stats(struct aq_nic_s *nic)
+{
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ struct aq_hw_s *hw = nic->aq_hw;
+ struct aq_macsec_txsc *aq_txsc;
+ struct aq_macsec_rxsc *aq_rxsc;
+ int i, sa_idx, assoc_num;
+ int ret = 0;
+
+ aq_get_macsec_common_stats(hw, &cfg->stats);
+
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!(cfg->txsc_idx_busy & BIT(i)))
+ continue;
+ aq_txsc = &cfg->aq_txsc[i];
+
+ ret = aq_get_txsc_stats(hw, aq_txsc->hw_sc_idx,
+ &aq_txsc->stats);
+ if (ret)
+ return ret;
+
+ for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
+ if (!test_bit(assoc_num, &aq_txsc->tx_sa_idx_busy))
+ continue;
+ sa_idx = aq_txsc->hw_sc_idx | assoc_num;
+ ret = aq_get_txsa_stats(hw, sa_idx,
+ &aq_txsc->tx_sa_stats[assoc_num]);
+ if (ret)
+ return ret;
+ }
+ }
+
+ for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ if (!(test_bit(i, &cfg->rxsc_idx_busy)))
+ continue;
+ aq_rxsc = &cfg->aq_rxsc[i];
+
+ for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
+ if (!test_bit(assoc_num, &aq_rxsc->rx_sa_idx_busy))
+ continue;
+ sa_idx = aq_rxsc->hw_sc_idx | assoc_num;
+
+ ret = aq_get_rxsa_stats(hw, sa_idx,
+ &aq_rxsc->rx_sa_stats[assoc_num]);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
+{
+ struct aq_macsec_cfg *cfg = nic->macsec_cfg;
+ struct aq_macsec_common_stats *common_stats;
+ struct aq_macsec_tx_sc_stats *txsc_stats;
+ struct aq_macsec_tx_sa_stats *txsa_stats;
+ struct aq_macsec_rx_sa_stats *rxsa_stats;
+ struct aq_macsec_txsc *aq_txsc;
+ struct aq_macsec_rxsc *aq_rxsc;
+ unsigned int assoc_num;
+ unsigned int sc_num;
+ unsigned int i = 0U;
+
+ if (!cfg)
+ return data;
+
+ aq_macsec_update_stats(nic);
+
+ common_stats = &cfg->stats;
+ data[i] = common_stats->in.ctl_pkts;
+ data[++i] = common_stats->in.tagged_miss_pkts;
+ data[++i] = common_stats->in.untagged_miss_pkts;
+ data[++i] = common_stats->in.notag_pkts;
+ data[++i] = common_stats->in.untagged_pkts;
+ data[++i] = common_stats->in.bad_tag_pkts;
+ data[++i] = common_stats->in.no_sci_pkts;
+ data[++i] = common_stats->in.unknown_sci_pkts;
+ data[++i] = common_stats->in.ctrl_prt_pass_pkts;
+ data[++i] = common_stats->in.unctrl_prt_pass_pkts;
+ data[++i] = common_stats->in.ctrl_prt_fail_pkts;
+ data[++i] = common_stats->in.unctrl_prt_fail_pkts;
+ data[++i] = common_stats->in.too_long_pkts;
+ data[++i] = common_stats->in.igpoc_ctl_pkts;
+ data[++i] = common_stats->in.ecc_error_pkts;
+ data[++i] = common_stats->in.unctrl_hit_drop_redir;
+ data[++i] = common_stats->out.ctl_pkts;
+ data[++i] = common_stats->out.unknown_sa_pkts;
+ data[++i] = common_stats->out.untagged_pkts;
+ data[++i] = common_stats->out.too_long;
+ data[++i] = common_stats->out.ecc_error_pkts;
+ data[++i] = common_stats->out.unctrl_hit_drop_redir;
+
+ for (sc_num = 0; sc_num < AQ_MACSEC_MAX_SC; sc_num++) {
+ if (!(test_bit(sc_num, &cfg->txsc_idx_busy)))
+ continue;
+
+ aq_txsc = &cfg->aq_txsc[sc_num];
+ txsc_stats = &aq_txsc->stats;
+
+ data[++i] = txsc_stats->sc_protected_pkts;
+ data[++i] = txsc_stats->sc_encrypted_pkts;
+ data[++i] = txsc_stats->sc_protected_octets;
+ data[++i] = txsc_stats->sc_encrypted_octets;
+
+ for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
+ if (!test_bit(assoc_num, &aq_txsc->tx_sa_idx_busy))
+ continue;
+
+ txsa_stats = &aq_txsc->tx_sa_stats[assoc_num];
+
+ data[++i] = txsa_stats->sa_hit_drop_redirect;
+ data[++i] = txsa_stats->sa_protected2_pkts;
+ data[++i] = txsa_stats->sa_protected_pkts;
+ data[++i] = txsa_stats->sa_encrypted_pkts;
+ }
+ }
+
+ for (sc_num = 0; sc_num < AQ_MACSEC_MAX_SC; sc_num++) {
+ if (!(test_bit(sc_num, &cfg->rxsc_idx_busy)))
+ continue;
+
+ aq_rxsc = &cfg->aq_rxsc[sc_num];
+
+ for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
+ if (!test_bit(assoc_num, &aq_rxsc->rx_sa_idx_busy))
+ continue;
+
+ rxsa_stats = &aq_rxsc->rx_sa_stats[assoc_num];
+
+ data[++i] = rxsa_stats->untagged_hit_pkts;
+ data[++i] = rxsa_stats->ctrl_hit_drop_redir_pkts;
+ data[++i] = rxsa_stats->not_using_sa;
+ data[++i] = rxsa_stats->unused_sa;
+ data[++i] = rxsa_stats->not_valid_pkts;
+ data[++i] = rxsa_stats->invalid_pkts;
+ data[++i] = rxsa_stats->ok_pkts;
+ data[++i] = rxsa_stats->late_pkts;
+ data[++i] = rxsa_stats->delayed_pkts;
+ data[++i] = rxsa_stats->unchecked_pkts;
+ data[++i] = rxsa_stats->validated_octets;
+ data[++i] = rxsa_stats->decrypted_octets;
+ }
+ }
+
+ i++;
+
+ data += i;
+
+ return data;
+}