1*617d795cSIyappan Subramanian /* 2*617d795cSIyappan Subramanian * Applied Micro X-Gene SoC Ethernet v2 Driver 3*617d795cSIyappan Subramanian * 4*617d795cSIyappan Subramanian * Copyright (c) 2017, Applied Micro Circuits Corporation 5*617d795cSIyappan Subramanian * Author(s): Iyappan Subramanian <isubramanian@apm.com> 6*617d795cSIyappan Subramanian * Keyur Chudgar <kchudgar@apm.com> 7*617d795cSIyappan Subramanian * 8*617d795cSIyappan Subramanian * This program is free software; you can redistribute it and/or modify it 9*617d795cSIyappan Subramanian * under the terms of the GNU General Public License as published by the 10*617d795cSIyappan Subramanian * Free Software Foundation; either version 2 of the License, or (at your 11*617d795cSIyappan Subramanian * option) any later version. 12*617d795cSIyappan Subramanian * 13*617d795cSIyappan Subramanian * This program is distributed in the hope that it will be useful, 14*617d795cSIyappan Subramanian * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*617d795cSIyappan Subramanian * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*617d795cSIyappan Subramanian * GNU General Public License for more details. 17*617d795cSIyappan Subramanian * 18*617d795cSIyappan Subramanian * You should have received a copy of the GNU General Public License 19*617d795cSIyappan Subramanian * along with this program. If not, see <http://www.gnu.org/licenses/>. 20*617d795cSIyappan Subramanian */ 21*617d795cSIyappan Subramanian 22*617d795cSIyappan Subramanian #include "main.h" 23*617d795cSIyappan Subramanian 24*617d795cSIyappan Subramanian struct xge_gstrings_stats { 25*617d795cSIyappan Subramanian char name[ETH_GSTRING_LEN]; 26*617d795cSIyappan Subramanian int offset; 27*617d795cSIyappan Subramanian }; 28*617d795cSIyappan Subramanian 29*617d795cSIyappan Subramanian #define XGE_STAT(m) { #m, offsetof(struct xge_pdata, stats.m) } 30*617d795cSIyappan Subramanian 31*617d795cSIyappan Subramanian static const struct xge_gstrings_stats gstrings_stats[] = { 32*617d795cSIyappan Subramanian XGE_STAT(rx_packets), 33*617d795cSIyappan Subramanian XGE_STAT(tx_packets), 34*617d795cSIyappan Subramanian XGE_STAT(rx_bytes), 35*617d795cSIyappan Subramanian XGE_STAT(tx_bytes), 36*617d795cSIyappan Subramanian XGE_STAT(rx_errors) 37*617d795cSIyappan Subramanian }; 38*617d795cSIyappan Subramanian 39*617d795cSIyappan Subramanian #define XGE_STATS_LEN ARRAY_SIZE(gstrings_stats) 40*617d795cSIyappan Subramanian 41*617d795cSIyappan Subramanian static void xge_get_drvinfo(struct net_device *ndev, 42*617d795cSIyappan Subramanian struct ethtool_drvinfo *info) 43*617d795cSIyappan Subramanian { 44*617d795cSIyappan Subramanian struct xge_pdata *pdata = netdev_priv(ndev); 45*617d795cSIyappan Subramanian struct platform_device *pdev = pdata->pdev; 46*617d795cSIyappan Subramanian 47*617d795cSIyappan Subramanian strcpy(info->driver, "xgene-enet-v2"); 48*617d795cSIyappan Subramanian strcpy(info->version, XGENE_ENET_V2_VERSION); 49*617d795cSIyappan Subramanian snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A"); 50*617d795cSIyappan Subramanian sprintf(info->bus_info, "%s", pdev->name); 51*617d795cSIyappan Subramanian } 52*617d795cSIyappan Subramanian 53*617d795cSIyappan Subramanian static void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 54*617d795cSIyappan Subramanian { 55*617d795cSIyappan Subramanian u8 *p = data; 56*617d795cSIyappan Subramanian int i; 57*617d795cSIyappan Subramanian 58*617d795cSIyappan Subramanian if (stringset != ETH_SS_STATS) 59*617d795cSIyappan Subramanian return; 60*617d795cSIyappan Subramanian 61*617d795cSIyappan Subramanian for (i = 0; i < XGE_STATS_LEN; i++) { 62*617d795cSIyappan Subramanian memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); 63*617d795cSIyappan Subramanian p += ETH_GSTRING_LEN; 64*617d795cSIyappan Subramanian } 65*617d795cSIyappan Subramanian } 66*617d795cSIyappan Subramanian 67*617d795cSIyappan Subramanian static int xge_get_sset_count(struct net_device *ndev, int sset) 68*617d795cSIyappan Subramanian { 69*617d795cSIyappan Subramanian if (sset != ETH_SS_STATS) 70*617d795cSIyappan Subramanian return -EINVAL; 71*617d795cSIyappan Subramanian 72*617d795cSIyappan Subramanian return XGE_STATS_LEN; 73*617d795cSIyappan Subramanian } 74*617d795cSIyappan Subramanian 75*617d795cSIyappan Subramanian static void xge_get_ethtool_stats(struct net_device *ndev, 76*617d795cSIyappan Subramanian struct ethtool_stats *dummy, 77*617d795cSIyappan Subramanian u64 *data) 78*617d795cSIyappan Subramanian { 79*617d795cSIyappan Subramanian void *pdata = netdev_priv(ndev); 80*617d795cSIyappan Subramanian int i; 81*617d795cSIyappan Subramanian 82*617d795cSIyappan Subramanian for (i = 0; i < XGE_STATS_LEN; i++) 83*617d795cSIyappan Subramanian *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); 84*617d795cSIyappan Subramanian } 85*617d795cSIyappan Subramanian 86*617d795cSIyappan Subramanian static int xge_get_link_ksettings(struct net_device *ndev, 87*617d795cSIyappan Subramanian struct ethtool_link_ksettings *cmd) 88*617d795cSIyappan Subramanian { 89*617d795cSIyappan Subramanian struct phy_device *phydev = ndev->phydev; 90*617d795cSIyappan Subramanian 91*617d795cSIyappan Subramanian if (!phydev) 92*617d795cSIyappan Subramanian return -ENODEV; 93*617d795cSIyappan Subramanian 94*617d795cSIyappan Subramanian return phy_ethtool_ksettings_get(phydev, cmd); 95*617d795cSIyappan Subramanian } 96*617d795cSIyappan Subramanian 97*617d795cSIyappan Subramanian static int xge_set_link_ksettings(struct net_device *ndev, 98*617d795cSIyappan Subramanian const struct ethtool_link_ksettings *cmd) 99*617d795cSIyappan Subramanian { 100*617d795cSIyappan Subramanian struct phy_device *phydev = ndev->phydev; 101*617d795cSIyappan Subramanian 102*617d795cSIyappan Subramanian if (!phydev) 103*617d795cSIyappan Subramanian return -ENODEV; 104*617d795cSIyappan Subramanian 105*617d795cSIyappan Subramanian return phy_ethtool_ksettings_set(phydev, cmd); 106*617d795cSIyappan Subramanian } 107*617d795cSIyappan Subramanian 108*617d795cSIyappan Subramanian static const struct ethtool_ops xge_ethtool_ops = { 109*617d795cSIyappan Subramanian .get_drvinfo = xge_get_drvinfo, 110*617d795cSIyappan Subramanian .get_link = ethtool_op_get_link, 111*617d795cSIyappan Subramanian .get_strings = xge_get_strings, 112*617d795cSIyappan Subramanian .get_sset_count = xge_get_sset_count, 113*617d795cSIyappan Subramanian .get_ethtool_stats = xge_get_ethtool_stats, 114*617d795cSIyappan Subramanian .get_link_ksettings = xge_get_link_ksettings, 115*617d795cSIyappan Subramanian .set_link_ksettings = xge_set_link_ksettings, 116*617d795cSIyappan Subramanian }; 117*617d795cSIyappan Subramanian 118*617d795cSIyappan Subramanian void xge_set_ethtool_ops(struct net_device *ndev) 119*617d795cSIyappan Subramanian { 120*617d795cSIyappan Subramanian ndev->ethtool_ops = &xge_ethtool_ops; 121*617d795cSIyappan Subramanian } 122