1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Applied Micro X-Gene SoC Ethernet v2 Driver 4 * 5 * Copyright (c) 2017, Applied Micro Circuits Corporation 6 * Author(s): Iyappan Subramanian <isubramanian@apm.com> 7 * Keyur Chudgar <kchudgar@apm.com> 8 */ 9 10 #include "main.h" 11 12 #define XGE_STAT(m) { #m, offsetof(struct xge_pdata, stats.m) } 13 #define XGE_EXTD_STAT(m, n) \ 14 { \ 15 #m, \ 16 n, \ 17 0 \ 18 } 19 20 static const struct xge_gstrings_stats gstrings_stats[] = { 21 XGE_STAT(rx_packets), 22 XGE_STAT(tx_packets), 23 XGE_STAT(rx_bytes), 24 XGE_STAT(tx_bytes), 25 XGE_STAT(rx_errors) 26 }; 27 28 static struct xge_gstrings_extd_stats gstrings_extd_stats[] = { 29 XGE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64), 30 XGE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127), 31 XGE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255), 32 XGE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511), 33 XGE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K), 34 XGE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX), 35 XGE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV), 36 XGE_EXTD_STAT(rx_fcs_error_cntr, RFCS), 37 XGE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA), 38 XGE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA), 39 XGE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF), 40 XGE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF), 41 XGE_EXTD_STAT(rx_unk_opcode_cntr, RXUO), 42 XGE_EXTD_STAT(rx_align_err_cntr, RALN), 43 XGE_EXTD_STAT(rx_frame_len_err_cntr, RFLR), 44 XGE_EXTD_STAT(rx_code_err_cntr, RCDE), 45 XGE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE), 46 XGE_EXTD_STAT(rx_undersize_pkt_cntr, RUND), 47 XGE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR), 48 XGE_EXTD_STAT(rx_fragments_cntr, RFRG), 49 XGE_EXTD_STAT(rx_jabber_cntr, RJBR), 50 XGE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP), 51 XGE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA), 52 XGE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA), 53 XGE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF), 54 XGE_EXTD_STAT(tx_defer_pkt_cntr, TDFR), 55 XGE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF), 56 XGE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL), 57 XGE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL), 58 XGE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL), 59 XGE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL), 60 XGE_EXTD_STAT(tx_total_col_cntr, TNCL), 61 XGE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH), 62 XGE_EXTD_STAT(tx_drop_frame_cntr, TDRP), 63 XGE_EXTD_STAT(tx_jabber_frame_cntr, TJBR), 64 XGE_EXTD_STAT(tx_fcs_error_cntr, TFCS), 65 XGE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF), 66 XGE_EXTD_STAT(tx_oversize_frame_cntr, TOVR), 67 XGE_EXTD_STAT(tx_undersize_frame_cntr, TUND), 68 XGE_EXTD_STAT(tx_fragments_cntr, TFRG) 69 }; 70 71 #define XGE_STATS_LEN ARRAY_SIZE(gstrings_stats) 72 #define XGE_EXTD_STATS_LEN ARRAY_SIZE(gstrings_extd_stats) 73 74 static void xge_mac_get_extd_stats(struct xge_pdata *pdata) 75 { 76 u32 data; 77 int i; 78 79 for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 80 data = xge_rd_csr(pdata, gstrings_extd_stats[i].addr); 81 gstrings_extd_stats[i].value += data; 82 } 83 } 84 85 static void xge_get_drvinfo(struct net_device *ndev, 86 struct ethtool_drvinfo *info) 87 { 88 struct xge_pdata *pdata = netdev_priv(ndev); 89 struct platform_device *pdev = pdata->pdev; 90 91 strcpy(info->driver, "xgene-enet-v2"); 92 sprintf(info->bus_info, "%s", pdev->name); 93 } 94 95 static void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 96 { 97 u8 *p = data; 98 int i; 99 100 if (stringset != ETH_SS_STATS) 101 return; 102 103 for (i = 0; i < XGE_STATS_LEN; i++) { 104 memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); 105 p += ETH_GSTRING_LEN; 106 } 107 108 for (i = 0; i < XGE_EXTD_STATS_LEN; i++) { 109 memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN); 110 p += ETH_GSTRING_LEN; 111 } 112 } 113 114 static int xge_get_sset_count(struct net_device *ndev, int sset) 115 { 116 if (sset != ETH_SS_STATS) 117 return -EINVAL; 118 119 return XGE_STATS_LEN + XGE_EXTD_STATS_LEN; 120 } 121 122 static void xge_get_ethtool_stats(struct net_device *ndev, 123 struct ethtool_stats *dummy, 124 u64 *data) 125 { 126 void *pdata = netdev_priv(ndev); 127 int i; 128 129 for (i = 0; i < XGE_STATS_LEN; i++) 130 *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); 131 132 xge_mac_get_extd_stats(pdata); 133 134 for (i = 0; i < XGE_EXTD_STATS_LEN; i++) 135 *data++ = gstrings_extd_stats[i].value; 136 } 137 138 static int xge_get_link_ksettings(struct net_device *ndev, 139 struct ethtool_link_ksettings *cmd) 140 { 141 struct phy_device *phydev = ndev->phydev; 142 143 if (!phydev) 144 return -ENODEV; 145 146 phy_ethtool_ksettings_get(phydev, cmd); 147 148 return 0; 149 } 150 151 static int xge_set_link_ksettings(struct net_device *ndev, 152 const struct ethtool_link_ksettings *cmd) 153 { 154 struct phy_device *phydev = ndev->phydev; 155 156 if (!phydev) 157 return -ENODEV; 158 159 return phy_ethtool_ksettings_set(phydev, cmd); 160 } 161 162 static const struct ethtool_ops xge_ethtool_ops = { 163 .get_drvinfo = xge_get_drvinfo, 164 .get_link = ethtool_op_get_link, 165 .get_strings = xge_get_strings, 166 .get_sset_count = xge_get_sset_count, 167 .get_ethtool_stats = xge_get_ethtool_stats, 168 .get_link_ksettings = xge_get_link_ksettings, 169 .set_link_ksettings = xge_set_link_ksettings, 170 }; 171 172 void xge_set_ethtool_ops(struct net_device *ndev) 173 { 174 ndev->ethtool_ops = &xge_ethtool_ops; 175 } 176