hns_ethtool.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  1. /*
  2. * Copyright (c) 2014-2015 Hisilicon Limited.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <linux/etherdevice.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/module.h>
  12. #include <linux/platform_device.h>
  13. #include "hns_enet.h"
  14. #define HNS_PHY_PAGE_MDIX 0
  15. #define HNS_PHY_PAGE_LED 3
  16. #define HNS_PHY_PAGE_COPPER 0
  17. #define HNS_PHY_PAGE_REG 22 /* Page Selection Reg. */
  18. #define HNS_PHY_CSC_REG 16 /* Copper Specific Control Register */
  19. #define HNS_PHY_CSS_REG 17 /* Copper Specific Status Register */
  20. #define HNS_LED_FC_REG 16 /* LED Function Control Reg. */
  21. #define HNS_LED_PC_REG 17 /* LED Polarity Control Reg. */
  22. #define HNS_LED_FORCE_ON 9
  23. #define HNS_LED_FORCE_OFF 8
  24. #define HNS_CHIP_VERSION 660
  25. #define HNS_NET_STATS_CNT 26
  26. #define PHY_MDIX_CTRL_S (5)
  27. #define PHY_MDIX_CTRL_M (3 << PHY_MDIX_CTRL_S)
  28. #define PHY_MDIX_STATUS_B (6)
  29. #define PHY_SPEED_DUP_RESOLVE_B (11)
  30. /**
  31. *hns_nic_get_link - get current link status
  32. *@net_dev: net_device
  33. *retuen 0 - success , negative --fail
  34. */
  35. static u32 hns_nic_get_link(struct net_device *net_dev)
  36. {
  37. struct hns_nic_priv *priv = netdev_priv(net_dev);
  38. u32 link_stat = priv->link;
  39. struct hnae_handle *h;
  40. assert(priv && priv->ae_handle);
  41. h = priv->ae_handle;
  42. if (priv->phy) {
  43. if (!genphy_update_link(priv->phy))
  44. link_stat = priv->phy->link;
  45. else
  46. link_stat = 0;
  47. }
  48. if (h->dev && h->dev->ops && h->dev->ops->get_status)
  49. link_stat = link_stat && h->dev->ops->get_status(h);
  50. else
  51. link_stat = 0;
  52. return link_stat;
  53. }
  54. static void hns_get_mdix_mode(struct net_device *net_dev,
  55. struct ethtool_cmd *cmd)
  56. {
  57. int mdix_ctrl, mdix, retval, is_resolved;
  58. struct hns_nic_priv *priv = netdev_priv(net_dev);
  59. struct phy_device *phy_dev = priv->phy;
  60. if (!phy_dev || !phy_dev->bus) {
  61. cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
  62. cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
  63. return;
  64. }
  65. (void)mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_PHY_PAGE_REG,
  66. HNS_PHY_PAGE_MDIX);
  67. retval = mdiobus_read(phy_dev->bus, phy_dev->addr, HNS_PHY_CSC_REG);
  68. mdix_ctrl = hnae_get_field(retval, PHY_MDIX_CTRL_M, PHY_MDIX_CTRL_S);
  69. retval = mdiobus_read(phy_dev->bus, phy_dev->addr, HNS_PHY_CSS_REG);
  70. mdix = hnae_get_bit(retval, PHY_MDIX_STATUS_B);
  71. is_resolved = hnae_get_bit(retval, PHY_SPEED_DUP_RESOLVE_B);
  72. (void)mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_PHY_PAGE_REG,
  73. HNS_PHY_PAGE_COPPER);
  74. switch (mdix_ctrl) {
  75. case 0x0:
  76. cmd->eth_tp_mdix_ctrl = ETH_TP_MDI;
  77. break;
  78. case 0x1:
  79. cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_X;
  80. break;
  81. case 0x3:
  82. cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
  83. break;
  84. default:
  85. cmd->eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
  86. break;
  87. }
  88. if (!is_resolved)
  89. cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
  90. else if (mdix)
  91. cmd->eth_tp_mdix = ETH_TP_MDI_X;
  92. else
  93. cmd->eth_tp_mdix = ETH_TP_MDI;
  94. }
  95. /**
  96. *hns_nic_get_settings - implement ethtool get settings
  97. *@net_dev: net_device
  98. *@cmd: ethtool_cmd
  99. *retuen 0 - success , negative --fail
  100. */
  101. static int hns_nic_get_settings(struct net_device *net_dev,
  102. struct ethtool_cmd *cmd)
  103. {
  104. struct hns_nic_priv *priv = netdev_priv(net_dev);
  105. struct hnae_handle *h;
  106. u32 link_stat;
  107. int ret;
  108. u8 duplex;
  109. u16 speed;
  110. if (!priv || !priv->ae_handle)
  111. return -ESRCH;
  112. h = priv->ae_handle;
  113. if (!h->dev || !h->dev->ops || !h->dev->ops->get_info)
  114. return -ESRCH;
  115. ret = h->dev->ops->get_info(h, NULL, &speed, &duplex);
  116. if (ret < 0) {
  117. netdev_err(net_dev, "%s get_info error!\n", __func__);
  118. return -EINVAL;
  119. }
  120. /* When there is no phy, autoneg is off. */
  121. cmd->autoneg = false;
  122. ethtool_cmd_speed_set(cmd, speed);
  123. cmd->duplex = duplex;
  124. if (priv->phy)
  125. (void)phy_ethtool_gset(priv->phy, cmd);
  126. link_stat = hns_nic_get_link(net_dev);
  127. if (!link_stat) {
  128. ethtool_cmd_speed_set(cmd, (u32)SPEED_UNKNOWN);
  129. cmd->duplex = DUPLEX_UNKNOWN;
  130. }
  131. if (cmd->autoneg)
  132. cmd->advertising |= ADVERTISED_Autoneg;
  133. cmd->supported |= h->if_support;
  134. if (h->phy_if == PHY_INTERFACE_MODE_SGMII) {
  135. cmd->supported |= SUPPORTED_TP;
  136. cmd->advertising |= ADVERTISED_1000baseT_Full;
  137. } else if (h->phy_if == PHY_INTERFACE_MODE_XGMII) {
  138. cmd->supported |= SUPPORTED_FIBRE;
  139. cmd->advertising |= ADVERTISED_10000baseKR_Full;
  140. }
  141. if (h->port_type == HNAE_PORT_SERVICE) {
  142. cmd->port = PORT_FIBRE;
  143. cmd->supported |= SUPPORTED_Pause;
  144. } else {
  145. cmd->port = PORT_TP;
  146. }
  147. cmd->transceiver = XCVR_EXTERNAL;
  148. cmd->mdio_support = (ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22);
  149. hns_get_mdix_mode(net_dev, cmd);
  150. return 0;
  151. }
  152. /**
  153. *hns_nic_set_settings - implement ethtool set settings
  154. *@net_dev: net_device
  155. *@cmd: ethtool_cmd
  156. *retuen 0 - success , negative --fail
  157. */
  158. static int hns_nic_set_settings(struct net_device *net_dev,
  159. struct ethtool_cmd *cmd)
  160. {
  161. struct hns_nic_priv *priv = netdev_priv(net_dev);
  162. struct hnae_handle *h;
  163. u32 speed;
  164. if (!netif_running(net_dev))
  165. return -ESRCH;
  166. if (!priv || !priv->ae_handle || !priv->ae_handle->dev ||
  167. !priv->ae_handle->dev->ops)
  168. return -ENODEV;
  169. h = priv->ae_handle;
  170. speed = ethtool_cmd_speed(cmd);
  171. if (h->phy_if == PHY_INTERFACE_MODE_XGMII) {
  172. if (cmd->autoneg == AUTONEG_ENABLE || speed != SPEED_10000 ||
  173. cmd->duplex != DUPLEX_FULL)
  174. return -EINVAL;
  175. } else if (h->phy_if == PHY_INTERFACE_MODE_SGMII) {
  176. if (!priv->phy && cmd->autoneg == AUTONEG_ENABLE)
  177. return -EINVAL;
  178. if (speed == SPEED_1000 && cmd->duplex == DUPLEX_HALF)
  179. return -EINVAL;
  180. if (priv->phy)
  181. return phy_ethtool_sset(priv->phy, cmd);
  182. if ((speed != SPEED_10 && speed != SPEED_100 &&
  183. speed != SPEED_1000) || (cmd->duplex != DUPLEX_HALF &&
  184. cmd->duplex != DUPLEX_FULL))
  185. return -EINVAL;
  186. } else {
  187. netdev_err(net_dev, "Not supported!");
  188. return -ENOTSUPP;
  189. }
  190. if (h->dev->ops->adjust_link) {
  191. h->dev->ops->adjust_link(h, (int)speed, cmd->duplex);
  192. return 0;
  193. }
  194. netdev_err(net_dev, "Not supported!");
  195. return -ENOTSUPP;
  196. }
  197. static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {
  198. "Mac Loopback test",
  199. "Serdes Loopback test",
  200. "Phy Loopback test"
  201. };
  202. static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
  203. {
  204. #define COPPER_CONTROL_REG 0
  205. #define PHY_LOOP_BACK BIT(14)
  206. u16 val = 0;
  207. if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
  208. return -ENOTSUPP;
  209. if (en) {
  210. /* speed : 1000M */
  211. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  212. HNS_PHY_PAGE_REG, 2);
  213. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  214. 21, 0x1046);
  215. /* Force Master */
  216. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  217. 9, 0x1F00);
  218. /* Soft-reset */
  219. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  220. 0, 0x9140);
  221. /* If autoneg disabled,two soft-reset operations */
  222. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  223. 0, 0x9140);
  224. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  225. 22, 0xFA);
  226. /* Default is 0x0400 */
  227. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  228. 1, 0x418);
  229. /* Force 1000M Link, Default is 0x0200 */
  230. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  231. 7, 0x20C);
  232. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  233. 22, 0);
  234. /* Enable MAC loop-back */
  235. val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
  236. COPPER_CONTROL_REG);
  237. val |= PHY_LOOP_BACK;
  238. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  239. COPPER_CONTROL_REG, val);
  240. } else {
  241. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  242. 22, 0xFA);
  243. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  244. 1, 0x400);
  245. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  246. 7, 0x200);
  247. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  248. 22, 0);
  249. val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
  250. COPPER_CONTROL_REG);
  251. val &= ~PHY_LOOP_BACK;
  252. (void)mdiobus_write(phy_dev->bus, phy_dev->addr,
  253. COPPER_CONTROL_REG, val);
  254. }
  255. return 0;
  256. }
  257. static int __lb_setup(struct net_device *ndev,
  258. enum hnae_loop loop)
  259. {
  260. int ret = 0;
  261. struct hns_nic_priv *priv = netdev_priv(ndev);
  262. struct phy_device *phy_dev = priv->phy;
  263. struct hnae_handle *h = priv->ae_handle;
  264. switch (loop) {
  265. case MAC_INTERNALLOOP_PHY:
  266. if ((phy_dev) && (!phy_dev->is_c45))
  267. ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
  268. break;
  269. case MAC_INTERNALLOOP_MAC:
  270. if ((h->dev->ops->set_loopback) &&
  271. (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII))
  272. ret = h->dev->ops->set_loopback(h, loop, 0x1);
  273. break;
  274. case MAC_INTERNALLOOP_SERDES:
  275. if (h->dev->ops->set_loopback)
  276. ret = h->dev->ops->set_loopback(h, loop, 0x1);
  277. break;
  278. case MAC_LOOP_NONE:
  279. if ((phy_dev) && (!phy_dev->is_c45))
  280. ret |= hns_nic_config_phy_loopback(phy_dev, 0x0);
  281. if (h->dev->ops->set_loopback) {
  282. if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
  283. ret |= h->dev->ops->set_loopback(h,
  284. MAC_INTERNALLOOP_MAC, 0x0);
  285. ret |= h->dev->ops->set_loopback(h,
  286. MAC_INTERNALLOOP_SERDES, 0x0);
  287. }
  288. break;
  289. default:
  290. ret = -EINVAL;
  291. break;
  292. }
  293. return ret;
  294. }
  295. static int __lb_up(struct net_device *ndev,
  296. enum hnae_loop loop_mode)
  297. {
  298. struct hns_nic_priv *priv = netdev_priv(ndev);
  299. struct hnae_handle *h = priv->ae_handle;
  300. int speed, duplex;
  301. int ret;
  302. hns_nic_net_reset(ndev);
  303. if (priv->phy) {
  304. phy_disconnect(priv->phy);
  305. msleep(100);
  306. ret = hns_nic_init_phy(ndev, h);
  307. if (ret)
  308. return ret;
  309. }
  310. ret = __lb_setup(ndev, loop_mode);
  311. if (ret)
  312. return ret;
  313. msleep(100);
  314. ret = h->dev->ops->start ? h->dev->ops->start(h) : 0;
  315. if (ret)
  316. return ret;
  317. if (priv->phy)
  318. phy_start(priv->phy);
  319. /* link adjust duplex*/
  320. if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
  321. speed = 1000;
  322. else
  323. speed = 10000;
  324. duplex = 1;
  325. h->dev->ops->adjust_link(h, speed, duplex);
  326. return 0;
  327. }
  328. static void __lb_other_process(struct hns_nic_ring_data *ring_data,
  329. struct sk_buff *skb)
  330. {
  331. struct net_device *ndev;
  332. struct hnae_ring *ring;
  333. struct netdev_queue *dev_queue;
  334. struct sk_buff *new_skb;
  335. unsigned int frame_size;
  336. int check_ok;
  337. u32 i;
  338. char buff[33]; /* 32B data and the last character '\0' */
  339. if (!ring_data) { /* Just for doing create frame*/
  340. frame_size = skb->len;
  341. memset(skb->data, 0xFF, frame_size);
  342. frame_size &= ~1ul;
  343. memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
  344. memset(&skb->data[frame_size / 2 + 10], 0xBE,
  345. frame_size / 2 - 11);
  346. memset(&skb->data[frame_size / 2 + 12], 0xAF,
  347. frame_size / 2 - 13);
  348. return;
  349. }
  350. ring = ring_data->ring;
  351. ndev = ring_data->napi.dev;
  352. if (is_tx_ring(ring)) { /* for tx queue reset*/
  353. dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
  354. netdev_tx_reset_queue(dev_queue);
  355. return;
  356. }
  357. frame_size = skb->len;
  358. frame_size &= ~1ul;
  359. /* for mutl buffer*/
  360. new_skb = skb_copy(skb, GFP_ATOMIC);
  361. dev_kfree_skb_any(skb);
  362. skb = new_skb;
  363. check_ok = 0;
  364. if (*(skb->data + 10) == 0xFF) { /* for rx check frame*/
  365. if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
  366. (*(skb->data + frame_size / 2 + 12) == 0xAF))
  367. check_ok = 1;
  368. }
  369. if (check_ok) {
  370. ndev->stats.rx_packets++;
  371. ndev->stats.rx_bytes += skb->len;
  372. } else {
  373. ndev->stats.rx_frame_errors++;
  374. for (i = 0; i < skb->len; i++) {
  375. snprintf(buff + i % 16 * 2, 3, /* tailing \0*/
  376. "%02x", *(skb->data + i));
  377. if ((i % 16 == 15) || (i == skb->len - 1))
  378. pr_info("%s\n", buff);
  379. }
  380. }
  381. dev_kfree_skb_any(skb);
  382. }
  383. static int __lb_clean_rings(struct hns_nic_priv *priv,
  384. int ringid0, int ringid1, int budget)
  385. {
  386. int i, ret;
  387. struct hns_nic_ring_data *ring_data;
  388. struct net_device *ndev = priv->netdev;
  389. unsigned long rx_packets = ndev->stats.rx_packets;
  390. unsigned long rx_bytes = ndev->stats.rx_bytes;
  391. unsigned long rx_frame_errors = ndev->stats.rx_frame_errors;
  392. for (i = ringid0; i <= ringid1; i++) {
  393. ring_data = &priv->ring_data[i];
  394. (void)ring_data->poll_one(ring_data,
  395. budget, __lb_other_process);
  396. }
  397. ret = (int)(ndev->stats.rx_packets - rx_packets);
  398. ndev->stats.rx_packets = rx_packets;
  399. ndev->stats.rx_bytes = rx_bytes;
  400. ndev->stats.rx_frame_errors = rx_frame_errors;
  401. return ret;
  402. }
  403. /**
  404. * nic_run_loopback_test - run loopback test
  405. * @nic_dev: net device
  406. * @loopback_type: loopback type
  407. */
  408. static int __lb_run_test(struct net_device *ndev,
  409. enum hnae_loop loop_mode)
  410. {
  411. #define NIC_LB_TEST_PKT_NUM_PER_CYCLE 1
  412. #define NIC_LB_TEST_RING_ID 0
  413. #define NIC_LB_TEST_FRAME_SIZE 128
  414. /* nic loopback test err */
  415. #define NIC_LB_TEST_NO_MEM_ERR 1
  416. #define NIC_LB_TEST_TX_CNT_ERR 2
  417. #define NIC_LB_TEST_RX_CNT_ERR 3
  418. #define NIC_LB_TEST_RX_PKG_ERR 4
  419. struct hns_nic_priv *priv = netdev_priv(ndev);
  420. struct hnae_handle *h = priv->ae_handle;
  421. int i, j, lc, good_cnt, ret_val = 0;
  422. unsigned int size;
  423. netdev_tx_t tx_ret_val;
  424. struct sk_buff *skb;
  425. size = NIC_LB_TEST_FRAME_SIZE;
  426. /* allocate test skb */
  427. skb = alloc_skb(size, GFP_KERNEL);
  428. if (!skb)
  429. return NIC_LB_TEST_NO_MEM_ERR;
  430. /* place data into test skb */
  431. (void)skb_put(skb, size);
  432. __lb_other_process(NULL, skb);
  433. skb->queue_mapping = NIC_LB_TEST_RING_ID;
  434. lc = 1;
  435. for (j = 0; j < lc; j++) {
  436. /* reset count of good packets */
  437. good_cnt = 0;
  438. /* place 64 packets on the transmit queue*/
  439. for (i = 0; i < NIC_LB_TEST_PKT_NUM_PER_CYCLE; i++) {
  440. (void)skb_get(skb);
  441. tx_ret_val = (netdev_tx_t)hns_nic_net_xmit_hw(
  442. ndev, skb,
  443. &tx_ring_data(priv, skb->queue_mapping));
  444. if (tx_ret_val == NETDEV_TX_OK)
  445. good_cnt++;
  446. else
  447. break;
  448. }
  449. if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
  450. ret_val = NIC_LB_TEST_TX_CNT_ERR;
  451. dev_err(priv->dev, "%s sent fail, cnt=0x%x, budget=0x%x\n",
  452. hns_nic_test_strs[loop_mode], good_cnt,
  453. NIC_LB_TEST_PKT_NUM_PER_CYCLE);
  454. break;
  455. }
  456. /* allow 100 milliseconds for packets to go from Tx to Rx */
  457. msleep(100);
  458. good_cnt = __lb_clean_rings(priv,
  459. h->q_num, h->q_num * 2 - 1,
  460. NIC_LB_TEST_PKT_NUM_PER_CYCLE);
  461. if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
  462. ret_val = NIC_LB_TEST_RX_CNT_ERR;
  463. dev_err(priv->dev, "%s recv fail, cnt=0x%x, budget=0x%x\n",
  464. hns_nic_test_strs[loop_mode], good_cnt,
  465. NIC_LB_TEST_PKT_NUM_PER_CYCLE);
  466. break;
  467. }
  468. (void)__lb_clean_rings(priv,
  469. NIC_LB_TEST_RING_ID, NIC_LB_TEST_RING_ID,
  470. NIC_LB_TEST_PKT_NUM_PER_CYCLE);
  471. }
  472. /* free the original skb */
  473. kfree_skb(skb);
  474. return ret_val;
  475. }
  476. static int __lb_down(struct net_device *ndev)
  477. {
  478. struct hns_nic_priv *priv = netdev_priv(ndev);
  479. struct hnae_handle *h = priv->ae_handle;
  480. int ret;
  481. ret = __lb_setup(ndev, MAC_LOOP_NONE);
  482. if (ret)
  483. netdev_err(ndev, "%s: __lb_setup return error(%d)!\n",
  484. __func__,
  485. ret);
  486. if (priv->phy)
  487. phy_stop(priv->phy);
  488. if (h->dev->ops->stop)
  489. h->dev->ops->stop(h);
  490. usleep_range(10000, 20000);
  491. (void)__lb_clean_rings(priv, 0, h->q_num - 1, 256);
  492. hns_nic_net_reset(ndev);
  493. return 0;
  494. }
  495. /**
  496. * hns_nic_self_test - self test
  497. * @dev: net device
  498. * @eth_test: test cmd
  499. * @data: test result
  500. */
  501. static void hns_nic_self_test(struct net_device *ndev,
  502. struct ethtool_test *eth_test, u64 *data)
  503. {
  504. struct hns_nic_priv *priv = netdev_priv(ndev);
  505. bool if_running = netif_running(ndev);
  506. #define SELF_TEST_TPYE_NUM 3
  507. int st_param[SELF_TEST_TPYE_NUM][2];
  508. int i;
  509. int test_index = 0;
  510. st_param[0][0] = MAC_INTERNALLOOP_MAC; /* XGE not supported lb */
  511. st_param[0][1] = (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII);
  512. st_param[1][0] = MAC_INTERNALLOOP_SERDES;
  513. st_param[1][1] = 1; /*serdes must exist*/
  514. st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/
  515. st_param[2][1] = ((!!(priv->ae_handle->phy_node)) &&
  516. (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII));
  517. if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
  518. set_bit(NIC_STATE_TESTING, &priv->state);
  519. if (if_running)
  520. (void)dev_close(ndev);
  521. for (i = 0; i < SELF_TEST_TPYE_NUM; i++) {
  522. if (!st_param[i][1])
  523. continue; /* NEXT testing */
  524. data[test_index] = __lb_up(ndev,
  525. (enum hnae_loop)st_param[i][0]);
  526. if (!data[test_index]) {
  527. data[test_index] = __lb_run_test(
  528. ndev, (enum hnae_loop)st_param[i][0]);
  529. (void)__lb_down(ndev);
  530. }
  531. if (data[test_index])
  532. eth_test->flags |= ETH_TEST_FL_FAILED;
  533. test_index++;
  534. }
  535. hns_nic_net_reset(priv->netdev);
  536. clear_bit(NIC_STATE_TESTING, &priv->state);
  537. if (if_running)
  538. (void)dev_open(ndev);
  539. }
  540. /* Online tests aren't run; pass by default */
  541. (void)msleep_interruptible(4 * 1000);
  542. }
  543. /**
  544. * hns_nic_get_drvinfo - get net driver info
  545. * @dev: net device
  546. * @drvinfo: driver info
  547. */
  548. static void hns_nic_get_drvinfo(struct net_device *net_dev,
  549. struct ethtool_drvinfo *drvinfo)
  550. {
  551. struct hns_nic_priv *priv = netdev_priv(net_dev);
  552. assert(priv);
  553. strncpy(drvinfo->version, HNAE_DRIVER_VERSION,
  554. sizeof(drvinfo->version));
  555. drvinfo->version[sizeof(drvinfo->version) - 1] = '\0';
  556. strncpy(drvinfo->driver, HNAE_DRIVER_NAME, sizeof(drvinfo->driver));
  557. drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
  558. strncpy(drvinfo->bus_info, priv->dev->bus->name,
  559. sizeof(drvinfo->bus_info));
  560. drvinfo->bus_info[ETHTOOL_BUSINFO_LEN - 1] = '\0';
  561. strncpy(drvinfo->fw_version, "N/A", ETHTOOL_FWVERS_LEN);
  562. }
  563. /**
  564. * hns_get_ringparam - get ring parameter
  565. * @dev: net device
  566. * @param: ethtool parameter
  567. */
  568. void hns_get_ringparam(struct net_device *net_dev,
  569. struct ethtool_ringparam *param)
  570. {
  571. struct hns_nic_priv *priv = netdev_priv(net_dev);
  572. struct hnae_ae_ops *ops;
  573. struct hnae_queue *queue;
  574. u32 uplimit = 0;
  575. queue = priv->ae_handle->qs[0];
  576. ops = priv->ae_handle->dev->ops;
  577. if (ops->get_ring_bdnum_limit)
  578. ops->get_ring_bdnum_limit(queue, &uplimit);
  579. param->rx_max_pending = uplimit;
  580. param->tx_max_pending = uplimit;
  581. param->rx_pending = queue->rx_ring.desc_num;
  582. param->tx_pending = queue->tx_ring.desc_num;
  583. }
  584. /**
  585. * hns_get_pauseparam - get pause parameter
  586. * @dev: net device
  587. * @param: pause parameter
  588. */
  589. static void hns_get_pauseparam(struct net_device *net_dev,
  590. struct ethtool_pauseparam *param)
  591. {
  592. struct hns_nic_priv *priv = netdev_priv(net_dev);
  593. struct hnae_ae_ops *ops;
  594. ops = priv->ae_handle->dev->ops;
  595. if (ops->get_pauseparam)
  596. ops->get_pauseparam(priv->ae_handle, &param->autoneg,
  597. &param->rx_pause, &param->tx_pause);
  598. }
  599. /**
  600. * hns_set_pauseparam - set pause parameter
  601. * @dev: net device
  602. * @param: pause parameter
  603. *
  604. * Return 0 on success, negative on failure
  605. */
  606. static int hns_set_pauseparam(struct net_device *net_dev,
  607. struct ethtool_pauseparam *param)
  608. {
  609. struct hns_nic_priv *priv = netdev_priv(net_dev);
  610. struct hnae_handle *h;
  611. struct hnae_ae_ops *ops;
  612. assert(priv || priv->ae_handle);
  613. h = priv->ae_handle;
  614. ops = h->dev->ops;
  615. if (!ops->set_pauseparam)
  616. return -ESRCH;
  617. return ops->set_pauseparam(priv->ae_handle, param->autoneg,
  618. param->rx_pause, param->tx_pause);
  619. }
  620. /**
  621. * hns_get_coalesce - get coalesce info.
  622. * @dev: net device
  623. * @ec: coalesce info.
  624. *
  625. * Return 0 on success, negative on failure.
  626. */
  627. static int hns_get_coalesce(struct net_device *net_dev,
  628. struct ethtool_coalesce *ec)
  629. {
  630. struct hns_nic_priv *priv = netdev_priv(net_dev);
  631. struct hnae_ae_ops *ops;
  632. ops = priv->ae_handle->dev->ops;
  633. ec->use_adaptive_rx_coalesce = 1;
  634. ec->use_adaptive_tx_coalesce = 1;
  635. if ((!ops->get_coalesce_usecs) ||
  636. (!ops->get_rx_max_coalesced_frames))
  637. return -ESRCH;
  638. ops->get_coalesce_usecs(priv->ae_handle,
  639. &ec->tx_coalesce_usecs,
  640. &ec->rx_coalesce_usecs);
  641. ops->get_rx_max_coalesced_frames(
  642. priv->ae_handle,
  643. &ec->tx_max_coalesced_frames,
  644. &ec->rx_max_coalesced_frames);
  645. return 0;
  646. }
  647. /**
  648. * hns_set_coalesce - set coalesce info.
  649. * @dev: net device
  650. * @ec: coalesce info.
  651. *
  652. * Return 0 on success, negative on failure.
  653. */
  654. static int hns_set_coalesce(struct net_device *net_dev,
  655. struct ethtool_coalesce *ec)
  656. {
  657. struct hns_nic_priv *priv = netdev_priv(net_dev);
  658. struct hnae_ae_ops *ops;
  659. int ret;
  660. assert(priv || priv->ae_handle);
  661. ops = priv->ae_handle->dev->ops;
  662. if (ec->tx_coalesce_usecs != ec->rx_coalesce_usecs)
  663. return -EINVAL;
  664. if (ec->rx_max_coalesced_frames != ec->tx_max_coalesced_frames)
  665. return -EINVAL;
  666. if ((!ops->set_coalesce_usecs) ||
  667. (!ops->set_coalesce_frames))
  668. return -ESRCH;
  669. ops->set_coalesce_usecs(priv->ae_handle,
  670. ec->rx_coalesce_usecs);
  671. ret = ops->set_coalesce_frames(
  672. priv->ae_handle,
  673. ec->rx_max_coalesced_frames);
  674. return ret;
  675. }
  676. /**
  677. * hns_get_channels - get channel info.
  678. * @dev: net device
  679. * @ch: channel info.
  680. */
  681. void hns_get_channels(struct net_device *net_dev, struct ethtool_channels *ch)
  682. {
  683. struct hns_nic_priv *priv = netdev_priv(net_dev);
  684. ch->max_rx = priv->ae_handle->q_num;
  685. ch->max_tx = priv->ae_handle->q_num;
  686. ch->rx_count = priv->ae_handle->q_num;
  687. ch->tx_count = priv->ae_handle->q_num;
  688. }
  689. /**
  690. * get_ethtool_stats - get detail statistics.
  691. * @dev: net device
  692. * @stats: statistics info.
  693. * @data: statistics data.
  694. */
  695. void hns_get_ethtool_stats(struct net_device *netdev,
  696. struct ethtool_stats *stats, u64 *data)
  697. {
  698. u64 *p = data;
  699. struct hns_nic_priv *priv = netdev_priv(netdev);
  700. struct hnae_handle *h = priv->ae_handle;
  701. const struct rtnl_link_stats64 *net_stats;
  702. struct rtnl_link_stats64 temp;
  703. if (!h->dev->ops->get_stats || !h->dev->ops->update_stats) {
  704. netdev_err(netdev, "get_stats or update_stats is null!\n");
  705. return;
  706. }
  707. h->dev->ops->update_stats(h, &netdev->stats);
  708. net_stats = dev_get_stats(netdev, &temp);
  709. /* get netdev statistics */
  710. p[0] = net_stats->rx_packets;
  711. p[1] = net_stats->tx_packets;
  712. p[2] = net_stats->rx_bytes;
  713. p[3] = net_stats->tx_bytes;
  714. p[4] = net_stats->rx_errors;
  715. p[5] = net_stats->tx_errors;
  716. p[6] = net_stats->rx_dropped;
  717. p[7] = net_stats->tx_dropped;
  718. p[8] = net_stats->multicast;
  719. p[9] = net_stats->collisions;
  720. p[10] = net_stats->rx_over_errors;
  721. p[11] = net_stats->rx_crc_errors;
  722. p[12] = net_stats->rx_frame_errors;
  723. p[13] = net_stats->rx_fifo_errors;
  724. p[14] = net_stats->rx_missed_errors;
  725. p[15] = net_stats->tx_aborted_errors;
  726. p[16] = net_stats->tx_carrier_errors;
  727. p[17] = net_stats->tx_fifo_errors;
  728. p[18] = net_stats->tx_heartbeat_errors;
  729. p[19] = net_stats->rx_length_errors;
  730. p[20] = net_stats->tx_window_errors;
  731. p[21] = net_stats->rx_compressed;
  732. p[22] = net_stats->tx_compressed;
  733. p[23] = netdev->rx_dropped.counter;
  734. p[24] = netdev->tx_dropped.counter;
  735. p[25] = priv->tx_timeout_count;
  736. /* get driver statistics */
  737. h->dev->ops->get_stats(h, &p[26]);
  738. }
  739. /**
  740. * get_strings: Return a set of strings that describe the requested objects
  741. * @dev: net device
  742. * @stats: string set ID.
  743. * @data: objects data.
  744. */
  745. void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
  746. {
  747. struct hns_nic_priv *priv = netdev_priv(netdev);
  748. struct hnae_handle *h = priv->ae_handle;
  749. char *buff = (char *)data;
  750. if (!h->dev->ops->get_strings) {
  751. netdev_err(netdev, "h->dev->ops->get_strings is null!\n");
  752. return;
  753. }
  754. if (stringset == ETH_SS_TEST) {
  755. if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII) {
  756. memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_MAC],
  757. ETH_GSTRING_LEN);
  758. buff += ETH_GSTRING_LEN;
  759. }
  760. memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_SERDES],
  761. ETH_GSTRING_LEN);
  762. buff += ETH_GSTRING_LEN;
  763. if ((priv->phy) && (!priv->phy->is_c45))
  764. memcpy(buff, hns_nic_test_strs[MAC_INTERNALLOOP_PHY],
  765. ETH_GSTRING_LEN);
  766. } else {
  767. snprintf(buff, ETH_GSTRING_LEN, "rx_packets");
  768. buff = buff + ETH_GSTRING_LEN;
  769. snprintf(buff, ETH_GSTRING_LEN, "tx_packets");
  770. buff = buff + ETH_GSTRING_LEN;
  771. snprintf(buff, ETH_GSTRING_LEN, "rx_bytes");
  772. buff = buff + ETH_GSTRING_LEN;
  773. snprintf(buff, ETH_GSTRING_LEN, "tx_bytes");
  774. buff = buff + ETH_GSTRING_LEN;
  775. snprintf(buff, ETH_GSTRING_LEN, "rx_errors");
  776. buff = buff + ETH_GSTRING_LEN;
  777. snprintf(buff, ETH_GSTRING_LEN, "tx_errors");
  778. buff = buff + ETH_GSTRING_LEN;
  779. snprintf(buff, ETH_GSTRING_LEN, "rx_dropped");
  780. buff = buff + ETH_GSTRING_LEN;
  781. snprintf(buff, ETH_GSTRING_LEN, "tx_dropped");
  782. buff = buff + ETH_GSTRING_LEN;
  783. snprintf(buff, ETH_GSTRING_LEN, "multicast");
  784. buff = buff + ETH_GSTRING_LEN;
  785. snprintf(buff, ETH_GSTRING_LEN, "collisions");
  786. buff = buff + ETH_GSTRING_LEN;
  787. snprintf(buff, ETH_GSTRING_LEN, "rx_over_errors");
  788. buff = buff + ETH_GSTRING_LEN;
  789. snprintf(buff, ETH_GSTRING_LEN, "rx_crc_errors");
  790. buff = buff + ETH_GSTRING_LEN;
  791. snprintf(buff, ETH_GSTRING_LEN, "rx_frame_errors");
  792. buff = buff + ETH_GSTRING_LEN;
  793. snprintf(buff, ETH_GSTRING_LEN, "rx_fifo_errors");
  794. buff = buff + ETH_GSTRING_LEN;
  795. snprintf(buff, ETH_GSTRING_LEN, "rx_missed_errors");
  796. buff = buff + ETH_GSTRING_LEN;
  797. snprintf(buff, ETH_GSTRING_LEN, "tx_aborted_errors");
  798. buff = buff + ETH_GSTRING_LEN;
  799. snprintf(buff, ETH_GSTRING_LEN, "tx_carrier_errors");
  800. buff = buff + ETH_GSTRING_LEN;
  801. snprintf(buff, ETH_GSTRING_LEN, "tx_fifo_errors");
  802. buff = buff + ETH_GSTRING_LEN;
  803. snprintf(buff, ETH_GSTRING_LEN, "tx_heartbeat_errors");
  804. buff = buff + ETH_GSTRING_LEN;
  805. snprintf(buff, ETH_GSTRING_LEN, "rx_length_errors");
  806. buff = buff + ETH_GSTRING_LEN;
  807. snprintf(buff, ETH_GSTRING_LEN, "tx_window_errors");
  808. buff = buff + ETH_GSTRING_LEN;
  809. snprintf(buff, ETH_GSTRING_LEN, "rx_compressed");
  810. buff = buff + ETH_GSTRING_LEN;
  811. snprintf(buff, ETH_GSTRING_LEN, "tx_compressed");
  812. buff = buff + ETH_GSTRING_LEN;
  813. snprintf(buff, ETH_GSTRING_LEN, "netdev_rx_dropped");
  814. buff = buff + ETH_GSTRING_LEN;
  815. snprintf(buff, ETH_GSTRING_LEN, "netdev_tx_dropped");
  816. buff = buff + ETH_GSTRING_LEN;
  817. snprintf(buff, ETH_GSTRING_LEN, "netdev_tx_timeout");
  818. buff = buff + ETH_GSTRING_LEN;
  819. h->dev->ops->get_strings(h, stringset, (u8 *)buff);
  820. }
  821. }
  822. /**
  823. * nic_get_sset_count - get string set count witch returned by nic_get_strings.
  824. * @dev: net device
  825. * @stringset: string set index, 0: self test string; 1: statistics string.
  826. *
  827. * Return string set count.
  828. */
  829. int hns_get_sset_count(struct net_device *netdev, int stringset)
  830. {
  831. struct hns_nic_priv *priv = netdev_priv(netdev);
  832. struct hnae_handle *h = priv->ae_handle;
  833. struct hnae_ae_ops *ops = h->dev->ops;
  834. if (!ops->get_sset_count) {
  835. netdev_err(netdev, "get_sset_count is null!\n");
  836. return -EOPNOTSUPP;
  837. }
  838. if (stringset == ETH_SS_TEST) {
  839. u32 cnt = (sizeof(hns_nic_test_strs) / ETH_GSTRING_LEN);
  840. if (priv->ae_handle->phy_if == PHY_INTERFACE_MODE_XGMII)
  841. cnt--;
  842. if ((!priv->phy) || (priv->phy->is_c45))
  843. cnt--;
  844. return cnt;
  845. } else if (stringset == ETH_SS_STATS) {
  846. return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset));
  847. } else {
  848. return -EOPNOTSUPP;
  849. }
  850. }
  851. /**
  852. * hns_phy_led_set - set phy LED status.
  853. * @dev: net device
  854. * @value: LED state.
  855. *
  856. * Return 0 on success, negative on failure.
  857. */
  858. int hns_phy_led_set(struct net_device *netdev, int value)
  859. {
  860. int retval;
  861. struct hns_nic_priv *priv = netdev_priv(netdev);
  862. struct phy_device *phy_dev = priv->phy;
  863. if (!phy_dev->bus) {
  864. netdev_err(netdev, "phy_dev->bus is null!\n");
  865. return -EINVAL;
  866. }
  867. retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
  868. HNS_PHY_PAGE_REG, HNS_PHY_PAGE_LED);
  869. retval = mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_LED_FC_REG,
  870. value);
  871. retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
  872. HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
  873. if (retval) {
  874. netdev_err(netdev, "mdiobus_write fail !\n");
  875. return retval;
  876. }
  877. return 0;
  878. }
  879. /**
  880. * nic_set_phys_id - set phy identify LED.
  881. * @dev: net device
  882. * @state: LED state.
  883. *
  884. * Return 0 on success, negative on failure.
  885. */
  886. int hns_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
  887. {
  888. struct hns_nic_priv *priv = netdev_priv(netdev);
  889. struct hnae_handle *h = priv->ae_handle;
  890. struct phy_device *phy_dev = priv->phy;
  891. int ret;
  892. if (phy_dev)
  893. switch (state) {
  894. case ETHTOOL_ID_ACTIVE:
  895. ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
  896. HNS_PHY_PAGE_REG,
  897. HNS_PHY_PAGE_LED);
  898. if (ret)
  899. return ret;
  900. priv->phy_led_val = (u16)mdiobus_read(phy_dev->bus,
  901. phy_dev->addr,
  902. HNS_LED_FC_REG);
  903. ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
  904. HNS_PHY_PAGE_REG,
  905. HNS_PHY_PAGE_COPPER);
  906. if (ret)
  907. return ret;
  908. return 2;
  909. case ETHTOOL_ID_ON:
  910. ret = hns_phy_led_set(netdev, HNS_LED_FORCE_ON);
  911. if (ret)
  912. return ret;
  913. break;
  914. case ETHTOOL_ID_OFF:
  915. ret = hns_phy_led_set(netdev, HNS_LED_FORCE_OFF);
  916. if (ret)
  917. return ret;
  918. break;
  919. case ETHTOOL_ID_INACTIVE:
  920. ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
  921. HNS_PHY_PAGE_REG,
  922. HNS_PHY_PAGE_LED);
  923. if (ret)
  924. return ret;
  925. ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
  926. HNS_LED_FC_REG, priv->phy_led_val);
  927. if (ret)
  928. return ret;
  929. ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
  930. HNS_PHY_PAGE_REG,
  931. HNS_PHY_PAGE_COPPER);
  932. if (ret)
  933. return ret;
  934. break;
  935. default:
  936. return -EINVAL;
  937. }
  938. else
  939. switch (state) {
  940. case ETHTOOL_ID_ACTIVE:
  941. return h->dev->ops->set_led_id(h, HNAE_LED_ACTIVE);
  942. case ETHTOOL_ID_ON:
  943. return h->dev->ops->set_led_id(h, HNAE_LED_ON);
  944. case ETHTOOL_ID_OFF:
  945. return h->dev->ops->set_led_id(h, HNAE_LED_OFF);
  946. case ETHTOOL_ID_INACTIVE:
  947. return h->dev->ops->set_led_id(h, HNAE_LED_INACTIVE);
  948. default:
  949. return -EINVAL;
  950. }
  951. return 0;
  952. }
  953. /**
  954. * hns_get_regs - get net device register
  955. * @dev: net device
  956. * @cmd: ethtool cmd
  957. * @date: register data
  958. */
  959. void hns_get_regs(struct net_device *net_dev, struct ethtool_regs *cmd,
  960. void *data)
  961. {
  962. struct hns_nic_priv *priv = netdev_priv(net_dev);
  963. struct hnae_ae_ops *ops;
  964. assert(priv || priv->ae_handle);
  965. ops = priv->ae_handle->dev->ops;
  966. cmd->version = HNS_CHIP_VERSION;
  967. if (!ops->get_regs) {
  968. netdev_err(net_dev, "ops->get_regs is null!\n");
  969. return;
  970. }
  971. ops->get_regs(priv->ae_handle, data);
  972. }
  973. /**
  974. * nic_get_regs_len - get total register len.
  975. * @dev: net device
  976. *
  977. * Return total register len.
  978. */
  979. static int hns_get_regs_len(struct net_device *net_dev)
  980. {
  981. u32 reg_num;
  982. struct hns_nic_priv *priv = netdev_priv(net_dev);
  983. struct hnae_ae_ops *ops;
  984. assert(priv || priv->ae_handle);
  985. ops = priv->ae_handle->dev->ops;
  986. if (!ops->get_regs_len) {
  987. netdev_err(net_dev, "ops->get_regs_len is null!\n");
  988. return -EOPNOTSUPP;
  989. }
  990. reg_num = ops->get_regs_len(priv->ae_handle);
  991. if (reg_num > 0)
  992. return reg_num * sizeof(u32);
  993. else
  994. return reg_num; /* error code */
  995. }
  996. /**
  997. * hns_nic_nway_reset - nway reset
  998. * @dev: net device
  999. *
  1000. * Return 0 on success, negative on failure
  1001. */
  1002. static int hns_nic_nway_reset(struct net_device *netdev)
  1003. {
  1004. int ret = 0;
  1005. struct hns_nic_priv *priv = netdev_priv(netdev);
  1006. struct phy_device *phy = priv->phy;
  1007. if (netif_running(netdev)) {
  1008. if (phy)
  1009. ret = genphy_restart_aneg(phy);
  1010. }
  1011. return ret;
  1012. }
  1013. static struct ethtool_ops hns_ethtool_ops = {
  1014. .get_drvinfo = hns_nic_get_drvinfo,
  1015. .get_link = hns_nic_get_link,
  1016. .get_settings = hns_nic_get_settings,
  1017. .set_settings = hns_nic_set_settings,
  1018. .get_ringparam = hns_get_ringparam,
  1019. .get_pauseparam = hns_get_pauseparam,
  1020. .set_pauseparam = hns_set_pauseparam,
  1021. .get_coalesce = hns_get_coalesce,
  1022. .set_coalesce = hns_set_coalesce,
  1023. .get_channels = hns_get_channels,
  1024. .self_test = hns_nic_self_test,
  1025. .get_strings = hns_get_strings,
  1026. .get_sset_count = hns_get_sset_count,
  1027. .get_ethtool_stats = hns_get_ethtool_stats,
  1028. .set_phys_id = hns_set_phys_id,
  1029. .get_regs_len = hns_get_regs_len,
  1030. .get_regs = hns_get_regs,
  1031. .nway_reset = hns_nic_nway_reset,
  1032. };
  1033. void hns_ethtool_set_ops(struct net_device *ndev)
  1034. {
  1035. ndev->ethtool_ops = &hns_ethtool_ops;
  1036. }