18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Applied Micro X-Gene SoC Ethernet v2 Driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2017, Applied Micro Circuits Corporation 68c2ecf20Sopenharmony_ci * Author(s): Iyappan Subramanian <isubramanian@apm.com> 78c2ecf20Sopenharmony_ci * Keyur Chudgar <kchudgar@apm.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "main.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define XGE_STAT(m) { #m, offsetof(struct xge_pdata, stats.m) } 138c2ecf20Sopenharmony_ci#define XGE_EXTD_STAT(m, n) \ 148c2ecf20Sopenharmony_ci { \ 158c2ecf20Sopenharmony_ci #m, \ 168c2ecf20Sopenharmony_ci n, \ 178c2ecf20Sopenharmony_ci 0 \ 188c2ecf20Sopenharmony_ci } 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistatic const struct xge_gstrings_stats gstrings_stats[] = { 218c2ecf20Sopenharmony_ci XGE_STAT(rx_packets), 228c2ecf20Sopenharmony_ci XGE_STAT(tx_packets), 238c2ecf20Sopenharmony_ci XGE_STAT(rx_bytes), 248c2ecf20Sopenharmony_ci XGE_STAT(tx_bytes), 258c2ecf20Sopenharmony_ci XGE_STAT(rx_errors) 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic struct xge_gstrings_extd_stats gstrings_extd_stats[] = { 298c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64), 308c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127), 318c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255), 328c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511), 338c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K), 348c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX), 358c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV), 368c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_fcs_error_cntr, RFCS), 378c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA), 388c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA), 398c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF), 408c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF), 418c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_unk_opcode_cntr, RXUO), 428c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_align_err_cntr, RALN), 438c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_frame_len_err_cntr, RFLR), 448c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_code_err_cntr, RCDE), 458c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE), 468c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_undersize_pkt_cntr, RUND), 478c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR), 488c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_fragments_cntr, RFRG), 498c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_jabber_cntr, RJBR), 508c2ecf20Sopenharmony_ci XGE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP), 518c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA), 528c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA), 538c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF), 548c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_defer_pkt_cntr, TDFR), 558c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF), 568c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL), 578c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL), 588c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL), 598c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL), 608c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_total_col_cntr, TNCL), 618c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH), 628c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_drop_frame_cntr, TDRP), 638c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_jabber_frame_cntr, TJBR), 648c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_fcs_error_cntr, TFCS), 658c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF), 668c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_oversize_frame_cntr, TOVR), 678c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_undersize_frame_cntr, TUND), 688c2ecf20Sopenharmony_ci XGE_EXTD_STAT(tx_fragments_cntr, TFRG) 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#define XGE_STATS_LEN ARRAY_SIZE(gstrings_stats) 728c2ecf20Sopenharmony_ci#define XGE_EXTD_STATS_LEN ARRAY_SIZE(gstrings_extd_stats) 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_cistatic void xge_mac_get_extd_stats(struct xge_pdata *pdata) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci u32 data; 778c2ecf20Sopenharmony_ci int i; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 808c2ecf20Sopenharmony_ci data = xge_rd_csr(pdata, gstrings_extd_stats[i].addr); 818c2ecf20Sopenharmony_ci gstrings_extd_stats[i].value += data; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic void xge_get_drvinfo(struct net_device *ndev, 868c2ecf20Sopenharmony_ci struct ethtool_drvinfo *info) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci struct xge_pdata *pdata = netdev_priv(ndev); 898c2ecf20Sopenharmony_ci struct platform_device *pdev = pdata->pdev; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci strcpy(info->driver, "xgene-enet-v2"); 928c2ecf20Sopenharmony_ci sprintf(info->bus_info, "%s", pdev->name); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci u8 *p = data; 988c2ecf20Sopenharmony_ci int i; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci if (stringset != ETH_SS_STATS) 1018c2ecf20Sopenharmony_ci return; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci for (i = 0; i < XGE_STATS_LEN; i++) { 1048c2ecf20Sopenharmony_ci memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); 1058c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 1098c2ecf20Sopenharmony_ci memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN); 1108c2ecf20Sopenharmony_ci p += ETH_GSTRING_LEN; 1118c2ecf20Sopenharmony_ci } 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic int xge_get_sset_count(struct net_device *ndev, int sset) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci if (sset != ETH_SS_STATS) 1178c2ecf20Sopenharmony_ci return -EINVAL; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci return XGE_STATS_LEN + XGE_EXTD_STATS_LEN; 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic void xge_get_ethtool_stats(struct net_device *ndev, 1238c2ecf20Sopenharmony_ci struct ethtool_stats *dummy, 1248c2ecf20Sopenharmony_ci u64 *data) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci void *pdata = netdev_priv(ndev); 1278c2ecf20Sopenharmony_ci int i; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci for (i = 0; i < XGE_STATS_LEN; i++) 1308c2ecf20Sopenharmony_ci *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci xge_mac_get_extd_stats(pdata); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci for (i = 0; i < XGE_EXTD_STATS_LEN; i++) 1358c2ecf20Sopenharmony_ci *data++ = gstrings_extd_stats[i].value; 1368c2ecf20Sopenharmony_ci} 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic int xge_get_link_ksettings(struct net_device *ndev, 1398c2ecf20Sopenharmony_ci struct ethtool_link_ksettings *cmd) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci struct phy_device *phydev = ndev->phydev; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (!phydev) 1448c2ecf20Sopenharmony_ci return -ENODEV; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci phy_ethtool_ksettings_get(phydev, cmd); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci return 0; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic int xge_set_link_ksettings(struct net_device *ndev, 1528c2ecf20Sopenharmony_ci const struct ethtool_link_ksettings *cmd) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci struct phy_device *phydev = ndev->phydev; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci if (!phydev) 1578c2ecf20Sopenharmony_ci return -ENODEV; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci return phy_ethtool_ksettings_set(phydev, cmd); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic const struct ethtool_ops xge_ethtool_ops = { 1638c2ecf20Sopenharmony_ci .get_drvinfo = xge_get_drvinfo, 1648c2ecf20Sopenharmony_ci .get_link = ethtool_op_get_link, 1658c2ecf20Sopenharmony_ci .get_strings = xge_get_strings, 1668c2ecf20Sopenharmony_ci .get_sset_count = xge_get_sset_count, 1678c2ecf20Sopenharmony_ci .get_ethtool_stats = xge_get_ethtool_stats, 1688c2ecf20Sopenharmony_ci .get_link_ksettings = xge_get_link_ksettings, 1698c2ecf20Sopenharmony_ci .set_link_ksettings = xge_set_link_ksettings, 1708c2ecf20Sopenharmony_ci}; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_civoid xge_set_ethtool_ops(struct net_device *ndev) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci ndev->ethtool_ops = &xge_ethtool_ops; 1758c2ecf20Sopenharmony_ci} 176