ethtool.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /****************************************************************************
  3. * Driver for Solarflare network controllers and boards
  4. * Copyright 2005-2006 Fen Systems Ltd.
  5. * Copyright 2006-2013 Solarflare Communications Inc.
  6. */
  7. #include <linux/netdevice.h>
  8. #include <linux/ethtool.h>
  9. #include <linux/rtnetlink.h>
  10. #include <linux/in.h>
  11. #include "net_driver.h"
  12. #include "workarounds.h"
  13. #include "selftest.h"
  14. #include "efx.h"
  15. #include "efx_channels.h"
  16. #include "rx_common.h"
  17. #include "tx_common.h"
  18. #include "ethtool_common.h"
  19. #include "filter.h"
  20. #include "nic.h"
  21. #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
  22. /**************************************************************************
  23. *
  24. * Ethtool operations
  25. *
  26. **************************************************************************
  27. */
  28. /* Identify device by flashing LEDs */
  29. static int efx_ethtool_phys_id(struct net_device *net_dev,
  30. enum ethtool_phys_id_state state)
  31. {
  32. struct efx_nic *efx = efx_netdev_priv(net_dev);
  33. enum efx_led_mode mode = EFX_LED_DEFAULT;
  34. switch (state) {
  35. case ETHTOOL_ID_ON:
  36. mode = EFX_LED_ON;
  37. break;
  38. case ETHTOOL_ID_OFF:
  39. mode = EFX_LED_OFF;
  40. break;
  41. case ETHTOOL_ID_INACTIVE:
  42. mode = EFX_LED_DEFAULT;
  43. break;
  44. case ETHTOOL_ID_ACTIVE:
  45. return 1; /* cycle on/off once per second */
  46. }
  47. return efx_mcdi_set_id_led(efx, mode);
  48. }
  49. static int efx_ethtool_get_regs_len(struct net_device *net_dev)
  50. {
  51. return efx_nic_get_regs_len(efx_netdev_priv(net_dev));
  52. }
  53. static void efx_ethtool_get_regs(struct net_device *net_dev,
  54. struct ethtool_regs *regs, void *buf)
  55. {
  56. struct efx_nic *efx = efx_netdev_priv(net_dev);
  57. regs->version = efx->type->revision;
  58. efx_nic_get_regs(efx, buf);
  59. }
  60. /*
  61. * Each channel has a single IRQ and moderation timer, started by any
  62. * completion (or other event). Unless the module parameter
  63. * separate_tx_channels is set, IRQs and moderation are therefore
  64. * shared between RX and TX completions. In this case, when RX IRQ
  65. * moderation is explicitly changed then TX IRQ moderation is
  66. * automatically changed too, but otherwise we fail if the two values
  67. * are requested to be different.
  68. *
  69. * The hardware does not support a limit on the number of completions
  70. * before an IRQ, so we do not use the max_frames fields. We should
  71. * report and require that max_frames == (usecs != 0), but this would
  72. * invalidate existing user documentation.
  73. *
  74. * The hardware does not have distinct settings for interrupt
  75. * moderation while the previous IRQ is being handled, so we should
  76. * not use the 'irq' fields. However, an earlier developer
  77. * misunderstood the meaning of the 'irq' fields and the driver did
  78. * not support the standard fields. To avoid invalidating existing
  79. * user documentation, we report and accept changes through either the
  80. * standard or 'irq' fields. If both are changed at the same time, we
  81. * prefer the standard field.
  82. *
  83. * We implement adaptive IRQ moderation, but use a different algorithm
  84. * from that assumed in the definition of struct ethtool_coalesce.
  85. * Therefore we do not use any of the adaptive moderation parameters
  86. * in it.
  87. */
  88. static int efx_ethtool_get_coalesce(struct net_device *net_dev,
  89. struct ethtool_coalesce *coalesce,
  90. struct kernel_ethtool_coalesce *kernel_coal,
  91. struct netlink_ext_ack *extack)
  92. {
  93. struct efx_nic *efx = efx_netdev_priv(net_dev);
  94. unsigned int tx_usecs, rx_usecs;
  95. bool rx_adaptive;
  96. efx_get_irq_moderation(efx, &tx_usecs, &rx_usecs, &rx_adaptive);
  97. coalesce->tx_coalesce_usecs = tx_usecs;
  98. coalesce->tx_coalesce_usecs_irq = tx_usecs;
  99. coalesce->rx_coalesce_usecs = rx_usecs;
  100. coalesce->rx_coalesce_usecs_irq = rx_usecs;
  101. coalesce->use_adaptive_rx_coalesce = rx_adaptive;
  102. return 0;
  103. }
  104. static int efx_ethtool_set_coalesce(struct net_device *net_dev,
  105. struct ethtool_coalesce *coalesce,
  106. struct kernel_ethtool_coalesce *kernel_coal,
  107. struct netlink_ext_ack *extack)
  108. {
  109. struct efx_nic *efx = efx_netdev_priv(net_dev);
  110. struct efx_channel *channel;
  111. unsigned int tx_usecs, rx_usecs;
  112. bool adaptive, rx_may_override_tx;
  113. int rc;
  114. efx_get_irq_moderation(efx, &tx_usecs, &rx_usecs, &adaptive);
  115. if (coalesce->rx_coalesce_usecs != rx_usecs)
  116. rx_usecs = coalesce->rx_coalesce_usecs;
  117. else
  118. rx_usecs = coalesce->rx_coalesce_usecs_irq;
  119. adaptive = coalesce->use_adaptive_rx_coalesce;
  120. /* If channels are shared, TX IRQ moderation can be quietly
  121. * overridden unless it is changed from its old value.
  122. */
  123. rx_may_override_tx = (coalesce->tx_coalesce_usecs == tx_usecs &&
  124. coalesce->tx_coalesce_usecs_irq == tx_usecs);
  125. if (coalesce->tx_coalesce_usecs != tx_usecs)
  126. tx_usecs = coalesce->tx_coalesce_usecs;
  127. else
  128. tx_usecs = coalesce->tx_coalesce_usecs_irq;
  129. rc = efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive,
  130. rx_may_override_tx);
  131. if (rc != 0)
  132. return rc;
  133. efx_for_each_channel(channel, efx)
  134. efx->type->push_irq_moderation(channel);
  135. return 0;
  136. }
  137. static void
  138. efx_ethtool_get_ringparam(struct net_device *net_dev,
  139. struct ethtool_ringparam *ring,
  140. struct kernel_ethtool_ringparam *kernel_ring,
  141. struct netlink_ext_ack *extack)
  142. {
  143. struct efx_nic *efx = efx_netdev_priv(net_dev);
  144. ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
  145. ring->tx_max_pending = EFX_TXQ_MAX_ENT(efx);
  146. ring->rx_pending = efx->rxq_entries;
  147. ring->tx_pending = efx->txq_entries;
  148. }
  149. static int
  150. efx_ethtool_set_ringparam(struct net_device *net_dev,
  151. struct ethtool_ringparam *ring,
  152. struct kernel_ethtool_ringparam *kernel_ring,
  153. struct netlink_ext_ack *extack)
  154. {
  155. struct efx_nic *efx = efx_netdev_priv(net_dev);
  156. u32 txq_entries;
  157. if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
  158. ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
  159. ring->tx_pending > EFX_TXQ_MAX_ENT(efx))
  160. return -EINVAL;
  161. if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
  162. netif_err(efx, drv, efx->net_dev,
  163. "RX queues cannot be smaller than %u\n",
  164. EFX_RXQ_MIN_ENT);
  165. return -EINVAL;
  166. }
  167. txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
  168. if (txq_entries != ring->tx_pending)
  169. netif_warn(efx, drv, efx->net_dev,
  170. "increasing TX queue size to minimum of %u\n",
  171. txq_entries);
  172. return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
  173. }
  174. static void efx_ethtool_get_wol(struct net_device *net_dev,
  175. struct ethtool_wolinfo *wol)
  176. {
  177. struct efx_nic *efx = efx_netdev_priv(net_dev);
  178. return efx->type->get_wol(efx, wol);
  179. }
  180. static int efx_ethtool_set_wol(struct net_device *net_dev,
  181. struct ethtool_wolinfo *wol)
  182. {
  183. struct efx_nic *efx = efx_netdev_priv(net_dev);
  184. return efx->type->set_wol(efx, wol->wolopts);
  185. }
  186. static void efx_ethtool_get_fec_stats(struct net_device *net_dev,
  187. struct ethtool_fec_stats *fec_stats)
  188. {
  189. struct efx_nic *efx = efx_netdev_priv(net_dev);
  190. if (efx->type->get_fec_stats)
  191. efx->type->get_fec_stats(efx, fec_stats);
  192. }
  193. static int efx_ethtool_get_ts_info(struct net_device *net_dev,
  194. struct ethtool_ts_info *ts_info)
  195. {
  196. struct efx_nic *efx = efx_netdev_priv(net_dev);
  197. /* Software capabilities */
  198. ts_info->so_timestamping = (SOF_TIMESTAMPING_RX_SOFTWARE |
  199. SOF_TIMESTAMPING_SOFTWARE);
  200. ts_info->phc_index = -1;
  201. efx_ptp_get_ts_info(efx, ts_info);
  202. return 0;
  203. }
  204. const struct ethtool_ops efx_ethtool_ops = {
  205. .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
  206. ETHTOOL_COALESCE_USECS_IRQ |
  207. ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
  208. .get_drvinfo = efx_ethtool_get_drvinfo,
  209. .get_regs_len = efx_ethtool_get_regs_len,
  210. .get_regs = efx_ethtool_get_regs,
  211. .get_msglevel = efx_ethtool_get_msglevel,
  212. .set_msglevel = efx_ethtool_set_msglevel,
  213. .get_link = ethtool_op_get_link,
  214. .get_coalesce = efx_ethtool_get_coalesce,
  215. .set_coalesce = efx_ethtool_set_coalesce,
  216. .get_ringparam = efx_ethtool_get_ringparam,
  217. .set_ringparam = efx_ethtool_set_ringparam,
  218. .get_pauseparam = efx_ethtool_get_pauseparam,
  219. .set_pauseparam = efx_ethtool_set_pauseparam,
  220. .get_sset_count = efx_ethtool_get_sset_count,
  221. .self_test = efx_ethtool_self_test,
  222. .get_strings = efx_ethtool_get_strings,
  223. .set_phys_id = efx_ethtool_phys_id,
  224. .get_ethtool_stats = efx_ethtool_get_stats,
  225. .get_wol = efx_ethtool_get_wol,
  226. .set_wol = efx_ethtool_set_wol,
  227. .reset = efx_ethtool_reset,
  228. .get_rxnfc = efx_ethtool_get_rxnfc,
  229. .set_rxnfc = efx_ethtool_set_rxnfc,
  230. .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
  231. .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
  232. .get_rxfh = efx_ethtool_get_rxfh,
  233. .set_rxfh = efx_ethtool_set_rxfh,
  234. .get_rxfh_context = efx_ethtool_get_rxfh_context,
  235. .set_rxfh_context = efx_ethtool_set_rxfh_context,
  236. .get_ts_info = efx_ethtool_get_ts_info,
  237. .get_module_info = efx_ethtool_get_module_info,
  238. .get_module_eeprom = efx_ethtool_get_module_eeprom,
  239. .get_link_ksettings = efx_ethtool_get_link_ksettings,
  240. .set_link_ksettings = efx_ethtool_set_link_ksettings,
  241. .get_fec_stats = efx_ethtool_get_fec_stats,
  242. .get_fecparam = efx_ethtool_get_fecparam,
  243. .set_fecparam = efx_ethtool_set_fecparam,
  244. };