18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* Atlantic Network Driver 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2014-2019 aQuantia Corporation 58c2ecf20Sopenharmony_ci * Copyright (C) 2019-2020 Marvell International Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci/* File aq_ethtool.c: Definition of ethertool related functions. */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "aq_ethtool.h" 118c2ecf20Sopenharmony_ci#include "aq_nic.h" 128c2ecf20Sopenharmony_ci#include "aq_vec.h" 138c2ecf20Sopenharmony_ci#include "aq_ptp.h" 148c2ecf20Sopenharmony_ci#include "aq_filters.h" 158c2ecf20Sopenharmony_ci#include "aq_macsec.h" 168c2ecf20Sopenharmony_ci#include "aq_main.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/ptp_clock_kernel.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic void aq_ethtool_get_regs(struct net_device *ndev, 218c2ecf20Sopenharmony_ci struct ethtool_regs *regs, void *p) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 248c2ecf20Sopenharmony_ci u32 regs_count; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci regs_count = aq_nic_get_regs_count(aq_nic); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci memset(p, 0, regs_count * sizeof(u32)); 298c2ecf20Sopenharmony_ci aq_nic_get_regs(aq_nic, regs, p); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic int aq_ethtool_get_regs_len(struct net_device *ndev) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 358c2ecf20Sopenharmony_ci u32 regs_count; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci regs_count = aq_nic_get_regs_count(aq_nic); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci return regs_count * sizeof(u32); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic u32 aq_ethtool_get_link(struct net_device *ndev) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci return ethtool_op_get_link(ndev); 458c2ecf20Sopenharmony_ci} 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic int aq_ethtool_get_link_ksettings(struct net_device *ndev, 488c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci aq_nic_get_link_ksettings(aq_nic, cmd); 538c2ecf20Sopenharmony_ci cmd->base.speed = netif_carrier_ok(ndev) ? 548c2ecf20Sopenharmony_ci aq_nic_get_link_speed(aq_nic) : 0U; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci return 0; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic int 608c2ecf20Sopenharmony_ciaq_ethtool_set_link_ksettings(struct net_device *ndev, 618c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *cmd) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return aq_nic_set_link_ksettings(aq_nic, cmd); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { 698c2ecf20Sopenharmony_ci "InPackets", 708c2ecf20Sopenharmony_ci "InUCast", 718c2ecf20Sopenharmony_ci "InMCast", 728c2ecf20Sopenharmony_ci "InBCast", 738c2ecf20Sopenharmony_ci "InErrors", 748c2ecf20Sopenharmony_ci "OutPackets", 758c2ecf20Sopenharmony_ci "OutUCast", 768c2ecf20Sopenharmony_ci "OutMCast", 778c2ecf20Sopenharmony_ci "OutBCast", 788c2ecf20Sopenharmony_ci "InUCastOctets", 798c2ecf20Sopenharmony_ci "OutUCastOctets", 808c2ecf20Sopenharmony_ci "InMCastOctets", 818c2ecf20Sopenharmony_ci "OutMCastOctets", 828c2ecf20Sopenharmony_ci "InBCastOctets", 838c2ecf20Sopenharmony_ci "OutBCastOctets", 848c2ecf20Sopenharmony_ci "InOctets", 858c2ecf20Sopenharmony_ci "OutOctets", 868c2ecf20Sopenharmony_ci "InPacketsDma", 878c2ecf20Sopenharmony_ci "OutPacketsDma", 888c2ecf20Sopenharmony_ci "InOctetsDma", 898c2ecf20Sopenharmony_ci "OutOctetsDma", 908c2ecf20Sopenharmony_ci "InDroppedDma", 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic const char * const aq_ethtool_queue_rx_stat_names[] = { 948c2ecf20Sopenharmony_ci "%sQueue[%d] InPackets", 958c2ecf20Sopenharmony_ci "%sQueue[%d] InJumboPackets", 968c2ecf20Sopenharmony_ci "%sQueue[%d] InLroPackets", 978c2ecf20Sopenharmony_ci "%sQueue[%d] InErrors", 988c2ecf20Sopenharmony_ci "%sQueue[%d] AllocFails", 998c2ecf20Sopenharmony_ci "%sQueue[%d] SkbAllocFails", 1008c2ecf20Sopenharmony_ci "%sQueue[%d] Polls", 1018c2ecf20Sopenharmony_ci}; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic const char * const aq_ethtool_queue_tx_stat_names[] = { 1048c2ecf20Sopenharmony_ci "%sQueue[%d] OutPackets", 1058c2ecf20Sopenharmony_ci "%sQueue[%d] Restarts", 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC) 1098c2ecf20Sopenharmony_cistatic const char aq_macsec_stat_names[][ETH_GSTRING_LEN] = { 1108c2ecf20Sopenharmony_ci "MACSec InCtlPackets", 1118c2ecf20Sopenharmony_ci "MACSec InTaggedMissPackets", 1128c2ecf20Sopenharmony_ci "MACSec InUntaggedMissPackets", 1138c2ecf20Sopenharmony_ci "MACSec InNotagPackets", 1148c2ecf20Sopenharmony_ci "MACSec InUntaggedPackets", 1158c2ecf20Sopenharmony_ci "MACSec InBadTagPackets", 1168c2ecf20Sopenharmony_ci "MACSec InNoSciPackets", 1178c2ecf20Sopenharmony_ci "MACSec InUnknownSciPackets", 1188c2ecf20Sopenharmony_ci "MACSec InCtrlPortPassPackets", 1198c2ecf20Sopenharmony_ci "MACSec InUnctrlPortPassPackets", 1208c2ecf20Sopenharmony_ci "MACSec InCtrlPortFailPackets", 1218c2ecf20Sopenharmony_ci "MACSec InUnctrlPortFailPackets", 1228c2ecf20Sopenharmony_ci "MACSec InTooLongPackets", 1238c2ecf20Sopenharmony_ci "MACSec InIgpocCtlPackets", 1248c2ecf20Sopenharmony_ci "MACSec InEccErrorPackets", 1258c2ecf20Sopenharmony_ci "MACSec InUnctrlHitDropRedir", 1268c2ecf20Sopenharmony_ci "MACSec OutCtlPackets", 1278c2ecf20Sopenharmony_ci "MACSec OutUnknownSaPackets", 1288c2ecf20Sopenharmony_ci "MACSec OutUntaggedPackets", 1298c2ecf20Sopenharmony_ci "MACSec OutTooLong", 1308c2ecf20Sopenharmony_ci "MACSec OutEccErrorPackets", 1318c2ecf20Sopenharmony_ci "MACSec OutUnctrlHitDropRedir", 1328c2ecf20Sopenharmony_ci}; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic const char * const aq_macsec_txsc_stat_names[] = { 1358c2ecf20Sopenharmony_ci "MACSecTXSC%d ProtectedPkts", 1368c2ecf20Sopenharmony_ci "MACSecTXSC%d EncryptedPkts", 1378c2ecf20Sopenharmony_ci "MACSecTXSC%d ProtectedOctets", 1388c2ecf20Sopenharmony_ci "MACSecTXSC%d EncryptedOctets", 1398c2ecf20Sopenharmony_ci}; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic const char * const aq_macsec_txsa_stat_names[] = { 1428c2ecf20Sopenharmony_ci "MACSecTXSC%dSA%d HitDropRedirect", 1438c2ecf20Sopenharmony_ci "MACSecTXSC%dSA%d Protected2Pkts", 1448c2ecf20Sopenharmony_ci "MACSecTXSC%dSA%d ProtectedPkts", 1458c2ecf20Sopenharmony_ci "MACSecTXSC%dSA%d EncryptedPkts", 1468c2ecf20Sopenharmony_ci}; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic const char * const aq_macsec_rxsa_stat_names[] = { 1498c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d UntaggedHitPkts", 1508c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d CtrlHitDrpRedir", 1518c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d NotUsingSa", 1528c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d UnusedSa", 1538c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d NotValidPkts", 1548c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d InvalidPkts", 1558c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d OkPkts", 1568c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d LatePkts", 1578c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d DelayedPkts", 1588c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d UncheckedPkts", 1598c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d ValidatedOctets", 1608c2ecf20Sopenharmony_ci "MACSecRXSC%dSA%d DecryptedOctets", 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci#endif 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = { 1658c2ecf20Sopenharmony_ci "DMASystemLoopback", 1668c2ecf20Sopenharmony_ci "PKTSystemLoopback", 1678c2ecf20Sopenharmony_ci "DMANetworkLoopback", 1688c2ecf20Sopenharmony_ci "PHYInternalLoopback", 1698c2ecf20Sopenharmony_ci "PHYExternalLoopback", 1708c2ecf20Sopenharmony_ci}; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic u32 aq_ethtool_n_stats(struct net_device *ndev) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names); 1758c2ecf20Sopenharmony_ci const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names); 1768c2ecf20Sopenharmony_ci struct aq_nic_s *nic = netdev_priv(ndev); 1778c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(nic); 1788c2ecf20Sopenharmony_ci u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) + 1798c2ecf20Sopenharmony_ci (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) 1828c2ecf20Sopenharmony_ci n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) + 1838c2ecf20Sopenharmony_ci tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX); 1848c2ecf20Sopenharmony_ci#endif 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC) 1878c2ecf20Sopenharmony_ci if (nic->macsec_cfg) { 1888c2ecf20Sopenharmony_ci n_stats += ARRAY_SIZE(aq_macsec_stat_names) + 1898c2ecf20Sopenharmony_ci ARRAY_SIZE(aq_macsec_txsc_stat_names) * 1908c2ecf20Sopenharmony_ci aq_macsec_tx_sc_cnt(nic) + 1918c2ecf20Sopenharmony_ci ARRAY_SIZE(aq_macsec_txsa_stat_names) * 1928c2ecf20Sopenharmony_ci aq_macsec_tx_sa_cnt(nic) + 1938c2ecf20Sopenharmony_ci ARRAY_SIZE(aq_macsec_rxsa_stat_names) * 1948c2ecf20Sopenharmony_ci aq_macsec_rx_sa_cnt(nic); 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci#endif 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci return n_stats; 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic void aq_ethtool_stats(struct net_device *ndev, 2028c2ecf20Sopenharmony_ci struct ethtool_stats *stats, u64 *data) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64)); 2078c2ecf20Sopenharmony_ci data = aq_nic_get_stats(aq_nic, data); 2088c2ecf20Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) 2098c2ecf20Sopenharmony_ci data = aq_ptp_get_stats(aq_nic, data); 2108c2ecf20Sopenharmony_ci#endif 2118c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC) 2128c2ecf20Sopenharmony_ci data = aq_macsec_get_stats(aq_nic, data); 2138c2ecf20Sopenharmony_ci#endif 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic void aq_ethtool_get_drvinfo(struct net_device *ndev, 2178c2ecf20Sopenharmony_ci struct ethtool_drvinfo *drvinfo) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); 2208c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 2218c2ecf20Sopenharmony_ci u32 firmware_version; 2228c2ecf20Sopenharmony_ci u32 regs_count; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci firmware_version = aq_nic_get_fw_version(aq_nic); 2258c2ecf20Sopenharmony_ci regs_count = aq_nic_get_regs_count(aq_nic); 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver)); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), 2308c2ecf20Sopenharmony_ci "%u.%u.%u", firmware_version >> 24, 2318c2ecf20Sopenharmony_ci (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", 2348c2ecf20Sopenharmony_ci sizeof(drvinfo->bus_info)); 2358c2ecf20Sopenharmony_ci drvinfo->n_stats = aq_ethtool_n_stats(ndev); 2368c2ecf20Sopenharmony_ci drvinfo->testinfo_len = 0; 2378c2ecf20Sopenharmony_ci drvinfo->regdump_len = regs_count; 2388c2ecf20Sopenharmony_ci drvinfo->eedump_len = 0; 2398c2ecf20Sopenharmony_ci} 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_cistatic void aq_ethtool_get_strings(struct net_device *ndev, 2428c2ecf20Sopenharmony_ci u32 stringset, u8 *data) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci struct aq_nic_s *nic = netdev_priv(ndev); 2458c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 2468c2ecf20Sopenharmony_ci u8 *p = data; 2478c2ecf20Sopenharmony_ci int i, si; 2488c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC) 2498c2ecf20Sopenharmony_ci int sa; 2508c2ecf20Sopenharmony_ci#endif 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(nic); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci switch (stringset) { 2558c2ecf20Sopenharmony_ci case ETH_SS_STATS: { 2568c2ecf20Sopenharmony_ci const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names); 2578c2ecf20Sopenharmony_ci const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names); 2588c2ecf20Sopenharmony_ci char tc_string[8]; 2598c2ecf20Sopenharmony_ci int tc; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci memset(tc_string, 0, sizeof(tc_string)); 2628c2ecf20Sopenharmony_ci memcpy(p, aq_ethtool_stat_names, 2638c2ecf20Sopenharmony_ci sizeof(aq_ethtool_stat_names)); 2648c2ecf20Sopenharmony_ci p = p + sizeof(aq_ethtool_stat_names); 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci for (tc = 0; tc < cfg->tcs; tc++) { 2678c2ecf20Sopenharmony_ci if (cfg->is_qos) 2688c2ecf20Sopenharmony_ci snprintf(tc_string, 8, "TC%d ", tc); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci for (i = 0; i < cfg->vecs; i++) { 2718c2ecf20Sopenharmony_ci for (si = 0; si < rx_stat_cnt; si++) { 2728c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 2738c2ecf20Sopenharmony_ci aq_ethtool_queue_rx_stat_names[si], 2748c2ecf20Sopenharmony_ci tc_string, 2758c2ecf20Sopenharmony_ci AQ_NIC_CFG_TCVEC2RING(cfg, tc, i)); 2768c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 2778c2ecf20Sopenharmony_ci } 2788c2ecf20Sopenharmony_ci for (si = 0; si < tx_stat_cnt; si++) { 2798c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 2808c2ecf20Sopenharmony_ci aq_ethtool_queue_tx_stat_names[si], 2818c2ecf20Sopenharmony_ci tc_string, 2828c2ecf20Sopenharmony_ci AQ_NIC_CFG_TCVEC2RING(cfg, tc, i)); 2838c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) 2888c2ecf20Sopenharmony_ci if (nic->aq_ptp) { 2898c2ecf20Sopenharmony_ci const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX); 2908c2ecf20Sopenharmony_ci const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX); 2918c2ecf20Sopenharmony_ci unsigned int ptp_ring_idx = 2928c2ecf20Sopenharmony_ci aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci snprintf(tc_string, 8, "PTP "); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) { 2978c2ecf20Sopenharmony_ci for (si = 0; si < rx_stat_cnt; si++) { 2988c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 2998c2ecf20Sopenharmony_ci aq_ethtool_queue_rx_stat_names[si], 3008c2ecf20Sopenharmony_ci tc_string, 3018c2ecf20Sopenharmony_ci i ? PTP_HWST_RING_IDX : ptp_ring_idx); 3028c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci if (i >= tx_ring_cnt) 3058c2ecf20Sopenharmony_ci continue; 3068c2ecf20Sopenharmony_ci for (si = 0; si < tx_stat_cnt; si++) { 3078c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 3088c2ecf20Sopenharmony_ci aq_ethtool_queue_tx_stat_names[si], 3098c2ecf20Sopenharmony_ci tc_string, 3108c2ecf20Sopenharmony_ci i ? PTP_HWST_RING_IDX : ptp_ring_idx); 3118c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci } 3158c2ecf20Sopenharmony_ci#endif 3168c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MACSEC) 3178c2ecf20Sopenharmony_ci if (!nic->macsec_cfg) 3188c2ecf20Sopenharmony_ci break; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci memcpy(p, aq_macsec_stat_names, sizeof(aq_macsec_stat_names)); 3218c2ecf20Sopenharmony_ci p = p + sizeof(aq_macsec_stat_names); 3228c2ecf20Sopenharmony_ci for (i = 0; i < AQ_MACSEC_MAX_SC; i++) { 3238c2ecf20Sopenharmony_ci struct aq_macsec_txsc *aq_txsc; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (!(test_bit(i, &nic->macsec_cfg->txsc_idx_busy))) 3268c2ecf20Sopenharmony_ci continue; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci for (si = 0; 3298c2ecf20Sopenharmony_ci si < ARRAY_SIZE(aq_macsec_txsc_stat_names); 3308c2ecf20Sopenharmony_ci si++) { 3318c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 3328c2ecf20Sopenharmony_ci aq_macsec_txsc_stat_names[si], i); 3338c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci aq_txsc = &nic->macsec_cfg->aq_txsc[i]; 3368c2ecf20Sopenharmony_ci for (sa = 0; sa < MACSEC_NUM_AN; sa++) { 3378c2ecf20Sopenharmony_ci if (!(test_bit(sa, &aq_txsc->tx_sa_idx_busy))) 3388c2ecf20Sopenharmony_ci continue; 3398c2ecf20Sopenharmony_ci for (si = 0; 3408c2ecf20Sopenharmony_ci si < ARRAY_SIZE(aq_macsec_txsa_stat_names); 3418c2ecf20Sopenharmony_ci si++) { 3428c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 3438c2ecf20Sopenharmony_ci aq_macsec_txsa_stat_names[si], 3448c2ecf20Sopenharmony_ci i, sa); 3458c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci } 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci for (i = 0; i < AQ_MACSEC_MAX_SC; i++) { 3508c2ecf20Sopenharmony_ci struct aq_macsec_rxsc *aq_rxsc; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci if (!(test_bit(i, &nic->macsec_cfg->rxsc_idx_busy))) 3538c2ecf20Sopenharmony_ci continue; 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci aq_rxsc = &nic->macsec_cfg->aq_rxsc[i]; 3568c2ecf20Sopenharmony_ci for (sa = 0; sa < MACSEC_NUM_AN; sa++) { 3578c2ecf20Sopenharmony_ci if (!(test_bit(sa, &aq_rxsc->rx_sa_idx_busy))) 3588c2ecf20Sopenharmony_ci continue; 3598c2ecf20Sopenharmony_ci for (si = 0; 3608c2ecf20Sopenharmony_ci si < ARRAY_SIZE(aq_macsec_rxsa_stat_names); 3618c2ecf20Sopenharmony_ci si++) { 3628c2ecf20Sopenharmony_ci snprintf(p, ETH_GSTRING_LEN, 3638c2ecf20Sopenharmony_ci aq_macsec_rxsa_stat_names[si], 3648c2ecf20Sopenharmony_ci i, sa); 3658c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci#endif 3708c2ecf20Sopenharmony_ci break; 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 3738c2ecf20Sopenharmony_ci memcpy(p, aq_ethtool_priv_flag_names, 3748c2ecf20Sopenharmony_ci sizeof(aq_ethtool_priv_flag_names)); 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci } 3778c2ecf20Sopenharmony_ci} 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_cistatic int aq_ethtool_set_phys_id(struct net_device *ndev, 3808c2ecf20Sopenharmony_ci enum ethtool_phys_id_state state) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 3838c2ecf20Sopenharmony_ci struct aq_hw_s *hw = aq_nic->aq_hw; 3848c2ecf20Sopenharmony_ci int ret = 0; 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci if (!aq_nic->aq_fw_ops->led_control) 3878c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci switch (state) { 3928c2ecf20Sopenharmony_ci case ETHTOOL_ID_ACTIVE: 3938c2ecf20Sopenharmony_ci ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK | 3948c2ecf20Sopenharmony_ci AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4); 3958c2ecf20Sopenharmony_ci break; 3968c2ecf20Sopenharmony_ci case ETHTOOL_ID_INACTIVE: 3978c2ecf20Sopenharmony_ci ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT); 3988c2ecf20Sopenharmony_ci break; 3998c2ecf20Sopenharmony_ci default: 4008c2ecf20Sopenharmony_ci break; 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci return ret; 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) 4098c2ecf20Sopenharmony_ci{ 4108c2ecf20Sopenharmony_ci int ret = 0; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci switch (stringset) { 4138c2ecf20Sopenharmony_ci case ETH_SS_STATS: 4148c2ecf20Sopenharmony_ci ret = aq_ethtool_n_stats(ndev); 4158c2ecf20Sopenharmony_ci break; 4168c2ecf20Sopenharmony_ci case ETH_SS_PRIV_FLAGS: 4178c2ecf20Sopenharmony_ci ret = ARRAY_SIZE(aq_ethtool_priv_flag_names); 4188c2ecf20Sopenharmony_ci break; 4198c2ecf20Sopenharmony_ci default: 4208c2ecf20Sopenharmony_ci ret = -EOPNOTSUPP; 4218c2ecf20Sopenharmony_ci } 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci return ret; 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_cistatic u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci return AQ_CFG_RSS_INDIRECTION_TABLE_MAX; 4298c2ecf20Sopenharmony_ci} 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_cistatic u32 aq_ethtool_get_rss_key_size(struct net_device *ndev) 4328c2ecf20Sopenharmony_ci{ 4338c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 4348c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci return sizeof(cfg->aq_rss.hash_secret_key); 4398c2ecf20Sopenharmony_ci} 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistatic int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key, 4428c2ecf20Sopenharmony_ci u8 *hfunc) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 4458c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 4468c2ecf20Sopenharmony_ci unsigned int i = 0U; 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci if (hfunc) 4518c2ecf20Sopenharmony_ci *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */ 4528c2ecf20Sopenharmony_ci if (indir) { 4538c2ecf20Sopenharmony_ci for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++) 4548c2ecf20Sopenharmony_ci indir[i] = cfg->aq_rss.indirection_table[i]; 4558c2ecf20Sopenharmony_ci } 4568c2ecf20Sopenharmony_ci if (key) 4578c2ecf20Sopenharmony_ci memcpy(key, cfg->aq_rss.hash_secret_key, 4588c2ecf20Sopenharmony_ci sizeof(cfg->aq_rss.hash_secret_key)); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci return 0; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir, 4648c2ecf20Sopenharmony_ci const u8 *key, const u8 hfunc) 4658c2ecf20Sopenharmony_ci{ 4668c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(netdev); 4678c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 4688c2ecf20Sopenharmony_ci unsigned int i = 0U; 4698c2ecf20Sopenharmony_ci u32 rss_entries; 4708c2ecf20Sopenharmony_ci int err = 0; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 4738c2ecf20Sopenharmony_ci rss_entries = cfg->aq_rss.indirection_table_size; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci /* We do not allow change in unsupported parameters */ 4768c2ecf20Sopenharmony_ci if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 4778c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 4788c2ecf20Sopenharmony_ci /* Fill out the redirection table */ 4798c2ecf20Sopenharmony_ci if (indir) 4808c2ecf20Sopenharmony_ci for (i = 0; i < rss_entries; i++) 4818c2ecf20Sopenharmony_ci cfg->aq_rss.indirection_table[i] = indir[i]; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci /* Fill out the rss hash key */ 4848c2ecf20Sopenharmony_ci if (key) { 4858c2ecf20Sopenharmony_ci memcpy(cfg->aq_rss.hash_secret_key, key, 4868c2ecf20Sopenharmony_ci sizeof(cfg->aq_rss.hash_secret_key)); 4878c2ecf20Sopenharmony_ci err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw, 4888c2ecf20Sopenharmony_ci &cfg->aq_rss); 4898c2ecf20Sopenharmony_ci if (err) 4908c2ecf20Sopenharmony_ci return err; 4918c2ecf20Sopenharmony_ci } 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss); 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci return err; 4968c2ecf20Sopenharmony_ci} 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_cistatic int aq_ethtool_get_rxnfc(struct net_device *ndev, 4998c2ecf20Sopenharmony_ci struct ethtool_rxnfc *cmd, 5008c2ecf20Sopenharmony_ci u32 *rule_locs) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 5038c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 5048c2ecf20Sopenharmony_ci int err = 0; 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci switch (cmd->cmd) { 5098c2ecf20Sopenharmony_ci case ETHTOOL_GRXRINGS: 5108c2ecf20Sopenharmony_ci cmd->data = cfg->vecs; 5118c2ecf20Sopenharmony_ci break; 5128c2ecf20Sopenharmony_ci case ETHTOOL_GRXCLSRLCNT: 5138c2ecf20Sopenharmony_ci cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic); 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci case ETHTOOL_GRXCLSRULE: 5168c2ecf20Sopenharmony_ci err = aq_get_rxnfc_rule(aq_nic, cmd); 5178c2ecf20Sopenharmony_ci break; 5188c2ecf20Sopenharmony_ci case ETHTOOL_GRXCLSRLALL: 5198c2ecf20Sopenharmony_ci err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs); 5208c2ecf20Sopenharmony_ci break; 5218c2ecf20Sopenharmony_ci default: 5228c2ecf20Sopenharmony_ci err = -EOPNOTSUPP; 5238c2ecf20Sopenharmony_ci break; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci return err; 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic int aq_ethtool_set_rxnfc(struct net_device *ndev, 5308c2ecf20Sopenharmony_ci struct ethtool_rxnfc *cmd) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 5338c2ecf20Sopenharmony_ci int err = 0; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci switch (cmd->cmd) { 5368c2ecf20Sopenharmony_ci case ETHTOOL_SRXCLSRLINS: 5378c2ecf20Sopenharmony_ci err = aq_add_rxnfc_rule(aq_nic, cmd); 5388c2ecf20Sopenharmony_ci break; 5398c2ecf20Sopenharmony_ci case ETHTOOL_SRXCLSRLDEL: 5408c2ecf20Sopenharmony_ci err = aq_del_rxnfc_rule(aq_nic, cmd); 5418c2ecf20Sopenharmony_ci break; 5428c2ecf20Sopenharmony_ci default: 5438c2ecf20Sopenharmony_ci err = -EOPNOTSUPP; 5448c2ecf20Sopenharmony_ci break; 5458c2ecf20Sopenharmony_ci } 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci return err; 5488c2ecf20Sopenharmony_ci} 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cistatic int aq_ethtool_get_coalesce(struct net_device *ndev, 5518c2ecf20Sopenharmony_ci struct ethtool_coalesce *coal) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 5548c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || 5598c2ecf20Sopenharmony_ci cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { 5608c2ecf20Sopenharmony_ci coal->rx_coalesce_usecs = cfg->rx_itr; 5618c2ecf20Sopenharmony_ci coal->tx_coalesce_usecs = cfg->tx_itr; 5628c2ecf20Sopenharmony_ci coal->rx_max_coalesced_frames = 0; 5638c2ecf20Sopenharmony_ci coal->tx_max_coalesced_frames = 0; 5648c2ecf20Sopenharmony_ci } else { 5658c2ecf20Sopenharmony_ci coal->rx_coalesce_usecs = 0; 5668c2ecf20Sopenharmony_ci coal->tx_coalesce_usecs = 0; 5678c2ecf20Sopenharmony_ci coal->rx_max_coalesced_frames = 1; 5688c2ecf20Sopenharmony_ci coal->tx_max_coalesced_frames = 1; 5698c2ecf20Sopenharmony_ci } 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci return 0; 5728c2ecf20Sopenharmony_ci} 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cistatic int aq_ethtool_set_coalesce(struct net_device *ndev, 5758c2ecf20Sopenharmony_ci struct ethtool_coalesce *coal) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 5788c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci /* Atlantic only supports timing based coalescing 5838c2ecf20Sopenharmony_ci */ 5848c2ecf20Sopenharmony_ci if (coal->rx_max_coalesced_frames > 1 || 5858c2ecf20Sopenharmony_ci coal->tx_max_coalesced_frames > 1) 5868c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci /* We do not support frame counting. Check this 5898c2ecf20Sopenharmony_ci */ 5908c2ecf20Sopenharmony_ci if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) 5918c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 5928c2ecf20Sopenharmony_ci if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) 5938c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || 5968c2ecf20Sopenharmony_ci coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) 5978c2ecf20Sopenharmony_ci return -EINVAL; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci cfg->rx_itr = coal->rx_coalesce_usecs; 6028c2ecf20Sopenharmony_ci cfg->tx_itr = coal->tx_coalesce_usecs; 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci return aq_nic_update_interrupt_moderation_settings(aq_nic); 6058c2ecf20Sopenharmony_ci} 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_cistatic void aq_ethtool_get_wol(struct net_device *ndev, 6088c2ecf20Sopenharmony_ci struct ethtool_wolinfo *wol) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 6118c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci wol->supported = AQ_NIC_WOL_MODES; 6168c2ecf20Sopenharmony_ci wol->wolopts = cfg->wol; 6178c2ecf20Sopenharmony_ci} 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_cistatic int aq_ethtool_set_wol(struct net_device *ndev, 6208c2ecf20Sopenharmony_ci struct ethtool_wolinfo *wol) 6218c2ecf20Sopenharmony_ci{ 6228c2ecf20Sopenharmony_ci struct pci_dev *pdev = to_pci_dev(ndev->dev.parent); 6238c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 6248c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 6258c2ecf20Sopenharmony_ci int err = 0; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci if (wol->wolopts & ~AQ_NIC_WOL_MODES) 6308c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci cfg->wol = wol->wolopts; 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol); 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci return err; 6378c2ecf20Sopenharmony_ci} 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_cistatic int aq_ethtool_get_ts_info(struct net_device *ndev, 6408c2ecf20Sopenharmony_ci struct ethtool_ts_info *info) 6418c2ecf20Sopenharmony_ci{ 6428c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci ethtool_op_get_ts_info(ndev, info); 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci if (!aq_nic->aq_ptp) 6478c2ecf20Sopenharmony_ci return 0; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci info->so_timestamping |= 6508c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_TX_HARDWARE | 6518c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_RX_HARDWARE | 6528c2ecf20Sopenharmony_ci SOF_TIMESTAMPING_RAW_HARDWARE; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci info->tx_types = BIT(HWTSTAMP_TX_OFF) | 6558c2ecf20Sopenharmony_ci BIT(HWTSTAMP_TX_ON); 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 6608c2ecf20Sopenharmony_ci BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 6618c2ecf20Sopenharmony_ci BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); 6628c2ecf20Sopenharmony_ci 6638c2ecf20Sopenharmony_ci#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK) 6648c2ecf20Sopenharmony_ci info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp)); 6658c2ecf20Sopenharmony_ci#endif 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci return 0; 6688c2ecf20Sopenharmony_ci} 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_cistatic u32 eee_mask_to_ethtool_mask(u32 speed) 6718c2ecf20Sopenharmony_ci{ 6728c2ecf20Sopenharmony_ci u32 rate = 0; 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci if (speed & AQ_NIC_RATE_EEE_10G) 6758c2ecf20Sopenharmony_ci rate |= SUPPORTED_10000baseT_Full; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci if (speed & AQ_NIC_RATE_EEE_1G) 6788c2ecf20Sopenharmony_ci rate |= SUPPORTED_1000baseT_Full; 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci if (speed & AQ_NIC_RATE_EEE_100M) 6818c2ecf20Sopenharmony_ci rate |= SUPPORTED_100baseT_Full; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci return rate; 6848c2ecf20Sopenharmony_ci} 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_cistatic int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee) 6878c2ecf20Sopenharmony_ci{ 6888c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 6898c2ecf20Sopenharmony_ci u32 rate, supported_rates; 6908c2ecf20Sopenharmony_ci int err = 0; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci if (!aq_nic->aq_fw_ops->get_eee_rate) 6938c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 6968c2ecf20Sopenharmony_ci err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 6978c2ecf20Sopenharmony_ci &supported_rates); 6988c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 6998c2ecf20Sopenharmony_ci if (err < 0) 7008c2ecf20Sopenharmony_ci return err; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci eee->supported = eee_mask_to_ethtool_mask(supported_rates); 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_ci if (aq_nic->aq_nic_cfg.eee_speeds) 7058c2ecf20Sopenharmony_ci eee->advertised = eee->supported; 7068c2ecf20Sopenharmony_ci 7078c2ecf20Sopenharmony_ci eee->lp_advertised = eee_mask_to_ethtool_mask(rate); 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci eee->eee_enabled = !!eee->advertised; 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci eee->tx_lpi_enabled = eee->eee_enabled; 7128c2ecf20Sopenharmony_ci if ((supported_rates & rate) & AQ_NIC_RATE_EEE_MSK) 7138c2ecf20Sopenharmony_ci eee->eee_active = true; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci return 0; 7168c2ecf20Sopenharmony_ci} 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_cistatic int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee) 7198c2ecf20Sopenharmony_ci{ 7208c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 7218c2ecf20Sopenharmony_ci u32 rate, supported_rates; 7228c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 7238c2ecf20Sopenharmony_ci int err = 0; 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate || 7288c2ecf20Sopenharmony_ci !aq_nic->aq_fw_ops->set_eee_rate)) 7298c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 7328c2ecf20Sopenharmony_ci err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate, 7338c2ecf20Sopenharmony_ci &supported_rates); 7348c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 7358c2ecf20Sopenharmony_ci if (err < 0) 7368c2ecf20Sopenharmony_ci return err; 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci if (eee->eee_enabled) { 7398c2ecf20Sopenharmony_ci rate = supported_rates; 7408c2ecf20Sopenharmony_ci cfg->eee_speeds = rate; 7418c2ecf20Sopenharmony_ci } else { 7428c2ecf20Sopenharmony_ci rate = 0; 7438c2ecf20Sopenharmony_ci cfg->eee_speeds = 0; 7448c2ecf20Sopenharmony_ci } 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 7478c2ecf20Sopenharmony_ci err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate); 7488c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci return err; 7518c2ecf20Sopenharmony_ci} 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_cistatic int aq_ethtool_nway_reset(struct net_device *ndev) 7548c2ecf20Sopenharmony_ci{ 7558c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 7568c2ecf20Sopenharmony_ci int err = 0; 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_ci if (unlikely(!aq_nic->aq_fw_ops->renegotiate)) 7598c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci if (netif_running(ndev)) { 7628c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 7638c2ecf20Sopenharmony_ci err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw); 7648c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 7658c2ecf20Sopenharmony_ci } 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci return err; 7688c2ecf20Sopenharmony_ci} 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_cistatic void aq_ethtool_get_pauseparam(struct net_device *ndev, 7718c2ecf20Sopenharmony_ci struct ethtool_pauseparam *pause) 7728c2ecf20Sopenharmony_ci{ 7738c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 7748c2ecf20Sopenharmony_ci int fc = aq_nic->aq_nic_cfg.fc.req; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci pause->autoneg = 0; 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci pause->rx_pause = !!(fc & AQ_NIC_FC_RX); 7798c2ecf20Sopenharmony_ci pause->tx_pause = !!(fc & AQ_NIC_FC_TX); 7808c2ecf20Sopenharmony_ci} 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_cistatic int aq_ethtool_set_pauseparam(struct net_device *ndev, 7838c2ecf20Sopenharmony_ci struct ethtool_pauseparam *pause) 7848c2ecf20Sopenharmony_ci{ 7858c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 7868c2ecf20Sopenharmony_ci int err = 0; 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci if (!aq_nic->aq_fw_ops->set_flow_control) 7898c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci if (pause->autoneg == AUTONEG_ENABLE) 7928c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 7938c2ecf20Sopenharmony_ci 7948c2ecf20Sopenharmony_ci if (pause->rx_pause) 7958c2ecf20Sopenharmony_ci aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX; 7968c2ecf20Sopenharmony_ci else 7978c2ecf20Sopenharmony_ci aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX; 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci if (pause->tx_pause) 8008c2ecf20Sopenharmony_ci aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX; 8018c2ecf20Sopenharmony_ci else 8028c2ecf20Sopenharmony_ci aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX; 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci mutex_lock(&aq_nic->fwreq_mutex); 8058c2ecf20Sopenharmony_ci err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw); 8068c2ecf20Sopenharmony_ci mutex_unlock(&aq_nic->fwreq_mutex); 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci return err; 8098c2ecf20Sopenharmony_ci} 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_cistatic void aq_get_ringparam(struct net_device *ndev, 8128c2ecf20Sopenharmony_ci struct ethtool_ringparam *ring) 8138c2ecf20Sopenharmony_ci{ 8148c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8158c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci ring->rx_pending = cfg->rxds; 8208c2ecf20Sopenharmony_ci ring->tx_pending = cfg->txds; 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci ring->rx_max_pending = cfg->aq_hw_caps->rxds_max; 8238c2ecf20Sopenharmony_ci ring->tx_max_pending = cfg->aq_hw_caps->txds_max; 8248c2ecf20Sopenharmony_ci} 8258c2ecf20Sopenharmony_ci 8268c2ecf20Sopenharmony_cistatic int aq_set_ringparam(struct net_device *ndev, 8278c2ecf20Sopenharmony_ci struct ethtool_ringparam *ring) 8288c2ecf20Sopenharmony_ci{ 8298c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8308c2ecf20Sopenharmony_ci const struct aq_hw_caps_s *hw_caps; 8318c2ecf20Sopenharmony_ci bool ndev_running = false; 8328c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 8338c2ecf20Sopenharmony_ci int err = 0; 8348c2ecf20Sopenharmony_ci 8358c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 8368c2ecf20Sopenharmony_ci hw_caps = cfg->aq_hw_caps; 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci if (ring->rx_mini_pending || ring->rx_jumbo_pending) { 8398c2ecf20Sopenharmony_ci err = -EOPNOTSUPP; 8408c2ecf20Sopenharmony_ci goto err_exit; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci if (netif_running(ndev)) { 8448c2ecf20Sopenharmony_ci ndev_running = true; 8458c2ecf20Sopenharmony_ci aq_ndev_close(ndev); 8468c2ecf20Sopenharmony_ci } 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); 8498c2ecf20Sopenharmony_ci cfg->rxds = min(cfg->rxds, hw_caps->rxds_max); 8508c2ecf20Sopenharmony_ci cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE); 8518c2ecf20Sopenharmony_ci 8528c2ecf20Sopenharmony_ci cfg->txds = max(ring->tx_pending, hw_caps->txds_min); 8538c2ecf20Sopenharmony_ci cfg->txds = min(cfg->txds, hw_caps->txds_max); 8548c2ecf20Sopenharmony_ci cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE); 8558c2ecf20Sopenharmony_ci 8568c2ecf20Sopenharmony_ci err = aq_nic_realloc_vectors(aq_nic); 8578c2ecf20Sopenharmony_ci if (err) 8588c2ecf20Sopenharmony_ci goto err_exit; 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci if (ndev_running) 8618c2ecf20Sopenharmony_ci err = aq_ndev_open(ndev); 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_cierr_exit: 8648c2ecf20Sopenharmony_ci return err; 8658c2ecf20Sopenharmony_ci} 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_cistatic u32 aq_get_msg_level(struct net_device *ndev) 8688c2ecf20Sopenharmony_ci{ 8698c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_ci return aq_nic->msg_enable; 8728c2ecf20Sopenharmony_ci} 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_cistatic void aq_set_msg_level(struct net_device *ndev, u32 data) 8758c2ecf20Sopenharmony_ci{ 8768c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci aq_nic->msg_enable = data; 8798c2ecf20Sopenharmony_ci} 8808c2ecf20Sopenharmony_ci 8818c2ecf20Sopenharmony_cistatic u32 aq_ethtool_get_priv_flags(struct net_device *ndev) 8828c2ecf20Sopenharmony_ci{ 8838c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci return aq_nic->aq_nic_cfg.priv_flags; 8868c2ecf20Sopenharmony_ci} 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_cistatic int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags) 8898c2ecf20Sopenharmony_ci{ 8908c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 8918c2ecf20Sopenharmony_ci struct aq_nic_cfg_s *cfg; 8928c2ecf20Sopenharmony_ci u32 priv_flags; 8938c2ecf20Sopenharmony_ci int ret = 0; 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci cfg = aq_nic_get_cfg(aq_nic); 8968c2ecf20Sopenharmony_ci priv_flags = cfg->priv_flags; 8978c2ecf20Sopenharmony_ci 8988c2ecf20Sopenharmony_ci if (flags & ~AQ_PRIV_FLAGS_MASK) 8998c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) { 9028c2ecf20Sopenharmony_ci netdev_info(ndev, "Can't enable more than one loopback simultaneously\n"); 9038c2ecf20Sopenharmony_ci return -EINVAL; 9048c2ecf20Sopenharmony_ci } 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci cfg->priv_flags = flags; 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_ci if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) { 9098c2ecf20Sopenharmony_ci if (netif_running(ndev)) { 9108c2ecf20Sopenharmony_ci dev_close(ndev); 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci dev_open(ndev, NULL); 9138c2ecf20Sopenharmony_ci } 9148c2ecf20Sopenharmony_ci } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) { 9158c2ecf20Sopenharmony_ci ret = aq_nic_set_loopback(aq_nic); 9168c2ecf20Sopenharmony_ci } 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci return ret; 9198c2ecf20Sopenharmony_ci} 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_cistatic int aq_ethtool_get_phy_tunable(struct net_device *ndev, 9228c2ecf20Sopenharmony_ci const struct ethtool_tunable *tuna, void *data) 9238c2ecf20Sopenharmony_ci{ 9248c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci switch (tuna->id) { 9278c2ecf20Sopenharmony_ci case ETHTOOL_PHY_EDPD: { 9288c2ecf20Sopenharmony_ci u16 *val = data; 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ci *val = aq_nic->aq_nic_cfg.is_media_detect ? AQ_HW_MEDIA_DETECT_CNT : 0; 9318c2ecf20Sopenharmony_ci break; 9328c2ecf20Sopenharmony_ci } 9338c2ecf20Sopenharmony_ci case ETHTOOL_PHY_DOWNSHIFT: { 9348c2ecf20Sopenharmony_ci u8 *val = data; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci *val = (u8)aq_nic->aq_nic_cfg.downshift_counter; 9378c2ecf20Sopenharmony_ci break; 9388c2ecf20Sopenharmony_ci } 9398c2ecf20Sopenharmony_ci default: 9408c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 9418c2ecf20Sopenharmony_ci } 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci return 0; 9448c2ecf20Sopenharmony_ci} 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_cistatic int aq_ethtool_set_phy_tunable(struct net_device *ndev, 9478c2ecf20Sopenharmony_ci const struct ethtool_tunable *tuna, const void *data) 9488c2ecf20Sopenharmony_ci{ 9498c2ecf20Sopenharmony_ci int err = -EOPNOTSUPP; 9508c2ecf20Sopenharmony_ci struct aq_nic_s *aq_nic = netdev_priv(ndev); 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci switch (tuna->id) { 9538c2ecf20Sopenharmony_ci case ETHTOOL_PHY_EDPD: { 9548c2ecf20Sopenharmony_ci const u16 *val = data; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci err = aq_nic_set_media_detect(aq_nic, *val); 9578c2ecf20Sopenharmony_ci break; 9588c2ecf20Sopenharmony_ci } 9598c2ecf20Sopenharmony_ci case ETHTOOL_PHY_DOWNSHIFT: { 9608c2ecf20Sopenharmony_ci const u8 *val = data; 9618c2ecf20Sopenharmony_ci 9628c2ecf20Sopenharmony_ci err = aq_nic_set_downshift(aq_nic, *val); 9638c2ecf20Sopenharmony_ci break; 9648c2ecf20Sopenharmony_ci } 9658c2ecf20Sopenharmony_ci default: 9668c2ecf20Sopenharmony_ci break; 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci return err; 9708c2ecf20Sopenharmony_ci} 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ciconst struct ethtool_ops aq_ethtool_ops = { 9738c2ecf20Sopenharmony_ci .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 9748c2ecf20Sopenharmony_ci ETHTOOL_COALESCE_MAX_FRAMES, 9758c2ecf20Sopenharmony_ci .get_link = aq_ethtool_get_link, 9768c2ecf20Sopenharmony_ci .get_regs_len = aq_ethtool_get_regs_len, 9778c2ecf20Sopenharmony_ci .get_regs = aq_ethtool_get_regs, 9788c2ecf20Sopenharmony_ci .get_drvinfo = aq_ethtool_get_drvinfo, 9798c2ecf20Sopenharmony_ci .get_strings = aq_ethtool_get_strings, 9808c2ecf20Sopenharmony_ci .set_phys_id = aq_ethtool_set_phys_id, 9818c2ecf20Sopenharmony_ci .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size, 9828c2ecf20Sopenharmony_ci .get_wol = aq_ethtool_get_wol, 9838c2ecf20Sopenharmony_ci .set_wol = aq_ethtool_set_wol, 9848c2ecf20Sopenharmony_ci .nway_reset = aq_ethtool_nway_reset, 9858c2ecf20Sopenharmony_ci .get_ringparam = aq_get_ringparam, 9868c2ecf20Sopenharmony_ci .set_ringparam = aq_set_ringparam, 9878c2ecf20Sopenharmony_ci .get_eee = aq_ethtool_get_eee, 9888c2ecf20Sopenharmony_ci .set_eee = aq_ethtool_set_eee, 9898c2ecf20Sopenharmony_ci .get_pauseparam = aq_ethtool_get_pauseparam, 9908c2ecf20Sopenharmony_ci .set_pauseparam = aq_ethtool_set_pauseparam, 9918c2ecf20Sopenharmony_ci .get_rxfh_key_size = aq_ethtool_get_rss_key_size, 9928c2ecf20Sopenharmony_ci .get_rxfh = aq_ethtool_get_rss, 9938c2ecf20Sopenharmony_ci .set_rxfh = aq_ethtool_set_rss, 9948c2ecf20Sopenharmony_ci .get_rxnfc = aq_ethtool_get_rxnfc, 9958c2ecf20Sopenharmony_ci .set_rxnfc = aq_ethtool_set_rxnfc, 9968c2ecf20Sopenharmony_ci .get_msglevel = aq_get_msg_level, 9978c2ecf20Sopenharmony_ci .set_msglevel = aq_set_msg_level, 9988c2ecf20Sopenharmony_ci .get_sset_count = aq_ethtool_get_sset_count, 9998c2ecf20Sopenharmony_ci .get_ethtool_stats = aq_ethtool_stats, 10008c2ecf20Sopenharmony_ci .get_priv_flags = aq_ethtool_get_priv_flags, 10018c2ecf20Sopenharmony_ci .set_priv_flags = aq_ethtool_set_priv_flags, 10028c2ecf20Sopenharmony_ci .get_link_ksettings = aq_ethtool_get_link_ksettings, 10038c2ecf20Sopenharmony_ci .set_link_ksettings = aq_ethtool_set_link_ksettings, 10048c2ecf20Sopenharmony_ci .get_coalesce = aq_ethtool_get_coalesce, 10058c2ecf20Sopenharmony_ci .set_coalesce = aq_ethtool_set_coalesce, 10068c2ecf20Sopenharmony_ci .get_ts_info = aq_ethtool_get_ts_info, 10078c2ecf20Sopenharmony_ci .get_phy_tunable = aq_ethtool_get_phy_tunable, 10088c2ecf20Sopenharmony_ci .set_phy_tunable = aq_ethtool_set_phy_tunable, 10098c2ecf20Sopenharmony_ci}; 1010