xref: /linux/drivers/net/ethernet/apm/xgene-v2/ethtool.c (revision 617d795c7cb2d1b636db33d428f830f3ed18a36f)
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