18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/* Atlantic Network Driver
38c2ecf20Sopenharmony_ci * Copyright (C) 2020 Marvell International Ltd.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include "aq_macsec.h"
78c2ecf20Sopenharmony_ci#include "aq_nic.h"
88c2ecf20Sopenharmony_ci#include <linux/rtnetlink.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "macsec/macsec_api.h"
118c2ecf20Sopenharmony_ci#define AQ_MACSEC_KEY_LEN_128_BIT 16
128c2ecf20Sopenharmony_ci#define AQ_MACSEC_KEY_LEN_192_BIT 24
138c2ecf20Sopenharmony_ci#define AQ_MACSEC_KEY_LEN_256_BIT 32
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cienum aq_clear_type {
168c2ecf20Sopenharmony_ci	/* update HW configuration */
178c2ecf20Sopenharmony_ci	AQ_CLEAR_HW = BIT(0),
188c2ecf20Sopenharmony_ci	/* update SW configuration (busy bits, pointers) */
198c2ecf20Sopenharmony_ci	AQ_CLEAR_SW = BIT(1),
208c2ecf20Sopenharmony_ci	/* update both HW and SW configuration */
218c2ecf20Sopenharmony_ci	AQ_CLEAR_ALL = AQ_CLEAR_HW | AQ_CLEAR_SW,
228c2ecf20Sopenharmony_ci};
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistatic int aq_clear_txsc(struct aq_nic_s *nic, const int txsc_idx,
258c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type);
268c2ecf20Sopenharmony_cistatic int aq_clear_txsa(struct aq_nic_s *nic, struct aq_macsec_txsc *aq_txsc,
278c2ecf20Sopenharmony_ci			 const int sa_num, enum aq_clear_type clear_type);
288c2ecf20Sopenharmony_cistatic int aq_clear_rxsc(struct aq_nic_s *nic, const int rxsc_idx,
298c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type);
308c2ecf20Sopenharmony_cistatic int aq_clear_rxsa(struct aq_nic_s *nic, struct aq_macsec_rxsc *aq_rxsc,
318c2ecf20Sopenharmony_ci			 const int sa_num, enum aq_clear_type clear_type);
328c2ecf20Sopenharmony_cistatic int aq_clear_secy(struct aq_nic_s *nic, const struct macsec_secy *secy,
338c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type);
348c2ecf20Sopenharmony_cistatic int aq_apply_macsec_cfg(struct aq_nic_s *nic);
358c2ecf20Sopenharmony_cistatic int aq_apply_secy_cfg(struct aq_nic_s *nic,
368c2ecf20Sopenharmony_ci			     const struct macsec_secy *secy);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic void aq_ether_addr_to_mac(u32 mac[2], unsigned char *emac)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	u32 tmp[2] = { 0 };
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	memcpy(((u8 *)tmp) + 2, emac, ETH_ALEN);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	mac[0] = swab32(tmp[1]);
458c2ecf20Sopenharmony_ci	mac[1] = swab32(tmp[0]);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* There's a 1:1 mapping between SecY and TX SC */
498c2ecf20Sopenharmony_cistatic int aq_get_txsc_idx_from_secy(struct aq_macsec_cfg *macsec_cfg,
508c2ecf20Sopenharmony_ci				     const struct macsec_secy *secy)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	int i;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	if (unlikely(!secy))
558c2ecf20Sopenharmony_ci		return -1;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
588c2ecf20Sopenharmony_ci		if (macsec_cfg->aq_txsc[i].sw_secy == secy)
598c2ecf20Sopenharmony_ci			return i;
608c2ecf20Sopenharmony_ci	}
618c2ecf20Sopenharmony_ci	return -1;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic int aq_get_rxsc_idx_from_rxsc(struct aq_macsec_cfg *macsec_cfg,
658c2ecf20Sopenharmony_ci				     const struct macsec_rx_sc *rxsc)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	int i;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	if (unlikely(!rxsc))
708c2ecf20Sopenharmony_ci		return -1;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
738c2ecf20Sopenharmony_ci		if (macsec_cfg->aq_rxsc[i].sw_rxsc == rxsc)
748c2ecf20Sopenharmony_ci			return i;
758c2ecf20Sopenharmony_ci	}
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	return -1;
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic int aq_get_txsc_idx_from_sc_idx(const enum aq_macsec_sc_sa sc_sa,
818c2ecf20Sopenharmony_ci				       const int sc_idx)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	switch (sc_sa) {
848c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_4sa_8sc:
858c2ecf20Sopenharmony_ci		return sc_idx >> 2;
868c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_2sa_16sc:
878c2ecf20Sopenharmony_ci		return sc_idx >> 1;
888c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_1sa_32sc:
898c2ecf20Sopenharmony_ci		return sc_idx;
908c2ecf20Sopenharmony_ci	default:
918c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid sc_sa");
928c2ecf20Sopenharmony_ci	}
938c2ecf20Sopenharmony_ci	return -1;
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/* Rotate keys u32[8] */
978c2ecf20Sopenharmony_cistatic void aq_rotate_keys(u32 (*key)[8], const int key_len)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	u32 tmp[8] = { 0 };
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	memcpy(&tmp, key, sizeof(tmp));
1028c2ecf20Sopenharmony_ci	memset(*key, 0, sizeof(*key));
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	if (key_len == AQ_MACSEC_KEY_LEN_128_BIT) {
1058c2ecf20Sopenharmony_ci		(*key)[0] = swab32(tmp[3]);
1068c2ecf20Sopenharmony_ci		(*key)[1] = swab32(tmp[2]);
1078c2ecf20Sopenharmony_ci		(*key)[2] = swab32(tmp[1]);
1088c2ecf20Sopenharmony_ci		(*key)[3] = swab32(tmp[0]);
1098c2ecf20Sopenharmony_ci	} else if (key_len == AQ_MACSEC_KEY_LEN_192_BIT) {
1108c2ecf20Sopenharmony_ci		(*key)[0] = swab32(tmp[5]);
1118c2ecf20Sopenharmony_ci		(*key)[1] = swab32(tmp[4]);
1128c2ecf20Sopenharmony_ci		(*key)[2] = swab32(tmp[3]);
1138c2ecf20Sopenharmony_ci		(*key)[3] = swab32(tmp[2]);
1148c2ecf20Sopenharmony_ci		(*key)[4] = swab32(tmp[1]);
1158c2ecf20Sopenharmony_ci		(*key)[5] = swab32(tmp[0]);
1168c2ecf20Sopenharmony_ci	} else if (key_len == AQ_MACSEC_KEY_LEN_256_BIT) {
1178c2ecf20Sopenharmony_ci		(*key)[0] = swab32(tmp[7]);
1188c2ecf20Sopenharmony_ci		(*key)[1] = swab32(tmp[6]);
1198c2ecf20Sopenharmony_ci		(*key)[2] = swab32(tmp[5]);
1208c2ecf20Sopenharmony_ci		(*key)[3] = swab32(tmp[4]);
1218c2ecf20Sopenharmony_ci		(*key)[4] = swab32(tmp[3]);
1228c2ecf20Sopenharmony_ci		(*key)[5] = swab32(tmp[2]);
1238c2ecf20Sopenharmony_ci		(*key)[6] = swab32(tmp[1]);
1248c2ecf20Sopenharmony_ci		(*key)[7] = swab32(tmp[0]);
1258c2ecf20Sopenharmony_ci	} else {
1268c2ecf20Sopenharmony_ci		pr_warn("Rotate_keys: invalid key_len\n");
1278c2ecf20Sopenharmony_ci	}
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci#define STATS_2x32_TO_64(stat_field)                                           \
1318c2ecf20Sopenharmony_ci	(((u64)stat_field[1] << 32) | stat_field[0])
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic int aq_get_macsec_common_stats(struct aq_hw_s *hw,
1348c2ecf20Sopenharmony_ci				      struct aq_macsec_common_stats *stats)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	struct aq_mss_ingress_common_counters ingress_counters;
1378c2ecf20Sopenharmony_ci	struct aq_mss_egress_common_counters egress_counters;
1388c2ecf20Sopenharmony_ci	int ret;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	/* MACSEC counters */
1418c2ecf20Sopenharmony_ci	ret = aq_mss_get_ingress_common_counters(hw, &ingress_counters);
1428c2ecf20Sopenharmony_ci	if (unlikely(ret))
1438c2ecf20Sopenharmony_ci		return ret;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	stats->in.ctl_pkts = STATS_2x32_TO_64(ingress_counters.ctl_pkts);
1468c2ecf20Sopenharmony_ci	stats->in.tagged_miss_pkts =
1478c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.tagged_miss_pkts);
1488c2ecf20Sopenharmony_ci	stats->in.untagged_miss_pkts =
1498c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.untagged_miss_pkts);
1508c2ecf20Sopenharmony_ci	stats->in.notag_pkts = STATS_2x32_TO_64(ingress_counters.notag_pkts);
1518c2ecf20Sopenharmony_ci	stats->in.untagged_pkts =
1528c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.untagged_pkts);
1538c2ecf20Sopenharmony_ci	stats->in.bad_tag_pkts =
1548c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.bad_tag_pkts);
1558c2ecf20Sopenharmony_ci	stats->in.no_sci_pkts = STATS_2x32_TO_64(ingress_counters.no_sci_pkts);
1568c2ecf20Sopenharmony_ci	stats->in.unknown_sci_pkts =
1578c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.unknown_sci_pkts);
1588c2ecf20Sopenharmony_ci	stats->in.ctrl_prt_pass_pkts =
1598c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.ctrl_prt_pass_pkts);
1608c2ecf20Sopenharmony_ci	stats->in.unctrl_prt_pass_pkts =
1618c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.unctrl_prt_pass_pkts);
1628c2ecf20Sopenharmony_ci	stats->in.ctrl_prt_fail_pkts =
1638c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.ctrl_prt_fail_pkts);
1648c2ecf20Sopenharmony_ci	stats->in.unctrl_prt_fail_pkts =
1658c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.unctrl_prt_fail_pkts);
1668c2ecf20Sopenharmony_ci	stats->in.too_long_pkts =
1678c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.too_long_pkts);
1688c2ecf20Sopenharmony_ci	stats->in.igpoc_ctl_pkts =
1698c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.igpoc_ctl_pkts);
1708c2ecf20Sopenharmony_ci	stats->in.ecc_error_pkts =
1718c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.ecc_error_pkts);
1728c2ecf20Sopenharmony_ci	stats->in.unctrl_hit_drop_redir =
1738c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(ingress_counters.unctrl_hit_drop_redir);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_common_counters(hw, &egress_counters);
1768c2ecf20Sopenharmony_ci	if (unlikely(ret))
1778c2ecf20Sopenharmony_ci		return ret;
1788c2ecf20Sopenharmony_ci	stats->out.ctl_pkts = STATS_2x32_TO_64(egress_counters.ctl_pkt);
1798c2ecf20Sopenharmony_ci	stats->out.unknown_sa_pkts =
1808c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(egress_counters.unknown_sa_pkts);
1818c2ecf20Sopenharmony_ci	stats->out.untagged_pkts =
1828c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(egress_counters.untagged_pkts);
1838c2ecf20Sopenharmony_ci	stats->out.too_long = STATS_2x32_TO_64(egress_counters.too_long);
1848c2ecf20Sopenharmony_ci	stats->out.ecc_error_pkts =
1858c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(egress_counters.ecc_error_pkts);
1868c2ecf20Sopenharmony_ci	stats->out.unctrl_hit_drop_redir =
1878c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(egress_counters.unctrl_hit_drop_redir);
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	return 0;
1908c2ecf20Sopenharmony_ci}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_cistatic int aq_get_rxsa_stats(struct aq_hw_s *hw, const int sa_idx,
1938c2ecf20Sopenharmony_ci			     struct aq_macsec_rx_sa_stats *stats)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	struct aq_mss_ingress_sa_counters i_sa_counters;
1968c2ecf20Sopenharmony_ci	int ret;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	ret = aq_mss_get_ingress_sa_counters(hw, &i_sa_counters, sa_idx);
1998c2ecf20Sopenharmony_ci	if (unlikely(ret))
2008c2ecf20Sopenharmony_ci		return ret;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	stats->untagged_hit_pkts =
2038c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(i_sa_counters.untagged_hit_pkts);
2048c2ecf20Sopenharmony_ci	stats->ctrl_hit_drop_redir_pkts =
2058c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(i_sa_counters.ctrl_hit_drop_redir_pkts);
2068c2ecf20Sopenharmony_ci	stats->not_using_sa = STATS_2x32_TO_64(i_sa_counters.not_using_sa);
2078c2ecf20Sopenharmony_ci	stats->unused_sa = STATS_2x32_TO_64(i_sa_counters.unused_sa);
2088c2ecf20Sopenharmony_ci	stats->not_valid_pkts = STATS_2x32_TO_64(i_sa_counters.not_valid_pkts);
2098c2ecf20Sopenharmony_ci	stats->invalid_pkts = STATS_2x32_TO_64(i_sa_counters.invalid_pkts);
2108c2ecf20Sopenharmony_ci	stats->ok_pkts = STATS_2x32_TO_64(i_sa_counters.ok_pkts);
2118c2ecf20Sopenharmony_ci	stats->late_pkts = STATS_2x32_TO_64(i_sa_counters.late_pkts);
2128c2ecf20Sopenharmony_ci	stats->delayed_pkts = STATS_2x32_TO_64(i_sa_counters.delayed_pkts);
2138c2ecf20Sopenharmony_ci	stats->unchecked_pkts = STATS_2x32_TO_64(i_sa_counters.unchecked_pkts);
2148c2ecf20Sopenharmony_ci	stats->validated_octets =
2158c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(i_sa_counters.validated_octets);
2168c2ecf20Sopenharmony_ci	stats->decrypted_octets =
2178c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(i_sa_counters.decrypted_octets);
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	return 0;
2208c2ecf20Sopenharmony_ci}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_cistatic int aq_get_txsa_stats(struct aq_hw_s *hw, const int sa_idx,
2238c2ecf20Sopenharmony_ci			     struct aq_macsec_tx_sa_stats *stats)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	struct aq_mss_egress_sa_counters e_sa_counters;
2268c2ecf20Sopenharmony_ci	int ret;
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_sa_counters(hw, &e_sa_counters, sa_idx);
2298c2ecf20Sopenharmony_ci	if (unlikely(ret))
2308c2ecf20Sopenharmony_ci		return ret;
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	stats->sa_hit_drop_redirect =
2338c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sa_counters.sa_hit_drop_redirect);
2348c2ecf20Sopenharmony_ci	stats->sa_protected2_pkts =
2358c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sa_counters.sa_protected2_pkts);
2368c2ecf20Sopenharmony_ci	stats->sa_protected_pkts =
2378c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sa_counters.sa_protected_pkts);
2388c2ecf20Sopenharmony_ci	stats->sa_encrypted_pkts =
2398c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sa_counters.sa_encrypted_pkts);
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	return 0;
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cistatic int aq_get_txsa_next_pn(struct aq_hw_s *hw, const int sa_idx, u32 *pn)
2458c2ecf20Sopenharmony_ci{
2468c2ecf20Sopenharmony_ci	struct aq_mss_egress_sa_record sa_rec;
2478c2ecf20Sopenharmony_ci	int ret;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_sa_record(hw, &sa_rec, sa_idx);
2508c2ecf20Sopenharmony_ci	if (likely(!ret))
2518c2ecf20Sopenharmony_ci		*pn = sa_rec.next_pn;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	return ret;
2548c2ecf20Sopenharmony_ci}
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cistatic int aq_get_rxsa_next_pn(struct aq_hw_s *hw, const int sa_idx, u32 *pn)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	struct aq_mss_ingress_sa_record sa_rec;
2598c2ecf20Sopenharmony_ci	int ret;
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	ret = aq_mss_get_ingress_sa_record(hw, &sa_rec, sa_idx);
2628c2ecf20Sopenharmony_ci	if (likely(!ret))
2638c2ecf20Sopenharmony_ci		*pn = (!sa_rec.sat_nextpn) ? sa_rec.next_pn : 0;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	return ret;
2668c2ecf20Sopenharmony_ci}
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_cistatic int aq_get_txsc_stats(struct aq_hw_s *hw, const int sc_idx,
2698c2ecf20Sopenharmony_ci			     struct aq_macsec_tx_sc_stats *stats)
2708c2ecf20Sopenharmony_ci{
2718c2ecf20Sopenharmony_ci	struct aq_mss_egress_sc_counters e_sc_counters;
2728c2ecf20Sopenharmony_ci	int ret;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_sc_counters(hw, &e_sc_counters, sc_idx);
2758c2ecf20Sopenharmony_ci	if (unlikely(ret))
2768c2ecf20Sopenharmony_ci		return ret;
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci	stats->sc_protected_pkts =
2798c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sc_counters.sc_protected_pkts);
2808c2ecf20Sopenharmony_ci	stats->sc_encrypted_pkts =
2818c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sc_counters.sc_encrypted_pkts);
2828c2ecf20Sopenharmony_ci	stats->sc_protected_octets =
2838c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sc_counters.sc_protected_octets);
2848c2ecf20Sopenharmony_ci	stats->sc_encrypted_octets =
2858c2ecf20Sopenharmony_ci		STATS_2x32_TO_64(e_sc_counters.sc_encrypted_octets);
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	return 0;
2888c2ecf20Sopenharmony_ci}
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_cistatic int aq_mdo_dev_open(struct macsec_context *ctx)
2918c2ecf20Sopenharmony_ci{
2928c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
2938c2ecf20Sopenharmony_ci	int ret = 0;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	if (ctx->prepare)
2968c2ecf20Sopenharmony_ci		return 0;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev))
2998c2ecf20Sopenharmony_ci		ret = aq_apply_secy_cfg(nic, ctx->secy);
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	return ret;
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cistatic int aq_mdo_dev_stop(struct macsec_context *ctx)
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
3078c2ecf20Sopenharmony_ci	int i;
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	if (ctx->prepare)
3108c2ecf20Sopenharmony_ci		return 0;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
3138c2ecf20Sopenharmony_ci		if (nic->macsec_cfg->txsc_idx_busy & BIT(i))
3148c2ecf20Sopenharmony_ci			aq_clear_secy(nic, nic->macsec_cfg->aq_txsc[i].sw_secy,
3158c2ecf20Sopenharmony_ci				      AQ_CLEAR_HW);
3168c2ecf20Sopenharmony_ci	}
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	return 0;
3198c2ecf20Sopenharmony_ci}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_cistatic int aq_set_txsc(struct aq_nic_s *nic, const int txsc_idx)
3228c2ecf20Sopenharmony_ci{
3238c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc = &nic->macsec_cfg->aq_txsc[txsc_idx];
3248c2ecf20Sopenharmony_ci	struct aq_mss_egress_class_record tx_class_rec = { 0 };
3258c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = aq_txsc->sw_secy;
3268c2ecf20Sopenharmony_ci	struct aq_mss_egress_sc_record sc_rec = { 0 };
3278c2ecf20Sopenharmony_ci	unsigned int sc_idx = aq_txsc->hw_sc_idx;
3288c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
3298c2ecf20Sopenharmony_ci	int ret = 0;
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	aq_ether_addr_to_mac(tx_class_rec.mac_sa, secy->netdev->dev_addr);
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	put_unaligned_be64((__force u64)secy->sci, tx_class_rec.sci);
3348c2ecf20Sopenharmony_ci	tx_class_rec.sci_mask = 0;
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	tx_class_rec.sa_mask = 0x3f;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	tx_class_rec.action = 0; /* forward to SA/SC table */
3398c2ecf20Sopenharmony_ci	tx_class_rec.valid = 1;
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci	tx_class_rec.sc_idx = sc_idx;
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	tx_class_rec.sc_sa = nic->macsec_cfg->sc_sa;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	ret = aq_mss_set_egress_class_record(hw, &tx_class_rec, txsc_idx);
3468c2ecf20Sopenharmony_ci	if (ret)
3478c2ecf20Sopenharmony_ci		return ret;
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	sc_rec.protect = secy->protect_frames;
3508c2ecf20Sopenharmony_ci	if (secy->tx_sc.encrypt)
3518c2ecf20Sopenharmony_ci		sc_rec.tci |= BIT(1);
3528c2ecf20Sopenharmony_ci	if (secy->tx_sc.scb)
3538c2ecf20Sopenharmony_ci		sc_rec.tci |= BIT(2);
3548c2ecf20Sopenharmony_ci	if (secy->tx_sc.send_sci)
3558c2ecf20Sopenharmony_ci		sc_rec.tci |= BIT(3);
3568c2ecf20Sopenharmony_ci	if (secy->tx_sc.end_station)
3578c2ecf20Sopenharmony_ci		sc_rec.tci |= BIT(4);
3588c2ecf20Sopenharmony_ci	/* The C bit is clear if and only if the Secure Data is
3598c2ecf20Sopenharmony_ci	 * exactly the same as the User Data and the ICV is 16 octets long.
3608c2ecf20Sopenharmony_ci	 */
3618c2ecf20Sopenharmony_ci	if (!(secy->icv_len == 16 && !secy->tx_sc.encrypt))
3628c2ecf20Sopenharmony_ci		sc_rec.tci |= BIT(0);
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	sc_rec.an_roll = 0;
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci	switch (secy->key_len) {
3678c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_128_BIT:
3688c2ecf20Sopenharmony_ci		sc_rec.sak_len = 0;
3698c2ecf20Sopenharmony_ci		break;
3708c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_192_BIT:
3718c2ecf20Sopenharmony_ci		sc_rec.sak_len = 1;
3728c2ecf20Sopenharmony_ci		break;
3738c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_256_BIT:
3748c2ecf20Sopenharmony_ci		sc_rec.sak_len = 2;
3758c2ecf20Sopenharmony_ci		break;
3768c2ecf20Sopenharmony_ci	default:
3778c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid sc_sa");
3788c2ecf20Sopenharmony_ci		return -EINVAL;
3798c2ecf20Sopenharmony_ci	}
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci	sc_rec.curr_an = secy->tx_sc.encoding_sa;
3828c2ecf20Sopenharmony_ci	sc_rec.valid = 1;
3838c2ecf20Sopenharmony_ci	sc_rec.fresh = 1;
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	return aq_mss_set_egress_sc_record(hw, &sc_rec, sc_idx);
3868c2ecf20Sopenharmony_ci}
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_cistatic u32 aq_sc_idx_max(const enum aq_macsec_sc_sa sc_sa)
3898c2ecf20Sopenharmony_ci{
3908c2ecf20Sopenharmony_ci	u32 result = 0;
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	switch (sc_sa) {
3938c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_4sa_8sc:
3948c2ecf20Sopenharmony_ci		result = 8;
3958c2ecf20Sopenharmony_ci		break;
3968c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_2sa_16sc:
3978c2ecf20Sopenharmony_ci		result = 16;
3988c2ecf20Sopenharmony_ci		break;
3998c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_1sa_32sc:
4008c2ecf20Sopenharmony_ci		result = 32;
4018c2ecf20Sopenharmony_ci		break;
4028c2ecf20Sopenharmony_ci	default:
4038c2ecf20Sopenharmony_ci		break;
4048c2ecf20Sopenharmony_ci	}
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	return result;
4078c2ecf20Sopenharmony_ci}
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_cistatic u32 aq_to_hw_sc_idx(const u32 sc_idx, const enum aq_macsec_sc_sa sc_sa)
4108c2ecf20Sopenharmony_ci{
4118c2ecf20Sopenharmony_ci	switch (sc_sa) {
4128c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_4sa_8sc:
4138c2ecf20Sopenharmony_ci		return sc_idx << 2;
4148c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_2sa_16sc:
4158c2ecf20Sopenharmony_ci		return sc_idx << 1;
4168c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_1sa_32sc:
4178c2ecf20Sopenharmony_ci		return sc_idx;
4188c2ecf20Sopenharmony_ci	default:
4198c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid sc_sa");
4208c2ecf20Sopenharmony_ci	}
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci	return sc_idx;
4238c2ecf20Sopenharmony_ci}
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_cistatic enum aq_macsec_sc_sa sc_sa_from_num_an(const int num_an)
4268c2ecf20Sopenharmony_ci{
4278c2ecf20Sopenharmony_ci	enum aq_macsec_sc_sa sc_sa = aq_macsec_sa_sc_not_used;
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	switch (num_an) {
4308c2ecf20Sopenharmony_ci	case 4:
4318c2ecf20Sopenharmony_ci		sc_sa = aq_macsec_sa_sc_4sa_8sc;
4328c2ecf20Sopenharmony_ci		break;
4338c2ecf20Sopenharmony_ci	case 2:
4348c2ecf20Sopenharmony_ci		sc_sa = aq_macsec_sa_sc_2sa_16sc;
4358c2ecf20Sopenharmony_ci		break;
4368c2ecf20Sopenharmony_ci	case 1:
4378c2ecf20Sopenharmony_ci		sc_sa = aq_macsec_sa_sc_1sa_32sc;
4388c2ecf20Sopenharmony_ci		break;
4398c2ecf20Sopenharmony_ci	default:
4408c2ecf20Sopenharmony_ci		break;
4418c2ecf20Sopenharmony_ci	}
4428c2ecf20Sopenharmony_ci
4438c2ecf20Sopenharmony_ci	return sc_sa;
4448c2ecf20Sopenharmony_ci}
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_cistatic int aq_mdo_add_secy(struct macsec_context *ctx)
4478c2ecf20Sopenharmony_ci{
4488c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
4498c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
4508c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
4518c2ecf20Sopenharmony_ci	enum aq_macsec_sc_sa sc_sa;
4528c2ecf20Sopenharmony_ci	u32 txsc_idx;
4538c2ecf20Sopenharmony_ci	int ret = 0;
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	if (secy->xpn)
4568c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	sc_sa = sc_sa_from_num_an(MACSEC_NUM_AN);
4598c2ecf20Sopenharmony_ci	if (sc_sa == aq_macsec_sa_sc_not_used)
4608c2ecf20Sopenharmony_ci		return -EINVAL;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	if (hweight32(cfg->txsc_idx_busy) >= aq_sc_idx_max(sc_sa))
4638c2ecf20Sopenharmony_ci		return -ENOSPC;
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	txsc_idx = ffz(cfg->txsc_idx_busy);
4668c2ecf20Sopenharmony_ci	if (txsc_idx == AQ_MACSEC_MAX_SC)
4678c2ecf20Sopenharmony_ci		return -ENOSPC;
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	if (ctx->prepare)
4708c2ecf20Sopenharmony_ci		return 0;
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	cfg->sc_sa = sc_sa;
4738c2ecf20Sopenharmony_ci	cfg->aq_txsc[txsc_idx].hw_sc_idx = aq_to_hw_sc_idx(txsc_idx, sc_sa);
4748c2ecf20Sopenharmony_ci	cfg->aq_txsc[txsc_idx].sw_secy = secy;
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
4778c2ecf20Sopenharmony_ci		ret = aq_set_txsc(nic, txsc_idx);
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	set_bit(txsc_idx, &cfg->txsc_idx_busy);
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	return ret;
4828c2ecf20Sopenharmony_ci}
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_cistatic int aq_mdo_upd_secy(struct macsec_context *ctx)
4858c2ecf20Sopenharmony_ci{
4868c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
4878c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
4888c2ecf20Sopenharmony_ci	int txsc_idx;
4898c2ecf20Sopenharmony_ci	int ret = 0;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(nic->macsec_cfg, secy);
4928c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
4938c2ecf20Sopenharmony_ci		return -ENOENT;
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	if (ctx->prepare)
4968c2ecf20Sopenharmony_ci		return 0;
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
4998c2ecf20Sopenharmony_ci		ret = aq_set_txsc(nic, txsc_idx);
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	return ret;
5028c2ecf20Sopenharmony_ci}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_cistatic int aq_clear_txsc(struct aq_nic_s *nic, const int txsc_idx,
5058c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type)
5068c2ecf20Sopenharmony_ci{
5078c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *tx_sc = &nic->macsec_cfg->aq_txsc[txsc_idx];
5088c2ecf20Sopenharmony_ci	struct aq_mss_egress_class_record tx_class_rec = { 0 };
5098c2ecf20Sopenharmony_ci	struct aq_mss_egress_sc_record sc_rec = { 0 };
5108c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
5118c2ecf20Sopenharmony_ci	int ret = 0;
5128c2ecf20Sopenharmony_ci	int sa_num;
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_ci	for_each_set_bit (sa_num, &tx_sc->tx_sa_idx_busy, AQ_MACSEC_MAX_SA) {
5158c2ecf20Sopenharmony_ci		ret = aq_clear_txsa(nic, tx_sc, sa_num, clear_type);
5168c2ecf20Sopenharmony_ci		if (ret)
5178c2ecf20Sopenharmony_ci			return ret;
5188c2ecf20Sopenharmony_ci	}
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_HW) {
5218c2ecf20Sopenharmony_ci		ret = aq_mss_set_egress_class_record(hw, &tx_class_rec,
5228c2ecf20Sopenharmony_ci						     txsc_idx);
5238c2ecf20Sopenharmony_ci		if (ret)
5248c2ecf20Sopenharmony_ci			return ret;
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci		sc_rec.fresh = 1;
5278c2ecf20Sopenharmony_ci		ret = aq_mss_set_egress_sc_record(hw, &sc_rec,
5288c2ecf20Sopenharmony_ci						  tx_sc->hw_sc_idx);
5298c2ecf20Sopenharmony_ci		if (ret)
5308c2ecf20Sopenharmony_ci			return ret;
5318c2ecf20Sopenharmony_ci	}
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_SW) {
5348c2ecf20Sopenharmony_ci		clear_bit(txsc_idx, &nic->macsec_cfg->txsc_idx_busy);
5358c2ecf20Sopenharmony_ci		nic->macsec_cfg->aq_txsc[txsc_idx].sw_secy = NULL;
5368c2ecf20Sopenharmony_ci	}
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	return ret;
5398c2ecf20Sopenharmony_ci}
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_cistatic int aq_mdo_del_secy(struct macsec_context *ctx)
5428c2ecf20Sopenharmony_ci{
5438c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
5448c2ecf20Sopenharmony_ci	int ret = 0;
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	if (ctx->prepare)
5478c2ecf20Sopenharmony_ci		return 0;
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci	if (!nic->macsec_cfg)
5508c2ecf20Sopenharmony_ci		return 0;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	ret = aq_clear_secy(nic, ctx->secy, AQ_CLEAR_ALL);
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci	return ret;
5558c2ecf20Sopenharmony_ci}
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_cistatic int aq_update_txsa(struct aq_nic_s *nic, const unsigned int sc_idx,
5588c2ecf20Sopenharmony_ci			  const struct macsec_secy *secy,
5598c2ecf20Sopenharmony_ci			  const struct macsec_tx_sa *tx_sa,
5608c2ecf20Sopenharmony_ci			  const unsigned char *key, const unsigned char an)
5618c2ecf20Sopenharmony_ci{
5628c2ecf20Sopenharmony_ci	const u32 next_pn = tx_sa->next_pn_halves.lower;
5638c2ecf20Sopenharmony_ci	struct aq_mss_egress_sakey_record key_rec;
5648c2ecf20Sopenharmony_ci	const unsigned int sa_idx = sc_idx | an;
5658c2ecf20Sopenharmony_ci	struct aq_mss_egress_sa_record sa_rec;
5668c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
5678c2ecf20Sopenharmony_ci	int ret = 0;
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	memset(&sa_rec, 0, sizeof(sa_rec));
5708c2ecf20Sopenharmony_ci	sa_rec.valid = tx_sa->active;
5718c2ecf20Sopenharmony_ci	sa_rec.fresh = 1;
5728c2ecf20Sopenharmony_ci	sa_rec.next_pn = next_pn;
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	ret = aq_mss_set_egress_sa_record(hw, &sa_rec, sa_idx);
5758c2ecf20Sopenharmony_ci	if (ret)
5768c2ecf20Sopenharmony_ci		return ret;
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	if (!key)
5798c2ecf20Sopenharmony_ci		return ret;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	memset(&key_rec, 0, sizeof(key_rec));
5828c2ecf20Sopenharmony_ci	memcpy(&key_rec.key, key, secy->key_len);
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci	aq_rotate_keys(&key_rec.key, secy->key_len);
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ci	ret = aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx);
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci	memzero_explicit(&key_rec, sizeof(key_rec));
5898c2ecf20Sopenharmony_ci	return ret;
5908c2ecf20Sopenharmony_ci}
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_cistatic int aq_mdo_add_txsa(struct macsec_context *ctx)
5938c2ecf20Sopenharmony_ci{
5948c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
5958c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
5968c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
5978c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
5988c2ecf20Sopenharmony_ci	int txsc_idx;
5998c2ecf20Sopenharmony_ci	int ret = 0;
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(cfg, secy);
6028c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
6038c2ecf20Sopenharmony_ci		return -EINVAL;
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci	if (ctx->prepare)
6068c2ecf20Sopenharmony_ci		return 0;
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci	aq_txsc = &cfg->aq_txsc[txsc_idx];
6098c2ecf20Sopenharmony_ci	set_bit(ctx->sa.assoc_num, &aq_txsc->tx_sa_idx_busy);
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci	memcpy(aq_txsc->tx_sa_key[ctx->sa.assoc_num], ctx->sa.key,
6128c2ecf20Sopenharmony_ci	       secy->key_len);
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
6158c2ecf20Sopenharmony_ci		ret = aq_update_txsa(nic, aq_txsc->hw_sc_idx, secy,
6168c2ecf20Sopenharmony_ci				     ctx->sa.tx_sa, ctx->sa.key,
6178c2ecf20Sopenharmony_ci				     ctx->sa.assoc_num);
6188c2ecf20Sopenharmony_ci
6198c2ecf20Sopenharmony_ci	return ret;
6208c2ecf20Sopenharmony_ci}
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_cistatic int aq_mdo_upd_txsa(struct macsec_context *ctx)
6238c2ecf20Sopenharmony_ci{
6248c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
6258c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
6268c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
6278c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
6288c2ecf20Sopenharmony_ci	int txsc_idx;
6298c2ecf20Sopenharmony_ci	int ret = 0;
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(cfg, secy);
6328c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
6338c2ecf20Sopenharmony_ci		return -EINVAL;
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci	if (ctx->prepare)
6368c2ecf20Sopenharmony_ci		return 0;
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci	aq_txsc = &cfg->aq_txsc[txsc_idx];
6398c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
6408c2ecf20Sopenharmony_ci		ret = aq_update_txsa(nic, aq_txsc->hw_sc_idx, secy,
6418c2ecf20Sopenharmony_ci				     ctx->sa.tx_sa, NULL, ctx->sa.assoc_num);
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	return ret;
6448c2ecf20Sopenharmony_ci}
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_cistatic int aq_clear_txsa(struct aq_nic_s *nic, struct aq_macsec_txsc *aq_txsc,
6478c2ecf20Sopenharmony_ci			 const int sa_num, enum aq_clear_type clear_type)
6488c2ecf20Sopenharmony_ci{
6498c2ecf20Sopenharmony_ci	const int sa_idx = aq_txsc->hw_sc_idx | sa_num;
6508c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
6518c2ecf20Sopenharmony_ci	int ret = 0;
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_SW)
6548c2ecf20Sopenharmony_ci		clear_bit(sa_num, &aq_txsc->tx_sa_idx_busy);
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_ci	if ((clear_type & AQ_CLEAR_HW) && netif_carrier_ok(nic->ndev)) {
6578c2ecf20Sopenharmony_ci		struct aq_mss_egress_sakey_record key_rec;
6588c2ecf20Sopenharmony_ci		struct aq_mss_egress_sa_record sa_rec;
6598c2ecf20Sopenharmony_ci
6608c2ecf20Sopenharmony_ci		memset(&sa_rec, 0, sizeof(sa_rec));
6618c2ecf20Sopenharmony_ci		sa_rec.fresh = 1;
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci		ret = aq_mss_set_egress_sa_record(hw, &sa_rec, sa_idx);
6648c2ecf20Sopenharmony_ci		if (ret)
6658c2ecf20Sopenharmony_ci			return ret;
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_ci		memset(&key_rec, 0, sizeof(key_rec));
6688c2ecf20Sopenharmony_ci		return aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx);
6698c2ecf20Sopenharmony_ci	}
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	return 0;
6728c2ecf20Sopenharmony_ci}
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_cistatic int aq_mdo_del_txsa(struct macsec_context *ctx)
6758c2ecf20Sopenharmony_ci{
6768c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
6778c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
6788c2ecf20Sopenharmony_ci	int txsc_idx;
6798c2ecf20Sopenharmony_ci	int ret = 0;
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(cfg, ctx->secy);
6828c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
6838c2ecf20Sopenharmony_ci		return -EINVAL;
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci	if (ctx->prepare)
6868c2ecf20Sopenharmony_ci		return 0;
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci	ret = aq_clear_txsa(nic, &cfg->aq_txsc[txsc_idx], ctx->sa.assoc_num,
6898c2ecf20Sopenharmony_ci			    AQ_CLEAR_ALL);
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	return ret;
6928c2ecf20Sopenharmony_ci}
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_cistatic int aq_rxsc_validate_frames(const enum macsec_validation_type validate)
6958c2ecf20Sopenharmony_ci{
6968c2ecf20Sopenharmony_ci	switch (validate) {
6978c2ecf20Sopenharmony_ci	case MACSEC_VALIDATE_DISABLED:
6988c2ecf20Sopenharmony_ci		return 2;
6998c2ecf20Sopenharmony_ci	case MACSEC_VALIDATE_CHECK:
7008c2ecf20Sopenharmony_ci		return 1;
7018c2ecf20Sopenharmony_ci	case MACSEC_VALIDATE_STRICT:
7028c2ecf20Sopenharmony_ci		return 0;
7038c2ecf20Sopenharmony_ci	default:
7048c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid validation type");
7058c2ecf20Sopenharmony_ci	}
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	return 0;
7088c2ecf20Sopenharmony_ci}
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_cistatic int aq_set_rxsc(struct aq_nic_s *nic, const u32 rxsc_idx)
7118c2ecf20Sopenharmony_ci{
7128c2ecf20Sopenharmony_ci	const struct aq_macsec_rxsc *aq_rxsc =
7138c2ecf20Sopenharmony_ci		&nic->macsec_cfg->aq_rxsc[rxsc_idx];
7148c2ecf20Sopenharmony_ci	struct aq_mss_ingress_preclass_record pre_class_record;
7158c2ecf20Sopenharmony_ci	const struct macsec_rx_sc *rx_sc = aq_rxsc->sw_rxsc;
7168c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = aq_rxsc->sw_secy;
7178c2ecf20Sopenharmony_ci	const u32 hw_sc_idx = aq_rxsc->hw_sc_idx;
7188c2ecf20Sopenharmony_ci	struct aq_mss_ingress_sc_record sc_record;
7198c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
7208c2ecf20Sopenharmony_ci	int ret = 0;
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_ci	memset(&pre_class_record, 0, sizeof(pre_class_record));
7238c2ecf20Sopenharmony_ci	put_unaligned_be64((__force u64)rx_sc->sci, pre_class_record.sci);
7248c2ecf20Sopenharmony_ci	pre_class_record.sci_mask = 0xff;
7258c2ecf20Sopenharmony_ci	/* match all MACSEC ethertype packets */
7268c2ecf20Sopenharmony_ci	pre_class_record.eth_type = ETH_P_MACSEC;
7278c2ecf20Sopenharmony_ci	pre_class_record.eth_type_mask = 0x3;
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci	aq_ether_addr_to_mac(pre_class_record.mac_sa, (char *)&rx_sc->sci);
7308c2ecf20Sopenharmony_ci	pre_class_record.sa_mask = 0x3f;
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci	pre_class_record.an_mask = nic->macsec_cfg->sc_sa;
7338c2ecf20Sopenharmony_ci	pre_class_record.sc_idx = hw_sc_idx;
7348c2ecf20Sopenharmony_ci	/* strip SecTAG & forward for decryption */
7358c2ecf20Sopenharmony_ci	pre_class_record.action = 0x0;
7368c2ecf20Sopenharmony_ci	pre_class_record.valid = 1;
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci	ret = aq_mss_set_ingress_preclass_record(hw, &pre_class_record,
7398c2ecf20Sopenharmony_ci						 2 * rxsc_idx + 1);
7408c2ecf20Sopenharmony_ci	if (ret)
7418c2ecf20Sopenharmony_ci		return ret;
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci	/* If SCI is absent, then match by SA alone */
7448c2ecf20Sopenharmony_ci	pre_class_record.sci_mask = 0;
7458c2ecf20Sopenharmony_ci	pre_class_record.sci_from_table = 1;
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci	ret = aq_mss_set_ingress_preclass_record(hw, &pre_class_record,
7488c2ecf20Sopenharmony_ci						 2 * rxsc_idx);
7498c2ecf20Sopenharmony_ci	if (ret)
7508c2ecf20Sopenharmony_ci		return ret;
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_ci	memset(&sc_record, 0, sizeof(sc_record));
7538c2ecf20Sopenharmony_ci	sc_record.validate_frames =
7548c2ecf20Sopenharmony_ci		aq_rxsc_validate_frames(secy->validate_frames);
7558c2ecf20Sopenharmony_ci	if (secy->replay_protect) {
7568c2ecf20Sopenharmony_ci		sc_record.replay_protect = 1;
7578c2ecf20Sopenharmony_ci		sc_record.anti_replay_window = secy->replay_window;
7588c2ecf20Sopenharmony_ci	}
7598c2ecf20Sopenharmony_ci	sc_record.valid = 1;
7608c2ecf20Sopenharmony_ci	sc_record.fresh = 1;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci	ret = aq_mss_set_ingress_sc_record(hw, &sc_record, hw_sc_idx);
7638c2ecf20Sopenharmony_ci	if (ret)
7648c2ecf20Sopenharmony_ci		return ret;
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_ci	return ret;
7678c2ecf20Sopenharmony_ci}
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_cistatic int aq_mdo_add_rxsc(struct macsec_context *ctx)
7708c2ecf20Sopenharmony_ci{
7718c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
7728c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
7738c2ecf20Sopenharmony_ci	const u32 rxsc_idx_max = aq_sc_idx_max(cfg->sc_sa);
7748c2ecf20Sopenharmony_ci	u32 rxsc_idx;
7758c2ecf20Sopenharmony_ci	int ret = 0;
7768c2ecf20Sopenharmony_ci
7778c2ecf20Sopenharmony_ci	if (hweight32(cfg->rxsc_idx_busy) >= rxsc_idx_max)
7788c2ecf20Sopenharmony_ci		return -ENOSPC;
7798c2ecf20Sopenharmony_ci
7808c2ecf20Sopenharmony_ci	rxsc_idx = ffz(cfg->rxsc_idx_busy);
7818c2ecf20Sopenharmony_ci	if (rxsc_idx >= rxsc_idx_max)
7828c2ecf20Sopenharmony_ci		return -ENOSPC;
7838c2ecf20Sopenharmony_ci
7848c2ecf20Sopenharmony_ci	if (ctx->prepare)
7858c2ecf20Sopenharmony_ci		return 0;
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci	cfg->aq_rxsc[rxsc_idx].hw_sc_idx = aq_to_hw_sc_idx(rxsc_idx,
7888c2ecf20Sopenharmony_ci							   cfg->sc_sa);
7898c2ecf20Sopenharmony_ci	cfg->aq_rxsc[rxsc_idx].sw_secy = ctx->secy;
7908c2ecf20Sopenharmony_ci	cfg->aq_rxsc[rxsc_idx].sw_rxsc = ctx->rx_sc;
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(ctx->secy->netdev))
7938c2ecf20Sopenharmony_ci		ret = aq_set_rxsc(nic, rxsc_idx);
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci	if (ret < 0)
7968c2ecf20Sopenharmony_ci		return ret;
7978c2ecf20Sopenharmony_ci
7988c2ecf20Sopenharmony_ci	set_bit(rxsc_idx, &cfg->rxsc_idx_busy);
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	return 0;
8018c2ecf20Sopenharmony_ci}
8028c2ecf20Sopenharmony_ci
8038c2ecf20Sopenharmony_cistatic int aq_mdo_upd_rxsc(struct macsec_context *ctx)
8048c2ecf20Sopenharmony_ci{
8058c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
8068c2ecf20Sopenharmony_ci	int rxsc_idx;
8078c2ecf20Sopenharmony_ci	int ret = 0;
8088c2ecf20Sopenharmony_ci
8098c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(nic->macsec_cfg, ctx->rx_sc);
8108c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
8118c2ecf20Sopenharmony_ci		return -ENOENT;
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_ci	if (ctx->prepare)
8148c2ecf20Sopenharmony_ci		return 0;
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(ctx->secy->netdev))
8178c2ecf20Sopenharmony_ci		ret = aq_set_rxsc(nic, rxsc_idx);
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ci	return ret;
8208c2ecf20Sopenharmony_ci}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_cistatic int aq_clear_rxsc(struct aq_nic_s *nic, const int rxsc_idx,
8238c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type)
8248c2ecf20Sopenharmony_ci{
8258c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *rx_sc = &nic->macsec_cfg->aq_rxsc[rxsc_idx];
8268c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
8278c2ecf20Sopenharmony_ci	int ret = 0;
8288c2ecf20Sopenharmony_ci	int sa_num;
8298c2ecf20Sopenharmony_ci
8308c2ecf20Sopenharmony_ci	for_each_set_bit (sa_num, &rx_sc->rx_sa_idx_busy, AQ_MACSEC_MAX_SA) {
8318c2ecf20Sopenharmony_ci		ret = aq_clear_rxsa(nic, rx_sc, sa_num, clear_type);
8328c2ecf20Sopenharmony_ci		if (ret)
8338c2ecf20Sopenharmony_ci			return ret;
8348c2ecf20Sopenharmony_ci	}
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_HW) {
8378c2ecf20Sopenharmony_ci		struct aq_mss_ingress_preclass_record pre_class_record;
8388c2ecf20Sopenharmony_ci		struct aq_mss_ingress_sc_record sc_record;
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci		memset(&pre_class_record, 0, sizeof(pre_class_record));
8418c2ecf20Sopenharmony_ci		memset(&sc_record, 0, sizeof(sc_record));
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci		ret = aq_mss_set_ingress_preclass_record(hw, &pre_class_record,
8448c2ecf20Sopenharmony_ci							 2 * rxsc_idx);
8458c2ecf20Sopenharmony_ci		if (ret)
8468c2ecf20Sopenharmony_ci			return ret;
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci		ret = aq_mss_set_ingress_preclass_record(hw, &pre_class_record,
8498c2ecf20Sopenharmony_ci							 2 * rxsc_idx + 1);
8508c2ecf20Sopenharmony_ci		if (ret)
8518c2ecf20Sopenharmony_ci			return ret;
8528c2ecf20Sopenharmony_ci
8538c2ecf20Sopenharmony_ci		sc_record.fresh = 1;
8548c2ecf20Sopenharmony_ci		ret = aq_mss_set_ingress_sc_record(hw, &sc_record,
8558c2ecf20Sopenharmony_ci						   rx_sc->hw_sc_idx);
8568c2ecf20Sopenharmony_ci		if (ret)
8578c2ecf20Sopenharmony_ci			return ret;
8588c2ecf20Sopenharmony_ci	}
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_SW) {
8618c2ecf20Sopenharmony_ci		clear_bit(rxsc_idx, &nic->macsec_cfg->rxsc_idx_busy);
8628c2ecf20Sopenharmony_ci		rx_sc->sw_secy = NULL;
8638c2ecf20Sopenharmony_ci		rx_sc->sw_rxsc = NULL;
8648c2ecf20Sopenharmony_ci	}
8658c2ecf20Sopenharmony_ci
8668c2ecf20Sopenharmony_ci	return ret;
8678c2ecf20Sopenharmony_ci}
8688c2ecf20Sopenharmony_ci
8698c2ecf20Sopenharmony_cistatic int aq_mdo_del_rxsc(struct macsec_context *ctx)
8708c2ecf20Sopenharmony_ci{
8718c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
8728c2ecf20Sopenharmony_ci	enum aq_clear_type clear_type = AQ_CLEAR_SW;
8738c2ecf20Sopenharmony_ci	int rxsc_idx;
8748c2ecf20Sopenharmony_ci	int ret = 0;
8758c2ecf20Sopenharmony_ci
8768c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(nic->macsec_cfg, ctx->rx_sc);
8778c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
8788c2ecf20Sopenharmony_ci		return -ENOENT;
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci	if (ctx->prepare)
8818c2ecf20Sopenharmony_ci		return 0;
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev))
8848c2ecf20Sopenharmony_ci		clear_type = AQ_CLEAR_ALL;
8858c2ecf20Sopenharmony_ci
8868c2ecf20Sopenharmony_ci	ret = aq_clear_rxsc(nic, rxsc_idx, clear_type);
8878c2ecf20Sopenharmony_ci
8888c2ecf20Sopenharmony_ci	return ret;
8898c2ecf20Sopenharmony_ci}
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_cistatic int aq_update_rxsa(struct aq_nic_s *nic, const unsigned int sc_idx,
8928c2ecf20Sopenharmony_ci			  const struct macsec_secy *secy,
8938c2ecf20Sopenharmony_ci			  const struct macsec_rx_sa *rx_sa,
8948c2ecf20Sopenharmony_ci			  const unsigned char *key, const unsigned char an)
8958c2ecf20Sopenharmony_ci{
8968c2ecf20Sopenharmony_ci	struct aq_mss_ingress_sakey_record sa_key_record;
8978c2ecf20Sopenharmony_ci	const u32 next_pn = rx_sa->next_pn_halves.lower;
8988c2ecf20Sopenharmony_ci	struct aq_mss_ingress_sa_record sa_record;
8998c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
9008c2ecf20Sopenharmony_ci	const int sa_idx = sc_idx | an;
9018c2ecf20Sopenharmony_ci	int ret = 0;
9028c2ecf20Sopenharmony_ci
9038c2ecf20Sopenharmony_ci	memset(&sa_record, 0, sizeof(sa_record));
9048c2ecf20Sopenharmony_ci	sa_record.valid = rx_sa->active;
9058c2ecf20Sopenharmony_ci	sa_record.fresh = 1;
9068c2ecf20Sopenharmony_ci	sa_record.next_pn = next_pn;
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci	ret = aq_mss_set_ingress_sa_record(hw, &sa_record, sa_idx);
9098c2ecf20Sopenharmony_ci	if (ret)
9108c2ecf20Sopenharmony_ci		return ret;
9118c2ecf20Sopenharmony_ci
9128c2ecf20Sopenharmony_ci	if (!key)
9138c2ecf20Sopenharmony_ci		return ret;
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_ci	memset(&sa_key_record, 0, sizeof(sa_key_record));
9168c2ecf20Sopenharmony_ci	memcpy(&sa_key_record.key, key, secy->key_len);
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_ci	switch (secy->key_len) {
9198c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_128_BIT:
9208c2ecf20Sopenharmony_ci		sa_key_record.key_len = 0;
9218c2ecf20Sopenharmony_ci		break;
9228c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_192_BIT:
9238c2ecf20Sopenharmony_ci		sa_key_record.key_len = 1;
9248c2ecf20Sopenharmony_ci		break;
9258c2ecf20Sopenharmony_ci	case AQ_MACSEC_KEY_LEN_256_BIT:
9268c2ecf20Sopenharmony_ci		sa_key_record.key_len = 2;
9278c2ecf20Sopenharmony_ci		break;
9288c2ecf20Sopenharmony_ci	default:
9298c2ecf20Sopenharmony_ci		return -1;
9308c2ecf20Sopenharmony_ci	}
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_ci	aq_rotate_keys(&sa_key_record.key, secy->key_len);
9338c2ecf20Sopenharmony_ci
9348c2ecf20Sopenharmony_ci	ret = aq_mss_set_ingress_sakey_record(hw, &sa_key_record, sa_idx);
9358c2ecf20Sopenharmony_ci
9368c2ecf20Sopenharmony_ci	memzero_explicit(&sa_key_record, sizeof(sa_key_record));
9378c2ecf20Sopenharmony_ci	return ret;
9388c2ecf20Sopenharmony_ci}
9398c2ecf20Sopenharmony_ci
9408c2ecf20Sopenharmony_cistatic int aq_mdo_add_rxsa(struct macsec_context *ctx)
9418c2ecf20Sopenharmony_ci{
9428c2ecf20Sopenharmony_ci	const struct macsec_rx_sc *rx_sc = ctx->sa.rx_sa->sc;
9438c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
9448c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
9458c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc;
9468c2ecf20Sopenharmony_ci	int rxsc_idx;
9478c2ecf20Sopenharmony_ci	int ret = 0;
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(nic->macsec_cfg, rx_sc);
9508c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
9518c2ecf20Sopenharmony_ci		return -EINVAL;
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	if (ctx->prepare)
9548c2ecf20Sopenharmony_ci		return 0;
9558c2ecf20Sopenharmony_ci
9568c2ecf20Sopenharmony_ci	aq_rxsc = &nic->macsec_cfg->aq_rxsc[rxsc_idx];
9578c2ecf20Sopenharmony_ci	set_bit(ctx->sa.assoc_num, &aq_rxsc->rx_sa_idx_busy);
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_ci	memcpy(aq_rxsc->rx_sa_key[ctx->sa.assoc_num], ctx->sa.key,
9608c2ecf20Sopenharmony_ci	       secy->key_len);
9618c2ecf20Sopenharmony_ci
9628c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
9638c2ecf20Sopenharmony_ci		ret = aq_update_rxsa(nic, aq_rxsc->hw_sc_idx, secy,
9648c2ecf20Sopenharmony_ci				     ctx->sa.rx_sa, ctx->sa.key,
9658c2ecf20Sopenharmony_ci				     ctx->sa.assoc_num);
9668c2ecf20Sopenharmony_ci
9678c2ecf20Sopenharmony_ci	return ret;
9688c2ecf20Sopenharmony_ci}
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_cistatic int aq_mdo_upd_rxsa(struct macsec_context *ctx)
9718c2ecf20Sopenharmony_ci{
9728c2ecf20Sopenharmony_ci	const struct macsec_rx_sc *rx_sc = ctx->sa.rx_sa->sc;
9738c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
9748c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
9758c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = ctx->secy;
9768c2ecf20Sopenharmony_ci	int rxsc_idx;
9778c2ecf20Sopenharmony_ci	int ret = 0;
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, rx_sc);
9808c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
9818c2ecf20Sopenharmony_ci		return -EINVAL;
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	if (ctx->prepare)
9848c2ecf20Sopenharmony_ci		return 0;
9858c2ecf20Sopenharmony_ci
9868c2ecf20Sopenharmony_ci	if (netif_carrier_ok(nic->ndev) && netif_running(secy->netdev))
9878c2ecf20Sopenharmony_ci		ret = aq_update_rxsa(nic, cfg->aq_rxsc[rxsc_idx].hw_sc_idx,
9888c2ecf20Sopenharmony_ci				     secy, ctx->sa.rx_sa, NULL,
9898c2ecf20Sopenharmony_ci				     ctx->sa.assoc_num);
9908c2ecf20Sopenharmony_ci
9918c2ecf20Sopenharmony_ci	return ret;
9928c2ecf20Sopenharmony_ci}
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_cistatic int aq_clear_rxsa(struct aq_nic_s *nic, struct aq_macsec_rxsc *aq_rxsc,
9958c2ecf20Sopenharmony_ci			 const int sa_num, enum aq_clear_type clear_type)
9968c2ecf20Sopenharmony_ci{
9978c2ecf20Sopenharmony_ci	int sa_idx = aq_rxsc->hw_sc_idx | sa_num;
9988c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
9998c2ecf20Sopenharmony_ci	int ret = 0;
10008c2ecf20Sopenharmony_ci
10018c2ecf20Sopenharmony_ci	if (clear_type & AQ_CLEAR_SW)
10028c2ecf20Sopenharmony_ci		clear_bit(sa_num, &aq_rxsc->rx_sa_idx_busy);
10038c2ecf20Sopenharmony_ci
10048c2ecf20Sopenharmony_ci	if ((clear_type & AQ_CLEAR_HW) && netif_carrier_ok(nic->ndev)) {
10058c2ecf20Sopenharmony_ci		struct aq_mss_ingress_sakey_record sa_key_record;
10068c2ecf20Sopenharmony_ci		struct aq_mss_ingress_sa_record sa_record;
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci		memset(&sa_key_record, 0, sizeof(sa_key_record));
10098c2ecf20Sopenharmony_ci		memset(&sa_record, 0, sizeof(sa_record));
10108c2ecf20Sopenharmony_ci		sa_record.fresh = 1;
10118c2ecf20Sopenharmony_ci		ret = aq_mss_set_ingress_sa_record(hw, &sa_record, sa_idx);
10128c2ecf20Sopenharmony_ci		if (ret)
10138c2ecf20Sopenharmony_ci			return ret;
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci		return aq_mss_set_ingress_sakey_record(hw, &sa_key_record,
10168c2ecf20Sopenharmony_ci						       sa_idx);
10178c2ecf20Sopenharmony_ci	}
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ci	return ret;
10208c2ecf20Sopenharmony_ci}
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_cistatic int aq_mdo_del_rxsa(struct macsec_context *ctx)
10238c2ecf20Sopenharmony_ci{
10248c2ecf20Sopenharmony_ci	const struct macsec_rx_sc *rx_sc = ctx->sa.rx_sa->sc;
10258c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
10268c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
10278c2ecf20Sopenharmony_ci	int rxsc_idx;
10288c2ecf20Sopenharmony_ci	int ret = 0;
10298c2ecf20Sopenharmony_ci
10308c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, rx_sc);
10318c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
10328c2ecf20Sopenharmony_ci		return -EINVAL;
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci	if (ctx->prepare)
10358c2ecf20Sopenharmony_ci		return 0;
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	ret = aq_clear_rxsa(nic, &cfg->aq_rxsc[rxsc_idx], ctx->sa.assoc_num,
10388c2ecf20Sopenharmony_ci			    AQ_CLEAR_ALL);
10398c2ecf20Sopenharmony_ci
10408c2ecf20Sopenharmony_ci	return ret;
10418c2ecf20Sopenharmony_ci}
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_cistatic int aq_mdo_get_dev_stats(struct macsec_context *ctx)
10448c2ecf20Sopenharmony_ci{
10458c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
10468c2ecf20Sopenharmony_ci	struct aq_macsec_common_stats *stats = &nic->macsec_cfg->stats;
10478c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
10488c2ecf20Sopenharmony_ci
10498c2ecf20Sopenharmony_ci	if (ctx->prepare)
10508c2ecf20Sopenharmony_ci		return 0;
10518c2ecf20Sopenharmony_ci
10528c2ecf20Sopenharmony_ci	aq_get_macsec_common_stats(hw, stats);
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->OutPktsUntagged = stats->out.untagged_pkts;
10558c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsUntagged = stats->in.untagged_pkts;
10568c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->OutPktsTooLong = stats->out.too_long;
10578c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsNoTag = stats->in.notag_pkts;
10588c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsBadTag = stats->in.bad_tag_pkts;
10598c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsUnknownSCI = stats->in.unknown_sci_pkts;
10608c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsNoSCI = stats->in.no_sci_pkts;
10618c2ecf20Sopenharmony_ci	ctx->stats.dev_stats->InPktsOverrun = 0;
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci	return 0;
10648c2ecf20Sopenharmony_ci}
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_cistatic int aq_mdo_get_tx_sc_stats(struct macsec_context *ctx)
10678c2ecf20Sopenharmony_ci{
10688c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
10698c2ecf20Sopenharmony_ci	struct aq_macsec_tx_sc_stats *stats;
10708c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
10718c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
10728c2ecf20Sopenharmony_ci	int txsc_idx;
10738c2ecf20Sopenharmony_ci
10748c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(nic->macsec_cfg, ctx->secy);
10758c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
10768c2ecf20Sopenharmony_ci		return -ENOENT;
10778c2ecf20Sopenharmony_ci
10788c2ecf20Sopenharmony_ci	if (ctx->prepare)
10798c2ecf20Sopenharmony_ci		return 0;
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci	aq_txsc = &nic->macsec_cfg->aq_txsc[txsc_idx];
10828c2ecf20Sopenharmony_ci	stats = &aq_txsc->stats;
10838c2ecf20Sopenharmony_ci	aq_get_txsc_stats(hw, aq_txsc->hw_sc_idx, stats);
10848c2ecf20Sopenharmony_ci
10858c2ecf20Sopenharmony_ci	ctx->stats.tx_sc_stats->OutPktsProtected = stats->sc_protected_pkts;
10868c2ecf20Sopenharmony_ci	ctx->stats.tx_sc_stats->OutPktsEncrypted = stats->sc_encrypted_pkts;
10878c2ecf20Sopenharmony_ci	ctx->stats.tx_sc_stats->OutOctetsProtected = stats->sc_protected_octets;
10888c2ecf20Sopenharmony_ci	ctx->stats.tx_sc_stats->OutOctetsEncrypted = stats->sc_encrypted_octets;
10898c2ecf20Sopenharmony_ci
10908c2ecf20Sopenharmony_ci	return 0;
10918c2ecf20Sopenharmony_ci}
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_cistatic int aq_mdo_get_tx_sa_stats(struct macsec_context *ctx)
10948c2ecf20Sopenharmony_ci{
10958c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
10968c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
10978c2ecf20Sopenharmony_ci	struct aq_macsec_tx_sa_stats *stats;
10988c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
10998c2ecf20Sopenharmony_ci	const struct macsec_secy *secy;
11008c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
11018c2ecf20Sopenharmony_ci	struct macsec_tx_sa *tx_sa;
11028c2ecf20Sopenharmony_ci	unsigned int sa_idx;
11038c2ecf20Sopenharmony_ci	int txsc_idx;
11048c2ecf20Sopenharmony_ci	u32 next_pn;
11058c2ecf20Sopenharmony_ci	int ret;
11068c2ecf20Sopenharmony_ci
11078c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(cfg, ctx->secy);
11088c2ecf20Sopenharmony_ci	if (txsc_idx < 0)
11098c2ecf20Sopenharmony_ci		return -EINVAL;
11108c2ecf20Sopenharmony_ci
11118c2ecf20Sopenharmony_ci	if (ctx->prepare)
11128c2ecf20Sopenharmony_ci		return 0;
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ci	aq_txsc = &cfg->aq_txsc[txsc_idx];
11158c2ecf20Sopenharmony_ci	sa_idx = aq_txsc->hw_sc_idx | ctx->sa.assoc_num;
11168c2ecf20Sopenharmony_ci	stats = &aq_txsc->tx_sa_stats[ctx->sa.assoc_num];
11178c2ecf20Sopenharmony_ci	ret = aq_get_txsa_stats(hw, sa_idx, stats);
11188c2ecf20Sopenharmony_ci	if (ret)
11198c2ecf20Sopenharmony_ci		return ret;
11208c2ecf20Sopenharmony_ci
11218c2ecf20Sopenharmony_ci	ctx->stats.tx_sa_stats->OutPktsProtected = stats->sa_protected_pkts;
11228c2ecf20Sopenharmony_ci	ctx->stats.tx_sa_stats->OutPktsEncrypted = stats->sa_encrypted_pkts;
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ci	secy = aq_txsc->sw_secy;
11258c2ecf20Sopenharmony_ci	tx_sa = rcu_dereference_bh(secy->tx_sc.sa[ctx->sa.assoc_num]);
11268c2ecf20Sopenharmony_ci	ret = aq_get_txsa_next_pn(hw, sa_idx, &next_pn);
11278c2ecf20Sopenharmony_ci	if (ret == 0) {
11288c2ecf20Sopenharmony_ci		spin_lock_bh(&tx_sa->lock);
11298c2ecf20Sopenharmony_ci		tx_sa->next_pn = next_pn;
11308c2ecf20Sopenharmony_ci		spin_unlock_bh(&tx_sa->lock);
11318c2ecf20Sopenharmony_ci	}
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_ci	return ret;
11348c2ecf20Sopenharmony_ci}
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_cistatic int aq_mdo_get_rx_sc_stats(struct macsec_context *ctx)
11378c2ecf20Sopenharmony_ci{
11388c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
11398c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
11408c2ecf20Sopenharmony_ci	struct aq_macsec_rx_sa_stats *stats;
11418c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
11428c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc;
11438c2ecf20Sopenharmony_ci	unsigned int sa_idx;
11448c2ecf20Sopenharmony_ci	int rxsc_idx;
11458c2ecf20Sopenharmony_ci	int ret = 0;
11468c2ecf20Sopenharmony_ci	int i;
11478c2ecf20Sopenharmony_ci
11488c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, ctx->rx_sc);
11498c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
11508c2ecf20Sopenharmony_ci		return -ENOENT;
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_ci	if (ctx->prepare)
11538c2ecf20Sopenharmony_ci		return 0;
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ci	aq_rxsc = &cfg->aq_rxsc[rxsc_idx];
11568c2ecf20Sopenharmony_ci	for (i = 0; i < MACSEC_NUM_AN; i++) {
11578c2ecf20Sopenharmony_ci		if (!test_bit(i, &aq_rxsc->rx_sa_idx_busy))
11588c2ecf20Sopenharmony_ci			continue;
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci		stats = &aq_rxsc->rx_sa_stats[i];
11618c2ecf20Sopenharmony_ci		sa_idx = aq_rxsc->hw_sc_idx | i;
11628c2ecf20Sopenharmony_ci		ret = aq_get_rxsa_stats(hw, sa_idx, stats);
11638c2ecf20Sopenharmony_ci		if (ret)
11648c2ecf20Sopenharmony_ci			break;
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InOctetsValidated +=
11678c2ecf20Sopenharmony_ci			stats->validated_octets;
11688c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InOctetsDecrypted +=
11698c2ecf20Sopenharmony_ci			stats->decrypted_octets;
11708c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsUnchecked +=
11718c2ecf20Sopenharmony_ci			stats->unchecked_pkts;
11728c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsDelayed += stats->delayed_pkts;
11738c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsOK += stats->ok_pkts;
11748c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsInvalid += stats->invalid_pkts;
11758c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsLate += stats->late_pkts;
11768c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsNotValid += stats->not_valid_pkts;
11778c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsNotUsingSA += stats->not_using_sa;
11788c2ecf20Sopenharmony_ci		ctx->stats.rx_sc_stats->InPktsUnusedSA += stats->unused_sa;
11798c2ecf20Sopenharmony_ci	}
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	return ret;
11828c2ecf20Sopenharmony_ci}
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_cistatic int aq_mdo_get_rx_sa_stats(struct macsec_context *ctx)
11858c2ecf20Sopenharmony_ci{
11868c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);
11878c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
11888c2ecf20Sopenharmony_ci	struct aq_macsec_rx_sa_stats *stats;
11898c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
11908c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc;
11918c2ecf20Sopenharmony_ci	struct macsec_rx_sa *rx_sa;
11928c2ecf20Sopenharmony_ci	unsigned int sa_idx;
11938c2ecf20Sopenharmony_ci	int rxsc_idx;
11948c2ecf20Sopenharmony_ci	u32 next_pn;
11958c2ecf20Sopenharmony_ci	int ret;
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_ci	rxsc_idx = aq_get_rxsc_idx_from_rxsc(cfg, ctx->rx_sc);
11988c2ecf20Sopenharmony_ci	if (rxsc_idx < 0)
11998c2ecf20Sopenharmony_ci		return -EINVAL;
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_ci	if (ctx->prepare)
12028c2ecf20Sopenharmony_ci		return 0;
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_ci	aq_rxsc = &cfg->aq_rxsc[rxsc_idx];
12058c2ecf20Sopenharmony_ci	stats = &aq_rxsc->rx_sa_stats[ctx->sa.assoc_num];
12068c2ecf20Sopenharmony_ci	sa_idx = aq_rxsc->hw_sc_idx | ctx->sa.assoc_num;
12078c2ecf20Sopenharmony_ci	ret = aq_get_rxsa_stats(hw, sa_idx, stats);
12088c2ecf20Sopenharmony_ci	if (ret)
12098c2ecf20Sopenharmony_ci		return ret;
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci	ctx->stats.rx_sa_stats->InPktsOK = stats->ok_pkts;
12128c2ecf20Sopenharmony_ci	ctx->stats.rx_sa_stats->InPktsInvalid = stats->invalid_pkts;
12138c2ecf20Sopenharmony_ci	ctx->stats.rx_sa_stats->InPktsNotValid = stats->not_valid_pkts;
12148c2ecf20Sopenharmony_ci	ctx->stats.rx_sa_stats->InPktsNotUsingSA = stats->not_using_sa;
12158c2ecf20Sopenharmony_ci	ctx->stats.rx_sa_stats->InPktsUnusedSA = stats->unused_sa;
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	rx_sa = rcu_dereference_bh(aq_rxsc->sw_rxsc->sa[ctx->sa.assoc_num]);
12188c2ecf20Sopenharmony_ci	ret = aq_get_rxsa_next_pn(hw, sa_idx, &next_pn);
12198c2ecf20Sopenharmony_ci	if (ret == 0) {
12208c2ecf20Sopenharmony_ci		spin_lock_bh(&rx_sa->lock);
12218c2ecf20Sopenharmony_ci		rx_sa->next_pn = next_pn;
12228c2ecf20Sopenharmony_ci		spin_unlock_bh(&rx_sa->lock);
12238c2ecf20Sopenharmony_ci	}
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	return ret;
12268c2ecf20Sopenharmony_ci}
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_cistatic int apply_txsc_cfg(struct aq_nic_s *nic, const int txsc_idx)
12298c2ecf20Sopenharmony_ci{
12308c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc = &nic->macsec_cfg->aq_txsc[txsc_idx];
12318c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = aq_txsc->sw_secy;
12328c2ecf20Sopenharmony_ci	struct macsec_tx_sa *tx_sa;
12338c2ecf20Sopenharmony_ci	int ret = 0;
12348c2ecf20Sopenharmony_ci	int i;
12358c2ecf20Sopenharmony_ci
12368c2ecf20Sopenharmony_ci	if (!netif_running(secy->netdev))
12378c2ecf20Sopenharmony_ci		return ret;
12388c2ecf20Sopenharmony_ci
12398c2ecf20Sopenharmony_ci	ret = aq_set_txsc(nic, txsc_idx);
12408c2ecf20Sopenharmony_ci	if (ret)
12418c2ecf20Sopenharmony_ci		return ret;
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ci	for (i = 0; i < MACSEC_NUM_AN; i++) {
12448c2ecf20Sopenharmony_ci		tx_sa = rcu_dereference_bh(secy->tx_sc.sa[i]);
12458c2ecf20Sopenharmony_ci		if (tx_sa) {
12468c2ecf20Sopenharmony_ci			ret = aq_update_txsa(nic, aq_txsc->hw_sc_idx, secy,
12478c2ecf20Sopenharmony_ci					     tx_sa, aq_txsc->tx_sa_key[i], i);
12488c2ecf20Sopenharmony_ci			if (ret)
12498c2ecf20Sopenharmony_ci				return ret;
12508c2ecf20Sopenharmony_ci		}
12518c2ecf20Sopenharmony_ci	}
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci	return ret;
12548c2ecf20Sopenharmony_ci}
12558c2ecf20Sopenharmony_ci
12568c2ecf20Sopenharmony_cistatic int apply_rxsc_cfg(struct aq_nic_s *nic, const int rxsc_idx)
12578c2ecf20Sopenharmony_ci{
12588c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc = &nic->macsec_cfg->aq_rxsc[rxsc_idx];
12598c2ecf20Sopenharmony_ci	const struct macsec_secy *secy = aq_rxsc->sw_secy;
12608c2ecf20Sopenharmony_ci	struct macsec_rx_sa *rx_sa;
12618c2ecf20Sopenharmony_ci	int ret = 0;
12628c2ecf20Sopenharmony_ci	int i;
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	if (!netif_running(secy->netdev))
12658c2ecf20Sopenharmony_ci		return ret;
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci	ret = aq_set_rxsc(nic, rxsc_idx);
12688c2ecf20Sopenharmony_ci	if (ret)
12698c2ecf20Sopenharmony_ci		return ret;
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_ci	for (i = 0; i < MACSEC_NUM_AN; i++) {
12728c2ecf20Sopenharmony_ci		rx_sa = rcu_dereference_bh(aq_rxsc->sw_rxsc->sa[i]);
12738c2ecf20Sopenharmony_ci		if (rx_sa) {
12748c2ecf20Sopenharmony_ci			ret = aq_update_rxsa(nic, aq_rxsc->hw_sc_idx, secy,
12758c2ecf20Sopenharmony_ci					     rx_sa, aq_rxsc->rx_sa_key[i], i);
12768c2ecf20Sopenharmony_ci			if (ret)
12778c2ecf20Sopenharmony_ci				return ret;
12788c2ecf20Sopenharmony_ci		}
12798c2ecf20Sopenharmony_ci	}
12808c2ecf20Sopenharmony_ci
12818c2ecf20Sopenharmony_ci	return ret;
12828c2ecf20Sopenharmony_ci}
12838c2ecf20Sopenharmony_ci
12848c2ecf20Sopenharmony_cistatic int aq_clear_secy(struct aq_nic_s *nic, const struct macsec_secy *secy,
12858c2ecf20Sopenharmony_ci			 enum aq_clear_type clear_type)
12868c2ecf20Sopenharmony_ci{
12878c2ecf20Sopenharmony_ci	struct macsec_rx_sc *rx_sc;
12888c2ecf20Sopenharmony_ci	int txsc_idx;
12898c2ecf20Sopenharmony_ci	int rxsc_idx;
12908c2ecf20Sopenharmony_ci	int ret = 0;
12918c2ecf20Sopenharmony_ci
12928c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(nic->macsec_cfg, secy);
12938c2ecf20Sopenharmony_ci	if (txsc_idx >= 0) {
12948c2ecf20Sopenharmony_ci		ret = aq_clear_txsc(nic, txsc_idx, clear_type);
12958c2ecf20Sopenharmony_ci		if (ret)
12968c2ecf20Sopenharmony_ci			return ret;
12978c2ecf20Sopenharmony_ci	}
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci	for (rx_sc = rcu_dereference_bh(secy->rx_sc); rx_sc;
13008c2ecf20Sopenharmony_ci	     rx_sc = rcu_dereference_bh(rx_sc->next)) {
13018c2ecf20Sopenharmony_ci		rxsc_idx = aq_get_rxsc_idx_from_rxsc(nic->macsec_cfg, rx_sc);
13028c2ecf20Sopenharmony_ci		if (rxsc_idx < 0)
13038c2ecf20Sopenharmony_ci			continue;
13048c2ecf20Sopenharmony_ci
13058c2ecf20Sopenharmony_ci		ret = aq_clear_rxsc(nic, rxsc_idx, clear_type);
13068c2ecf20Sopenharmony_ci		if (ret)
13078c2ecf20Sopenharmony_ci			return ret;
13088c2ecf20Sopenharmony_ci	}
13098c2ecf20Sopenharmony_ci
13108c2ecf20Sopenharmony_ci	return ret;
13118c2ecf20Sopenharmony_ci}
13128c2ecf20Sopenharmony_ci
13138c2ecf20Sopenharmony_cistatic int aq_apply_secy_cfg(struct aq_nic_s *nic,
13148c2ecf20Sopenharmony_ci			     const struct macsec_secy *secy)
13158c2ecf20Sopenharmony_ci{
13168c2ecf20Sopenharmony_ci	struct macsec_rx_sc *rx_sc;
13178c2ecf20Sopenharmony_ci	int txsc_idx;
13188c2ecf20Sopenharmony_ci	int rxsc_idx;
13198c2ecf20Sopenharmony_ci	int ret = 0;
13208c2ecf20Sopenharmony_ci
13218c2ecf20Sopenharmony_ci	txsc_idx = aq_get_txsc_idx_from_secy(nic->macsec_cfg, secy);
13228c2ecf20Sopenharmony_ci	if (txsc_idx >= 0)
13238c2ecf20Sopenharmony_ci		apply_txsc_cfg(nic, txsc_idx);
13248c2ecf20Sopenharmony_ci
13258c2ecf20Sopenharmony_ci	for (rx_sc = rcu_dereference_bh(secy->rx_sc); rx_sc && rx_sc->active;
13268c2ecf20Sopenharmony_ci	     rx_sc = rcu_dereference_bh(rx_sc->next)) {
13278c2ecf20Sopenharmony_ci		rxsc_idx = aq_get_rxsc_idx_from_rxsc(nic->macsec_cfg, rx_sc);
13288c2ecf20Sopenharmony_ci		if (unlikely(rxsc_idx < 0))
13298c2ecf20Sopenharmony_ci			continue;
13308c2ecf20Sopenharmony_ci
13318c2ecf20Sopenharmony_ci		ret = apply_rxsc_cfg(nic, rxsc_idx);
13328c2ecf20Sopenharmony_ci		if (ret)
13338c2ecf20Sopenharmony_ci			return ret;
13348c2ecf20Sopenharmony_ci	}
13358c2ecf20Sopenharmony_ci
13368c2ecf20Sopenharmony_ci	return ret;
13378c2ecf20Sopenharmony_ci}
13388c2ecf20Sopenharmony_ci
13398c2ecf20Sopenharmony_cistatic int aq_apply_macsec_cfg(struct aq_nic_s *nic)
13408c2ecf20Sopenharmony_ci{
13418c2ecf20Sopenharmony_ci	int ret = 0;
13428c2ecf20Sopenharmony_ci	int i;
13438c2ecf20Sopenharmony_ci
13448c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
13458c2ecf20Sopenharmony_ci		if (nic->macsec_cfg->txsc_idx_busy & BIT(i)) {
13468c2ecf20Sopenharmony_ci			ret = apply_txsc_cfg(nic, i);
13478c2ecf20Sopenharmony_ci			if (ret)
13488c2ecf20Sopenharmony_ci				return ret;
13498c2ecf20Sopenharmony_ci		}
13508c2ecf20Sopenharmony_ci	}
13518c2ecf20Sopenharmony_ci
13528c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
13538c2ecf20Sopenharmony_ci		if (nic->macsec_cfg->rxsc_idx_busy & BIT(i)) {
13548c2ecf20Sopenharmony_ci			ret = apply_rxsc_cfg(nic, i);
13558c2ecf20Sopenharmony_ci			if (ret)
13568c2ecf20Sopenharmony_ci				return ret;
13578c2ecf20Sopenharmony_ci		}
13588c2ecf20Sopenharmony_ci	}
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci	return ret;
13618c2ecf20Sopenharmony_ci}
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_cistatic int aq_sa_from_sa_idx(const enum aq_macsec_sc_sa sc_sa, const int sa_idx)
13648c2ecf20Sopenharmony_ci{
13658c2ecf20Sopenharmony_ci	switch (sc_sa) {
13668c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_4sa_8sc:
13678c2ecf20Sopenharmony_ci		return sa_idx & 3;
13688c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_2sa_16sc:
13698c2ecf20Sopenharmony_ci		return sa_idx & 1;
13708c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_1sa_32sc:
13718c2ecf20Sopenharmony_ci		return 0;
13728c2ecf20Sopenharmony_ci	default:
13738c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid sc_sa");
13748c2ecf20Sopenharmony_ci	}
13758c2ecf20Sopenharmony_ci	return -EINVAL;
13768c2ecf20Sopenharmony_ci}
13778c2ecf20Sopenharmony_ci
13788c2ecf20Sopenharmony_cistatic int aq_sc_idx_from_sa_idx(const enum aq_macsec_sc_sa sc_sa,
13798c2ecf20Sopenharmony_ci				 const int sa_idx)
13808c2ecf20Sopenharmony_ci{
13818c2ecf20Sopenharmony_ci	switch (sc_sa) {
13828c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_4sa_8sc:
13838c2ecf20Sopenharmony_ci		return sa_idx & ~3;
13848c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_2sa_16sc:
13858c2ecf20Sopenharmony_ci		return sa_idx & ~1;
13868c2ecf20Sopenharmony_ci	case aq_macsec_sa_sc_1sa_32sc:
13878c2ecf20Sopenharmony_ci		return sa_idx;
13888c2ecf20Sopenharmony_ci	default:
13898c2ecf20Sopenharmony_ci		WARN_ONCE(true, "Invalid sc_sa");
13908c2ecf20Sopenharmony_ci	}
13918c2ecf20Sopenharmony_ci	return -EINVAL;
13928c2ecf20Sopenharmony_ci}
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_cistatic void aq_check_txsa_expiration(struct aq_nic_s *nic)
13958c2ecf20Sopenharmony_ci{
13968c2ecf20Sopenharmony_ci	u32 egress_sa_expired, egress_sa_threshold_expired;
13978c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
13988c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
13998c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
14008c2ecf20Sopenharmony_ci	const struct macsec_secy *secy;
14018c2ecf20Sopenharmony_ci	int sc_idx = 0, txsc_idx = 0;
14028c2ecf20Sopenharmony_ci	enum aq_macsec_sc_sa sc_sa;
14038c2ecf20Sopenharmony_ci	struct macsec_tx_sa *tx_sa;
14048c2ecf20Sopenharmony_ci	unsigned char an = 0;
14058c2ecf20Sopenharmony_ci	int ret;
14068c2ecf20Sopenharmony_ci	int i;
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	sc_sa = cfg->sc_sa;
14098c2ecf20Sopenharmony_ci
14108c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_sa_expired(hw, &egress_sa_expired);
14118c2ecf20Sopenharmony_ci	if (unlikely(ret))
14128c2ecf20Sopenharmony_ci		return;
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci	ret = aq_mss_get_egress_sa_threshold_expired(hw,
14158c2ecf20Sopenharmony_ci		&egress_sa_threshold_expired);
14168c2ecf20Sopenharmony_ci
14178c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SA; i++) {
14188c2ecf20Sopenharmony_ci		if (egress_sa_expired & BIT(i)) {
14198c2ecf20Sopenharmony_ci			an = aq_sa_from_sa_idx(sc_sa, i);
14208c2ecf20Sopenharmony_ci			sc_idx = aq_sc_idx_from_sa_idx(sc_sa, i);
14218c2ecf20Sopenharmony_ci			txsc_idx = aq_get_txsc_idx_from_sc_idx(sc_sa, sc_idx);
14228c2ecf20Sopenharmony_ci			if (txsc_idx < 0)
14238c2ecf20Sopenharmony_ci				continue;
14248c2ecf20Sopenharmony_ci
14258c2ecf20Sopenharmony_ci			aq_txsc = &cfg->aq_txsc[txsc_idx];
14268c2ecf20Sopenharmony_ci			if (!(cfg->txsc_idx_busy & BIT(txsc_idx))) {
14278c2ecf20Sopenharmony_ci				netdev_warn(nic->ndev,
14288c2ecf20Sopenharmony_ci					"PN threshold expired on invalid TX SC");
14298c2ecf20Sopenharmony_ci				continue;
14308c2ecf20Sopenharmony_ci			}
14318c2ecf20Sopenharmony_ci
14328c2ecf20Sopenharmony_ci			secy = aq_txsc->sw_secy;
14338c2ecf20Sopenharmony_ci			if (!netif_running(secy->netdev)) {
14348c2ecf20Sopenharmony_ci				netdev_warn(nic->ndev,
14358c2ecf20Sopenharmony_ci					"PN threshold expired on down TX SC");
14368c2ecf20Sopenharmony_ci				continue;
14378c2ecf20Sopenharmony_ci			}
14388c2ecf20Sopenharmony_ci
14398c2ecf20Sopenharmony_ci			if (unlikely(!(aq_txsc->tx_sa_idx_busy & BIT(an)))) {
14408c2ecf20Sopenharmony_ci				netdev_warn(nic->ndev,
14418c2ecf20Sopenharmony_ci					"PN threshold expired on invalid TX SA");
14428c2ecf20Sopenharmony_ci				continue;
14438c2ecf20Sopenharmony_ci			}
14448c2ecf20Sopenharmony_ci
14458c2ecf20Sopenharmony_ci			tx_sa = rcu_dereference_bh(secy->tx_sc.sa[an]);
14468c2ecf20Sopenharmony_ci			macsec_pn_wrapped((struct macsec_secy *)secy, tx_sa);
14478c2ecf20Sopenharmony_ci		}
14488c2ecf20Sopenharmony_ci	}
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci	aq_mss_set_egress_sa_expired(hw, egress_sa_expired);
14518c2ecf20Sopenharmony_ci	if (likely(!ret))
14528c2ecf20Sopenharmony_ci		aq_mss_set_egress_sa_threshold_expired(hw,
14538c2ecf20Sopenharmony_ci			egress_sa_threshold_expired);
14548c2ecf20Sopenharmony_ci}
14558c2ecf20Sopenharmony_ci
14568c2ecf20Sopenharmony_ci#define AQ_LOCKED_MDO_DEF(mdo)						\
14578c2ecf20Sopenharmony_cistatic int aq_locked_mdo_##mdo(struct macsec_context *ctx)		\
14588c2ecf20Sopenharmony_ci{									\
14598c2ecf20Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ctx->netdev);		\
14608c2ecf20Sopenharmony_ci	int ret;							\
14618c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);					\
14628c2ecf20Sopenharmony_ci	ret = aq_mdo_##mdo(ctx);					\
14638c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);				\
14648c2ecf20Sopenharmony_ci	return ret;							\
14658c2ecf20Sopenharmony_ci}
14668c2ecf20Sopenharmony_ci
14678c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(dev_open)
14688c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(dev_stop)
14698c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(add_secy)
14708c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(upd_secy)
14718c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(del_secy)
14728c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(add_rxsc)
14738c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(upd_rxsc)
14748c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(del_rxsc)
14758c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(add_rxsa)
14768c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(upd_rxsa)
14778c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(del_rxsa)
14788c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(add_txsa)
14798c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(upd_txsa)
14808c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(del_txsa)
14818c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(get_dev_stats)
14828c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(get_tx_sc_stats)
14838c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(get_tx_sa_stats)
14848c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(get_rx_sc_stats)
14858c2ecf20Sopenharmony_ciAQ_LOCKED_MDO_DEF(get_rx_sa_stats)
14868c2ecf20Sopenharmony_ci
14878c2ecf20Sopenharmony_ciconst struct macsec_ops aq_macsec_ops = {
14888c2ecf20Sopenharmony_ci	.mdo_dev_open = aq_locked_mdo_dev_open,
14898c2ecf20Sopenharmony_ci	.mdo_dev_stop = aq_locked_mdo_dev_stop,
14908c2ecf20Sopenharmony_ci	.mdo_add_secy = aq_locked_mdo_add_secy,
14918c2ecf20Sopenharmony_ci	.mdo_upd_secy = aq_locked_mdo_upd_secy,
14928c2ecf20Sopenharmony_ci	.mdo_del_secy = aq_locked_mdo_del_secy,
14938c2ecf20Sopenharmony_ci	.mdo_add_rxsc = aq_locked_mdo_add_rxsc,
14948c2ecf20Sopenharmony_ci	.mdo_upd_rxsc = aq_locked_mdo_upd_rxsc,
14958c2ecf20Sopenharmony_ci	.mdo_del_rxsc = aq_locked_mdo_del_rxsc,
14968c2ecf20Sopenharmony_ci	.mdo_add_rxsa = aq_locked_mdo_add_rxsa,
14978c2ecf20Sopenharmony_ci	.mdo_upd_rxsa = aq_locked_mdo_upd_rxsa,
14988c2ecf20Sopenharmony_ci	.mdo_del_rxsa = aq_locked_mdo_del_rxsa,
14998c2ecf20Sopenharmony_ci	.mdo_add_txsa = aq_locked_mdo_add_txsa,
15008c2ecf20Sopenharmony_ci	.mdo_upd_txsa = aq_locked_mdo_upd_txsa,
15018c2ecf20Sopenharmony_ci	.mdo_del_txsa = aq_locked_mdo_del_txsa,
15028c2ecf20Sopenharmony_ci	.mdo_get_dev_stats = aq_locked_mdo_get_dev_stats,
15038c2ecf20Sopenharmony_ci	.mdo_get_tx_sc_stats = aq_locked_mdo_get_tx_sc_stats,
15048c2ecf20Sopenharmony_ci	.mdo_get_tx_sa_stats = aq_locked_mdo_get_tx_sa_stats,
15058c2ecf20Sopenharmony_ci	.mdo_get_rx_sc_stats = aq_locked_mdo_get_rx_sc_stats,
15068c2ecf20Sopenharmony_ci	.mdo_get_rx_sa_stats = aq_locked_mdo_get_rx_sa_stats,
15078c2ecf20Sopenharmony_ci};
15088c2ecf20Sopenharmony_ci
15098c2ecf20Sopenharmony_ciint aq_macsec_init(struct aq_nic_s *nic)
15108c2ecf20Sopenharmony_ci{
15118c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg;
15128c2ecf20Sopenharmony_ci	u32 caps_lo;
15138c2ecf20Sopenharmony_ci
15148c2ecf20Sopenharmony_ci	if (!nic->aq_fw_ops->get_link_capabilities)
15158c2ecf20Sopenharmony_ci		return 0;
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	caps_lo = nic->aq_fw_ops->get_link_capabilities(nic->aq_hw);
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	if (!(caps_lo & BIT(CAPS_LO_MACSEC)))
15208c2ecf20Sopenharmony_ci		return 0;
15218c2ecf20Sopenharmony_ci
15228c2ecf20Sopenharmony_ci	nic->macsec_cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
15238c2ecf20Sopenharmony_ci	if (!nic->macsec_cfg)
15248c2ecf20Sopenharmony_ci		return -ENOMEM;
15258c2ecf20Sopenharmony_ci
15268c2ecf20Sopenharmony_ci	nic->ndev->features |= NETIF_F_HW_MACSEC;
15278c2ecf20Sopenharmony_ci	nic->ndev->macsec_ops = &aq_macsec_ops;
15288c2ecf20Sopenharmony_ci	mutex_init(&nic->macsec_mutex);
15298c2ecf20Sopenharmony_ci
15308c2ecf20Sopenharmony_ci	return 0;
15318c2ecf20Sopenharmony_ci}
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_civoid aq_macsec_free(struct aq_nic_s *nic)
15348c2ecf20Sopenharmony_ci{
15358c2ecf20Sopenharmony_ci	kfree(nic->macsec_cfg);
15368c2ecf20Sopenharmony_ci	nic->macsec_cfg = NULL;
15378c2ecf20Sopenharmony_ci}
15388c2ecf20Sopenharmony_ci
15398c2ecf20Sopenharmony_ciint aq_macsec_enable(struct aq_nic_s *nic)
15408c2ecf20Sopenharmony_ci{
15418c2ecf20Sopenharmony_ci	u32 ctl_ether_types[1] = { ETH_P_PAE };
15428c2ecf20Sopenharmony_ci	struct macsec_msg_fw_response resp = { 0 };
15438c2ecf20Sopenharmony_ci	struct macsec_msg_fw_request msg = { 0 };
15448c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
15458c2ecf20Sopenharmony_ci	int num_ctl_ether_types = 0;
15468c2ecf20Sopenharmony_ci	int index = 0, tbl_idx;
15478c2ecf20Sopenharmony_ci	int ret;
15488c2ecf20Sopenharmony_ci
15498c2ecf20Sopenharmony_ci	if (!nic->macsec_cfg)
15508c2ecf20Sopenharmony_ci		return 0;
15518c2ecf20Sopenharmony_ci
15528c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
15538c2ecf20Sopenharmony_ci
15548c2ecf20Sopenharmony_ci	if (nic->aq_fw_ops->send_macsec_req) {
15558c2ecf20Sopenharmony_ci		struct macsec_cfg_request cfg = { 0 };
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_ci		cfg.enabled = 1;
15588c2ecf20Sopenharmony_ci		cfg.egress_threshold = 0xffffffff;
15598c2ecf20Sopenharmony_ci		cfg.ingress_threshold = 0xffffffff;
15608c2ecf20Sopenharmony_ci		cfg.interrupts_enabled = 1;
15618c2ecf20Sopenharmony_ci
15628c2ecf20Sopenharmony_ci		msg.msg_type = macsec_cfg_msg;
15638c2ecf20Sopenharmony_ci		msg.cfg = cfg;
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci		ret = nic->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
15668c2ecf20Sopenharmony_ci		if (ret)
15678c2ecf20Sopenharmony_ci			goto unlock;
15688c2ecf20Sopenharmony_ci	}
15698c2ecf20Sopenharmony_ci
15708c2ecf20Sopenharmony_ci	/* Init Ethertype bypass filters */
15718c2ecf20Sopenharmony_ci	for (index = 0; index < ARRAY_SIZE(ctl_ether_types); index++) {
15728c2ecf20Sopenharmony_ci		struct aq_mss_ingress_prectlf_record rx_prectlf_rec;
15738c2ecf20Sopenharmony_ci		struct aq_mss_egress_ctlf_record tx_ctlf_rec;
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci		if (ctl_ether_types[index] == 0)
15768c2ecf20Sopenharmony_ci			continue;
15778c2ecf20Sopenharmony_ci
15788c2ecf20Sopenharmony_ci		memset(&tx_ctlf_rec, 0, sizeof(tx_ctlf_rec));
15798c2ecf20Sopenharmony_ci		tx_ctlf_rec.eth_type = ctl_ether_types[index];
15808c2ecf20Sopenharmony_ci		tx_ctlf_rec.match_type = 4; /* Match eth_type only */
15818c2ecf20Sopenharmony_ci		tx_ctlf_rec.match_mask = 0xf; /* match for eth_type */
15828c2ecf20Sopenharmony_ci		tx_ctlf_rec.action = 0; /* Bypass MACSEC modules */
15838c2ecf20Sopenharmony_ci		tbl_idx = NUMROWS_EGRESSCTLFRECORD - num_ctl_ether_types - 1;
15848c2ecf20Sopenharmony_ci		aq_mss_set_egress_ctlf_record(hw, &tx_ctlf_rec, tbl_idx);
15858c2ecf20Sopenharmony_ci
15868c2ecf20Sopenharmony_ci		memset(&rx_prectlf_rec, 0, sizeof(rx_prectlf_rec));
15878c2ecf20Sopenharmony_ci		rx_prectlf_rec.eth_type = ctl_ether_types[index];
15888c2ecf20Sopenharmony_ci		rx_prectlf_rec.match_type = 4; /* Match eth_type only */
15898c2ecf20Sopenharmony_ci		rx_prectlf_rec.match_mask = 0xf; /* match for eth_type */
15908c2ecf20Sopenharmony_ci		rx_prectlf_rec.action = 0; /* Bypass MACSEC modules */
15918c2ecf20Sopenharmony_ci		tbl_idx =
15928c2ecf20Sopenharmony_ci			NUMROWS_INGRESSPRECTLFRECORD - num_ctl_ether_types - 1;
15938c2ecf20Sopenharmony_ci		aq_mss_set_ingress_prectlf_record(hw, &rx_prectlf_rec, tbl_idx);
15948c2ecf20Sopenharmony_ci
15958c2ecf20Sopenharmony_ci		num_ctl_ether_types++;
15968c2ecf20Sopenharmony_ci	}
15978c2ecf20Sopenharmony_ci
15988c2ecf20Sopenharmony_ci	ret = aq_apply_macsec_cfg(nic);
15998c2ecf20Sopenharmony_ci
16008c2ecf20Sopenharmony_ciunlock:
16018c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
16028c2ecf20Sopenharmony_ci	return ret;
16038c2ecf20Sopenharmony_ci}
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_civoid aq_macsec_work(struct aq_nic_s *nic)
16068c2ecf20Sopenharmony_ci{
16078c2ecf20Sopenharmony_ci	if (!nic->macsec_cfg)
16088c2ecf20Sopenharmony_ci		return;
16098c2ecf20Sopenharmony_ci
16108c2ecf20Sopenharmony_ci	if (!netif_carrier_ok(nic->ndev))
16118c2ecf20Sopenharmony_ci		return;
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
16148c2ecf20Sopenharmony_ci	aq_check_txsa_expiration(nic);
16158c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
16168c2ecf20Sopenharmony_ci}
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_ciint aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
16198c2ecf20Sopenharmony_ci{
16208c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
16218c2ecf20Sopenharmony_ci	int i, cnt = 0;
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci	if (!cfg)
16248c2ecf20Sopenharmony_ci		return 0;
16258c2ecf20Sopenharmony_ci
16268c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
16298c2ecf20Sopenharmony_ci		if (!test_bit(i, &cfg->rxsc_idx_busy))
16308c2ecf20Sopenharmony_ci			continue;
16318c2ecf20Sopenharmony_ci		cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy);
16328c2ecf20Sopenharmony_ci	}
16338c2ecf20Sopenharmony_ci
16348c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
16358c2ecf20Sopenharmony_ci	return cnt;
16368c2ecf20Sopenharmony_ci}
16378c2ecf20Sopenharmony_ci
16388c2ecf20Sopenharmony_ciint aq_macsec_tx_sc_cnt(struct aq_nic_s *nic)
16398c2ecf20Sopenharmony_ci{
16408c2ecf20Sopenharmony_ci	int cnt;
16418c2ecf20Sopenharmony_ci
16428c2ecf20Sopenharmony_ci	if (!nic->macsec_cfg)
16438c2ecf20Sopenharmony_ci		return 0;
16448c2ecf20Sopenharmony_ci
16458c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
16468c2ecf20Sopenharmony_ci	cnt = hweight_long(nic->macsec_cfg->txsc_idx_busy);
16478c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
16488c2ecf20Sopenharmony_ci
16498c2ecf20Sopenharmony_ci	return cnt;
16508c2ecf20Sopenharmony_ci}
16518c2ecf20Sopenharmony_ci
16528c2ecf20Sopenharmony_ciint aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
16538c2ecf20Sopenharmony_ci{
16548c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
16558c2ecf20Sopenharmony_ci	int i, cnt = 0;
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci	if (!cfg)
16588c2ecf20Sopenharmony_ci		return 0;
16598c2ecf20Sopenharmony_ci
16608c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
16618c2ecf20Sopenharmony_ci
16628c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
16638c2ecf20Sopenharmony_ci		if (!test_bit(i, &cfg->txsc_idx_busy))
16648c2ecf20Sopenharmony_ci			continue;
16658c2ecf20Sopenharmony_ci		cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy);
16668c2ecf20Sopenharmony_ci	}
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
16698c2ecf20Sopenharmony_ci	return cnt;
16708c2ecf20Sopenharmony_ci}
16718c2ecf20Sopenharmony_ci
16728c2ecf20Sopenharmony_cistatic int aq_macsec_update_stats(struct aq_nic_s *nic)
16738c2ecf20Sopenharmony_ci{
16748c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
16758c2ecf20Sopenharmony_ci	struct aq_hw_s *hw = nic->aq_hw;
16768c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
16778c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc;
16788c2ecf20Sopenharmony_ci	int i, sa_idx, assoc_num;
16798c2ecf20Sopenharmony_ci	int ret = 0;
16808c2ecf20Sopenharmony_ci
16818c2ecf20Sopenharmony_ci	aq_get_macsec_common_stats(hw, &cfg->stats);
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
16848c2ecf20Sopenharmony_ci		if (!(cfg->txsc_idx_busy & BIT(i)))
16858c2ecf20Sopenharmony_ci			continue;
16868c2ecf20Sopenharmony_ci		aq_txsc = &cfg->aq_txsc[i];
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci		ret = aq_get_txsc_stats(hw, aq_txsc->hw_sc_idx,
16898c2ecf20Sopenharmony_ci					&aq_txsc->stats);
16908c2ecf20Sopenharmony_ci		if (ret)
16918c2ecf20Sopenharmony_ci			return ret;
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_ci		for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
16948c2ecf20Sopenharmony_ci			if (!test_bit(assoc_num, &aq_txsc->tx_sa_idx_busy))
16958c2ecf20Sopenharmony_ci				continue;
16968c2ecf20Sopenharmony_ci			sa_idx = aq_txsc->hw_sc_idx | assoc_num;
16978c2ecf20Sopenharmony_ci			ret = aq_get_txsa_stats(hw, sa_idx,
16988c2ecf20Sopenharmony_ci					      &aq_txsc->tx_sa_stats[assoc_num]);
16998c2ecf20Sopenharmony_ci			if (ret)
17008c2ecf20Sopenharmony_ci				return ret;
17018c2ecf20Sopenharmony_ci		}
17028c2ecf20Sopenharmony_ci	}
17038c2ecf20Sopenharmony_ci
17048c2ecf20Sopenharmony_ci	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
17058c2ecf20Sopenharmony_ci		if (!(test_bit(i, &cfg->rxsc_idx_busy)))
17068c2ecf20Sopenharmony_ci			continue;
17078c2ecf20Sopenharmony_ci		aq_rxsc = &cfg->aq_rxsc[i];
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_ci		for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
17108c2ecf20Sopenharmony_ci			if (!test_bit(assoc_num, &aq_rxsc->rx_sa_idx_busy))
17118c2ecf20Sopenharmony_ci				continue;
17128c2ecf20Sopenharmony_ci			sa_idx = aq_rxsc->hw_sc_idx | assoc_num;
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_ci			ret = aq_get_rxsa_stats(hw, sa_idx,
17158c2ecf20Sopenharmony_ci					      &aq_rxsc->rx_sa_stats[assoc_num]);
17168c2ecf20Sopenharmony_ci			if (ret)
17178c2ecf20Sopenharmony_ci				return ret;
17188c2ecf20Sopenharmony_ci		}
17198c2ecf20Sopenharmony_ci	}
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci	return ret;
17228c2ecf20Sopenharmony_ci}
17238c2ecf20Sopenharmony_ci
17248c2ecf20Sopenharmony_ciu64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
17258c2ecf20Sopenharmony_ci{
17268c2ecf20Sopenharmony_ci	struct aq_macsec_cfg *cfg = nic->macsec_cfg;
17278c2ecf20Sopenharmony_ci	struct aq_macsec_common_stats *common_stats;
17288c2ecf20Sopenharmony_ci	struct aq_macsec_tx_sc_stats *txsc_stats;
17298c2ecf20Sopenharmony_ci	struct aq_macsec_tx_sa_stats *txsa_stats;
17308c2ecf20Sopenharmony_ci	struct aq_macsec_rx_sa_stats *rxsa_stats;
17318c2ecf20Sopenharmony_ci	struct aq_macsec_txsc *aq_txsc;
17328c2ecf20Sopenharmony_ci	struct aq_macsec_rxsc *aq_rxsc;
17338c2ecf20Sopenharmony_ci	unsigned int assoc_num;
17348c2ecf20Sopenharmony_ci	unsigned int sc_num;
17358c2ecf20Sopenharmony_ci	unsigned int i = 0U;
17368c2ecf20Sopenharmony_ci
17378c2ecf20Sopenharmony_ci	if (!cfg)
17388c2ecf20Sopenharmony_ci		return data;
17398c2ecf20Sopenharmony_ci
17408c2ecf20Sopenharmony_ci	mutex_lock(&nic->macsec_mutex);
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_ci	aq_macsec_update_stats(nic);
17438c2ecf20Sopenharmony_ci
17448c2ecf20Sopenharmony_ci	common_stats = &cfg->stats;
17458c2ecf20Sopenharmony_ci	data[i] = common_stats->in.ctl_pkts;
17468c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.tagged_miss_pkts;
17478c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.untagged_miss_pkts;
17488c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.notag_pkts;
17498c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.untagged_pkts;
17508c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.bad_tag_pkts;
17518c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.no_sci_pkts;
17528c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.unknown_sci_pkts;
17538c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.ctrl_prt_pass_pkts;
17548c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.unctrl_prt_pass_pkts;
17558c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.ctrl_prt_fail_pkts;
17568c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.unctrl_prt_fail_pkts;
17578c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.too_long_pkts;
17588c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.igpoc_ctl_pkts;
17598c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.ecc_error_pkts;
17608c2ecf20Sopenharmony_ci	data[++i] = common_stats->in.unctrl_hit_drop_redir;
17618c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.ctl_pkts;
17628c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.unknown_sa_pkts;
17638c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.untagged_pkts;
17648c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.too_long;
17658c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.ecc_error_pkts;
17668c2ecf20Sopenharmony_ci	data[++i] = common_stats->out.unctrl_hit_drop_redir;
17678c2ecf20Sopenharmony_ci
17688c2ecf20Sopenharmony_ci	for (sc_num = 0; sc_num < AQ_MACSEC_MAX_SC; sc_num++) {
17698c2ecf20Sopenharmony_ci		if (!(test_bit(sc_num, &cfg->txsc_idx_busy)))
17708c2ecf20Sopenharmony_ci			continue;
17718c2ecf20Sopenharmony_ci
17728c2ecf20Sopenharmony_ci		aq_txsc = &cfg->aq_txsc[sc_num];
17738c2ecf20Sopenharmony_ci		txsc_stats = &aq_txsc->stats;
17748c2ecf20Sopenharmony_ci
17758c2ecf20Sopenharmony_ci		data[++i] = txsc_stats->sc_protected_pkts;
17768c2ecf20Sopenharmony_ci		data[++i] = txsc_stats->sc_encrypted_pkts;
17778c2ecf20Sopenharmony_ci		data[++i] = txsc_stats->sc_protected_octets;
17788c2ecf20Sopenharmony_ci		data[++i] = txsc_stats->sc_encrypted_octets;
17798c2ecf20Sopenharmony_ci
17808c2ecf20Sopenharmony_ci		for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
17818c2ecf20Sopenharmony_ci			if (!test_bit(assoc_num, &aq_txsc->tx_sa_idx_busy))
17828c2ecf20Sopenharmony_ci				continue;
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_ci			txsa_stats = &aq_txsc->tx_sa_stats[assoc_num];
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci			data[++i] = txsa_stats->sa_hit_drop_redirect;
17878c2ecf20Sopenharmony_ci			data[++i] = txsa_stats->sa_protected2_pkts;
17888c2ecf20Sopenharmony_ci			data[++i] = txsa_stats->sa_protected_pkts;
17898c2ecf20Sopenharmony_ci			data[++i] = txsa_stats->sa_encrypted_pkts;
17908c2ecf20Sopenharmony_ci		}
17918c2ecf20Sopenharmony_ci	}
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_ci	for (sc_num = 0; sc_num < AQ_MACSEC_MAX_SC; sc_num++) {
17948c2ecf20Sopenharmony_ci		if (!(test_bit(sc_num, &cfg->rxsc_idx_busy)))
17958c2ecf20Sopenharmony_ci			continue;
17968c2ecf20Sopenharmony_ci
17978c2ecf20Sopenharmony_ci		aq_rxsc = &cfg->aq_rxsc[sc_num];
17988c2ecf20Sopenharmony_ci
17998c2ecf20Sopenharmony_ci		for (assoc_num = 0; assoc_num < MACSEC_NUM_AN; assoc_num++) {
18008c2ecf20Sopenharmony_ci			if (!test_bit(assoc_num, &aq_rxsc->rx_sa_idx_busy))
18018c2ecf20Sopenharmony_ci				continue;
18028c2ecf20Sopenharmony_ci
18038c2ecf20Sopenharmony_ci			rxsa_stats = &aq_rxsc->rx_sa_stats[assoc_num];
18048c2ecf20Sopenharmony_ci
18058c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->untagged_hit_pkts;
18068c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->ctrl_hit_drop_redir_pkts;
18078c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->not_using_sa;
18088c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->unused_sa;
18098c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->not_valid_pkts;
18108c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->invalid_pkts;
18118c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->ok_pkts;
18128c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->late_pkts;
18138c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->delayed_pkts;
18148c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->unchecked_pkts;
18158c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->validated_octets;
18168c2ecf20Sopenharmony_ci			data[++i] = rxsa_stats->decrypted_octets;
18178c2ecf20Sopenharmony_ci		}
18188c2ecf20Sopenharmony_ci	}
18198c2ecf20Sopenharmony_ci
18208c2ecf20Sopenharmony_ci	i++;
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci	data += i;
18238c2ecf20Sopenharmony_ci
18248c2ecf20Sopenharmony_ci	mutex_unlock(&nic->macsec_mutex);
18258c2ecf20Sopenharmony_ci
18268c2ecf20Sopenharmony_ci	return data;
18278c2ecf20Sopenharmony_ci}
1828