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