i40evf_ethtool.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright(c) 2013 - 2018 Intel Corporation. */
  3. /* ethtool support for i40evf */
  4. #include "i40evf.h"
  5. #include <linux/uaccess.h>
  6. struct i40evf_stats {
  7. char stat_string[ETH_GSTRING_LEN];
  8. int stat_offset;
  9. };
  10. #define I40EVF_STAT(_name, _stat) { \
  11. .stat_string = _name, \
  12. .stat_offset = offsetof(struct i40evf_adapter, _stat) \
  13. }
  14. /* All stats are u64, so we don't need to track the size of the field. */
  15. static const struct i40evf_stats i40evf_gstrings_stats[] = {
  16. I40EVF_STAT("rx_bytes", current_stats.rx_bytes),
  17. I40EVF_STAT("rx_unicast", current_stats.rx_unicast),
  18. I40EVF_STAT("rx_multicast", current_stats.rx_multicast),
  19. I40EVF_STAT("rx_broadcast", current_stats.rx_broadcast),
  20. I40EVF_STAT("rx_discards", current_stats.rx_discards),
  21. I40EVF_STAT("rx_unknown_protocol", current_stats.rx_unknown_protocol),
  22. I40EVF_STAT("tx_bytes", current_stats.tx_bytes),
  23. I40EVF_STAT("tx_unicast", current_stats.tx_unicast),
  24. I40EVF_STAT("tx_multicast", current_stats.tx_multicast),
  25. I40EVF_STAT("tx_broadcast", current_stats.tx_broadcast),
  26. I40EVF_STAT("tx_discards", current_stats.tx_discards),
  27. I40EVF_STAT("tx_errors", current_stats.tx_errors),
  28. };
  29. #define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats)
  30. #define I40EVF_QUEUE_STATS_LEN(_dev) \
  31. (((struct i40evf_adapter *)\
  32. netdev_priv(_dev))->num_active_queues \
  33. * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
  34. #define I40EVF_STATS_LEN(_dev) \
  35. (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
  36. /* For now we have one and only one private flag and it is only defined
  37. * when we have support for the SKIP_CPU_SYNC DMA attribute. Instead
  38. * of leaving all this code sitting around empty we will strip it unless
  39. * our one private flag is actually available.
  40. */
  41. struct i40evf_priv_flags {
  42. char flag_string[ETH_GSTRING_LEN];
  43. u32 flag;
  44. bool read_only;
  45. };
  46. #define I40EVF_PRIV_FLAG(_name, _flag, _read_only) { \
  47. .flag_string = _name, \
  48. .flag = _flag, \
  49. .read_only = _read_only, \
  50. }
  51. static const struct i40evf_priv_flags i40evf_gstrings_priv_flags[] = {
  52. I40EVF_PRIV_FLAG("legacy-rx", I40EVF_FLAG_LEGACY_RX, 0),
  53. };
  54. #define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_gstrings_priv_flags)
  55. /**
  56. * i40evf_get_link_ksettings - Get Link Speed and Duplex settings
  57. * @netdev: network interface device structure
  58. * @cmd: ethtool command
  59. *
  60. * Reports speed/duplex settings. Because this is a VF, we don't know what
  61. * kind of link we really have, so we fake it.
  62. **/
  63. static int i40evf_get_link_ksettings(struct net_device *netdev,
  64. struct ethtool_link_ksettings *cmd)
  65. {
  66. struct i40evf_adapter *adapter = netdev_priv(netdev);
  67. ethtool_link_ksettings_zero_link_mode(cmd, supported);
  68. cmd->base.autoneg = AUTONEG_DISABLE;
  69. cmd->base.port = PORT_NONE;
  70. /* Set speed and duplex */
  71. switch (adapter->link_speed) {
  72. case I40E_LINK_SPEED_40GB:
  73. cmd->base.speed = SPEED_40000;
  74. break;
  75. case I40E_LINK_SPEED_25GB:
  76. #ifdef SPEED_25000
  77. cmd->base.speed = SPEED_25000;
  78. #else
  79. netdev_info(netdev,
  80. "Speed is 25G, display not supported by this version of ethtool.\n");
  81. #endif
  82. break;
  83. case I40E_LINK_SPEED_20GB:
  84. cmd->base.speed = SPEED_20000;
  85. break;
  86. case I40E_LINK_SPEED_10GB:
  87. cmd->base.speed = SPEED_10000;
  88. break;
  89. case I40E_LINK_SPEED_1GB:
  90. cmd->base.speed = SPEED_1000;
  91. break;
  92. case I40E_LINK_SPEED_100MB:
  93. cmd->base.speed = SPEED_100;
  94. break;
  95. default:
  96. break;
  97. }
  98. cmd->base.duplex = DUPLEX_FULL;
  99. return 0;
  100. }
  101. /**
  102. * i40evf_get_sset_count - Get length of string set
  103. * @netdev: network interface device structure
  104. * @sset: id of string set
  105. *
  106. * Reports size of string table. This driver only supports
  107. * strings for statistics.
  108. **/
  109. static int i40evf_get_sset_count(struct net_device *netdev, int sset)
  110. {
  111. if (sset == ETH_SS_STATS)
  112. return I40EVF_STATS_LEN(netdev);
  113. else if (sset == ETH_SS_PRIV_FLAGS)
  114. return I40EVF_PRIV_FLAGS_STR_LEN;
  115. else
  116. return -EINVAL;
  117. }
  118. /**
  119. * i40evf_get_ethtool_stats - report device statistics
  120. * @netdev: network interface device structure
  121. * @stats: ethtool statistics structure
  122. * @data: pointer to data buffer
  123. *
  124. * All statistics are added to the data buffer as an array of u64.
  125. **/
  126. static void i40evf_get_ethtool_stats(struct net_device *netdev,
  127. struct ethtool_stats *stats, u64 *data)
  128. {
  129. struct i40evf_adapter *adapter = netdev_priv(netdev);
  130. unsigned int i, j;
  131. char *p;
  132. for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
  133. p = (char *)adapter + i40evf_gstrings_stats[i].stat_offset;
  134. data[i] = *(u64 *)p;
  135. }
  136. for (j = 0; j < adapter->num_active_queues; j++) {
  137. data[i++] = adapter->tx_rings[j].stats.packets;
  138. data[i++] = adapter->tx_rings[j].stats.bytes;
  139. }
  140. for (j = 0; j < adapter->num_active_queues; j++) {
  141. data[i++] = adapter->rx_rings[j].stats.packets;
  142. data[i++] = adapter->rx_rings[j].stats.bytes;
  143. }
  144. }
  145. /**
  146. * i40evf_get_strings - Get string set
  147. * @netdev: network interface device structure
  148. * @sset: id of string set
  149. * @data: buffer for string data
  150. *
  151. * Builds stats string table.
  152. **/
  153. static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
  154. {
  155. struct i40evf_adapter *adapter = netdev_priv(netdev);
  156. u8 *p = data;
  157. int i;
  158. if (sset == ETH_SS_STATS) {
  159. for (i = 0; i < (int)I40EVF_GLOBAL_STATS_LEN; i++) {
  160. memcpy(p, i40evf_gstrings_stats[i].stat_string,
  161. ETH_GSTRING_LEN);
  162. p += ETH_GSTRING_LEN;
  163. }
  164. for (i = 0; i < adapter->num_active_queues; i++) {
  165. snprintf(p, ETH_GSTRING_LEN, "tx-%u.packets", i);
  166. p += ETH_GSTRING_LEN;
  167. snprintf(p, ETH_GSTRING_LEN, "tx-%u.bytes", i);
  168. p += ETH_GSTRING_LEN;
  169. }
  170. for (i = 0; i < adapter->num_active_queues; i++) {
  171. snprintf(p, ETH_GSTRING_LEN, "rx-%u.packets", i);
  172. p += ETH_GSTRING_LEN;
  173. snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
  174. p += ETH_GSTRING_LEN;
  175. }
  176. } else if (sset == ETH_SS_PRIV_FLAGS) {
  177. for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
  178. snprintf(p, ETH_GSTRING_LEN, "%s",
  179. i40evf_gstrings_priv_flags[i].flag_string);
  180. p += ETH_GSTRING_LEN;
  181. }
  182. }
  183. }
  184. /**
  185. * i40evf_get_priv_flags - report device private flags
  186. * @netdev: network interface device structure
  187. *
  188. * The get string set count and the string set should be matched for each
  189. * flag returned. Add new strings for each flag to the i40e_gstrings_priv_flags
  190. * array.
  191. *
  192. * Returns a u32 bitmap of flags.
  193. **/
  194. static u32 i40evf_get_priv_flags(struct net_device *netdev)
  195. {
  196. struct i40evf_adapter *adapter = netdev_priv(netdev);
  197. u32 i, ret_flags = 0;
  198. for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
  199. const struct i40evf_priv_flags *priv_flags;
  200. priv_flags = &i40evf_gstrings_priv_flags[i];
  201. if (priv_flags->flag & adapter->flags)
  202. ret_flags |= BIT(i);
  203. }
  204. return ret_flags;
  205. }
  206. /**
  207. * i40evf_set_priv_flags - set private flags
  208. * @netdev: network interface device structure
  209. * @flags: bit flags to be set
  210. **/
  211. static int i40evf_set_priv_flags(struct net_device *netdev, u32 flags)
  212. {
  213. struct i40evf_adapter *adapter = netdev_priv(netdev);
  214. u32 orig_flags, new_flags, changed_flags;
  215. u32 i;
  216. orig_flags = READ_ONCE(adapter->flags);
  217. new_flags = orig_flags;
  218. for (i = 0; i < I40EVF_PRIV_FLAGS_STR_LEN; i++) {
  219. const struct i40evf_priv_flags *priv_flags;
  220. priv_flags = &i40evf_gstrings_priv_flags[i];
  221. if (flags & BIT(i))
  222. new_flags |= priv_flags->flag;
  223. else
  224. new_flags &= ~(priv_flags->flag);
  225. if (priv_flags->read_only &&
  226. ((orig_flags ^ new_flags) & ~BIT(i)))
  227. return -EOPNOTSUPP;
  228. }
  229. /* Before we finalize any flag changes, any checks which we need to
  230. * perform to determine if the new flags will be supported should go
  231. * here...
  232. */
  233. /* Compare and exchange the new flags into place. If we failed, that
  234. * is if cmpxchg returns anything but the old value, this means
  235. * something else must have modified the flags variable since we
  236. * copied it. We'll just punt with an error and log something in the
  237. * message buffer.
  238. */
  239. if (cmpxchg(&adapter->flags, orig_flags, new_flags) != orig_flags) {
  240. dev_warn(&adapter->pdev->dev,
  241. "Unable to update adapter->flags as it was modified by another thread...\n");
  242. return -EAGAIN;
  243. }
  244. changed_flags = orig_flags ^ new_flags;
  245. /* Process any additional changes needed as a result of flag changes.
  246. * The changed_flags value reflects the list of bits that were changed
  247. * in the code above.
  248. */
  249. /* issue a reset to force legacy-rx change to take effect */
  250. if (changed_flags & I40EVF_FLAG_LEGACY_RX) {
  251. if (netif_running(netdev)) {
  252. adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
  253. schedule_work(&adapter->reset_task);
  254. }
  255. }
  256. return 0;
  257. }
  258. /**
  259. * i40evf_get_msglevel - Get debug message level
  260. * @netdev: network interface device structure
  261. *
  262. * Returns current debug message level.
  263. **/
  264. static u32 i40evf_get_msglevel(struct net_device *netdev)
  265. {
  266. struct i40evf_adapter *adapter = netdev_priv(netdev);
  267. return adapter->msg_enable;
  268. }
  269. /**
  270. * i40evf_set_msglevel - Set debug message level
  271. * @netdev: network interface device structure
  272. * @data: message level
  273. *
  274. * Set current debug message level. Higher values cause the driver to
  275. * be noisier.
  276. **/
  277. static void i40evf_set_msglevel(struct net_device *netdev, u32 data)
  278. {
  279. struct i40evf_adapter *adapter = netdev_priv(netdev);
  280. if (I40E_DEBUG_USER & data)
  281. adapter->hw.debug_mask = data;
  282. adapter->msg_enable = data;
  283. }
  284. /**
  285. * i40evf_get_drvinfo - Get driver info
  286. * @netdev: network interface device structure
  287. * @drvinfo: ethool driver info structure
  288. *
  289. * Returns information about the driver and device for display to the user.
  290. **/
  291. static void i40evf_get_drvinfo(struct net_device *netdev,
  292. struct ethtool_drvinfo *drvinfo)
  293. {
  294. struct i40evf_adapter *adapter = netdev_priv(netdev);
  295. strlcpy(drvinfo->driver, i40evf_driver_name, 32);
  296. strlcpy(drvinfo->version, i40evf_driver_version, 32);
  297. strlcpy(drvinfo->fw_version, "N/A", 4);
  298. strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
  299. drvinfo->n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN;
  300. }
  301. /**
  302. * i40evf_get_ringparam - Get ring parameters
  303. * @netdev: network interface device structure
  304. * @ring: ethtool ringparam structure
  305. *
  306. * Returns current ring parameters. TX and RX rings are reported separately,
  307. * but the number of rings is not reported.
  308. **/
  309. static void i40evf_get_ringparam(struct net_device *netdev,
  310. struct ethtool_ringparam *ring)
  311. {
  312. struct i40evf_adapter *adapter = netdev_priv(netdev);
  313. ring->rx_max_pending = I40EVF_MAX_RXD;
  314. ring->tx_max_pending = I40EVF_MAX_TXD;
  315. ring->rx_pending = adapter->rx_desc_count;
  316. ring->tx_pending = adapter->tx_desc_count;
  317. }
  318. /**
  319. * i40evf_set_ringparam - Set ring parameters
  320. * @netdev: network interface device structure
  321. * @ring: ethtool ringparam structure
  322. *
  323. * Sets ring parameters. TX and RX rings are controlled separately, but the
  324. * number of rings is not specified, so all rings get the same settings.
  325. **/
  326. static int i40evf_set_ringparam(struct net_device *netdev,
  327. struct ethtool_ringparam *ring)
  328. {
  329. struct i40evf_adapter *adapter = netdev_priv(netdev);
  330. u32 new_rx_count, new_tx_count;
  331. if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
  332. return -EINVAL;
  333. new_tx_count = clamp_t(u32, ring->tx_pending,
  334. I40EVF_MIN_TXD,
  335. I40EVF_MAX_TXD);
  336. new_tx_count = ALIGN(new_tx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
  337. new_rx_count = clamp_t(u32, ring->rx_pending,
  338. I40EVF_MIN_RXD,
  339. I40EVF_MAX_RXD);
  340. new_rx_count = ALIGN(new_rx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
  341. /* if nothing to do return success */
  342. if ((new_tx_count == adapter->tx_desc_count) &&
  343. (new_rx_count == adapter->rx_desc_count))
  344. return 0;
  345. adapter->tx_desc_count = new_tx_count;
  346. adapter->rx_desc_count = new_rx_count;
  347. if (netif_running(netdev)) {
  348. adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
  349. schedule_work(&adapter->reset_task);
  350. }
  351. return 0;
  352. }
  353. /**
  354. * __i40evf_get_coalesce - get per-queue coalesce settings
  355. * @netdev: the netdev to check
  356. * @ec: ethtool coalesce data structure
  357. * @queue: which queue to pick
  358. *
  359. * Gets the per-queue settings for coalescence. Specifically Rx and Tx usecs
  360. * are per queue. If queue is <0 then we default to queue 0 as the
  361. * representative value.
  362. **/
  363. static int __i40evf_get_coalesce(struct net_device *netdev,
  364. struct ethtool_coalesce *ec,
  365. int queue)
  366. {
  367. struct i40evf_adapter *adapter = netdev_priv(netdev);
  368. struct i40e_vsi *vsi = &adapter->vsi;
  369. struct i40e_ring *rx_ring, *tx_ring;
  370. ec->tx_max_coalesced_frames = vsi->work_limit;
  371. ec->rx_max_coalesced_frames = vsi->work_limit;
  372. /* Rx and Tx usecs per queue value. If user doesn't specify the
  373. * queue, return queue 0's value to represent.
  374. */
  375. if (queue < 0)
  376. queue = 0;
  377. else if (queue >= adapter->num_active_queues)
  378. return -EINVAL;
  379. rx_ring = &adapter->rx_rings[queue];
  380. tx_ring = &adapter->tx_rings[queue];
  381. if (ITR_IS_DYNAMIC(rx_ring->itr_setting))
  382. ec->use_adaptive_rx_coalesce = 1;
  383. if (ITR_IS_DYNAMIC(tx_ring->itr_setting))
  384. ec->use_adaptive_tx_coalesce = 1;
  385. ec->rx_coalesce_usecs = rx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
  386. ec->tx_coalesce_usecs = tx_ring->itr_setting & ~I40E_ITR_DYNAMIC;
  387. return 0;
  388. }
  389. /**
  390. * i40evf_get_coalesce - Get interrupt coalescing settings
  391. * @netdev: network interface device structure
  392. * @ec: ethtool coalesce structure
  393. *
  394. * Returns current coalescing settings. This is referred to elsewhere in the
  395. * driver as Interrupt Throttle Rate, as this is how the hardware describes
  396. * this functionality. Note that if per-queue settings have been modified this
  397. * only represents the settings of queue 0.
  398. **/
  399. static int i40evf_get_coalesce(struct net_device *netdev,
  400. struct ethtool_coalesce *ec)
  401. {
  402. return __i40evf_get_coalesce(netdev, ec, -1);
  403. }
  404. /**
  405. * i40evf_get_per_queue_coalesce - get coalesce values for specific queue
  406. * @netdev: netdev to read
  407. * @ec: coalesce settings from ethtool
  408. * @queue: the queue to read
  409. *
  410. * Read specific queue's coalesce settings.
  411. **/
  412. static int i40evf_get_per_queue_coalesce(struct net_device *netdev,
  413. u32 queue,
  414. struct ethtool_coalesce *ec)
  415. {
  416. return __i40evf_get_coalesce(netdev, ec, queue);
  417. }
  418. /**
  419. * i40evf_set_itr_per_queue - set ITR values for specific queue
  420. * @adapter: the VF adapter struct to set values for
  421. * @ec: coalesce settings from ethtool
  422. * @queue: the queue to modify
  423. *
  424. * Change the ITR settings for a specific queue.
  425. **/
  426. static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,
  427. struct ethtool_coalesce *ec,
  428. int queue)
  429. {
  430. struct i40e_ring *rx_ring = &adapter->rx_rings[queue];
  431. struct i40e_ring *tx_ring = &adapter->tx_rings[queue];
  432. struct i40e_q_vector *q_vector;
  433. rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs);
  434. tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs);
  435. rx_ring->itr_setting |= I40E_ITR_DYNAMIC;
  436. if (!ec->use_adaptive_rx_coalesce)
  437. rx_ring->itr_setting ^= I40E_ITR_DYNAMIC;
  438. tx_ring->itr_setting |= I40E_ITR_DYNAMIC;
  439. if (!ec->use_adaptive_tx_coalesce)
  440. tx_ring->itr_setting ^= I40E_ITR_DYNAMIC;
  441. q_vector = rx_ring->q_vector;
  442. q_vector->rx.target_itr = ITR_TO_REG(rx_ring->itr_setting);
  443. q_vector = tx_ring->q_vector;
  444. q_vector->tx.target_itr = ITR_TO_REG(tx_ring->itr_setting);
  445. /* The interrupt handler itself will take care of programming
  446. * the Tx and Rx ITR values based on the values we have entered
  447. * into the q_vector, no need to write the values now.
  448. */
  449. }
  450. /**
  451. * __i40evf_set_coalesce - set coalesce settings for particular queue
  452. * @netdev: the netdev to change
  453. * @ec: ethtool coalesce settings
  454. * @queue: the queue to change
  455. *
  456. * Sets the coalesce settings for a particular queue.
  457. **/
  458. static int __i40evf_set_coalesce(struct net_device *netdev,
  459. struct ethtool_coalesce *ec,
  460. int queue)
  461. {
  462. struct i40evf_adapter *adapter = netdev_priv(netdev);
  463. struct i40e_vsi *vsi = &adapter->vsi;
  464. int i;
  465. if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
  466. vsi->work_limit = ec->tx_max_coalesced_frames_irq;
  467. if (ec->rx_coalesce_usecs == 0) {
  468. if (ec->use_adaptive_rx_coalesce)
  469. netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
  470. } else if ((ec->rx_coalesce_usecs < I40E_MIN_ITR) ||
  471. (ec->rx_coalesce_usecs > I40E_MAX_ITR)) {
  472. netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
  473. return -EINVAL;
  474. }
  475. else
  476. if (ec->tx_coalesce_usecs == 0) {
  477. if (ec->use_adaptive_tx_coalesce)
  478. netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n");
  479. } else if ((ec->tx_coalesce_usecs < I40E_MIN_ITR) ||
  480. (ec->tx_coalesce_usecs > I40E_MAX_ITR)) {
  481. netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
  482. return -EINVAL;
  483. }
  484. /* Rx and Tx usecs has per queue value. If user doesn't specify the
  485. * queue, apply to all queues.
  486. */
  487. if (queue < 0) {
  488. for (i = 0; i < adapter->num_active_queues; i++)
  489. i40evf_set_itr_per_queue(adapter, ec, i);
  490. } else if (queue < adapter->num_active_queues) {
  491. i40evf_set_itr_per_queue(adapter, ec, queue);
  492. } else {
  493. netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
  494. adapter->num_active_queues - 1);
  495. return -EINVAL;
  496. }
  497. return 0;
  498. }
  499. /**
  500. * i40evf_set_coalesce - Set interrupt coalescing settings
  501. * @netdev: network interface device structure
  502. * @ec: ethtool coalesce structure
  503. *
  504. * Change current coalescing settings for every queue.
  505. **/
  506. static int i40evf_set_coalesce(struct net_device *netdev,
  507. struct ethtool_coalesce *ec)
  508. {
  509. return __i40evf_set_coalesce(netdev, ec, -1);
  510. }
  511. /**
  512. * i40evf_set_per_queue_coalesce - set specific queue's coalesce settings
  513. * @netdev: the netdev to change
  514. * @ec: ethtool's coalesce settings
  515. * @queue: the queue to modify
  516. *
  517. * Modifies a specific queue's coalesce settings.
  518. */
  519. static int i40evf_set_per_queue_coalesce(struct net_device *netdev,
  520. u32 queue,
  521. struct ethtool_coalesce *ec)
  522. {
  523. return __i40evf_set_coalesce(netdev, ec, queue);
  524. }
  525. /**
  526. * i40evf_get_rxnfc - command to get RX flow classification rules
  527. * @netdev: network interface device structure
  528. * @cmd: ethtool rxnfc command
  529. * @rule_locs: pointer to store rule locations
  530. *
  531. * Returns Success if the command is supported.
  532. **/
  533. static int i40evf_get_rxnfc(struct net_device *netdev,
  534. struct ethtool_rxnfc *cmd,
  535. u32 *rule_locs)
  536. {
  537. struct i40evf_adapter *adapter = netdev_priv(netdev);
  538. int ret = -EOPNOTSUPP;
  539. switch (cmd->cmd) {
  540. case ETHTOOL_GRXRINGS:
  541. cmd->data = adapter->num_active_queues;
  542. ret = 0;
  543. break;
  544. case ETHTOOL_GRXFH:
  545. netdev_info(netdev,
  546. "RSS hash info is not available to vf, use pf.\n");
  547. break;
  548. default:
  549. break;
  550. }
  551. return ret;
  552. }
  553. /**
  554. * i40evf_get_channels: get the number of channels supported by the device
  555. * @netdev: network interface device structure
  556. * @ch: channel information structure
  557. *
  558. * For the purposes of our device, we only use combined channels, i.e. a tx/rx
  559. * queue pair. Report one extra channel to match our "other" MSI-X vector.
  560. **/
  561. static void i40evf_get_channels(struct net_device *netdev,
  562. struct ethtool_channels *ch)
  563. {
  564. struct i40evf_adapter *adapter = netdev_priv(netdev);
  565. /* Report maximum channels */
  566. ch->max_combined = I40EVF_MAX_REQ_QUEUES;
  567. ch->max_other = NONQ_VECS;
  568. ch->other_count = NONQ_VECS;
  569. ch->combined_count = adapter->num_active_queues;
  570. }
  571. /**
  572. * i40evf_set_channels: set the new channel count
  573. * @netdev: network interface device structure
  574. * @ch: channel information structure
  575. *
  576. * Negotiate a new number of channels with the PF then do a reset. During
  577. * reset we'll realloc queues and fix the RSS table. Returns 0 on success,
  578. * negative on failure.
  579. **/
  580. static int i40evf_set_channels(struct net_device *netdev,
  581. struct ethtool_channels *ch)
  582. {
  583. struct i40evf_adapter *adapter = netdev_priv(netdev);
  584. int num_req = ch->combined_count;
  585. if (num_req != adapter->num_active_queues &&
  586. !(adapter->vf_res->vf_cap_flags &
  587. VIRTCHNL_VF_OFFLOAD_REQ_QUEUES)) {
  588. dev_info(&adapter->pdev->dev, "PF is not capable of queue negotiation.\n");
  589. return -EINVAL;
  590. }
  591. if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) &&
  592. adapter->num_tc) {
  593. dev_info(&adapter->pdev->dev, "Cannot set channels since ADq is enabled.\n");
  594. return -EINVAL;
  595. }
  596. /* All of these should have already been checked by ethtool before this
  597. * even gets to us, but just to be sure.
  598. */
  599. if (num_req <= 0 || num_req > I40EVF_MAX_REQ_QUEUES)
  600. return -EINVAL;
  601. if (ch->rx_count || ch->tx_count || ch->other_count != NONQ_VECS)
  602. return -EINVAL;
  603. adapter->num_req_queues = num_req;
  604. return i40evf_request_queues(adapter, num_req);
  605. }
  606. /**
  607. * i40evf_get_rxfh_key_size - get the RSS hash key size
  608. * @netdev: network interface device structure
  609. *
  610. * Returns the table size.
  611. **/
  612. static u32 i40evf_get_rxfh_key_size(struct net_device *netdev)
  613. {
  614. struct i40evf_adapter *adapter = netdev_priv(netdev);
  615. return adapter->rss_key_size;
  616. }
  617. /**
  618. * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
  619. * @netdev: network interface device structure
  620. *
  621. * Returns the table size.
  622. **/
  623. static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
  624. {
  625. struct i40evf_adapter *adapter = netdev_priv(netdev);
  626. return adapter->rss_lut_size;
  627. }
  628. /**
  629. * i40evf_get_rxfh - get the rx flow hash indirection table
  630. * @netdev: network interface device structure
  631. * @indir: indirection table
  632. * @key: hash key
  633. * @hfunc: hash function in use
  634. *
  635. * Reads the indirection table directly from the hardware. Always returns 0.
  636. **/
  637. static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
  638. u8 *hfunc)
  639. {
  640. struct i40evf_adapter *adapter = netdev_priv(netdev);
  641. u16 i;
  642. if (hfunc)
  643. *hfunc = ETH_RSS_HASH_TOP;
  644. if (!indir)
  645. return 0;
  646. memcpy(key, adapter->rss_key, adapter->rss_key_size);
  647. /* Each 32 bits pointed by 'indir' is stored with a lut entry */
  648. for (i = 0; i < adapter->rss_lut_size; i++)
  649. indir[i] = (u32)adapter->rss_lut[i];
  650. return 0;
  651. }
  652. /**
  653. * i40evf_set_rxfh - set the rx flow hash indirection table
  654. * @netdev: network interface device structure
  655. * @indir: indirection table
  656. * @key: hash key
  657. * @hfunc: hash function to use
  658. *
  659. * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
  660. * returns 0 after programming the table.
  661. **/
  662. static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
  663. const u8 *key, const u8 hfunc)
  664. {
  665. struct i40evf_adapter *adapter = netdev_priv(netdev);
  666. u16 i;
  667. /* We do not allow change in unsupported parameters */
  668. if (key ||
  669. (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
  670. return -EOPNOTSUPP;
  671. if (!indir)
  672. return 0;
  673. if (key) {
  674. memcpy(adapter->rss_key, key, adapter->rss_key_size);
  675. }
  676. /* Each 32 bits pointed by 'indir' is stored with a lut entry */
  677. for (i = 0; i < adapter->rss_lut_size; i++)
  678. adapter->rss_lut[i] = (u8)(indir[i]);
  679. return i40evf_config_rss(adapter);
  680. }
  681. static const struct ethtool_ops i40evf_ethtool_ops = {
  682. .get_drvinfo = i40evf_get_drvinfo,
  683. .get_link = ethtool_op_get_link,
  684. .get_ringparam = i40evf_get_ringparam,
  685. .set_ringparam = i40evf_set_ringparam,
  686. .get_strings = i40evf_get_strings,
  687. .get_ethtool_stats = i40evf_get_ethtool_stats,
  688. .get_sset_count = i40evf_get_sset_count,
  689. .get_priv_flags = i40evf_get_priv_flags,
  690. .set_priv_flags = i40evf_set_priv_flags,
  691. .get_msglevel = i40evf_get_msglevel,
  692. .set_msglevel = i40evf_set_msglevel,
  693. .get_coalesce = i40evf_get_coalesce,
  694. .set_coalesce = i40evf_set_coalesce,
  695. .get_per_queue_coalesce = i40evf_get_per_queue_coalesce,
  696. .set_per_queue_coalesce = i40evf_set_per_queue_coalesce,
  697. .get_rxnfc = i40evf_get_rxnfc,
  698. .get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
  699. .get_rxfh = i40evf_get_rxfh,
  700. .set_rxfh = i40evf_set_rxfh,
  701. .get_channels = i40evf_get_channels,
  702. .set_channels = i40evf_set_channels,
  703. .get_rxfh_key_size = i40evf_get_rxfh_key_size,
  704. .get_link_ksettings = i40evf_get_link_ksettings,
  705. };
  706. /**
  707. * i40evf_set_ethtool_ops - Initialize ethtool ops struct
  708. * @netdev: network interface device structure
  709. *
  710. * Sets ethtool ops struct in our netdev so that ethtool can call
  711. * our functions.
  712. **/
  713. void i40evf_set_ethtool_ops(struct net_device *netdev)
  714. {
  715. netdev->ethtool_ops = &i40evf_ethtool_ops;
  716. }