i40evf_ethtool.c 25 KB

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