162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/* Atlantic Network Driver
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2014-2019 aQuantia Corporation
562306a36Sopenharmony_ci * Copyright (C) 2019-2020 Marvell International Ltd.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/* File aq_ethtool.c: Definition of ethertool related functions. */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "aq_ethtool.h"
1162306a36Sopenharmony_ci#include "aq_nic.h"
1262306a36Sopenharmony_ci#include "aq_vec.h"
1362306a36Sopenharmony_ci#include "aq_ptp.h"
1462306a36Sopenharmony_ci#include "aq_filters.h"
1562306a36Sopenharmony_ci#include "aq_macsec.h"
1662306a36Sopenharmony_ci#include "aq_main.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include <linux/ptp_clock_kernel.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic void aq_ethtool_get_regs(struct net_device *ndev,
2162306a36Sopenharmony_ci				struct ethtool_regs *regs, void *p)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
2462306a36Sopenharmony_ci	u32 regs_count;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	regs_count = aq_nic_get_regs_count(aq_nic);
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	memset(p, 0, regs_count * sizeof(u32));
2962306a36Sopenharmony_ci	aq_nic_get_regs(aq_nic, regs, p);
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic int aq_ethtool_get_regs_len(struct net_device *ndev)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
3562306a36Sopenharmony_ci	u32 regs_count;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	regs_count = aq_nic_get_regs_count(aq_nic);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	return regs_count * sizeof(u32);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic u32 aq_ethtool_get_link(struct net_device *ndev)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	return ethtool_op_get_link(ndev);
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic int aq_ethtool_get_link_ksettings(struct net_device *ndev,
4862306a36Sopenharmony_ci					 struct ethtool_link_ksettings *cmd)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	aq_nic_get_link_ksettings(aq_nic, cmd);
5362306a36Sopenharmony_ci	cmd->base.speed = netif_carrier_ok(ndev) ?
5462306a36Sopenharmony_ci				aq_nic_get_link_speed(aq_nic) : 0U;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	return 0;
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic int
6062306a36Sopenharmony_ciaq_ethtool_set_link_ksettings(struct net_device *ndev,
6162306a36Sopenharmony_ci			      const struct ethtool_link_ksettings *cmd)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	return aq_nic_set_link_ksettings(aq_nic, cmd);
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
6962306a36Sopenharmony_ci	"InPackets",
7062306a36Sopenharmony_ci	"InUCast",
7162306a36Sopenharmony_ci	"InMCast",
7262306a36Sopenharmony_ci	"InBCast",
7362306a36Sopenharmony_ci	"InErrors",
7462306a36Sopenharmony_ci	"OutPackets",
7562306a36Sopenharmony_ci	"OutUCast",
7662306a36Sopenharmony_ci	"OutMCast",
7762306a36Sopenharmony_ci	"OutBCast",
7862306a36Sopenharmony_ci	"InUCastOctets",
7962306a36Sopenharmony_ci	"OutUCastOctets",
8062306a36Sopenharmony_ci	"InMCastOctets",
8162306a36Sopenharmony_ci	"OutMCastOctets",
8262306a36Sopenharmony_ci	"InBCastOctets",
8362306a36Sopenharmony_ci	"OutBCastOctets",
8462306a36Sopenharmony_ci	"InOctets",
8562306a36Sopenharmony_ci	"OutOctets",
8662306a36Sopenharmony_ci	"InPacketsDma",
8762306a36Sopenharmony_ci	"OutPacketsDma",
8862306a36Sopenharmony_ci	"InOctetsDma",
8962306a36Sopenharmony_ci	"OutOctetsDma",
9062306a36Sopenharmony_ci	"InDroppedDma",
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic const char * const aq_ethtool_queue_rx_stat_names[] = {
9462306a36Sopenharmony_ci	"%sQueue[%d] InPackets",
9562306a36Sopenharmony_ci	"%sQueue[%d] InJumboPackets",
9662306a36Sopenharmony_ci	"%sQueue[%d] InLroPackets",
9762306a36Sopenharmony_ci	"%sQueue[%d] InErrors",
9862306a36Sopenharmony_ci	"%sQueue[%d] AllocFails",
9962306a36Sopenharmony_ci	"%sQueue[%d] SkbAllocFails",
10062306a36Sopenharmony_ci	"%sQueue[%d] Polls",
10162306a36Sopenharmony_ci	"%sQueue[%d] PageFlips",
10262306a36Sopenharmony_ci	"%sQueue[%d] PageReuses",
10362306a36Sopenharmony_ci	"%sQueue[%d] PageFrees",
10462306a36Sopenharmony_ci	"%sQueue[%d] XdpAbort",
10562306a36Sopenharmony_ci	"%sQueue[%d] XdpDrop",
10662306a36Sopenharmony_ci	"%sQueue[%d] XdpPass",
10762306a36Sopenharmony_ci	"%sQueue[%d] XdpTx",
10862306a36Sopenharmony_ci	"%sQueue[%d] XdpInvalid",
10962306a36Sopenharmony_ci	"%sQueue[%d] XdpRedirect",
11062306a36Sopenharmony_ci};
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistatic const char * const aq_ethtool_queue_tx_stat_names[] = {
11362306a36Sopenharmony_ci	"%sQueue[%d] OutPackets",
11462306a36Sopenharmony_ci	"%sQueue[%d] Restarts",
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC)
11862306a36Sopenharmony_cistatic const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = {
11962306a36Sopenharmony_ci	"MACSec InCtlPackets",
12062306a36Sopenharmony_ci	"MACSec InTaggedMissPackets",
12162306a36Sopenharmony_ci	"MACSec InUntaggedMissPackets",
12262306a36Sopenharmony_ci	"MACSec InNotagPackets",
12362306a36Sopenharmony_ci	"MACSec InUntaggedPackets",
12462306a36Sopenharmony_ci	"MACSec InBadTagPackets",
12562306a36Sopenharmony_ci	"MACSec InNoSciPackets",
12662306a36Sopenharmony_ci	"MACSec InUnknownSciPackets",
12762306a36Sopenharmony_ci	"MACSec InCtrlPortPassPackets",
12862306a36Sopenharmony_ci	"MACSec InUnctrlPortPassPackets",
12962306a36Sopenharmony_ci	"MACSec InCtrlPortFailPackets",
13062306a36Sopenharmony_ci	"MACSec InUnctrlPortFailPackets",
13162306a36Sopenharmony_ci	"MACSec InTooLongPackets",
13262306a36Sopenharmony_ci	"MACSec InIgpocCtlPackets",
13362306a36Sopenharmony_ci	"MACSec InEccErrorPackets",
13462306a36Sopenharmony_ci	"MACSec InUnctrlHitDropRedir",
13562306a36Sopenharmony_ci	"MACSec OutCtlPackets",
13662306a36Sopenharmony_ci	"MACSec OutUnknownSaPackets",
13762306a36Sopenharmony_ci	"MACSec OutUntaggedPackets",
13862306a36Sopenharmony_ci	"MACSec OutTooLong",
13962306a36Sopenharmony_ci	"MACSec OutEccErrorPackets",
14062306a36Sopenharmony_ci	"MACSec OutUnctrlHitDropRedir",
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistatic const char * const aq_macsec_txsc_stat_names[] = {
14462306a36Sopenharmony_ci	"MACSecTXSC%d ProtectedPkts",
14562306a36Sopenharmony_ci	"MACSecTXSC%d EncryptedPkts",
14662306a36Sopenharmony_ci	"MACSecTXSC%d ProtectedOctets",
14762306a36Sopenharmony_ci	"MACSecTXSC%d EncryptedOctets",
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic const char * const aq_macsec_txsa_stat_names[] = {
15162306a36Sopenharmony_ci	"MACSecTXSC%dSA%d HitDropRedirect",
15262306a36Sopenharmony_ci	"MACSecTXSC%dSA%d Protected2Pkts",
15362306a36Sopenharmony_ci	"MACSecTXSC%dSA%d ProtectedPkts",
15462306a36Sopenharmony_ci	"MACSecTXSC%dSA%d EncryptedPkts",
15562306a36Sopenharmony_ci};
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_cistatic const char * const aq_macsec_rxsa_stat_names[] = {
15862306a36Sopenharmony_ci	"MACSecRXSC%dSA%d UntaggedHitPkts",
15962306a36Sopenharmony_ci	"MACSecRXSC%dSA%d CtrlHitDrpRedir",
16062306a36Sopenharmony_ci	"MACSecRXSC%dSA%d NotUsingSa",
16162306a36Sopenharmony_ci	"MACSecRXSC%dSA%d UnusedSa",
16262306a36Sopenharmony_ci	"MACSecRXSC%dSA%d NotValidPkts",
16362306a36Sopenharmony_ci	"MACSecRXSC%dSA%d InvalidPkts",
16462306a36Sopenharmony_ci	"MACSecRXSC%dSA%d OkPkts",
16562306a36Sopenharmony_ci	"MACSecRXSC%dSA%d LatePkts",
16662306a36Sopenharmony_ci	"MACSecRXSC%dSA%d DelayedPkts",
16762306a36Sopenharmony_ci	"MACSecRXSC%dSA%d UncheckedPkts",
16862306a36Sopenharmony_ci	"MACSecRXSC%dSA%d ValidatedOctets",
16962306a36Sopenharmony_ci	"MACSecRXSC%dSA%d DecryptedOctets",
17062306a36Sopenharmony_ci};
17162306a36Sopenharmony_ci#endif
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistatic const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
17462306a36Sopenharmony_ci	"DMASystemLoopback",
17562306a36Sopenharmony_ci	"PKTSystemLoopback",
17662306a36Sopenharmony_ci	"DMANetworkLoopback",
17762306a36Sopenharmony_ci	"PHYInternalLoopback",
17862306a36Sopenharmony_ci	"PHYExternalLoopback",
17962306a36Sopenharmony_ci};
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic u32 aq_ethtool_n_stats(struct net_device *ndev)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
18462306a36Sopenharmony_ci	const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
18562306a36Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ndev);
18662306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic);
18762306a36Sopenharmony_ci	u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
18862306a36Sopenharmony_ci		      (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
19162306a36Sopenharmony_ci	n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
19262306a36Sopenharmony_ci		   tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
19362306a36Sopenharmony_ci#endif
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC)
19662306a36Sopenharmony_ci	if (nic->macsec_cfg) {
19762306a36Sopenharmony_ci		n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
19862306a36Sopenharmony_ci			   ARRAY_SIZE(aq_macsec_txsc_stat_names) *
19962306a36Sopenharmony_ci				   aq_macsec_tx_sc_cnt(nic) +
20062306a36Sopenharmony_ci			   ARRAY_SIZE(aq_macsec_txsa_stat_names) *
20162306a36Sopenharmony_ci				   aq_macsec_tx_sa_cnt(nic) +
20262306a36Sopenharmony_ci			   ARRAY_SIZE(aq_macsec_rxsa_stat_names) *
20362306a36Sopenharmony_ci				   aq_macsec_rx_sa_cnt(nic);
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci#endif
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	return n_stats;
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic void aq_ethtool_stats(struct net_device *ndev,
21162306a36Sopenharmony_ci			     struct ethtool_stats *stats, u64 *data)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
21662306a36Sopenharmony_ci	data = aq_nic_get_stats(aq_nic, data);
21762306a36Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
21862306a36Sopenharmony_ci	data = aq_ptp_get_stats(aq_nic, data);
21962306a36Sopenharmony_ci#endif
22062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC)
22162306a36Sopenharmony_ci	data = aq_macsec_get_stats(aq_nic, data);
22262306a36Sopenharmony_ci#endif
22362306a36Sopenharmony_ci}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistatic void aq_ethtool_get_drvinfo(struct net_device *ndev,
22662306a36Sopenharmony_ci				   struct ethtool_drvinfo *drvinfo)
22762306a36Sopenharmony_ci{
22862306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
22962306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
23062306a36Sopenharmony_ci	u32 firmware_version;
23162306a36Sopenharmony_ci	u32 regs_count;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	firmware_version = aq_nic_get_fw_version(aq_nic);
23462306a36Sopenharmony_ci	regs_count = aq_nic_get_regs_count(aq_nic);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
23962306a36Sopenharmony_ci		 "%u.%u.%u", firmware_version >> 24,
24062306a36Sopenharmony_ci		 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	strscpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
24362306a36Sopenharmony_ci		sizeof(drvinfo->bus_info));
24462306a36Sopenharmony_ci	drvinfo->n_stats = aq_ethtool_n_stats(ndev);
24562306a36Sopenharmony_ci	drvinfo->testinfo_len = 0;
24662306a36Sopenharmony_ci	drvinfo->regdump_len = regs_count;
24762306a36Sopenharmony_ci	drvinfo->eedump_len = 0;
24862306a36Sopenharmony_ci}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cistatic void aq_ethtool_get_strings(struct net_device *ndev,
25162306a36Sopenharmony_ci				   u32 stringset, u8 *data)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	struct aq_nic_s *nic = netdev_priv(ndev);
25462306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
25562306a36Sopenharmony_ci	u8 *p = data;
25662306a36Sopenharmony_ci	int i, si;
25762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC)
25862306a36Sopenharmony_ci	int sa;
25962306a36Sopenharmony_ci#endif
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(nic);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	switch (stringset) {
26462306a36Sopenharmony_ci	case ETH_SS_STATS: {
26562306a36Sopenharmony_ci		const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
26662306a36Sopenharmony_ci		const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
26762306a36Sopenharmony_ci		char tc_string[8];
26862306a36Sopenharmony_ci		int tc;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci		memset(tc_string, 0, sizeof(tc_string));
27162306a36Sopenharmony_ci		memcpy(p, aq_ethtool_stat_names,
27262306a36Sopenharmony_ci		       sizeof(aq_ethtool_stat_names));
27362306a36Sopenharmony_ci		p = p + sizeof(aq_ethtool_stat_names);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci		for (tc = 0; tc < cfg->tcs; tc++) {
27662306a36Sopenharmony_ci			if (cfg->is_qos)
27762306a36Sopenharmony_ci				snprintf(tc_string, 8, "TC%d ", tc);
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci			for (i = 0; i < cfg->vecs; i++) {
28062306a36Sopenharmony_ci				for (si = 0; si < rx_stat_cnt; si++) {
28162306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
28262306a36Sopenharmony_ci					     aq_ethtool_queue_rx_stat_names[si],
28362306a36Sopenharmony_ci					     tc_string,
28462306a36Sopenharmony_ci					     AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
28562306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
28662306a36Sopenharmony_ci				}
28762306a36Sopenharmony_ci				for (si = 0; si < tx_stat_cnt; si++) {
28862306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
28962306a36Sopenharmony_ci					     aq_ethtool_queue_tx_stat_names[si],
29062306a36Sopenharmony_ci					     tc_string,
29162306a36Sopenharmony_ci					     AQ_NIC_CFG_TCVEC2RING(cfg, tc, i));
29262306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
29362306a36Sopenharmony_ci				}
29462306a36Sopenharmony_ci			}
29562306a36Sopenharmony_ci		}
29662306a36Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
29762306a36Sopenharmony_ci		if (nic->aq_ptp) {
29862306a36Sopenharmony_ci			const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX);
29962306a36Sopenharmony_ci			const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
30062306a36Sopenharmony_ci			unsigned int ptp_ring_idx =
30162306a36Sopenharmony_ci				aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci			snprintf(tc_string, 8, "PTP ");
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci			for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) {
30662306a36Sopenharmony_ci				for (si = 0; si < rx_stat_cnt; si++) {
30762306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
30862306a36Sopenharmony_ci						 aq_ethtool_queue_rx_stat_names[si],
30962306a36Sopenharmony_ci						 tc_string,
31062306a36Sopenharmony_ci						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
31162306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
31262306a36Sopenharmony_ci				}
31362306a36Sopenharmony_ci				if (i >= tx_ring_cnt)
31462306a36Sopenharmony_ci					continue;
31562306a36Sopenharmony_ci				for (si = 0; si < tx_stat_cnt; si++) {
31662306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
31762306a36Sopenharmony_ci						 aq_ethtool_queue_tx_stat_names[si],
31862306a36Sopenharmony_ci						 tc_string,
31962306a36Sopenharmony_ci						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
32062306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
32162306a36Sopenharmony_ci				}
32262306a36Sopenharmony_ci			}
32362306a36Sopenharmony_ci		}
32462306a36Sopenharmony_ci#endif
32562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC)
32662306a36Sopenharmony_ci		if (!nic->macsec_cfg)
32762306a36Sopenharmony_ci			break;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci		memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names));
33062306a36Sopenharmony_ci		p = p + sizeof(aq_macsec_stat_names);
33162306a36Sopenharmony_ci		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
33262306a36Sopenharmony_ci			struct aq_macsec_txsc *aq_txsc;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci			if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy)))
33562306a36Sopenharmony_ci				continue;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci			for (si = 0;
33862306a36Sopenharmony_ci				si < ARRAY_SIZE(aq_macsec_txsc_stat_names);
33962306a36Sopenharmony_ci				si++) {
34062306a36Sopenharmony_ci				snprintf(p, ETH_GSTRING_LEN,
34162306a36Sopenharmony_ci					 aq_macsec_txsc_stat_names[si], i);
34262306a36Sopenharmony_ci				p += ETH_GSTRING_LEN;
34362306a36Sopenharmony_ci			}
34462306a36Sopenharmony_ci			aq_txsc = &nic->macsec_cfg->aq_txsc[i];
34562306a36Sopenharmony_ci			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
34662306a36Sopenharmony_ci				if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy)))
34762306a36Sopenharmony_ci					continue;
34862306a36Sopenharmony_ci				for (si = 0;
34962306a36Sopenharmony_ci				     si < ARRAY_SIZE(aq_macsec_txsa_stat_names);
35062306a36Sopenharmony_ci				     si++) {
35162306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
35262306a36Sopenharmony_ci						 aq_macsec_txsa_stat_names[si],
35362306a36Sopenharmony_ci						 i, sa);
35462306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
35562306a36Sopenharmony_ci				}
35662306a36Sopenharmony_ci			}
35762306a36Sopenharmony_ci		}
35862306a36Sopenharmony_ci		for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
35962306a36Sopenharmony_ci			struct aq_macsec_rxsc *aq_rxsc;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci			if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy)))
36262306a36Sopenharmony_ci				continue;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci			aq_rxsc = &nic->macsec_cfg->aq_rxsc[i];
36562306a36Sopenharmony_ci			for (sa = 0; sa < MACSEC_NUM_AN; sa++) {
36662306a36Sopenharmony_ci				if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy)))
36762306a36Sopenharmony_ci					continue;
36862306a36Sopenharmony_ci				for (si = 0;
36962306a36Sopenharmony_ci				     si < ARRAY_SIZE(aq_macsec_rxsa_stat_names);
37062306a36Sopenharmony_ci				     si++) {
37162306a36Sopenharmony_ci					snprintf(p, ETH_GSTRING_LEN,
37262306a36Sopenharmony_ci						 aq_macsec_rxsa_stat_names[si],
37362306a36Sopenharmony_ci						 i, sa);
37462306a36Sopenharmony_ci					p += ETH_GSTRING_LEN;
37562306a36Sopenharmony_ci				}
37662306a36Sopenharmony_ci			}
37762306a36Sopenharmony_ci		}
37862306a36Sopenharmony_ci#endif
37962306a36Sopenharmony_ci		break;
38062306a36Sopenharmony_ci	}
38162306a36Sopenharmony_ci	case ETH_SS_PRIV_FLAGS:
38262306a36Sopenharmony_ci		memcpy(p, aq_ethtool_priv_flag_names,
38362306a36Sopenharmony_ci		       sizeof(aq_ethtool_priv_flag_names));
38462306a36Sopenharmony_ci		break;
38562306a36Sopenharmony_ci	}
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic int aq_ethtool_set_phys_id(struct net_device *ndev,
38962306a36Sopenharmony_ci				  enum ethtool_phys_id_state state)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
39262306a36Sopenharmony_ci	struct aq_hw_s *hw = aq_nic->aq_hw;
39362306a36Sopenharmony_ci	int ret = 0;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	if (!aq_nic->aq_fw_ops->led_control)
39662306a36Sopenharmony_ci		return -EOPNOTSUPP;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	mutex_lock(&aq_nic->fwreq_mutex);
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	switch (state) {
40162306a36Sopenharmony_ci	case ETHTOOL_ID_ACTIVE:
40262306a36Sopenharmony_ci		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
40362306a36Sopenharmony_ci				 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
40462306a36Sopenharmony_ci		break;
40562306a36Sopenharmony_ci	case ETHTOOL_ID_INACTIVE:
40662306a36Sopenharmony_ci		ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
40762306a36Sopenharmony_ci		break;
40862306a36Sopenharmony_ci	default:
40962306a36Sopenharmony_ci		break;
41062306a36Sopenharmony_ci	}
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	mutex_unlock(&aq_nic->fwreq_mutex);
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	return ret;
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	int ret = 0;
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	switch (stringset) {
42262306a36Sopenharmony_ci	case ETH_SS_STATS:
42362306a36Sopenharmony_ci		ret = aq_ethtool_n_stats(ndev);
42462306a36Sopenharmony_ci		break;
42562306a36Sopenharmony_ci	case ETH_SS_PRIV_FLAGS:
42662306a36Sopenharmony_ci		ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
42762306a36Sopenharmony_ci		break;
42862306a36Sopenharmony_ci	default:
42962306a36Sopenharmony_ci		ret = -EOPNOTSUPP;
43062306a36Sopenharmony_ci	}
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	return ret;
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_cistatic u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
43662306a36Sopenharmony_ci{
43762306a36Sopenharmony_ci	return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
43862306a36Sopenharmony_ci}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
44162306a36Sopenharmony_ci{
44262306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
44362306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	return sizeof(cfg->aq_rss.hash_secret_key);
44862306a36Sopenharmony_ci}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_cistatic int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
45162306a36Sopenharmony_ci			      u8 *hfunc)
45262306a36Sopenharmony_ci{
45362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
45462306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
45562306a36Sopenharmony_ci	unsigned int i = 0U;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	if (hfunc)
46062306a36Sopenharmony_ci		*hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
46162306a36Sopenharmony_ci	if (indir) {
46262306a36Sopenharmony_ci		for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
46362306a36Sopenharmony_ci			indir[i] = cfg->aq_rss.indirection_table[i];
46462306a36Sopenharmony_ci	}
46562306a36Sopenharmony_ci	if (key)
46662306a36Sopenharmony_ci		memcpy(key, cfg->aq_rss.hash_secret_key,
46762306a36Sopenharmony_ci		       sizeof(cfg->aq_rss.hash_secret_key));
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	return 0;
47062306a36Sopenharmony_ci}
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_cistatic int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
47362306a36Sopenharmony_ci			      const u8 *key, const u8 hfunc)
47462306a36Sopenharmony_ci{
47562306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(netdev);
47662306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
47762306a36Sopenharmony_ci	unsigned int i = 0U;
47862306a36Sopenharmony_ci	u32 rss_entries;
47962306a36Sopenharmony_ci	int err = 0;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
48262306a36Sopenharmony_ci	rss_entries = cfg->aq_rss.indirection_table_size;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	/* We do not allow change in unsupported parameters */
48562306a36Sopenharmony_ci	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
48662306a36Sopenharmony_ci		return -EOPNOTSUPP;
48762306a36Sopenharmony_ci	/* Fill out the redirection table */
48862306a36Sopenharmony_ci	if (indir)
48962306a36Sopenharmony_ci		for (i = 0; i < rss_entries; i++)
49062306a36Sopenharmony_ci			cfg->aq_rss.indirection_table[i] = indir[i];
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	/* Fill out the rss hash key */
49362306a36Sopenharmony_ci	if (key) {
49462306a36Sopenharmony_ci		memcpy(cfg->aq_rss.hash_secret_key, key,
49562306a36Sopenharmony_ci		       sizeof(cfg->aq_rss.hash_secret_key));
49662306a36Sopenharmony_ci		err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
49762306a36Sopenharmony_ci			&cfg->aq_rss);
49862306a36Sopenharmony_ci		if (err)
49962306a36Sopenharmony_ci			return err;
50062306a36Sopenharmony_ci	}
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci	return err;
50562306a36Sopenharmony_ci}
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_cistatic int aq_ethtool_get_rxnfc(struct net_device *ndev,
50862306a36Sopenharmony_ci				struct ethtool_rxnfc *cmd,
50962306a36Sopenharmony_ci				u32 *rule_locs)
51062306a36Sopenharmony_ci{
51162306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
51262306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
51362306a36Sopenharmony_ci	int err = 0;
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	switch (cmd->cmd) {
51862306a36Sopenharmony_ci	case ETHTOOL_GRXRINGS:
51962306a36Sopenharmony_ci		cmd->data = cfg->vecs;
52062306a36Sopenharmony_ci		break;
52162306a36Sopenharmony_ci	case ETHTOOL_GRXCLSRLCNT:
52262306a36Sopenharmony_ci		cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
52362306a36Sopenharmony_ci		break;
52462306a36Sopenharmony_ci	case ETHTOOL_GRXCLSRULE:
52562306a36Sopenharmony_ci		err = aq_get_rxnfc_rule(aq_nic, cmd);
52662306a36Sopenharmony_ci		break;
52762306a36Sopenharmony_ci	case ETHTOOL_GRXCLSRLALL:
52862306a36Sopenharmony_ci		err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
52962306a36Sopenharmony_ci		break;
53062306a36Sopenharmony_ci	default:
53162306a36Sopenharmony_ci		err = -EOPNOTSUPP;
53262306a36Sopenharmony_ci		break;
53362306a36Sopenharmony_ci	}
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	return err;
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistatic int aq_ethtool_set_rxnfc(struct net_device *ndev,
53962306a36Sopenharmony_ci				struct ethtool_rxnfc *cmd)
54062306a36Sopenharmony_ci{
54162306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
54262306a36Sopenharmony_ci	int err = 0;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	switch (cmd->cmd) {
54562306a36Sopenharmony_ci	case ETHTOOL_SRXCLSRLINS:
54662306a36Sopenharmony_ci		err = aq_add_rxnfc_rule(aq_nic, cmd);
54762306a36Sopenharmony_ci		break;
54862306a36Sopenharmony_ci	case ETHTOOL_SRXCLSRLDEL:
54962306a36Sopenharmony_ci		err = aq_del_rxnfc_rule(aq_nic, cmd);
55062306a36Sopenharmony_ci		break;
55162306a36Sopenharmony_ci	default:
55262306a36Sopenharmony_ci		err = -EOPNOTSUPP;
55362306a36Sopenharmony_ci		break;
55462306a36Sopenharmony_ci	}
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	return err;
55762306a36Sopenharmony_ci}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_cistatic int aq_ethtool_get_coalesce(struct net_device *ndev,
56062306a36Sopenharmony_ci				   struct ethtool_coalesce *coal,
56162306a36Sopenharmony_ci				   struct kernel_ethtool_coalesce *kernel_coal,
56262306a36Sopenharmony_ci				   struct netlink_ext_ack *extack)
56362306a36Sopenharmony_ci{
56462306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
56562306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
57062306a36Sopenharmony_ci	    cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
57162306a36Sopenharmony_ci		coal->rx_coalesce_usecs = cfg->rx_itr;
57262306a36Sopenharmony_ci		coal->tx_coalesce_usecs = cfg->tx_itr;
57362306a36Sopenharmony_ci		coal->rx_max_coalesced_frames = 0;
57462306a36Sopenharmony_ci		coal->tx_max_coalesced_frames = 0;
57562306a36Sopenharmony_ci	} else {
57662306a36Sopenharmony_ci		coal->rx_coalesce_usecs = 0;
57762306a36Sopenharmony_ci		coal->tx_coalesce_usecs = 0;
57862306a36Sopenharmony_ci		coal->rx_max_coalesced_frames = 1;
57962306a36Sopenharmony_ci		coal->tx_max_coalesced_frames = 1;
58062306a36Sopenharmony_ci	}
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	return 0;
58362306a36Sopenharmony_ci}
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_cistatic int aq_ethtool_set_coalesce(struct net_device *ndev,
58662306a36Sopenharmony_ci				   struct ethtool_coalesce *coal,
58762306a36Sopenharmony_ci				   struct kernel_ethtool_coalesce *kernel_coal,
58862306a36Sopenharmony_ci				   struct netlink_ext_ack *extack)
58962306a36Sopenharmony_ci{
59062306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
59162306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	/* Atlantic only supports timing based coalescing
59662306a36Sopenharmony_ci	 */
59762306a36Sopenharmony_ci	if (coal->rx_max_coalesced_frames > 1 ||
59862306a36Sopenharmony_ci	    coal->tx_max_coalesced_frames > 1)
59962306a36Sopenharmony_ci		return -EOPNOTSUPP;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	/* We do not support frame counting. Check this
60262306a36Sopenharmony_ci	 */
60362306a36Sopenharmony_ci	if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
60462306a36Sopenharmony_ci		return -EOPNOTSUPP;
60562306a36Sopenharmony_ci	if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
60662306a36Sopenharmony_ci		return -EOPNOTSUPP;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
60962306a36Sopenharmony_ci	    coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
61062306a36Sopenharmony_ci		return -EINVAL;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	cfg->rx_itr = coal->rx_coalesce_usecs;
61562306a36Sopenharmony_ci	cfg->tx_itr = coal->tx_coalesce_usecs;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	return aq_nic_update_interrupt_moderation_settings(aq_nic);
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_cistatic void aq_ethtool_get_wol(struct net_device *ndev,
62162306a36Sopenharmony_ci			       struct ethtool_wolinfo *wol)
62262306a36Sopenharmony_ci{
62362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
62462306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	wol->supported = AQ_NIC_WOL_MODES;
62962306a36Sopenharmony_ci	wol->wolopts = cfg->wol;
63062306a36Sopenharmony_ci}
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistatic int aq_ethtool_set_wol(struct net_device *ndev,
63362306a36Sopenharmony_ci			      struct ethtool_wolinfo *wol)
63462306a36Sopenharmony_ci{
63562306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
63662306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
63762306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
63862306a36Sopenharmony_ci	int err = 0;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	if (wol->wolopts & ~AQ_NIC_WOL_MODES)
64362306a36Sopenharmony_ci		return -EOPNOTSUPP;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	cfg->wol = wol->wolopts;
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_ci	err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	return err;
65062306a36Sopenharmony_ci}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic int aq_ethtool_get_ts_info(struct net_device *ndev,
65362306a36Sopenharmony_ci				  struct ethtool_ts_info *info)
65462306a36Sopenharmony_ci{
65562306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	ethtool_op_get_ts_info(ndev, info);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	if (!aq_nic->aq_ptp)
66062306a36Sopenharmony_ci		return 0;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	info->so_timestamping |=
66362306a36Sopenharmony_ci		SOF_TIMESTAMPING_TX_HARDWARE |
66462306a36Sopenharmony_ci		SOF_TIMESTAMPING_RX_HARDWARE |
66562306a36Sopenharmony_ci		SOF_TIMESTAMPING_RAW_HARDWARE;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
66862306a36Sopenharmony_ci			 BIT(HWTSTAMP_TX_ON);
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
67362306a36Sopenharmony_ci			    BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
67462306a36Sopenharmony_ci			    BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
67762306a36Sopenharmony_ci	info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
67862306a36Sopenharmony_ci#endif
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	return 0;
68162306a36Sopenharmony_ci}
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_cistatic u32 eee_mask_to_ethtool_mask(u32 speed)
68462306a36Sopenharmony_ci{
68562306a36Sopenharmony_ci	u32 rate = 0;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	if (speed & AQ_NIC_RATE_EEE_10G)
68862306a36Sopenharmony_ci		rate |= SUPPORTED_10000baseT_Full;
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	if (speed & AQ_NIC_RATE_EEE_1G)
69162306a36Sopenharmony_ci		rate |= SUPPORTED_1000baseT_Full;
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	if (speed & AQ_NIC_RATE_EEE_100M)
69462306a36Sopenharmony_ci		rate |= SUPPORTED_100baseT_Full;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	return rate;
69762306a36Sopenharmony_ci}
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_cistatic int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
70062306a36Sopenharmony_ci{
70162306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
70262306a36Sopenharmony_ci	u32 rate, supported_rates;
70362306a36Sopenharmony_ci	int err = 0;
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	if (!aq_nic->aq_fw_ops->get_eee_rate)
70662306a36Sopenharmony_ci		return -EOPNOTSUPP;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	mutex_lock(&aq_nic->fwreq_mutex);
70962306a36Sopenharmony_ci	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
71062306a36Sopenharmony_ci					      &supported_rates);
71162306a36Sopenharmony_ci	mutex_unlock(&aq_nic->fwreq_mutex);
71262306a36Sopenharmony_ci	if (err < 0)
71362306a36Sopenharmony_ci		return err;
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_ci	eee->supported = eee_mask_to_ethtool_mask(supported_rates);
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	if (aq_nic->aq_nic_cfg.eee_speeds)
71862306a36Sopenharmony_ci		eee->advertised = eee->supported;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	eee->eee_enabled = !!eee->advertised;
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	eee->tx_lpi_enabled = eee->eee_enabled;
72562306a36Sopenharmony_ci	if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK)
72662306a36Sopenharmony_ci		eee->eee_active = true;
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	return 0;
72962306a36Sopenharmony_ci}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_cistatic int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
73262306a36Sopenharmony_ci{
73362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
73462306a36Sopenharmony_ci	u32 rate, supported_rates;
73562306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
73662306a36Sopenharmony_ci	int err = 0;
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
74162306a36Sopenharmony_ci		     !aq_nic->aq_fw_ops->set_eee_rate))
74262306a36Sopenharmony_ci		return -EOPNOTSUPP;
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	mutex_lock(&aq_nic->fwreq_mutex);
74562306a36Sopenharmony_ci	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
74662306a36Sopenharmony_ci					      &supported_rates);
74762306a36Sopenharmony_ci	mutex_unlock(&aq_nic->fwreq_mutex);
74862306a36Sopenharmony_ci	if (err < 0)
74962306a36Sopenharmony_ci		return err;
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	if (eee->eee_enabled) {
75262306a36Sopenharmony_ci		rate = supported_rates;
75362306a36Sopenharmony_ci		cfg->eee_speeds = rate;
75462306a36Sopenharmony_ci	} else {
75562306a36Sopenharmony_ci		rate = 0;
75662306a36Sopenharmony_ci		cfg->eee_speeds = 0;
75762306a36Sopenharmony_ci	}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	mutex_lock(&aq_nic->fwreq_mutex);
76062306a36Sopenharmony_ci	err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
76162306a36Sopenharmony_ci	mutex_unlock(&aq_nic->fwreq_mutex);
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci	return err;
76462306a36Sopenharmony_ci}
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_cistatic int aq_ethtool_nway_reset(struct net_device *ndev)
76762306a36Sopenharmony_ci{
76862306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
76962306a36Sopenharmony_ci	int err = 0;
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
77262306a36Sopenharmony_ci		return -EOPNOTSUPP;
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	if (netif_running(ndev)) {
77562306a36Sopenharmony_ci		mutex_lock(&aq_nic->fwreq_mutex);
77662306a36Sopenharmony_ci		err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
77762306a36Sopenharmony_ci		mutex_unlock(&aq_nic->fwreq_mutex);
77862306a36Sopenharmony_ci	}
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	return err;
78162306a36Sopenharmony_ci}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_cistatic void aq_ethtool_get_pauseparam(struct net_device *ndev,
78462306a36Sopenharmony_ci				      struct ethtool_pauseparam *pause)
78562306a36Sopenharmony_ci{
78662306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
78762306a36Sopenharmony_ci	int fc = aq_nic->aq_nic_cfg.fc.req;
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci	pause->autoneg = 0;
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
79262306a36Sopenharmony_ci	pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic int aq_ethtool_set_pauseparam(struct net_device *ndev,
79662306a36Sopenharmony_ci				     struct ethtool_pauseparam *pause)
79762306a36Sopenharmony_ci{
79862306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
79962306a36Sopenharmony_ci	int err = 0;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci	if (!aq_nic->aq_fw_ops->set_flow_control)
80262306a36Sopenharmony_ci		return -EOPNOTSUPP;
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	if (pause->autoneg == AUTONEG_ENABLE)
80562306a36Sopenharmony_ci		return -EOPNOTSUPP;
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	if (pause->rx_pause)
80862306a36Sopenharmony_ci		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
80962306a36Sopenharmony_ci	else
81062306a36Sopenharmony_ci		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	if (pause->tx_pause)
81362306a36Sopenharmony_ci		aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
81462306a36Sopenharmony_ci	else
81562306a36Sopenharmony_ci		aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci	mutex_lock(&aq_nic->fwreq_mutex);
81862306a36Sopenharmony_ci	err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
81962306a36Sopenharmony_ci	mutex_unlock(&aq_nic->fwreq_mutex);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	return err;
82262306a36Sopenharmony_ci}
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_cistatic void aq_get_ringparam(struct net_device *ndev,
82562306a36Sopenharmony_ci			     struct ethtool_ringparam *ring,
82662306a36Sopenharmony_ci			     struct kernel_ethtool_ringparam *kernel_ring,
82762306a36Sopenharmony_ci			     struct netlink_ext_ack *extack)
82862306a36Sopenharmony_ci{
82962306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
83062306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	ring->rx_pending = cfg->rxds;
83562306a36Sopenharmony_ci	ring->tx_pending = cfg->txds;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
83862306a36Sopenharmony_ci	ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
83962306a36Sopenharmony_ci}
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_cistatic int aq_set_ringparam(struct net_device *ndev,
84262306a36Sopenharmony_ci			    struct ethtool_ringparam *ring,
84362306a36Sopenharmony_ci			    struct kernel_ethtool_ringparam *kernel_ring,
84462306a36Sopenharmony_ci			    struct netlink_ext_ack *extack)
84562306a36Sopenharmony_ci{
84662306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
84762306a36Sopenharmony_ci	const struct aq_hw_caps_s *hw_caps;
84862306a36Sopenharmony_ci	bool ndev_running = false;
84962306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
85062306a36Sopenharmony_ci	int err = 0;
85162306a36Sopenharmony_ci
85262306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
85362306a36Sopenharmony_ci	hw_caps = cfg->aq_hw_caps;
85462306a36Sopenharmony_ci
85562306a36Sopenharmony_ci	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
85662306a36Sopenharmony_ci		err = -EOPNOTSUPP;
85762306a36Sopenharmony_ci		goto err_exit;
85862306a36Sopenharmony_ci	}
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	if (netif_running(ndev)) {
86162306a36Sopenharmony_ci		ndev_running = true;
86262306a36Sopenharmony_ci		aq_ndev_close(ndev);
86362306a36Sopenharmony_ci	}
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
86662306a36Sopenharmony_ci	cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
86762306a36Sopenharmony_ci	cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ci	cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
87062306a36Sopenharmony_ci	cfg->txds = min(cfg->txds, hw_caps->txds_max);
87162306a36Sopenharmony_ci	cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	err = aq_nic_realloc_vectors(aq_nic);
87462306a36Sopenharmony_ci	if (err)
87562306a36Sopenharmony_ci		goto err_exit;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	if (ndev_running)
87862306a36Sopenharmony_ci		err = aq_ndev_open(ndev);
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_cierr_exit:
88162306a36Sopenharmony_ci	return err;
88262306a36Sopenharmony_ci}
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_cistatic u32 aq_get_msg_level(struct net_device *ndev)
88562306a36Sopenharmony_ci{
88662306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	return aq_nic->msg_enable;
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_cistatic void aq_set_msg_level(struct net_device *ndev, u32 data)
89262306a36Sopenharmony_ci{
89362306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	aq_nic->msg_enable = data;
89662306a36Sopenharmony_ci}
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_cistatic u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
89962306a36Sopenharmony_ci{
90062306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci	return aq_nic->aq_nic_cfg.priv_flags;
90362306a36Sopenharmony_ci}
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_cistatic int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
90662306a36Sopenharmony_ci{
90762306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
90862306a36Sopenharmony_ci	struct aq_nic_cfg_s *cfg;
90962306a36Sopenharmony_ci	u32 priv_flags;
91062306a36Sopenharmony_ci	int ret = 0;
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	cfg = aq_nic_get_cfg(aq_nic);
91362306a36Sopenharmony_ci	priv_flags = cfg->priv_flags;
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci	if (flags & ~AQ_PRIV_FLAGS_MASK)
91662306a36Sopenharmony_ci		return -EOPNOTSUPP;
91762306a36Sopenharmony_ci
91862306a36Sopenharmony_ci	if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
91962306a36Sopenharmony_ci		netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
92062306a36Sopenharmony_ci		return -EINVAL;
92162306a36Sopenharmony_ci	}
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	cfg->priv_flags = flags;
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
92662306a36Sopenharmony_ci		if (netif_running(ndev)) {
92762306a36Sopenharmony_ci			dev_close(ndev);
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci			dev_open(ndev, NULL);
93062306a36Sopenharmony_ci		}
93162306a36Sopenharmony_ci	} else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
93262306a36Sopenharmony_ci		ret = aq_nic_set_loopback(aq_nic);
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	return ret;
93662306a36Sopenharmony_ci}
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_cistatic int aq_ethtool_get_phy_tunable(struct net_device *ndev,
93962306a36Sopenharmony_ci				      const struct ethtool_tunable *tuna, void *data)
94062306a36Sopenharmony_ci{
94162306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	switch (tuna->id) {
94462306a36Sopenharmony_ci	case ETHTOOL_PHY_EDPD: {
94562306a36Sopenharmony_ci		u16 *val = data;
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci		*val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0;
94862306a36Sopenharmony_ci		break;
94962306a36Sopenharmony_ci	}
95062306a36Sopenharmony_ci	case ETHTOOL_PHY_DOWNSHIFT: {
95162306a36Sopenharmony_ci		u8 *val = data;
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci		*val = (u8)aq_nic->aq_nic_cfg.downshift_counter;
95462306a36Sopenharmony_ci		break;
95562306a36Sopenharmony_ci	}
95662306a36Sopenharmony_ci	default:
95762306a36Sopenharmony_ci		return -EOPNOTSUPP;
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	return 0;
96162306a36Sopenharmony_ci}
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_cistatic int aq_ethtool_set_phy_tunable(struct net_device *ndev,
96462306a36Sopenharmony_ci				      const struct ethtool_tunable *tuna, const void *data)
96562306a36Sopenharmony_ci{
96662306a36Sopenharmony_ci	int err = -EOPNOTSUPP;
96762306a36Sopenharmony_ci	struct aq_nic_s *aq_nic = netdev_priv(ndev);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	switch (tuna->id) {
97062306a36Sopenharmony_ci	case ETHTOOL_PHY_EDPD: {
97162306a36Sopenharmony_ci		const u16 *val = data;
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci		err = aq_nic_set_media_detect(aq_nic, *val);
97462306a36Sopenharmony_ci		break;
97562306a36Sopenharmony_ci	}
97662306a36Sopenharmony_ci	case ETHTOOL_PHY_DOWNSHIFT: {
97762306a36Sopenharmony_ci		const u8 *val = data;
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci		err = aq_nic_set_downshift(aq_nic, *val);
98062306a36Sopenharmony_ci		break;
98162306a36Sopenharmony_ci	}
98262306a36Sopenharmony_ci	default:
98362306a36Sopenharmony_ci		break;
98462306a36Sopenharmony_ci	}
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ci	return err;
98762306a36Sopenharmony_ci}
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ciconst struct ethtool_ops aq_ethtool_ops = {
99062306a36Sopenharmony_ci	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
99162306a36Sopenharmony_ci				     ETHTOOL_COALESCE_MAX_FRAMES,
99262306a36Sopenharmony_ci	.get_link            = aq_ethtool_get_link,
99362306a36Sopenharmony_ci	.get_regs_len        = aq_ethtool_get_regs_len,
99462306a36Sopenharmony_ci	.get_regs            = aq_ethtool_get_regs,
99562306a36Sopenharmony_ci	.get_drvinfo         = aq_ethtool_get_drvinfo,
99662306a36Sopenharmony_ci	.get_strings         = aq_ethtool_get_strings,
99762306a36Sopenharmony_ci	.set_phys_id         = aq_ethtool_set_phys_id,
99862306a36Sopenharmony_ci	.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
99962306a36Sopenharmony_ci	.get_wol             = aq_ethtool_get_wol,
100062306a36Sopenharmony_ci	.set_wol             = aq_ethtool_set_wol,
100162306a36Sopenharmony_ci	.nway_reset          = aq_ethtool_nway_reset,
100262306a36Sopenharmony_ci	.get_ringparam       = aq_get_ringparam,
100362306a36Sopenharmony_ci	.set_ringparam       = aq_set_ringparam,
100462306a36Sopenharmony_ci	.get_eee             = aq_ethtool_get_eee,
100562306a36Sopenharmony_ci	.set_eee             = aq_ethtool_set_eee,
100662306a36Sopenharmony_ci	.get_pauseparam      = aq_ethtool_get_pauseparam,
100762306a36Sopenharmony_ci	.set_pauseparam      = aq_ethtool_set_pauseparam,
100862306a36Sopenharmony_ci	.get_rxfh_key_size   = aq_ethtool_get_rss_key_size,
100962306a36Sopenharmony_ci	.get_rxfh            = aq_ethtool_get_rss,
101062306a36Sopenharmony_ci	.set_rxfh            = aq_ethtool_set_rss,
101162306a36Sopenharmony_ci	.get_rxnfc           = aq_ethtool_get_rxnfc,
101262306a36Sopenharmony_ci	.set_rxnfc           = aq_ethtool_set_rxnfc,
101362306a36Sopenharmony_ci	.get_msglevel        = aq_get_msg_level,
101462306a36Sopenharmony_ci	.set_msglevel        = aq_set_msg_level,
101562306a36Sopenharmony_ci	.get_sset_count      = aq_ethtool_get_sset_count,
101662306a36Sopenharmony_ci	.get_ethtool_stats   = aq_ethtool_stats,
101762306a36Sopenharmony_ci	.get_priv_flags      = aq_ethtool_get_priv_flags,
101862306a36Sopenharmony_ci	.set_priv_flags      = aq_ethtool_set_priv_flags,
101962306a36Sopenharmony_ci	.get_link_ksettings  = aq_ethtool_get_link_ksettings,
102062306a36Sopenharmony_ci	.set_link_ksettings  = aq_ethtool_set_link_ksettings,
102162306a36Sopenharmony_ci	.get_coalesce	     = aq_ethtool_get_coalesce,
102262306a36Sopenharmony_ci	.set_coalesce	     = aq_ethtool_set_coalesce,
102362306a36Sopenharmony_ci	.get_ts_info         = aq_ethtool_get_ts_info,
102462306a36Sopenharmony_ci	.get_phy_tunable     = aq_ethtool_get_phy_tunable,
102562306a36Sopenharmony_ci	.set_phy_tunable     = aq_ethtool_set_phy_tunable,
102662306a36Sopenharmony_ci};
1027