ethtool.c 4.8 KB

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