Commit 5e6a024bebea5bad6b787cf2c0ee28116b4147f0

Authored by Iyappan Subramanian
Committed by David S. Miller
1 parent 32f784b50e

drivers: net: xgene: Add SGMII based 1GbE ethtool support

Signed-off-by: Iyappan Subramanian <isubramanian@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 17 additions and 8 deletions Inline Diff

drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
1 /* Applied Micro X-Gene SoC Ethernet Driver 1 /* Applied Micro X-Gene SoC Ethernet Driver
2 * 2 *
3 * Copyright (c) 2014, Applied Micro Circuits Corporation 3 * Copyright (c) 2014, Applied Micro Circuits Corporation
4 * Authors: Iyappan Subramanian <isubramanian@apm.com> 4 * Authors: Iyappan Subramanian <isubramanian@apm.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 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 8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. 9 * option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 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/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20 #include <linux/ethtool.h> 20 #include <linux/ethtool.h>
21 #include "xgene_enet_main.h" 21 #include "xgene_enet_main.h"
22 22
23 struct xgene_gstrings_stats { 23 struct xgene_gstrings_stats {
24 char name[ETH_GSTRING_LEN]; 24 char name[ETH_GSTRING_LEN];
25 int offset; 25 int offset;
26 }; 26 };
27 27
28 #define XGENE_STAT(m) { #m, offsetof(struct xgene_enet_pdata, stats.m) } 28 #define XGENE_STAT(m) { #m, offsetof(struct xgene_enet_pdata, stats.m) }
29 29
30 static const struct xgene_gstrings_stats gstrings_stats[] = { 30 static const struct xgene_gstrings_stats gstrings_stats[] = {
31 XGENE_STAT(rx_packets), 31 XGENE_STAT(rx_packets),
32 XGENE_STAT(tx_packets), 32 XGENE_STAT(tx_packets),
33 XGENE_STAT(rx_bytes), 33 XGENE_STAT(rx_bytes),
34 XGENE_STAT(tx_bytes), 34 XGENE_STAT(tx_bytes),
35 XGENE_STAT(rx_errors), 35 XGENE_STAT(rx_errors),
36 XGENE_STAT(tx_errors), 36 XGENE_STAT(tx_errors),
37 XGENE_STAT(rx_length_errors), 37 XGENE_STAT(rx_length_errors),
38 XGENE_STAT(rx_crc_errors), 38 XGENE_STAT(rx_crc_errors),
39 XGENE_STAT(rx_frame_errors), 39 XGENE_STAT(rx_frame_errors),
40 XGENE_STAT(rx_fifo_errors) 40 XGENE_STAT(rx_fifo_errors)
41 }; 41 };
42 42
43 #define XGENE_STATS_LEN ARRAY_SIZE(gstrings_stats) 43 #define XGENE_STATS_LEN ARRAY_SIZE(gstrings_stats)
44 44
45 static void xgene_get_drvinfo(struct net_device *ndev, 45 static void xgene_get_drvinfo(struct net_device *ndev,
46 struct ethtool_drvinfo *info) 46 struct ethtool_drvinfo *info)
47 { 47 {
48 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 48 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
49 struct platform_device *pdev = pdata->pdev; 49 struct platform_device *pdev = pdata->pdev;
50 50
51 strcpy(info->driver, "xgene_enet"); 51 strcpy(info->driver, "xgene_enet");
52 strcpy(info->version, XGENE_DRV_VERSION); 52 strcpy(info->version, XGENE_DRV_VERSION);
53 snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A"); 53 snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A");
54 sprintf(info->bus_info, "%s", pdev->name); 54 sprintf(info->bus_info, "%s", pdev->name);
55 } 55 }
56 56
57 static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 57 static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
58 { 58 {
59 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 59 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
60 struct phy_device *phydev = pdata->phy_dev; 60 struct phy_device *phydev = pdata->phy_dev;
61 61
62 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { 62 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
63 if (phydev == NULL) 63 if (phydev == NULL)
64 return -ENODEV; 64 return -ENODEV;
65 65
66 return phy_ethtool_gset(phydev, cmd); 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;
73 cmd->port = PORT_MII;
74 cmd->transceiver = XCVR_INTERNAL;
75 cmd->autoneg = AUTONEG_ENABLE;
76 } else {
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;
67 } 84 }
68
69 cmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE;
70 cmd->advertising = cmd->supported;
71 ethtool_cmd_speed_set(cmd, SPEED_10000);
72 cmd->duplex = DUPLEX_FULL;
73 cmd->port = PORT_FIBRE;
74 cmd->transceiver = XCVR_EXTERNAL;
75 cmd->autoneg = AUTONEG_DISABLE;
76 85
77 return 0; 86 return 0;
78 } 87 }
79 88
80 static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 89 static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
81 { 90 {
82 struct xgene_enet_pdata *pdata = netdev_priv(ndev); 91 struct xgene_enet_pdata *pdata = netdev_priv(ndev);
83 struct phy_device *phydev = pdata->phy_dev; 92 struct phy_device *phydev = pdata->phy_dev;
84 93
85 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { 94 if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) {
86 if (phydev == NULL) 95 if (phydev == NULL)
87 return -ENODEV; 96 return -ENODEV;
88 97
89 return phy_ethtool_sset(phydev, cmd); 98 return phy_ethtool_sset(phydev, cmd);
90 } 99 }
91 100
92 return -EINVAL; 101 return -EINVAL;
93 } 102 }
94 103
95 static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 104 static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
96 { 105 {
97 int i; 106 int i;
98 u8 *p = data; 107 u8 *p = data;
99 108
100 if (stringset != ETH_SS_STATS) 109 if (stringset != ETH_SS_STATS)
101 return; 110 return;
102 111
103 for (i = 0; i < XGENE_STATS_LEN; i++) { 112 for (i = 0; i < XGENE_STATS_LEN; i++) {
104 memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); 113 memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN);
105 p += ETH_GSTRING_LEN; 114 p += ETH_GSTRING_LEN;
106 } 115 }
107 } 116 }
108 117
109 static int xgene_get_sset_count(struct net_device *ndev, int sset) 118 static int xgene_get_sset_count(struct net_device *ndev, int sset)
110 { 119 {
111 if (sset != ETH_SS_STATS) 120 if (sset != ETH_SS_STATS)
112 return -EINVAL; 121 return -EINVAL;
113 122
114 return XGENE_STATS_LEN; 123 return XGENE_STATS_LEN;
115 } 124 }
116 125
117 static void xgene_get_ethtool_stats(struct net_device *ndev, 126 static void xgene_get_ethtool_stats(struct net_device *ndev,
118 struct ethtool_stats *dummy, 127 struct ethtool_stats *dummy,
119 u64 *data) 128 u64 *data)
120 { 129 {
121 void *pdata = netdev_priv(ndev); 130 void *pdata = netdev_priv(ndev);
122 int i; 131 int i;
123 132
124 for (i = 0; i < XGENE_STATS_LEN; i++) 133 for (i = 0; i < XGENE_STATS_LEN; i++)
125 *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); 134 *data++ = *(u64 *)(pdata + gstrings_stats[i].offset);
126 } 135 }
127 136
128 static const struct ethtool_ops xgene_ethtool_ops = { 137 static const struct ethtool_ops xgene_ethtool_ops = {
129 .get_drvinfo = xgene_get_drvinfo, 138 .get_drvinfo = xgene_get_drvinfo,
130 .get_settings = xgene_get_settings, 139 .get_settings = xgene_get_settings,
131 .set_settings = xgene_set_settings, 140 .set_settings = xgene_set_settings,
132 .get_link = ethtool_op_get_link, 141 .get_link = ethtool_op_get_link,
133 .get_strings = xgene_get_strings, 142 .get_strings = xgene_get_strings,
134 .get_sset_count = xgene_get_sset_count, 143 .get_sset_count = xgene_get_sset_count,