1617d795cSIyappan Subramanian /* 2617d795cSIyappan Subramanian * Applied Micro X-Gene SoC Ethernet v2 Driver 3617d795cSIyappan Subramanian * 4617d795cSIyappan Subramanian * Copyright (c) 2017, Applied Micro Circuits Corporation 5617d795cSIyappan Subramanian * Author(s): Iyappan Subramanian <isubramanian@apm.com> 6617d795cSIyappan Subramanian * Keyur Chudgar <kchudgar@apm.com> 7617d795cSIyappan Subramanian * 8617d795cSIyappan Subramanian * This program is free software; you can redistribute it and/or modify it 9617d795cSIyappan Subramanian * under the terms of the GNU General Public License as published by the 10617d795cSIyappan Subramanian * Free Software Foundation; either version 2 of the License, or (at your 11617d795cSIyappan Subramanian * option) any later version. 12617d795cSIyappan Subramanian * 13617d795cSIyappan Subramanian * This program is distributed in the hope that it will be useful, 14617d795cSIyappan Subramanian * but WITHOUT ANY WARRANTY; without even the implied warranty of 15617d795cSIyappan Subramanian * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16617d795cSIyappan Subramanian * GNU General Public License for more details. 17617d795cSIyappan Subramanian * 18617d795cSIyappan Subramanian * You should have received a copy of the GNU General Public License 19617d795cSIyappan Subramanian * along with this program. If not, see <http://www.gnu.org/licenses/>. 20617d795cSIyappan Subramanian */ 21617d795cSIyappan Subramanian 22617d795cSIyappan Subramanian #include "main.h" 23617d795cSIyappan Subramanian 24617d795cSIyappan Subramanian #define XGE_STAT(m) { #m, offsetof(struct xge_pdata, stats.m) } 25e05ddafdSIyappan Subramanian #define XGE_EXTD_STAT(m, n) \ 26e05ddafdSIyappan Subramanian { \ 27e05ddafdSIyappan Subramanian #m, \ 28e05ddafdSIyappan Subramanian n, \ 29e05ddafdSIyappan Subramanian 0 \ 30e05ddafdSIyappan Subramanian } 31617d795cSIyappan Subramanian 32617d795cSIyappan Subramanian static const struct xge_gstrings_stats gstrings_stats[] = { 33617d795cSIyappan Subramanian XGE_STAT(rx_packets), 34617d795cSIyappan Subramanian XGE_STAT(tx_packets), 35617d795cSIyappan Subramanian XGE_STAT(rx_bytes), 36617d795cSIyappan Subramanian XGE_STAT(tx_bytes), 37617d795cSIyappan Subramanian XGE_STAT(rx_errors) 38617d795cSIyappan Subramanian }; 39617d795cSIyappan Subramanian 40e05ddafdSIyappan Subramanian static struct xge_gstrings_extd_stats gstrings_extd_stats[] = { 41e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64), 42e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127), 43e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255), 44e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511), 45e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K), 46e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX), 47e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV), 48e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_fcs_error_cntr, RFCS), 49e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA), 50e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA), 51e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF), 52e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF), 53e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_unk_opcode_cntr, RXUO), 54e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_align_err_cntr, RALN), 55e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_frame_len_err_cntr, RFLR), 56e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_code_err_cntr, RCDE), 57e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE), 58e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_undersize_pkt_cntr, RUND), 59e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR), 60e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_fragments_cntr, RFRG), 61e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_jabber_cntr, RJBR), 62e05ddafdSIyappan Subramanian XGE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP), 63e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA), 64e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA), 65e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF), 66e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_defer_pkt_cntr, TDFR), 67e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF), 68e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL), 69e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL), 70e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL), 71e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL), 72e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_total_col_cntr, TNCL), 73e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH), 74e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_drop_frame_cntr, TDRP), 75e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_jabber_frame_cntr, TJBR), 76e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_fcs_error_cntr, TFCS), 77e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF), 78e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_oversize_frame_cntr, TOVR), 79e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_undersize_frame_cntr, TUND), 80e05ddafdSIyappan Subramanian XGE_EXTD_STAT(tx_fragments_cntr, TFRG) 81e05ddafdSIyappan Subramanian }; 82e05ddafdSIyappan Subramanian 83617d795cSIyappan Subramanian #define XGE_STATS_LEN ARRAY_SIZE(gstrings_stats) 84e05ddafdSIyappan Subramanian #define XGE_EXTD_STATS_LEN ARRAY_SIZE(gstrings_extd_stats) 85e05ddafdSIyappan Subramanian 86e05ddafdSIyappan Subramanian static void xge_mac_get_extd_stats(struct xge_pdata *pdata) 87e05ddafdSIyappan Subramanian { 88e05ddafdSIyappan Subramanian u32 data; 89e05ddafdSIyappan Subramanian int i; 90e05ddafdSIyappan Subramanian 91e05ddafdSIyappan Subramanian for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 92e05ddafdSIyappan Subramanian data = xge_rd_csr(pdata, gstrings_extd_stats[i].addr); 93e05ddafdSIyappan Subramanian gstrings_extd_stats[i].value += data; 94e05ddafdSIyappan Subramanian } 95e05ddafdSIyappan Subramanian } 96617d795cSIyappan Subramanian 97617d795cSIyappan Subramanian static void xge_get_drvinfo(struct net_device *ndev, 98617d795cSIyappan Subramanian struct ethtool_drvinfo *info) 99617d795cSIyappan Subramanian { 100617d795cSIyappan Subramanian struct xge_pdata *pdata = netdev_priv(ndev); 101617d795cSIyappan Subramanian struct platform_device *pdev = pdata->pdev; 102617d795cSIyappan Subramanian 103617d795cSIyappan Subramanian strcpy(info->driver, "xgene-enet-v2"); 104617d795cSIyappan Subramanian strcpy(info->version, XGENE_ENET_V2_VERSION); 105617d795cSIyappan Subramanian snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A"); 106617d795cSIyappan Subramanian sprintf(info->bus_info, "%s", pdev->name); 107617d795cSIyappan Subramanian } 108617d795cSIyappan Subramanian 109617d795cSIyappan Subramanian static void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 110617d795cSIyappan Subramanian { 111617d795cSIyappan Subramanian u8 *p = data; 112617d795cSIyappan Subramanian int i; 113617d795cSIyappan Subramanian 114617d795cSIyappan Subramanian if (stringset != ETH_SS_STATS) 115617d795cSIyappan Subramanian return; 116617d795cSIyappan Subramanian 117617d795cSIyappan Subramanian for (i = 0; i < XGE_STATS_LEN; i++) { 118617d795cSIyappan Subramanian memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); 119617d795cSIyappan Subramanian p += ETH_GSTRING_LEN; 120617d795cSIyappan Subramanian } 121e05ddafdSIyappan Subramanian 122e05ddafdSIyappan Subramanian for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 123e05ddafdSIyappan Subramanian memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN); 124e05ddafdSIyappan Subramanian p += ETH_GSTRING_LEN; 125e05ddafdSIyappan Subramanian } 126617d795cSIyappan Subramanian } 127617d795cSIyappan Subramanian 128617d795cSIyappan Subramanian static int xge_get_sset_count(struct net_device *ndev, int sset) 129617d795cSIyappan Subramanian { 130617d795cSIyappan Subramanian if (sset != ETH_SS_STATS) 131617d795cSIyappan Subramanian return -EINVAL; 132617d795cSIyappan Subramanian 133e05ddafdSIyappan Subramanian return XGE_STATS_LEN + XGE_EXTD_STATS_LEN; 134617d795cSIyappan Subramanian } 135617d795cSIyappan Subramanian 136617d795cSIyappan Subramanian static void xge_get_ethtool_stats(struct net_device *ndev, 137617d795cSIyappan Subramanian struct ethtool_stats *dummy, 138617d795cSIyappan Subramanian u64 *data) 139617d795cSIyappan Subramanian { 140617d795cSIyappan Subramanian void *pdata = netdev_priv(ndev); 141617d795cSIyappan Subramanian int i; 142617d795cSIyappan Subramanian 143617d795cSIyappan Subramanian for (i = 0; i < XGE_STATS_LEN; i++) 144617d795cSIyappan Subramanian *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); 145e05ddafdSIyappan Subramanian 146e05ddafdSIyappan Subramanian xge_mac_get_extd_stats(pdata); 147e05ddafdSIyappan Subramanian 148e05ddafdSIyappan Subramanian for (i = 0; i < XGE_EXTD_STATS_LEN; i++) 149e05ddafdSIyappan Subramanian *data++ = gstrings_extd_stats[i].value; 150617d795cSIyappan Subramanian } 151617d795cSIyappan Subramanian 152617d795cSIyappan Subramanian static int xge_get_link_ksettings(struct net_device *ndev, 153617d795cSIyappan Subramanian struct ethtool_link_ksettings *cmd) 154617d795cSIyappan Subramanian { 155617d795cSIyappan Subramanian struct phy_device *phydev = ndev->phydev; 156617d795cSIyappan Subramanian 157617d795cSIyappan Subramanian if (!phydev) 158617d795cSIyappan Subramanian return -ENODEV; 159617d795cSIyappan Subramanian 160*5514174fSyuval.shaia@oracle.com phy_ethtool_ksettings_get(phydev, cmd); 161*5514174fSyuval.shaia@oracle.com 162*5514174fSyuval.shaia@oracle.com return 0; 163617d795cSIyappan Subramanian } 164617d795cSIyappan Subramanian 165617d795cSIyappan Subramanian static int xge_set_link_ksettings(struct net_device *ndev, 166617d795cSIyappan Subramanian const struct ethtool_link_ksettings *cmd) 167617d795cSIyappan Subramanian { 168617d795cSIyappan Subramanian struct phy_device *phydev = ndev->phydev; 169617d795cSIyappan Subramanian 170617d795cSIyappan Subramanian if (!phydev) 171617d795cSIyappan Subramanian return -ENODEV; 172617d795cSIyappan Subramanian 173617d795cSIyappan Subramanian return phy_ethtool_ksettings_set(phydev, cmd); 174617d795cSIyappan Subramanian } 175617d795cSIyappan Subramanian 176617d795cSIyappan Subramanian static const struct ethtool_ops xge_ethtool_ops = { 177617d795cSIyappan Subramanian .get_drvinfo = xge_get_drvinfo, 178617d795cSIyappan Subramanian .get_link = ethtool_op_get_link, 179617d795cSIyappan Subramanian .get_strings = xge_get_strings, 180617d795cSIyappan Subramanian .get_sset_count = xge_get_sset_count, 181617d795cSIyappan Subramanian .get_ethtool_stats = xge_get_ethtool_stats, 182617d795cSIyappan Subramanian .get_link_ksettings = xge_get_link_ksettings, 183617d795cSIyappan Subramanian .set_link_ksettings = xge_set_link_ksettings, 184617d795cSIyappan Subramanian }; 185617d795cSIyappan Subramanian 186617d795cSIyappan Subramanian void xge_set_ethtool_ops(struct net_device *ndev) 187617d795cSIyappan Subramanian { 188617d795cSIyappan Subramanian ndev->ethtool_ops = &xge_ethtool_ops; 189617d795cSIyappan Subramanian } 190