emac-ethtool.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* Copyright (c) 2016, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/ethtool.h>
  13. #include <linux/phy.h>
  14. #include "emac.h"
  15. static const char * const emac_ethtool_stat_strings[] = {
  16. "rx_ok",
  17. "rx_bcast",
  18. "rx_mcast",
  19. "rx_pause",
  20. "rx_ctrl",
  21. "rx_fcs_err",
  22. "rx_len_err",
  23. "rx_byte_cnt",
  24. "rx_runt",
  25. "rx_frag",
  26. "rx_sz_64",
  27. "rx_sz_65_127",
  28. "rx_sz_128_255",
  29. "rx_sz_256_511",
  30. "rx_sz_512_1023",
  31. "rx_sz_1024_1518",
  32. "rx_sz_1519_max",
  33. "rx_sz_ov",
  34. "rx_rxf_ov",
  35. "rx_align_err",
  36. "rx_bcast_byte_cnt",
  37. "rx_mcast_byte_cnt",
  38. "rx_err_addr",
  39. "rx_crc_align",
  40. "rx_jabbers",
  41. "tx_ok",
  42. "tx_bcast",
  43. "tx_mcast",
  44. "tx_pause",
  45. "tx_exc_defer",
  46. "tx_ctrl",
  47. "tx_defer",
  48. "tx_byte_cnt",
  49. "tx_sz_64",
  50. "tx_sz_65_127",
  51. "tx_sz_128_255",
  52. "tx_sz_256_511",
  53. "tx_sz_512_1023",
  54. "tx_sz_1024_1518",
  55. "tx_sz_1519_max",
  56. "tx_1_col",
  57. "tx_2_col",
  58. "tx_late_col",
  59. "tx_abort_col",
  60. "tx_underrun",
  61. "tx_rd_eop",
  62. "tx_len_err",
  63. "tx_trunc",
  64. "tx_bcast_byte",
  65. "tx_mcast_byte",
  66. "tx_col",
  67. };
  68. #define EMAC_STATS_LEN ARRAY_SIZE(emac_ethtool_stat_strings)
  69. static u32 emac_get_msglevel(struct net_device *netdev)
  70. {
  71. struct emac_adapter *adpt = netdev_priv(netdev);
  72. return adpt->msg_enable;
  73. }
  74. static void emac_set_msglevel(struct net_device *netdev, u32 data)
  75. {
  76. struct emac_adapter *adpt = netdev_priv(netdev);
  77. adpt->msg_enable = data;
  78. }
  79. static int emac_get_sset_count(struct net_device *netdev, int sset)
  80. {
  81. switch (sset) {
  82. case ETH_SS_PRIV_FLAGS:
  83. return 1;
  84. case ETH_SS_STATS:
  85. return EMAC_STATS_LEN;
  86. default:
  87. return -EOPNOTSUPP;
  88. }
  89. }
  90. static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
  91. {
  92. unsigned int i;
  93. switch (stringset) {
  94. case ETH_SS_PRIV_FLAGS:
  95. strcpy(data, "single-pause-mode");
  96. break;
  97. case ETH_SS_STATS:
  98. for (i = 0; i < EMAC_STATS_LEN; i++) {
  99. strlcpy(data, emac_ethtool_stat_strings[i],
  100. ETH_GSTRING_LEN);
  101. data += ETH_GSTRING_LEN;
  102. }
  103. break;
  104. }
  105. }
  106. static void emac_get_ethtool_stats(struct net_device *netdev,
  107. struct ethtool_stats *stats,
  108. u64 *data)
  109. {
  110. struct emac_adapter *adpt = netdev_priv(netdev);
  111. spin_lock(&adpt->stats.lock);
  112. emac_update_hw_stats(adpt);
  113. memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
  114. spin_unlock(&adpt->stats.lock);
  115. }
  116. static int emac_nway_reset(struct net_device *netdev)
  117. {
  118. struct phy_device *phydev = netdev->phydev;
  119. if (!phydev)
  120. return -ENODEV;
  121. return genphy_restart_aneg(phydev);
  122. }
  123. static void emac_get_ringparam(struct net_device *netdev,
  124. struct ethtool_ringparam *ring)
  125. {
  126. struct emac_adapter *adpt = netdev_priv(netdev);
  127. ring->rx_max_pending = EMAC_MAX_RX_DESCS;
  128. ring->tx_max_pending = EMAC_MAX_TX_DESCS;
  129. ring->rx_pending = adpt->rx_desc_cnt;
  130. ring->tx_pending = adpt->tx_desc_cnt;
  131. }
  132. static int emac_set_ringparam(struct net_device *netdev,
  133. struct ethtool_ringparam *ring)
  134. {
  135. struct emac_adapter *adpt = netdev_priv(netdev);
  136. /* We don't have separate queues/rings for small/large frames, so
  137. * reject any attempt to specify those values separately.
  138. */
  139. if (ring->rx_mini_pending || ring->rx_jumbo_pending)
  140. return -EINVAL;
  141. adpt->tx_desc_cnt =
  142. clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
  143. adpt->rx_desc_cnt =
  144. clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
  145. if (netif_running(netdev))
  146. return emac_reinit_locked(adpt);
  147. return 0;
  148. }
  149. static void emac_get_pauseparam(struct net_device *netdev,
  150. struct ethtool_pauseparam *pause)
  151. {
  152. struct emac_adapter *adpt = netdev_priv(netdev);
  153. pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
  154. pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
  155. pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
  156. }
  157. static int emac_set_pauseparam(struct net_device *netdev,
  158. struct ethtool_pauseparam *pause)
  159. {
  160. struct emac_adapter *adpt = netdev_priv(netdev);
  161. adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
  162. adpt->rx_flow_control = pause->rx_pause != 0;
  163. adpt->tx_flow_control = pause->tx_pause != 0;
  164. if (netif_running(netdev))
  165. return emac_reinit_locked(adpt);
  166. return 0;
  167. }
  168. /* Selected registers that might want to track during runtime. */
  169. static const u16 emac_regs[] = {
  170. EMAC_DMA_MAS_CTRL,
  171. EMAC_MAC_CTRL,
  172. EMAC_TXQ_CTRL_0,
  173. EMAC_RXQ_CTRL_0,
  174. EMAC_DMA_CTRL,
  175. EMAC_INT_MASK,
  176. EMAC_AXI_MAST_CTRL,
  177. EMAC_CORE_HW_VERSION,
  178. EMAC_MISC_CTRL,
  179. };
  180. /* Every time emac_regs[] above is changed, increase this version number. */
  181. #define EMAC_REGS_VERSION 0
  182. #define EMAC_MAX_REG_SIZE ARRAY_SIZE(emac_regs)
  183. static void emac_get_regs(struct net_device *netdev,
  184. struct ethtool_regs *regs, void *buff)
  185. {
  186. struct emac_adapter *adpt = netdev_priv(netdev);
  187. u32 *val = buff;
  188. unsigned int i;
  189. regs->version = EMAC_REGS_VERSION;
  190. regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
  191. for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
  192. val[i] = readl(adpt->base + emac_regs[i]);
  193. }
  194. static int emac_get_regs_len(struct net_device *netdev)
  195. {
  196. return EMAC_MAX_REG_SIZE * sizeof(u32);
  197. }
  198. #define EMAC_PRIV_ENABLE_SINGLE_PAUSE BIT(0)
  199. static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
  200. {
  201. struct emac_adapter *adpt = netdev_priv(netdev);
  202. adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
  203. if (netif_running(netdev))
  204. return emac_reinit_locked(adpt);
  205. return 0;
  206. }
  207. static u32 emac_get_priv_flags(struct net_device *netdev)
  208. {
  209. struct emac_adapter *adpt = netdev_priv(netdev);
  210. return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
  211. }
  212. static const struct ethtool_ops emac_ethtool_ops = {
  213. .get_link_ksettings = phy_ethtool_get_link_ksettings,
  214. .set_link_ksettings = phy_ethtool_set_link_ksettings,
  215. .get_msglevel = emac_get_msglevel,
  216. .set_msglevel = emac_set_msglevel,
  217. .get_sset_count = emac_get_sset_count,
  218. .get_strings = emac_get_strings,
  219. .get_ethtool_stats = emac_get_ethtool_stats,
  220. .get_ringparam = emac_get_ringparam,
  221. .set_ringparam = emac_set_ringparam,
  222. .get_pauseparam = emac_get_pauseparam,
  223. .set_pauseparam = emac_set_pauseparam,
  224. .nway_reset = emac_nway_reset,
  225. .get_link = ethtool_op_get_link,
  226. .get_regs_len = emac_get_regs_len,
  227. .get_regs = emac_get_regs,
  228. .set_priv_flags = emac_set_priv_flags,
  229. .get_priv_flags = emac_get_priv_flags,
  230. };
  231. void emac_set_ethtool_ops(struct net_device *netdev)
  232. {
  233. netdev->ethtool_ops = &emac_ethtool_ops;
  234. }