0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "main.h"
0011
0012 #define XGE_STAT(m) { #m, offsetof(struct xge_pdata, stats.m) }
0013 #define XGE_EXTD_STAT(m, n) \
0014 { \
0015 #m, \
0016 n, \
0017 0 \
0018 }
0019
0020 static const struct xge_gstrings_stats gstrings_stats[] = {
0021 XGE_STAT(rx_packets),
0022 XGE_STAT(tx_packets),
0023 XGE_STAT(rx_bytes),
0024 XGE_STAT(tx_bytes),
0025 XGE_STAT(rx_errors)
0026 };
0027
0028 static struct xge_gstrings_extd_stats gstrings_extd_stats[] = {
0029 XGE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64),
0030 XGE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127),
0031 XGE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255),
0032 XGE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511),
0033 XGE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K),
0034 XGE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX),
0035 XGE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV),
0036 XGE_EXTD_STAT(rx_fcs_error_cntr, RFCS),
0037 XGE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA),
0038 XGE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA),
0039 XGE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF),
0040 XGE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF),
0041 XGE_EXTD_STAT(rx_unk_opcode_cntr, RXUO),
0042 XGE_EXTD_STAT(rx_align_err_cntr, RALN),
0043 XGE_EXTD_STAT(rx_frame_len_err_cntr, RFLR),
0044 XGE_EXTD_STAT(rx_code_err_cntr, RCDE),
0045 XGE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE),
0046 XGE_EXTD_STAT(rx_undersize_pkt_cntr, RUND),
0047 XGE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR),
0048 XGE_EXTD_STAT(rx_fragments_cntr, RFRG),
0049 XGE_EXTD_STAT(rx_jabber_cntr, RJBR),
0050 XGE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP),
0051 XGE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA),
0052 XGE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA),
0053 XGE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF),
0054 XGE_EXTD_STAT(tx_defer_pkt_cntr, TDFR),
0055 XGE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF),
0056 XGE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL),
0057 XGE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL),
0058 XGE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL),
0059 XGE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL),
0060 XGE_EXTD_STAT(tx_total_col_cntr, TNCL),
0061 XGE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH),
0062 XGE_EXTD_STAT(tx_drop_frame_cntr, TDRP),
0063 XGE_EXTD_STAT(tx_jabber_frame_cntr, TJBR),
0064 XGE_EXTD_STAT(tx_fcs_error_cntr, TFCS),
0065 XGE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF),
0066 XGE_EXTD_STAT(tx_oversize_frame_cntr, TOVR),
0067 XGE_EXTD_STAT(tx_undersize_frame_cntr, TUND),
0068 XGE_EXTD_STAT(tx_fragments_cntr, TFRG)
0069 };
0070
0071 #define XGE_STATS_LEN ARRAY_SIZE(gstrings_stats)
0072 #define XGE_EXTD_STATS_LEN ARRAY_SIZE(gstrings_extd_stats)
0073
0074 static void xge_mac_get_extd_stats(struct xge_pdata *pdata)
0075 {
0076 u32 data;
0077 int i;
0078
0079 for (i = 0; i < XGE_EXTD_STATS_LEN; i++) {
0080 data = xge_rd_csr(pdata, gstrings_extd_stats[i].addr);
0081 gstrings_extd_stats[i].value += data;
0082 }
0083 }
0084
0085 static void xge_get_drvinfo(struct net_device *ndev,
0086 struct ethtool_drvinfo *info)
0087 {
0088 struct xge_pdata *pdata = netdev_priv(ndev);
0089 struct platform_device *pdev = pdata->pdev;
0090
0091 strcpy(info->driver, "xgene-enet-v2");
0092 sprintf(info->bus_info, "%s", pdev->name);
0093 }
0094
0095 static void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
0096 {
0097 u8 *p = data;
0098 int i;
0099
0100 if (stringset != ETH_SS_STATS)
0101 return;
0102
0103 for (i = 0; i < XGE_STATS_LEN; i++) {
0104 memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN);
0105 p += ETH_GSTRING_LEN;
0106 }
0107
0108 for (i = 0; i < XGE_EXTD_STATS_LEN; i++) {
0109 memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN);
0110 p += ETH_GSTRING_LEN;
0111 }
0112 }
0113
0114 static int xge_get_sset_count(struct net_device *ndev, int sset)
0115 {
0116 if (sset != ETH_SS_STATS)
0117 return -EINVAL;
0118
0119 return XGE_STATS_LEN + XGE_EXTD_STATS_LEN;
0120 }
0121
0122 static void xge_get_ethtool_stats(struct net_device *ndev,
0123 struct ethtool_stats *dummy,
0124 u64 *data)
0125 {
0126 void *pdata = netdev_priv(ndev);
0127 int i;
0128
0129 for (i = 0; i < XGE_STATS_LEN; i++)
0130 *data++ = *(u64 *)(pdata + gstrings_stats[i].offset);
0131
0132 xge_mac_get_extd_stats(pdata);
0133
0134 for (i = 0; i < XGE_EXTD_STATS_LEN; i++)
0135 *data++ = gstrings_extd_stats[i].value;
0136 }
0137
0138 static int xge_get_link_ksettings(struct net_device *ndev,
0139 struct ethtool_link_ksettings *cmd)
0140 {
0141 struct phy_device *phydev = ndev->phydev;
0142
0143 if (!phydev)
0144 return -ENODEV;
0145
0146 phy_ethtool_ksettings_get(phydev, cmd);
0147
0148 return 0;
0149 }
0150
0151 static int xge_set_link_ksettings(struct net_device *ndev,
0152 const struct ethtool_link_ksettings *cmd)
0153 {
0154 struct phy_device *phydev = ndev->phydev;
0155
0156 if (!phydev)
0157 return -ENODEV;
0158
0159 return phy_ethtool_ksettings_set(phydev, cmd);
0160 }
0161
0162 static const struct ethtool_ops xge_ethtool_ops = {
0163 .get_drvinfo = xge_get_drvinfo,
0164 .get_link = ethtool_op_get_link,
0165 .get_strings = xge_get_strings,
0166 .get_sset_count = xge_get_sset_count,
0167 .get_ethtool_stats = xge_get_ethtool_stats,
0168 .get_link_ksettings = xge_get_link_ksettings,
0169 .set_link_ksettings = xge_set_link_ksettings,
0170 };
0171
0172 void xge_set_ethtool_ops(struct net_device *ndev)
0173 {
0174 ndev->ethtool_ops = &xge_ethtool_ops;
0175 }