1 /* Applied Micro X-Gene SoC Ethernet Driver
3 * Copyright (c) 2014, Applied Micro Circuits Corporation
4 * Authors: Iyappan Subramanian <isubramanian@apm.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <linux/ethtool.h>
21 #include "xgene_enet_main.h"
23 struct xgene_gstrings_stats
{
24 char name
[ETH_GSTRING_LEN
];
28 #define XGENE_STAT(m) { #m, offsetof(struct xgene_enet_pdata, stats.m) }
30 static const struct xgene_gstrings_stats gstrings_stats
[] = {
31 XGENE_STAT(rx_packets
),
32 XGENE_STAT(tx_packets
),
35 XGENE_STAT(rx_errors
),
36 XGENE_STAT(tx_errors
),
37 XGENE_STAT(rx_length_errors
),
38 XGENE_STAT(rx_crc_errors
),
39 XGENE_STAT(rx_frame_errors
),
40 XGENE_STAT(rx_fifo_errors
)
43 #define XGENE_STATS_LEN ARRAY_SIZE(gstrings_stats)
45 static void xgene_get_drvinfo(struct net_device
*ndev
,
46 struct ethtool_drvinfo
*info
)
48 struct xgene_enet_pdata
*pdata
= netdev_priv(ndev
);
49 struct platform_device
*pdev
= pdata
->pdev
;
51 strcpy(info
->driver
, "xgene_enet");
52 strcpy(info
->version
, XGENE_DRV_VERSION
);
53 snprintf(info
->fw_version
, ETHTOOL_FWVERS_LEN
, "N/A");
54 sprintf(info
->bus_info
, "%s", pdev
->name
);
57 static int xgene_get_settings(struct net_device
*ndev
, struct ethtool_cmd
*cmd
)
59 struct xgene_enet_pdata
*pdata
= netdev_priv(ndev
);
60 struct phy_device
*phydev
= pdata
->phy_dev
;
62 if (pdata
->phy_mode
== PHY_INTERFACE_MODE_RGMII
) {
66 return phy_ethtool_gset(phydev
, cmd
);
67 } else if (pdata
->phy_mode
== PHY_INTERFACE_MODE_SGMII
) {
68 cmd
->supported
= SUPPORTED_1000baseT_Full
|
69 SUPPORTED_Autoneg
| SUPPORTED_MII
;
70 cmd
->advertising
= cmd
->supported
;
71 ethtool_cmd_speed_set(cmd
, SPEED_1000
);
72 cmd
->duplex
= DUPLEX_FULL
;
74 cmd
->transceiver
= XCVR_INTERNAL
;
75 cmd
->autoneg
= AUTONEG_ENABLE
;
77 cmd
->supported
= SUPPORTED_10000baseT_Full
| SUPPORTED_FIBRE
;
78 cmd
->advertising
= cmd
->supported
;
79 ethtool_cmd_speed_set(cmd
, SPEED_10000
);
80 cmd
->duplex
= DUPLEX_FULL
;
81 cmd
->port
= PORT_FIBRE
;
82 cmd
->transceiver
= XCVR_INTERNAL
;
83 cmd
->autoneg
= AUTONEG_DISABLE
;
89 static int xgene_set_settings(struct net_device
*ndev
, struct ethtool_cmd
*cmd
)
91 struct xgene_enet_pdata
*pdata
= netdev_priv(ndev
);
92 struct phy_device
*phydev
= pdata
->phy_dev
;
94 if (pdata
->phy_mode
== PHY_INTERFACE_MODE_RGMII
) {
98 return phy_ethtool_sset(phydev
, cmd
);
104 static void xgene_get_strings(struct net_device
*ndev
, u32 stringset
, u8
*data
)
109 if (stringset
!= ETH_SS_STATS
)
112 for (i
= 0; i
< XGENE_STATS_LEN
; i
++) {
113 memcpy(p
, gstrings_stats
[i
].name
, ETH_GSTRING_LEN
);
114 p
+= ETH_GSTRING_LEN
;
118 static int xgene_get_sset_count(struct net_device
*ndev
, int sset
)
120 if (sset
!= ETH_SS_STATS
)
123 return XGENE_STATS_LEN
;
126 static void xgene_get_ethtool_stats(struct net_device
*ndev
,
127 struct ethtool_stats
*dummy
,
130 void *pdata
= netdev_priv(ndev
);
133 for (i
= 0; i
< XGENE_STATS_LEN
; i
++)
134 *data
++ = *(u64
*)(pdata
+ gstrings_stats
[i
].offset
);
137 static const struct ethtool_ops xgene_ethtool_ops
= {
138 .get_drvinfo
= xgene_get_drvinfo
,
139 .get_settings
= xgene_get_settings
,
140 .set_settings
= xgene_set_settings
,
141 .get_link
= ethtool_op_get_link
,
142 .get_strings
= xgene_get_strings
,
143 .get_sset_count
= xgene_get_sset_count
,
144 .get_ethtool_stats
= xgene_get_ethtool_stats
147 void xgene_enet_set_ethtool_ops(struct net_device
*ndev
)
149 ndev
->ethtool_ops
= &xgene_ethtool_ops
;