fm10k_ethtool.c 32 KB

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