fm10k_ethtool.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. /* Intel(R) Ethernet Switch Host Interface Driver
  2. * Copyright(c) 2013 - 2016 Intel Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * The full GNU General Public License is included in this distribution in
  14. * the file called "COPYING".
  15. *
  16. * Contact Information:
  17. * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  18. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  19. */
  20. #include <linux/vmalloc.h>
  21. #include "fm10k.h"
  22. struct fm10k_stats {
  23. char stat_string[ETH_GSTRING_LEN];
  24. int sizeof_stat;
  25. int stat_offset;
  26. };
  27. #define FM10K_NETDEV_STAT(_net_stat) { \
  28. .stat_string = #_net_stat, \
  29. .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \
  30. .stat_offset = offsetof(struct net_device_stats, _net_stat) \
  31. }
  32. static const struct fm10k_stats fm10k_gstrings_net_stats[] = {
  33. FM10K_NETDEV_STAT(tx_packets),
  34. FM10K_NETDEV_STAT(tx_bytes),
  35. FM10K_NETDEV_STAT(tx_errors),
  36. FM10K_NETDEV_STAT(rx_packets),
  37. FM10K_NETDEV_STAT(rx_bytes),
  38. FM10K_NETDEV_STAT(rx_errors),
  39. FM10K_NETDEV_STAT(rx_dropped),
  40. /* detailed Rx errors */
  41. FM10K_NETDEV_STAT(rx_length_errors),
  42. FM10K_NETDEV_STAT(rx_crc_errors),
  43. FM10K_NETDEV_STAT(rx_fifo_errors),
  44. };
  45. #define FM10K_NETDEV_STATS_LEN ARRAY_SIZE(fm10k_gstrings_net_stats)
  46. #define FM10K_STAT(_name, _stat) { \
  47. .stat_string = _name, \
  48. .sizeof_stat = FIELD_SIZEOF(struct fm10k_intfc, _stat), \
  49. .stat_offset = offsetof(struct fm10k_intfc, _stat) \
  50. }
  51. static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
  52. FM10K_STAT("tx_restart_queue", restart_queue),
  53. FM10K_STAT("tx_busy", tx_busy),
  54. FM10K_STAT("tx_csum_errors", tx_csum_errors),
  55. FM10K_STAT("rx_alloc_failed", alloc_failed),
  56. FM10K_STAT("rx_csum_errors", rx_csum_errors),
  57. FM10K_STAT("tx_packets_nic", tx_packets_nic),
  58. FM10K_STAT("tx_bytes_nic", tx_bytes_nic),
  59. FM10K_STAT("rx_packets_nic", rx_packets_nic),
  60. FM10K_STAT("rx_bytes_nic", rx_bytes_nic),
  61. FM10K_STAT("rx_drops_nic", rx_drops_nic),
  62. FM10K_STAT("rx_overrun_pf", rx_overrun_pf),
  63. FM10K_STAT("rx_overrun_vf", rx_overrun_vf),
  64. FM10K_STAT("swapi_status", hw.swapi.status),
  65. FM10K_STAT("mac_rules_used", hw.swapi.mac.used),
  66. FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail),
  67. FM10K_STAT("reset_while_pending", hw.mac.reset_while_pending),
  68. FM10K_STAT("tx_hang_count", tx_timeout_count),
  69. };
  70. static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
  71. FM10K_STAT("timeout", stats.timeout.count),
  72. FM10K_STAT("ur", stats.ur.count),
  73. FM10K_STAT("ca", stats.ca.count),
  74. FM10K_STAT("um", stats.um.count),
  75. FM10K_STAT("xec", stats.xec.count),
  76. FM10K_STAT("vlan_drop", stats.vlan_drop.count),
  77. FM10K_STAT("loopback_drop", stats.loopback_drop.count),
  78. FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
  79. };
  80. #define FM10K_MBX_STAT(_name, _stat) { \
  81. .stat_string = _name, \
  82. .sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \
  83. .stat_offset = offsetof(struct fm10k_mbx_info, _stat) \
  84. }
  85. static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
  86. FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
  87. FM10K_MBX_STAT("mbx_tx_dropped", tx_dropped),
  88. FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
  89. FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
  90. FM10K_MBX_STAT("mbx_tx_mbmem_pulled", tx_mbmem_pulled),
  91. FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
  92. FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
  93. FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
  94. FM10K_MBX_STAT("mbx_rx_mbmem_pushed", rx_mbmem_pushed),
  95. };
  96. #define FM10K_QUEUE_STAT(_name, _stat) { \
  97. .stat_string = _name, \
  98. .sizeof_stat = FIELD_SIZEOF(struct fm10k_ring, _stat), \
  99. .stat_offset = offsetof(struct fm10k_ring, _stat) \
  100. }
  101. static const struct fm10k_stats fm10k_gstrings_queue_stats[] = {
  102. FM10K_QUEUE_STAT("packets", stats.packets),
  103. FM10K_QUEUE_STAT("bytes", stats.bytes),
  104. };
  105. #define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
  106. #define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
  107. #define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)
  108. #define FM10K_QUEUE_STATS_LEN ARRAY_SIZE(fm10k_gstrings_queue_stats)
  109. #define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
  110. FM10K_NETDEV_STATS_LEN + \
  111. FM10K_MBX_STATS_LEN)
  112. static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
  113. "Mailbox test (on/offline)"
  114. };
  115. #define FM10K_TEST_LEN (sizeof(fm10k_gstrings_test) / ETH_GSTRING_LEN)
  116. enum fm10k_self_test_types {
  117. FM10K_TEST_MBX,
  118. FM10K_TEST_MAX = FM10K_TEST_LEN
  119. };
  120. enum {
  121. FM10K_PRV_FLAG_LEN,
  122. };
  123. static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
  124. };
  125. static void fm10k_add_stat_strings(char **p, const char *prefix,
  126. const struct fm10k_stats stats[],
  127. const unsigned int size)
  128. {
  129. unsigned int i;
  130. for (i = 0; i < size; i++) {
  131. snprintf(*p, ETH_GSTRING_LEN, "%s%s",
  132. prefix, stats[i].stat_string);
  133. *p += ETH_GSTRING_LEN;
  134. }
  135. }
  136. static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
  137. {
  138. struct fm10k_intfc *interface = netdev_priv(dev);
  139. char *p = (char *)data;
  140. unsigned int i;
  141. fm10k_add_stat_strings(&p, "", fm10k_gstrings_net_stats,
  142. FM10K_NETDEV_STATS_LEN);
  143. fm10k_add_stat_strings(&p, "", fm10k_gstrings_global_stats,
  144. FM10K_GLOBAL_STATS_LEN);
  145. fm10k_add_stat_strings(&p, "", fm10k_gstrings_mbx_stats,
  146. FM10K_MBX_STATS_LEN);
  147. if (interface->hw.mac.type != fm10k_mac_vf)
  148. fm10k_add_stat_strings(&p, "", fm10k_gstrings_pf_stats,
  149. FM10K_PF_STATS_LEN);
  150. for (i = 0; i < interface->hw.mac.max_queues; i++) {
  151. char prefix[ETH_GSTRING_LEN];
  152. snprintf(prefix, ETH_GSTRING_LEN, "tx_queue_%u_", i);
  153. fm10k_add_stat_strings(&p, prefix,
  154. fm10k_gstrings_queue_stats,
  155. FM10K_QUEUE_STATS_LEN);
  156. snprintf(prefix, ETH_GSTRING_LEN, "rx_queue_%u_", i);
  157. fm10k_add_stat_strings(&p, prefix,
  158. fm10k_gstrings_queue_stats,
  159. FM10K_QUEUE_STATS_LEN);
  160. }
  161. }
  162. static void fm10k_get_strings(struct net_device *dev,
  163. u32 stringset, u8 *data)
  164. {
  165. char *p = (char *)data;
  166. switch (stringset) {
  167. case ETH_SS_TEST:
  168. memcpy(data, *fm10k_gstrings_test,
  169. FM10K_TEST_LEN * ETH_GSTRING_LEN);
  170. break;
  171. case ETH_SS_STATS:
  172. fm10k_get_stat_strings(dev, data);
  173. break;
  174. case ETH_SS_PRIV_FLAGS:
  175. memcpy(p, fm10k_prv_flags,
  176. FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
  177. break;
  178. }
  179. }
  180. static int fm10k_get_sset_count(struct net_device *dev, int sset)
  181. {
  182. struct fm10k_intfc *interface = netdev_priv(dev);
  183. struct fm10k_hw *hw = &interface->hw;
  184. int stats_len = FM10K_STATIC_STATS_LEN;
  185. switch (sset) {
  186. case ETH_SS_TEST:
  187. return FM10K_TEST_LEN;
  188. case ETH_SS_STATS:
  189. stats_len += hw->mac.max_queues * 2 * FM10K_QUEUE_STATS_LEN;
  190. if (hw->mac.type != fm10k_mac_vf)
  191. stats_len += FM10K_PF_STATS_LEN;
  192. return stats_len;
  193. case ETH_SS_PRIV_FLAGS:
  194. return FM10K_PRV_FLAG_LEN;
  195. default:
  196. return -EOPNOTSUPP;
  197. }
  198. }
  199. static void fm10k_add_ethtool_stats(u64 **data, void *pointer,
  200. const struct fm10k_stats stats[],
  201. const unsigned int size)
  202. {
  203. unsigned int i;
  204. char *p;
  205. if (!pointer) {
  206. /* memory is not zero allocated so we have to clear it */
  207. for (i = 0; i < size; i++)
  208. *((*data)++) = 0;
  209. return;
  210. }
  211. for (i = 0; i < size; i++) {
  212. p = (char *)pointer + stats[i].stat_offset;
  213. switch (stats[i].sizeof_stat) {
  214. case sizeof(u64):
  215. *((*data)++) = *(u64 *)p;
  216. break;
  217. case sizeof(u32):
  218. *((*data)++) = *(u32 *)p;
  219. break;
  220. case sizeof(u16):
  221. *((*data)++) = *(u16 *)p;
  222. break;
  223. case sizeof(u8):
  224. *((*data)++) = *(u8 *)p;
  225. break;
  226. default:
  227. *((*data)++) = 0;
  228. }
  229. }
  230. }
  231. static void fm10k_get_ethtool_stats(struct net_device *netdev,
  232. struct ethtool_stats __always_unused *stats,
  233. u64 *data)
  234. {
  235. struct fm10k_intfc *interface = netdev_priv(netdev);
  236. struct net_device_stats *net_stats = &netdev->stats;
  237. int i;
  238. fm10k_update_stats(interface);
  239. fm10k_add_ethtool_stats(&data, net_stats, fm10k_gstrings_net_stats,
  240. FM10K_NETDEV_STATS_LEN);
  241. fm10k_add_ethtool_stats(&data, interface, fm10k_gstrings_global_stats,
  242. FM10K_GLOBAL_STATS_LEN);
  243. fm10k_add_ethtool_stats(&data, &interface->hw.mbx,
  244. fm10k_gstrings_mbx_stats,
  245. FM10K_MBX_STATS_LEN);
  246. if (interface->hw.mac.type != fm10k_mac_vf) {
  247. fm10k_add_ethtool_stats(&data, interface,
  248. fm10k_gstrings_pf_stats,
  249. FM10K_PF_STATS_LEN);
  250. }
  251. for (i = 0; i < interface->hw.mac.max_queues; i++) {
  252. struct fm10k_ring *ring;
  253. ring = interface->tx_ring[i];
  254. fm10k_add_ethtool_stats(&data, ring,
  255. fm10k_gstrings_queue_stats,
  256. FM10K_QUEUE_STATS_LEN);
  257. ring = interface->rx_ring[i];
  258. fm10k_add_ethtool_stats(&data, ring,
  259. fm10k_gstrings_queue_stats,
  260. FM10K_QUEUE_STATS_LEN);
  261. }
  262. }
  263. /* If function below adds more registers this define needs to be updated */
  264. #define FM10K_REGS_LEN_Q 29
  265. static void fm10k_get_reg_q(struct fm10k_hw *hw, u32 *buff, int i)
  266. {
  267. int idx = 0;
  268. buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAL(i));
  269. buff[idx++] = fm10k_read_reg(hw, FM10K_RDBAH(i));
  270. buff[idx++] = fm10k_read_reg(hw, FM10K_RDLEN(i));
  271. buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_RXCTRL(i));
  272. buff[idx++] = fm10k_read_reg(hw, FM10K_RDH(i));
  273. buff[idx++] = fm10k_read_reg(hw, FM10K_RDT(i));
  274. buff[idx++] = fm10k_read_reg(hw, FM10K_RXQCTL(i));
  275. buff[idx++] = fm10k_read_reg(hw, FM10K_RXDCTL(i));
  276. buff[idx++] = fm10k_read_reg(hw, FM10K_RXINT(i));
  277. buff[idx++] = fm10k_read_reg(hw, FM10K_SRRCTL(i));
  278. buff[idx++] = fm10k_read_reg(hw, FM10K_QPRC(i));
  279. buff[idx++] = fm10k_read_reg(hw, FM10K_QPRDC(i));
  280. buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_L(i));
  281. buff[idx++] = fm10k_read_reg(hw, FM10K_QBRC_H(i));
  282. buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAL(i));
  283. buff[idx++] = fm10k_read_reg(hw, FM10K_TDBAH(i));
  284. buff[idx++] = fm10k_read_reg(hw, FM10K_TDLEN(i));
  285. buff[idx++] = fm10k_read_reg(hw, FM10K_TPH_TXCTRL(i));
  286. buff[idx++] = fm10k_read_reg(hw, FM10K_TDH(i));
  287. buff[idx++] = fm10k_read_reg(hw, FM10K_TDT(i));
  288. buff[idx++] = fm10k_read_reg(hw, FM10K_TXDCTL(i));
  289. buff[idx++] = fm10k_read_reg(hw, FM10K_TXQCTL(i));
  290. buff[idx++] = fm10k_read_reg(hw, FM10K_TXINT(i));
  291. buff[idx++] = fm10k_read_reg(hw, FM10K_QPTC(i));
  292. buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_L(i));
  293. buff[idx++] = fm10k_read_reg(hw, FM10K_QBTC_H(i));
  294. buff[idx++] = fm10k_read_reg(hw, FM10K_TQDLOC(i));
  295. buff[idx++] = fm10k_read_reg(hw, FM10K_TX_SGLORT(i));
  296. buff[idx++] = fm10k_read_reg(hw, FM10K_PFVTCTL(i));
  297. BUG_ON(idx != FM10K_REGS_LEN_Q);
  298. }
  299. /* If function above adds more registers this define needs to be updated */
  300. #define FM10K_REGS_LEN_VSI 43
  301. static void fm10k_get_reg_vsi(struct fm10k_hw *hw, u32 *buff, int i)
  302. {
  303. int idx = 0, j;
  304. buff[idx++] = fm10k_read_reg(hw, FM10K_MRQC(i));
  305. for (j = 0; j < 10; j++)
  306. buff[idx++] = fm10k_read_reg(hw, FM10K_RSSRK(i, j));
  307. for (j = 0; j < 32; j++)
  308. buff[idx++] = fm10k_read_reg(hw, FM10K_RETA(i, j));
  309. BUG_ON(idx != FM10K_REGS_LEN_VSI);
  310. }
  311. static void fm10k_get_regs(struct net_device *netdev,
  312. struct ethtool_regs *regs, void *p)
  313. {
  314. struct fm10k_intfc *interface = netdev_priv(netdev);
  315. struct fm10k_hw *hw = &interface->hw;
  316. u32 *buff = p;
  317. u16 i;
  318. regs->version = BIT(24) | (hw->revision_id << 16) | hw->device_id;
  319. switch (hw->mac.type) {
  320. case fm10k_mac_pf:
  321. /* General PF Registers */
  322. *(buff++) = fm10k_read_reg(hw, FM10K_CTRL);
  323. *(buff++) = fm10k_read_reg(hw, FM10K_CTRL_EXT);
  324. *(buff++) = fm10k_read_reg(hw, FM10K_GCR);
  325. *(buff++) = fm10k_read_reg(hw, FM10K_GCR_EXT);
  326. for (i = 0; i < 8; i++) {
  327. *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTMAP(i));
  328. *(buff++) = fm10k_read_reg(hw, FM10K_DGLORTDEC(i));
  329. }
  330. for (i = 0; i < 65; i++) {
  331. fm10k_get_reg_vsi(hw, buff, i);
  332. buff += FM10K_REGS_LEN_VSI;
  333. }
  334. *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL);
  335. *(buff++) = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
  336. for (i = 0; i < FM10K_MAX_QUEUES_PF; i++) {
  337. fm10k_get_reg_q(hw, buff, i);
  338. buff += FM10K_REGS_LEN_Q;
  339. }
  340. *(buff++) = fm10k_read_reg(hw, FM10K_TPH_CTRL);
  341. for (i = 0; i < 8; i++)
  342. *(buff++) = fm10k_read_reg(hw, FM10K_INT_MAP(i));
  343. /* Interrupt Throttling Registers */
  344. for (i = 0; i < 130; i++)
  345. *(buff++) = fm10k_read_reg(hw, FM10K_ITR(i));
  346. break;
  347. case fm10k_mac_vf:
  348. /* General VF registers */
  349. *(buff++) = fm10k_read_reg(hw, FM10K_VFCTRL);
  350. *(buff++) = fm10k_read_reg(hw, FM10K_VFINT_MAP);
  351. *(buff++) = fm10k_read_reg(hw, FM10K_VFSYSTIME);
  352. /* Interrupt Throttling Registers */
  353. for (i = 0; i < 8; i++)
  354. *(buff++) = fm10k_read_reg(hw, FM10K_VFITR(i));
  355. fm10k_get_reg_vsi(hw, buff, 0);
  356. buff += FM10K_REGS_LEN_VSI;
  357. for (i = 0; i < FM10K_MAX_QUEUES_POOL; i++) {
  358. if (i < hw->mac.max_queues)
  359. fm10k_get_reg_q(hw, buff, i);
  360. else
  361. memset(buff, 0, sizeof(u32) * FM10K_REGS_LEN_Q);
  362. buff += FM10K_REGS_LEN_Q;
  363. }
  364. break;
  365. default:
  366. return;
  367. }
  368. }
  369. /* If function above adds more registers these define need to be updated */
  370. #define FM10K_REGS_LEN_PF \
  371. (162 + (65 * FM10K_REGS_LEN_VSI) + (FM10K_MAX_QUEUES_PF * FM10K_REGS_LEN_Q))
  372. #define FM10K_REGS_LEN_VF \
  373. (11 + FM10K_REGS_LEN_VSI + (FM10K_MAX_QUEUES_POOL * FM10K_REGS_LEN_Q))
  374. static int fm10k_get_regs_len(struct net_device *netdev)
  375. {
  376. struct fm10k_intfc *interface = netdev_priv(netdev);
  377. struct fm10k_hw *hw = &interface->hw;
  378. switch (hw->mac.type) {
  379. case fm10k_mac_pf:
  380. return FM10K_REGS_LEN_PF * sizeof(u32);
  381. case fm10k_mac_vf:
  382. return FM10K_REGS_LEN_VF * sizeof(u32);
  383. default:
  384. return 0;
  385. }
  386. }
  387. static void fm10k_get_drvinfo(struct net_device *dev,
  388. struct ethtool_drvinfo *info)
  389. {
  390. struct fm10k_intfc *interface = netdev_priv(dev);
  391. strncpy(info->driver, fm10k_driver_name,
  392. sizeof(info->driver) - 1);
  393. strncpy(info->version, fm10k_driver_version,
  394. sizeof(info->version) - 1);
  395. strncpy(info->bus_info, pci_name(interface->pdev),
  396. sizeof(info->bus_info) - 1);
  397. }
  398. static void fm10k_get_pauseparam(struct net_device *dev,
  399. struct ethtool_pauseparam *pause)
  400. {
  401. struct fm10k_intfc *interface = netdev_priv(dev);
  402. /* record fixed values for autoneg and tx pause */
  403. pause->autoneg = 0;
  404. pause->tx_pause = 1;
  405. pause->rx_pause = interface->rx_pause ? 1 : 0;
  406. }
  407. static int fm10k_set_pauseparam(struct net_device *dev,
  408. struct ethtool_pauseparam *pause)
  409. {
  410. struct fm10k_intfc *interface = netdev_priv(dev);
  411. struct fm10k_hw *hw = &interface->hw;
  412. if (pause->autoneg || !pause->tx_pause)
  413. return -EINVAL;
  414. /* we can only support pause on the PF to avoid head-of-line blocking */
  415. if (hw->mac.type == fm10k_mac_pf)
  416. interface->rx_pause = pause->rx_pause ? ~0 : 0;
  417. else if (pause->rx_pause)
  418. return -EINVAL;
  419. if (netif_running(dev))
  420. fm10k_update_rx_drop_en(interface);
  421. return 0;
  422. }
  423. static u32 fm10k_get_msglevel(struct net_device *netdev)
  424. {
  425. struct fm10k_intfc *interface = netdev_priv(netdev);
  426. return interface->msg_enable;
  427. }
  428. static void fm10k_set_msglevel(struct net_device *netdev, u32 data)
  429. {
  430. struct fm10k_intfc *interface = netdev_priv(netdev);
  431. interface->msg_enable = data;
  432. }
  433. static void fm10k_get_ringparam(struct net_device *netdev,
  434. struct ethtool_ringparam *ring)
  435. {
  436. struct fm10k_intfc *interface = netdev_priv(netdev);
  437. ring->rx_max_pending = FM10K_MAX_RXD;
  438. ring->tx_max_pending = FM10K_MAX_TXD;
  439. ring->rx_mini_max_pending = 0;
  440. ring->rx_jumbo_max_pending = 0;
  441. ring->rx_pending = interface->rx_ring_count;
  442. ring->tx_pending = interface->tx_ring_count;
  443. ring->rx_mini_pending = 0;
  444. ring->rx_jumbo_pending = 0;
  445. }
  446. static int fm10k_set_ringparam(struct net_device *netdev,
  447. struct ethtool_ringparam *ring)
  448. {
  449. struct fm10k_intfc *interface = netdev_priv(netdev);
  450. struct fm10k_ring *temp_ring;
  451. int i, err = 0;
  452. u32 new_rx_count, new_tx_count;
  453. if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
  454. return -EINVAL;
  455. new_tx_count = clamp_t(u32, ring->tx_pending,
  456. FM10K_MIN_TXD, FM10K_MAX_TXD);
  457. new_tx_count = ALIGN(new_tx_count, FM10K_REQ_TX_DESCRIPTOR_MULTIPLE);
  458. new_rx_count = clamp_t(u32, ring->rx_pending,
  459. FM10K_MIN_RXD, FM10K_MAX_RXD);
  460. new_rx_count = ALIGN(new_rx_count, FM10K_REQ_RX_DESCRIPTOR_MULTIPLE);
  461. if ((new_tx_count == interface->tx_ring_count) &&
  462. (new_rx_count == interface->rx_ring_count)) {
  463. /* nothing to do */
  464. return 0;
  465. }
  466. while (test_and_set_bit(__FM10K_RESETTING, &interface->state))
  467. usleep_range(1000, 2000);
  468. if (!netif_running(interface->netdev)) {
  469. for (i = 0; i < interface->num_tx_queues; i++)
  470. interface->tx_ring[i]->count = new_tx_count;
  471. for (i = 0; i < interface->num_rx_queues; i++)
  472. interface->rx_ring[i]->count = new_rx_count;
  473. interface->tx_ring_count = new_tx_count;
  474. interface->rx_ring_count = new_rx_count;
  475. goto clear_reset;
  476. }
  477. /* allocate temporary buffer to store rings in */
  478. i = max_t(int, interface->num_tx_queues, interface->num_rx_queues);
  479. temp_ring = vmalloc(i * sizeof(struct fm10k_ring));
  480. if (!temp_ring) {
  481. err = -ENOMEM;
  482. goto clear_reset;
  483. }
  484. fm10k_down(interface);
  485. /* Setup new Tx resources and free the old Tx resources in that order.
  486. * We can then assign the new resources to the rings via a memcpy.
  487. * The advantage to this approach is that we are guaranteed to still
  488. * have resources even in the case of an allocation failure.
  489. */
  490. if (new_tx_count != interface->tx_ring_count) {
  491. for (i = 0; i < interface->num_tx_queues; i++) {
  492. memcpy(&temp_ring[i], interface->tx_ring[i],
  493. sizeof(struct fm10k_ring));
  494. temp_ring[i].count = new_tx_count;
  495. err = fm10k_setup_tx_resources(&temp_ring[i]);
  496. if (err) {
  497. while (i) {
  498. i--;
  499. fm10k_free_tx_resources(&temp_ring[i]);
  500. }
  501. goto err_setup;
  502. }
  503. }
  504. for (i = 0; i < interface->num_tx_queues; i++) {
  505. fm10k_free_tx_resources(interface->tx_ring[i]);
  506. memcpy(interface->tx_ring[i], &temp_ring[i],
  507. sizeof(struct fm10k_ring));
  508. }
  509. interface->tx_ring_count = new_tx_count;
  510. }
  511. /* Repeat the process for the Rx rings if needed */
  512. if (new_rx_count != interface->rx_ring_count) {
  513. for (i = 0; i < interface->num_rx_queues; i++) {
  514. memcpy(&temp_ring[i], interface->rx_ring[i],
  515. sizeof(struct fm10k_ring));
  516. temp_ring[i].count = new_rx_count;
  517. err = fm10k_setup_rx_resources(&temp_ring[i]);
  518. if (err) {
  519. while (i) {
  520. i--;
  521. fm10k_free_rx_resources(&temp_ring[i]);
  522. }
  523. goto err_setup;
  524. }
  525. }
  526. for (i = 0; i < interface->num_rx_queues; i++) {
  527. fm10k_free_rx_resources(interface->rx_ring[i]);
  528. memcpy(interface->rx_ring[i], &temp_ring[i],
  529. sizeof(struct fm10k_ring));
  530. }
  531. interface->rx_ring_count = new_rx_count;
  532. }
  533. err_setup:
  534. fm10k_up(interface);
  535. vfree(temp_ring);
  536. clear_reset:
  537. clear_bit(__FM10K_RESETTING, &interface->state);
  538. return err;
  539. }
  540. static int fm10k_get_coalesce(struct net_device *dev,
  541. struct ethtool_coalesce *ec)
  542. {
  543. struct fm10k_intfc *interface = netdev_priv(dev);
  544. ec->use_adaptive_tx_coalesce = ITR_IS_ADAPTIVE(interface->tx_itr);
  545. ec->tx_coalesce_usecs = interface->tx_itr & ~FM10K_ITR_ADAPTIVE;
  546. ec->use_adaptive_rx_coalesce = ITR_IS_ADAPTIVE(interface->rx_itr);
  547. ec->rx_coalesce_usecs = interface->rx_itr & ~FM10K_ITR_ADAPTIVE;
  548. return 0;
  549. }
  550. static int fm10k_set_coalesce(struct net_device *dev,
  551. struct ethtool_coalesce *ec)
  552. {
  553. struct fm10k_intfc *interface = netdev_priv(dev);
  554. struct fm10k_q_vector *qv;
  555. u16 tx_itr, rx_itr;
  556. int i;
  557. /* verify limits */
  558. if ((ec->rx_coalesce_usecs > FM10K_ITR_MAX) ||
  559. (ec->tx_coalesce_usecs > FM10K_ITR_MAX))
  560. return -EINVAL;
  561. /* record settings */
  562. tx_itr = ec->tx_coalesce_usecs;
  563. rx_itr = ec->rx_coalesce_usecs;
  564. /* set initial values for adaptive ITR */
  565. if (ec->use_adaptive_tx_coalesce)
  566. tx_itr = FM10K_ITR_ADAPTIVE | FM10K_TX_ITR_DEFAULT;
  567. if (ec->use_adaptive_rx_coalesce)
  568. rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
  569. /* update interface */
  570. interface->tx_itr = tx_itr;
  571. interface->rx_itr = rx_itr;
  572. /* update q_vectors */
  573. for (i = 0; i < interface->num_q_vectors; i++) {
  574. qv = interface->q_vector[i];
  575. qv->tx.itr = tx_itr;
  576. qv->rx.itr = rx_itr;
  577. }
  578. return 0;
  579. }
  580. static int fm10k_get_rss_hash_opts(struct fm10k_intfc *interface,
  581. struct ethtool_rxnfc *cmd)
  582. {
  583. cmd->data = 0;
  584. /* Report default options for RSS on fm10k */
  585. switch (cmd->flow_type) {
  586. case TCP_V4_FLOW:
  587. case TCP_V6_FLOW:
  588. cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
  589. /* fall through */
  590. case UDP_V4_FLOW:
  591. if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
  592. cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
  593. /* fall through */
  594. case SCTP_V4_FLOW:
  595. case SCTP_V6_FLOW:
  596. case AH_ESP_V4_FLOW:
  597. case AH_ESP_V6_FLOW:
  598. case AH_V4_FLOW:
  599. case AH_V6_FLOW:
  600. case ESP_V4_FLOW:
  601. case ESP_V6_FLOW:
  602. case IPV4_FLOW:
  603. case IPV6_FLOW:
  604. cmd->data |= RXH_IP_SRC | RXH_IP_DST;
  605. break;
  606. case UDP_V6_FLOW:
  607. if (interface->flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
  608. cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
  609. cmd->data |= RXH_IP_SRC | RXH_IP_DST;
  610. break;
  611. default:
  612. return -EINVAL;
  613. }
  614. return 0;
  615. }
  616. static int fm10k_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
  617. u32 __always_unused *rule_locs)
  618. {
  619. struct fm10k_intfc *interface = netdev_priv(dev);
  620. int ret = -EOPNOTSUPP;
  621. switch (cmd->cmd) {
  622. case ETHTOOL_GRXRINGS:
  623. cmd->data = interface->num_rx_queues;
  624. ret = 0;
  625. break;
  626. case ETHTOOL_GRXFH:
  627. ret = fm10k_get_rss_hash_opts(interface, cmd);
  628. break;
  629. default:
  630. break;
  631. }
  632. return ret;
  633. }
  634. #define UDP_RSS_FLAGS (FM10K_FLAG_RSS_FIELD_IPV4_UDP | \
  635. FM10K_FLAG_RSS_FIELD_IPV6_UDP)
  636. static int fm10k_set_rss_hash_opt(struct fm10k_intfc *interface,
  637. struct ethtool_rxnfc *nfc)
  638. {
  639. u32 flags = interface->flags;
  640. /* RSS does not support anything other than hashing
  641. * to queues on src and dst IPs and ports
  642. */
  643. if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
  644. RXH_L4_B_0_1 | RXH_L4_B_2_3))
  645. return -EINVAL;
  646. switch (nfc->flow_type) {
  647. case TCP_V4_FLOW:
  648. case TCP_V6_FLOW:
  649. if (!(nfc->data & RXH_IP_SRC) ||
  650. !(nfc->data & RXH_IP_DST) ||
  651. !(nfc->data & RXH_L4_B_0_1) ||
  652. !(nfc->data & RXH_L4_B_2_3))
  653. return -EINVAL;
  654. break;
  655. case UDP_V4_FLOW:
  656. if (!(nfc->data & RXH_IP_SRC) ||
  657. !(nfc->data & RXH_IP_DST))
  658. return -EINVAL;
  659. switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
  660. case 0:
  661. flags &= ~FM10K_FLAG_RSS_FIELD_IPV4_UDP;
  662. break;
  663. case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
  664. flags |= FM10K_FLAG_RSS_FIELD_IPV4_UDP;
  665. break;
  666. default:
  667. return -EINVAL;
  668. }
  669. break;
  670. case UDP_V6_FLOW:
  671. if (!(nfc->data & RXH_IP_SRC) ||
  672. !(nfc->data & RXH_IP_DST))
  673. return -EINVAL;
  674. switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
  675. case 0:
  676. flags &= ~FM10K_FLAG_RSS_FIELD_IPV6_UDP;
  677. break;
  678. case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
  679. flags |= FM10K_FLAG_RSS_FIELD_IPV6_UDP;
  680. break;
  681. default:
  682. return -EINVAL;
  683. }
  684. break;
  685. case AH_ESP_V4_FLOW:
  686. case AH_V4_FLOW:
  687. case ESP_V4_FLOW:
  688. case SCTP_V4_FLOW:
  689. case AH_ESP_V6_FLOW:
  690. case AH_V6_FLOW:
  691. case ESP_V6_FLOW:
  692. case SCTP_V6_FLOW:
  693. if (!(nfc->data & RXH_IP_SRC) ||
  694. !(nfc->data & RXH_IP_DST) ||
  695. (nfc->data & RXH_L4_B_0_1) ||
  696. (nfc->data & RXH_L4_B_2_3))
  697. return -EINVAL;
  698. break;
  699. default:
  700. return -EINVAL;
  701. }
  702. /* if we changed something we need to update flags */
  703. if (flags != interface->flags) {
  704. struct fm10k_hw *hw = &interface->hw;
  705. u32 mrqc;
  706. if ((flags & UDP_RSS_FLAGS) &&
  707. !(interface->flags & UDP_RSS_FLAGS))
  708. netif_warn(interface, drv, interface->netdev,
  709. "enabling UDP RSS: fragmented packets may arrive out of order to the stack above\n");
  710. interface->flags = flags;
  711. /* Perform hash on these packet types */
  712. mrqc = FM10K_MRQC_IPV4 |
  713. FM10K_MRQC_TCP_IPV4 |
  714. FM10K_MRQC_IPV6 |
  715. FM10K_MRQC_TCP_IPV6;
  716. if (flags & FM10K_FLAG_RSS_FIELD_IPV4_UDP)
  717. mrqc |= FM10K_MRQC_UDP_IPV4;
  718. if (flags & FM10K_FLAG_RSS_FIELD_IPV6_UDP)
  719. mrqc |= FM10K_MRQC_UDP_IPV6;
  720. fm10k_write_reg(hw, FM10K_MRQC(0), mrqc);
  721. }
  722. return 0;
  723. }
  724. static int fm10k_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
  725. {
  726. struct fm10k_intfc *interface = netdev_priv(dev);
  727. int ret = -EOPNOTSUPP;
  728. switch (cmd->cmd) {
  729. case ETHTOOL_SRXFH:
  730. ret = fm10k_set_rss_hash_opt(interface, cmd);
  731. break;
  732. default:
  733. break;
  734. }
  735. return ret;
  736. }
  737. static int fm10k_mbx_test(struct fm10k_intfc *interface, u64 *data)
  738. {
  739. struct fm10k_hw *hw = &interface->hw;
  740. struct fm10k_mbx_info *mbx = &hw->mbx;
  741. u32 attr_flag, test_msg[6];
  742. unsigned long timeout;
  743. int err = -EINVAL;
  744. /* For now this is a VF only feature */
  745. if (hw->mac.type != fm10k_mac_vf)
  746. return 0;
  747. /* loop through both nested and unnested attribute types */
  748. for (attr_flag = BIT(FM10K_TEST_MSG_UNSET);
  749. attr_flag < BIT(2 * FM10K_TEST_MSG_NESTED);
  750. attr_flag += attr_flag) {
  751. /* generate message to be tested */
  752. fm10k_tlv_msg_test_create(test_msg, attr_flag);
  753. fm10k_mbx_lock(interface);
  754. mbx->test_result = FM10K_NOT_IMPLEMENTED;
  755. err = mbx->ops.enqueue_tx(hw, mbx, test_msg);
  756. fm10k_mbx_unlock(interface);
  757. /* wait up to 1 second for response */
  758. timeout = jiffies + HZ;
  759. do {
  760. if (err < 0)
  761. goto err_out;
  762. usleep_range(500, 1000);
  763. fm10k_mbx_lock(interface);
  764. mbx->ops.process(hw, mbx);
  765. fm10k_mbx_unlock(interface);
  766. err = mbx->test_result;
  767. if (!err)
  768. break;
  769. } while (time_is_after_jiffies(timeout));
  770. /* reporting errors */
  771. if (err)
  772. goto err_out;
  773. }
  774. err_out:
  775. *data = err < 0 ? (attr_flag) : (err > 0);
  776. return err;
  777. }
  778. static void fm10k_self_test(struct net_device *dev,
  779. struct ethtool_test *eth_test, u64 *data)
  780. {
  781. struct fm10k_intfc *interface = netdev_priv(dev);
  782. struct fm10k_hw *hw = &interface->hw;
  783. memset(data, 0, sizeof(*data) * FM10K_TEST_LEN);
  784. if (FM10K_REMOVED(hw->hw_addr)) {
  785. netif_err(interface, drv, dev,
  786. "Interface removed - test blocked\n");
  787. eth_test->flags |= ETH_TEST_FL_FAILED;
  788. return;
  789. }
  790. if (fm10k_mbx_test(interface, &data[FM10K_TEST_MBX]))
  791. eth_test->flags |= ETH_TEST_FL_FAILED;
  792. }
  793. static u32 fm10k_get_priv_flags(struct net_device *netdev)
  794. {
  795. return 0;
  796. }
  797. static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
  798. {
  799. if (priv_flags >= BIT(FM10K_PRV_FLAG_LEN))
  800. return -EINVAL;
  801. return 0;
  802. }
  803. static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
  804. {
  805. return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
  806. }
  807. void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir)
  808. {
  809. u16 rss_i = interface->ring_feature[RING_F_RSS].indices;
  810. struct fm10k_hw *hw = &interface->hw;
  811. u32 table[4];
  812. int i, j;
  813. /* record entries to reta table */
  814. for (i = 0; i < FM10K_RETA_SIZE; i++) {
  815. u32 reta, n;
  816. /* generate a new table if we weren't given one */
  817. for (j = 0; j < 4; j++) {
  818. if (indir)
  819. n = indir[4 * i + j];
  820. else
  821. n = ethtool_rxfh_indir_default(4 * i + j,
  822. rss_i);
  823. table[j] = n;
  824. }
  825. reta = table[0] |
  826. (table[1] << 8) |
  827. (table[2] << 16) |
  828. (table[3] << 24);
  829. if (interface->reta[i] == reta)
  830. continue;
  831. interface->reta[i] = reta;
  832. fm10k_write_reg(hw, FM10K_RETA(0, i), reta);
  833. }
  834. }
  835. static int fm10k_get_reta(struct net_device *netdev, u32 *indir)
  836. {
  837. struct fm10k_intfc *interface = netdev_priv(netdev);
  838. int i;
  839. if (!indir)
  840. return 0;
  841. for (i = 0; i < FM10K_RETA_SIZE; i++, indir += 4) {
  842. u32 reta = interface->reta[i];
  843. indir[0] = (reta << 24) >> 24;
  844. indir[1] = (reta << 16) >> 24;
  845. indir[2] = (reta << 8) >> 24;
  846. indir[3] = (reta) >> 24;
  847. }
  848. return 0;
  849. }
  850. static int fm10k_set_reta(struct net_device *netdev, const u32 *indir)
  851. {
  852. struct fm10k_intfc *interface = netdev_priv(netdev);
  853. int i;
  854. u16 rss_i;
  855. if (!indir)
  856. return 0;
  857. /* Verify user input. */
  858. rss_i = interface->ring_feature[RING_F_RSS].indices;
  859. for (i = fm10k_get_reta_size(netdev); i--;) {
  860. if (indir[i] < rss_i)
  861. continue;
  862. return -EINVAL;
  863. }
  864. fm10k_write_reta(interface, indir);
  865. return 0;
  866. }
  867. static u32 fm10k_get_rssrk_size(struct net_device __always_unused *netdev)
  868. {
  869. return FM10K_RSSRK_SIZE * FM10K_RSSRK_ENTRIES_PER_REG;
  870. }
  871. static int fm10k_get_rssh(struct net_device *netdev, u32 *indir, u8 *key,
  872. u8 *hfunc)
  873. {
  874. struct fm10k_intfc *interface = netdev_priv(netdev);
  875. int i, err;
  876. if (hfunc)
  877. *hfunc = ETH_RSS_HASH_TOP;
  878. err = fm10k_get_reta(netdev, indir);
  879. if (err || !key)
  880. return err;
  881. for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4)
  882. *(__le32 *)key = cpu_to_le32(interface->rssrk[i]);
  883. return 0;
  884. }
  885. static int fm10k_set_rssh(struct net_device *netdev, const u32 *indir,
  886. const u8 *key, const u8 hfunc)
  887. {
  888. struct fm10k_intfc *interface = netdev_priv(netdev);
  889. struct fm10k_hw *hw = &interface->hw;
  890. int i, err;
  891. /* We do not allow change in unsupported parameters */
  892. if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
  893. return -EOPNOTSUPP;
  894. err = fm10k_set_reta(netdev, indir);
  895. if (err || !key)
  896. return err;
  897. for (i = 0; i < FM10K_RSSRK_SIZE; i++, key += 4) {
  898. u32 rssrk = le32_to_cpu(*(__le32 *)key);
  899. if (interface->rssrk[i] == rssrk)
  900. continue;
  901. interface->rssrk[i] = rssrk;
  902. fm10k_write_reg(hw, FM10K_RSSRK(0, i), rssrk);
  903. }
  904. return 0;
  905. }
  906. static unsigned int fm10k_max_channels(struct net_device *dev)
  907. {
  908. struct fm10k_intfc *interface = netdev_priv(dev);
  909. unsigned int max_combined = interface->hw.mac.max_queues;
  910. u8 tcs = netdev_get_num_tc(dev);
  911. /* For QoS report channels per traffic class */
  912. if (tcs > 1)
  913. max_combined = BIT((fls(max_combined / tcs) - 1));
  914. return max_combined;
  915. }
  916. static void fm10k_get_channels(struct net_device *dev,
  917. struct ethtool_channels *ch)
  918. {
  919. struct fm10k_intfc *interface = netdev_priv(dev);
  920. struct fm10k_hw *hw = &interface->hw;
  921. /* report maximum channels */
  922. ch->max_combined = fm10k_max_channels(dev);
  923. /* report info for other vector */
  924. ch->max_other = NON_Q_VECTORS(hw);
  925. ch->other_count = ch->max_other;
  926. /* record RSS queues */
  927. ch->combined_count = interface->ring_feature[RING_F_RSS].indices;
  928. }
  929. static int fm10k_set_channels(struct net_device *dev,
  930. struct ethtool_channels *ch)
  931. {
  932. struct fm10k_intfc *interface = netdev_priv(dev);
  933. unsigned int count = ch->combined_count;
  934. struct fm10k_hw *hw = &interface->hw;
  935. /* verify they are not requesting separate vectors */
  936. if (!count || ch->rx_count || ch->tx_count)
  937. return -EINVAL;
  938. /* verify other_count has not changed */
  939. if (ch->other_count != NON_Q_VECTORS(hw))
  940. return -EINVAL;
  941. /* verify the number of channels does not exceed hardware limits */
  942. if (count > fm10k_max_channels(dev))
  943. return -EINVAL;
  944. interface->ring_feature[RING_F_RSS].limit = count;
  945. /* use setup TC to update any traffic class queue mapping */
  946. return fm10k_setup_tc(dev, netdev_get_num_tc(dev));
  947. }
  948. static const struct ethtool_ops fm10k_ethtool_ops = {
  949. .get_strings = fm10k_get_strings,
  950. .get_sset_count = fm10k_get_sset_count,
  951. .get_ethtool_stats = fm10k_get_ethtool_stats,
  952. .get_drvinfo = fm10k_get_drvinfo,
  953. .get_link = ethtool_op_get_link,
  954. .get_pauseparam = fm10k_get_pauseparam,
  955. .set_pauseparam = fm10k_set_pauseparam,
  956. .get_msglevel = fm10k_get_msglevel,
  957. .set_msglevel = fm10k_set_msglevel,
  958. .get_ringparam = fm10k_get_ringparam,
  959. .set_ringparam = fm10k_set_ringparam,
  960. .get_coalesce = fm10k_get_coalesce,
  961. .set_coalesce = fm10k_set_coalesce,
  962. .get_rxnfc = fm10k_get_rxnfc,
  963. .set_rxnfc = fm10k_set_rxnfc,
  964. .get_regs = fm10k_get_regs,
  965. .get_regs_len = fm10k_get_regs_len,
  966. .self_test = fm10k_self_test,
  967. .get_priv_flags = fm10k_get_priv_flags,
  968. .set_priv_flags = fm10k_set_priv_flags,
  969. .get_rxfh_indir_size = fm10k_get_reta_size,
  970. .get_rxfh_key_size = fm10k_get_rssrk_size,
  971. .get_rxfh = fm10k_get_rssh,
  972. .set_rxfh = fm10k_set_rssh,
  973. .get_channels = fm10k_get_channels,
  974. .set_channels = fm10k_set_channels,
  975. .get_ts_info = ethtool_op_get_ts_info,
  976. };
  977. void fm10k_set_ethtool_ops(struct net_device *dev)
  978. {
  979. dev->ethtool_ops = &fm10k_ethtool_ops;
  980. }