1 // SPDX-License-Identifier: GPL-2.0
2 /* Huawei HiNIC PCI Express Linux driver
3  * Copyright(c) 2017 Huawei Technologies Co., Ltd
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/pci.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include <linux/types.h>
21 #include <linux/errno.h>
22 #include <linux/interrupt.h>
23 #include <linux/etherdevice.h>
24 #include <linux/netdevice.h>
25 #include <linux/if_vlan.h>
26 #include <linux/ethtool.h>
27 #include <linux/vmalloc.h>
28 
29 #include "hinic_hw_qp.h"
30 #include "hinic_hw_dev.h"
31 #include "hinic_port.h"
32 #include "hinic_tx.h"
33 #include "hinic_rx.h"
34 #include "hinic_dev.h"
35 
36 #define SET_LINK_STR_MAX_LEN	128
37 
38 #define GET_SUPPORTED_MODE	0
39 #define GET_ADVERTISED_MODE	1
40 
41 #define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode)	\
42 		((ecmd)->supported |=	\
43 		(1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit))
44 #define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode)	\
45 		((ecmd)->advertising |=	\
46 		(1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit))
47 #define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode)	\
48 				((ecmd)->supported |= SUPPORTED_##mode)
49 #define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode)	\
50 				((ecmd)->advertising |= ADVERTISED_##mode)
51 
52 struct hw2ethtool_link_mode {
53 	enum ethtool_link_mode_bit_indices link_mode_bit;
54 	u32 speed;
55 	enum hinic_link_mode hw_link_mode;
56 };
57 
58 struct cmd_link_settings {
59 	u64	supported;
60 	u64	advertising;
61 
62 	u32	speed;
63 	u8	duplex;
64 	u8	port;
65 	u8	autoneg;
66 };
67 
68 static u32 hw_to_ethtool_speed[LINK_SPEED_LEVELS] = {
69 	SPEED_10, SPEED_100,
70 	SPEED_1000, SPEED_10000,
71 	SPEED_25000, SPEED_40000,
72 	SPEED_100000
73 };
74 
75 static struct hw2ethtool_link_mode
76 	hw_to_ethtool_link_mode_table[HINIC_LINK_MODE_NUMBERS] = {
77 	{
78 		.link_mode_bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
79 		.speed = SPEED_10000,
80 		.hw_link_mode = HINIC_10GE_BASE_KR,
81 	},
82 	{
83 		.link_mode_bit = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
84 		.speed = SPEED_40000,
85 		.hw_link_mode = HINIC_40GE_BASE_KR4,
86 	},
87 	{
88 		.link_mode_bit = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
89 		.speed = SPEED_40000,
90 		.hw_link_mode = HINIC_40GE_BASE_CR4,
91 	},
92 	{
93 		.link_mode_bit = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
94 		.speed = SPEED_100000,
95 		.hw_link_mode = HINIC_100GE_BASE_KR4,
96 	},
97 	{
98 		.link_mode_bit = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
99 		.speed = SPEED_100000,
100 		.hw_link_mode = HINIC_100GE_BASE_CR4,
101 	},
102 	{
103 		.link_mode_bit = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
104 		.speed = SPEED_25000,
105 		.hw_link_mode = HINIC_25GE_BASE_KR_S,
106 	},
107 	{
108 		.link_mode_bit = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
109 		.speed = SPEED_25000,
110 		.hw_link_mode = HINIC_25GE_BASE_CR_S,
111 	},
112 	{
113 		.link_mode_bit = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
114 		.speed = SPEED_25000,
115 		.hw_link_mode = HINIC_25GE_BASE_KR,
116 	},
117 	{
118 		.link_mode_bit = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
119 		.speed = SPEED_25000,
120 		.hw_link_mode = HINIC_25GE_BASE_CR,
121 	},
122 	{
123 		.link_mode_bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
124 		.speed = SPEED_1000,
125 		.hw_link_mode = HINIC_GE_BASE_KX,
126 	},
127 };
128 
129 static void set_link_speed(struct ethtool_link_ksettings *link_ksettings,
130 			   enum hinic_speed speed)
131 {
132 	switch (speed) {
133 	case HINIC_SPEED_10MB_LINK:
134 		link_ksettings->base.speed = SPEED_10;
135 		break;
136 
137 	case HINIC_SPEED_100MB_LINK:
138 		link_ksettings->base.speed = SPEED_100;
139 		break;
140 
141 	case HINIC_SPEED_1000MB_LINK:
142 		link_ksettings->base.speed = SPEED_1000;
143 		break;
144 
145 	case HINIC_SPEED_10GB_LINK:
146 		link_ksettings->base.speed = SPEED_10000;
147 		break;
148 
149 	case HINIC_SPEED_25GB_LINK:
150 		link_ksettings->base.speed = SPEED_25000;
151 		break;
152 
153 	case HINIC_SPEED_40GB_LINK:
154 		link_ksettings->base.speed = SPEED_40000;
155 		break;
156 
157 	case HINIC_SPEED_100GB_LINK:
158 		link_ksettings->base.speed = SPEED_100000;
159 		break;
160 
161 	default:
162 		link_ksettings->base.speed = SPEED_UNKNOWN;
163 		break;
164 	}
165 }
166 
167 static int hinic_get_link_mode_index(enum hinic_link_mode link_mode)
168 {
169 	int i = 0;
170 
171 	for (i = 0; i < HINIC_LINK_MODE_NUMBERS; i++) {
172 		if (link_mode == hw_to_ethtool_link_mode_table[i].hw_link_mode)
173 			break;
174 	}
175 
176 	return i;
177 }
178 
179 static void hinic_add_ethtool_link_mode(struct cmd_link_settings *link_settings,
180 					enum hinic_link_mode hw_link_mode,
181 					u32 name)
182 {
183 	enum hinic_link_mode link_mode;
184 	int idx = 0;
185 
186 	for (link_mode = 0; link_mode < HINIC_LINK_MODE_NUMBERS; link_mode++) {
187 		if (hw_link_mode & ((u32)1 << link_mode)) {
188 			idx = hinic_get_link_mode_index(link_mode);
189 			if (idx >= HINIC_LINK_MODE_NUMBERS)
190 				continue;
191 
192 			if (name == GET_SUPPORTED_MODE)
193 				ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE
194 					(link_settings, idx);
195 			else
196 				ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE
197 					(link_settings, idx);
198 		}
199 	}
200 }
201 
202 static void hinic_link_port_type(struct cmd_link_settings *link_settings,
203 				 enum hinic_port_type port_type)
204 {
205 	switch (port_type) {
206 	case HINIC_PORT_ELEC:
207 	case HINIC_PORT_TP:
208 		ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP);
209 		ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP);
210 		link_settings->port = PORT_TP;
211 		break;
212 
213 	case HINIC_PORT_AOC:
214 	case HINIC_PORT_FIBRE:
215 		ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
216 		ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
217 		link_settings->port = PORT_FIBRE;
218 		break;
219 
220 	case HINIC_PORT_COPPER:
221 		ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE);
222 		ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE);
223 		link_settings->port = PORT_DA;
224 		break;
225 
226 	case HINIC_PORT_BACKPLANE:
227 		ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane);
228 		ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane);
229 		link_settings->port = PORT_NONE;
230 		break;
231 
232 	default:
233 		link_settings->port = PORT_OTHER;
234 		break;
235 	}
236 }
237 
238 static int hinic_get_link_ksettings(struct net_device *netdev,
239 				    struct ethtool_link_ksettings
240 				    *link_ksettings)
241 {
242 	struct hinic_dev *nic_dev = netdev_priv(netdev);
243 	struct hinic_link_mode_cmd link_mode = { 0 };
244 	struct hinic_pause_config pause_info = { 0 };
245 	struct cmd_link_settings settings = { 0 };
246 	enum hinic_port_link_state link_state;
247 	struct hinic_port_cap port_cap;
248 	int err;
249 
250 	ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
251 	ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
252 
253 	link_ksettings->base.speed = SPEED_UNKNOWN;
254 	link_ksettings->base.autoneg = AUTONEG_DISABLE;
255 	link_ksettings->base.duplex = DUPLEX_UNKNOWN;
256 
257 	err = hinic_port_get_cap(nic_dev, &port_cap);
258 	if (err)
259 		return err;
260 
261 	hinic_link_port_type(&settings, port_cap.port_type);
262 	link_ksettings->base.port = settings.port;
263 
264 	err = hinic_port_link_state(nic_dev, &link_state);
265 	if (err)
266 		return err;
267 
268 	if (link_state == HINIC_LINK_STATE_UP) {
269 		set_link_speed(link_ksettings, port_cap.speed);
270 		link_ksettings->base.duplex =
271 			(port_cap.duplex == HINIC_DUPLEX_FULL) ?
272 			DUPLEX_FULL : DUPLEX_HALF;
273 	}
274 
275 	if (!!(port_cap.autoneg_cap & HINIC_AUTONEG_SUPPORTED))
276 		ethtool_link_ksettings_add_link_mode(link_ksettings,
277 						     advertising, Autoneg);
278 
279 	if (port_cap.autoneg_state == HINIC_AUTONEG_ACTIVE)
280 		link_ksettings->base.autoneg = AUTONEG_ENABLE;
281 
282 	err = hinic_get_link_mode(nic_dev->hwdev, &link_mode);
283 	if (err || link_mode.supported == HINIC_SUPPORTED_UNKNOWN ||
284 	    link_mode.advertised == HINIC_SUPPORTED_UNKNOWN)
285 		return -EIO;
286 
287 	hinic_add_ethtool_link_mode(&settings, link_mode.supported,
288 				    GET_SUPPORTED_MODE);
289 	hinic_add_ethtool_link_mode(&settings, link_mode.advertised,
290 				    GET_ADVERTISED_MODE);
291 
292 	if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) {
293 		err = hinic_get_hw_pause_info(nic_dev->hwdev, &pause_info);
294 		if (err)
295 			return err;
296 		ETHTOOL_ADD_SUPPORTED_LINK_MODE(&settings, Pause);
297 		if (pause_info.rx_pause && pause_info.tx_pause) {
298 			ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Pause);
299 		} else if (pause_info.tx_pause) {
300 			ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Asym_Pause);
301 		} else if (pause_info.rx_pause) {
302 			ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Pause);
303 			ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Asym_Pause);
304 		}
305 	}
306 
307 	bitmap_copy(link_ksettings->link_modes.supported,
308 		    (unsigned long *)&settings.supported,
309 		    __ETHTOOL_LINK_MODE_MASK_NBITS);
310 	bitmap_copy(link_ksettings->link_modes.advertising,
311 		    (unsigned long *)&settings.advertising,
312 		    __ETHTOOL_LINK_MODE_MASK_NBITS);
313 
314 	return 0;
315 }
316 
317 static int hinic_ethtool_to_hw_speed_level(u32 speed)
318 {
319 	int i;
320 
321 	for (i = 0; i < LINK_SPEED_LEVELS; i++) {
322 		if (hw_to_ethtool_speed[i] == speed)
323 			break;
324 	}
325 
326 	return i;
327 }
328 
329 static bool hinic_is_support_speed(enum hinic_link_mode supported_link,
330 				   u32 speed)
331 {
332 	enum hinic_link_mode link_mode;
333 	int idx;
334 
335 	for (link_mode = 0; link_mode < HINIC_LINK_MODE_NUMBERS; link_mode++) {
336 		if (!(supported_link & ((u32)1 << link_mode)))
337 			continue;
338 
339 		idx = hinic_get_link_mode_index(link_mode);
340 		if (idx >= HINIC_LINK_MODE_NUMBERS)
341 			continue;
342 
343 		if (hw_to_ethtool_link_mode_table[idx].speed == speed)
344 			return true;
345 	}
346 
347 	return false;
348 }
349 
350 static bool hinic_is_speed_legal(struct hinic_dev *nic_dev, u32 speed)
351 {
352 	struct hinic_link_mode_cmd link_mode = { 0 };
353 	struct net_device *netdev = nic_dev->netdev;
354 	enum nic_speed_level speed_level = 0;
355 	int err;
356 
357 	err = hinic_get_link_mode(nic_dev->hwdev, &link_mode);
358 	if (err)
359 		return false;
360 
361 	if (link_mode.supported == HINIC_SUPPORTED_UNKNOWN ||
362 	    link_mode.advertised == HINIC_SUPPORTED_UNKNOWN)
363 		return false;
364 
365 	speed_level = hinic_ethtool_to_hw_speed_level(speed);
366 	if (speed_level >= LINK_SPEED_LEVELS ||
367 	    !hinic_is_support_speed(link_mode.supported, speed)) {
368 		netif_err(nic_dev, drv, netdev,
369 			  "Unsupported speed: %d\n", speed);
370 		return false;
371 	}
372 
373 	return true;
374 }
375 
376 static int get_link_settings_type(struct hinic_dev *nic_dev,
377 				  u8 autoneg, u32 speed, u32 *set_settings)
378 {
379 	struct hinic_port_cap port_cap = { 0 };
380 	int err;
381 
382 	err = hinic_port_get_cap(nic_dev, &port_cap);
383 	if (err)
384 		return err;
385 
386 	/* always set autonegotiation */
387 	if (port_cap.autoneg_cap)
388 		*set_settings |= HILINK_LINK_SET_AUTONEG;
389 
390 	if (autoneg == AUTONEG_ENABLE) {
391 		if (!port_cap.autoneg_cap) {
392 			netif_err(nic_dev, drv, nic_dev->netdev, "Not support autoneg\n");
393 			return -EOPNOTSUPP;
394 		}
395 	} else if (speed != (u32)SPEED_UNKNOWN) {
396 		/* set speed only when autoneg is disabled */
397 		if (!hinic_is_speed_legal(nic_dev, speed))
398 			return -EINVAL;
399 		*set_settings |= HILINK_LINK_SET_SPEED;
400 	} else {
401 		netif_err(nic_dev, drv, nic_dev->netdev, "Need to set speed when autoneg is off\n");
402 		return -EOPNOTSUPP;
403 	}
404 
405 	return 0;
406 }
407 
408 static int set_link_settings_separate_cmd(struct hinic_dev *nic_dev,
409 					  u32 set_settings, u8 autoneg,
410 					  u32 speed)
411 {
412 	enum nic_speed_level speed_level = 0;
413 	int err = 0;
414 
415 	if (set_settings & HILINK_LINK_SET_AUTONEG) {
416 		err = hinic_set_autoneg(nic_dev->hwdev,
417 					(autoneg == AUTONEG_ENABLE));
418 		if (err)
419 			netif_err(nic_dev, drv, nic_dev->netdev, "%s autoneg failed\n",
420 				  (autoneg == AUTONEG_ENABLE) ?
421 				  "Enable" : "Disable");
422 		else
423 			netif_info(nic_dev, drv, nic_dev->netdev, "%s autoneg successfully\n",
424 				   (autoneg == AUTONEG_ENABLE) ?
425 				   "Enable" : "Disable");
426 	}
427 
428 	if (!err && (set_settings & HILINK_LINK_SET_SPEED)) {
429 		speed_level = hinic_ethtool_to_hw_speed_level(speed);
430 		err = hinic_set_speed(nic_dev->hwdev, speed_level);
431 		if (err)
432 			netif_err(nic_dev, drv, nic_dev->netdev, "Set speed %d failed\n",
433 				  speed);
434 		else
435 			netif_info(nic_dev, drv, nic_dev->netdev, "Set speed %d successfully\n",
436 				   speed);
437 	}
438 
439 	return err;
440 }
441 
442 static int hinic_set_settings_to_hw(struct hinic_dev *nic_dev,
443 				    u32 set_settings, u8 autoneg, u32 speed)
444 {
445 	struct hinic_link_ksettings_info settings = {0};
446 	char set_link_str[SET_LINK_STR_MAX_LEN] = {0};
447 	struct net_device *netdev = nic_dev->netdev;
448 	enum nic_speed_level speed_level = 0;
449 	int err;
450 
451 	err = snprintf(set_link_str, SET_LINK_STR_MAX_LEN, "%s",
452 		       (set_settings & HILINK_LINK_SET_AUTONEG) ?
453 		       (autoneg ? "autong enable " : "autong disable ") : "");
454 	if (err < 0 || err >= SET_LINK_STR_MAX_LEN) {
455 		netif_err(nic_dev, drv, netdev, "Failed to snprintf link state, function return(%d) and dest_len(%d)\n",
456 			  err, SET_LINK_STR_MAX_LEN);
457 		return -EFAULT;
458 	}
459 
460 	if (set_settings & HILINK_LINK_SET_SPEED) {
461 		speed_level = hinic_ethtool_to_hw_speed_level(speed);
462 		err = snprintf(set_link_str, SET_LINK_STR_MAX_LEN,
463 			       "%sspeed %d ", set_link_str, speed);
464 		if (err <= 0 || err >= SET_LINK_STR_MAX_LEN) {
465 			netif_err(nic_dev, drv, netdev, "Failed to snprintf link speed, function return(%d) and dest_len(%d)\n",
466 				  err, SET_LINK_STR_MAX_LEN);
467 			return -EFAULT;
468 		}
469 	}
470 
471 	settings.func_id = HINIC_HWIF_FUNC_IDX(nic_dev->hwdev->hwif);
472 	settings.valid_bitmap = set_settings;
473 	settings.autoneg = autoneg;
474 	settings.speed = speed_level;
475 
476 	err = hinic_set_link_settings(nic_dev->hwdev, &settings);
477 	if (err != HINIC_MGMT_CMD_UNSUPPORTED) {
478 		if (err)
479 			netif_err(nic_dev, drv, netdev, "Set %s failed\n",
480 				  set_link_str);
481 		else
482 			netif_info(nic_dev, drv, netdev, "Set %s successfully\n",
483 				   set_link_str);
484 
485 		return err;
486 	}
487 
488 	return set_link_settings_separate_cmd(nic_dev, set_settings, autoneg,
489 					      speed);
490 }
491 
492 static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed)
493 {
494 	struct hinic_dev *nic_dev = netdev_priv(netdev);
495 	u32 set_settings = 0;
496 	int err;
497 
498 	err = get_link_settings_type(nic_dev, autoneg, speed, &set_settings);
499 	if (err)
500 		return err;
501 
502 	if (set_settings)
503 		err = hinic_set_settings_to_hw(nic_dev, set_settings,
504 					       autoneg, speed);
505 	else
506 		netif_info(nic_dev, drv, netdev, "Nothing changed, exit without setting anything\n");
507 
508 	return err;
509 }
510 
511 static int hinic_set_link_ksettings(struct net_device *netdev, const struct
512 				    ethtool_link_ksettings *link_settings)
513 {
514 	/* only support to set autoneg and speed */
515 	return set_link_settings(netdev, link_settings->base.autoneg,
516 				 link_settings->base.speed);
517 }
518 
519 static void hinic_get_drvinfo(struct net_device *netdev,
520 			      struct ethtool_drvinfo *info)
521 {
522 	struct hinic_dev *nic_dev = netdev_priv(netdev);
523 	u8 mgmt_ver[HINIC_MGMT_VERSION_MAX_LEN] = {0};
524 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
525 	struct hinic_hwif *hwif = hwdev->hwif;
526 	int err;
527 
528 	strlcpy(info->driver, HINIC_DRV_NAME, sizeof(info->driver));
529 	strlcpy(info->bus_info, pci_name(hwif->pdev), sizeof(info->bus_info));
530 
531 	err = hinic_get_mgmt_version(nic_dev, mgmt_ver);
532 	if (err)
533 		return;
534 
535 	snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver);
536 }
537 
538 static void hinic_get_ringparam(struct net_device *netdev,
539 				struct ethtool_ringparam *ring)
540 {
541 	struct hinic_dev *nic_dev = netdev_priv(netdev);
542 
543 	ring->rx_max_pending = HINIC_MAX_QUEUE_DEPTH;
544 	ring->tx_max_pending = HINIC_MAX_QUEUE_DEPTH;
545 	ring->rx_pending = nic_dev->rq_depth;
546 	ring->tx_pending = nic_dev->sq_depth;
547 }
548 
549 static int check_ringparam_valid(struct hinic_dev *nic_dev,
550 				 struct ethtool_ringparam *ring)
551 {
552 	if (ring->rx_jumbo_pending || ring->rx_mini_pending) {
553 		netif_err(nic_dev, drv, nic_dev->netdev,
554 			  "Unsupported rx_jumbo_pending/rx_mini_pending\n");
555 		return -EINVAL;
556 	}
557 
558 	if (ring->tx_pending > HINIC_MAX_QUEUE_DEPTH ||
559 	    ring->tx_pending < HINIC_MIN_QUEUE_DEPTH ||
560 	    ring->rx_pending > HINIC_MAX_QUEUE_DEPTH ||
561 	    ring->rx_pending < HINIC_MIN_QUEUE_DEPTH) {
562 		netif_err(nic_dev, drv, nic_dev->netdev,
563 			  "Queue depth out of range [%d-%d]\n",
564 			  HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH);
565 		return -EINVAL;
566 	}
567 
568 	return 0;
569 }
570 
571 static int hinic_set_ringparam(struct net_device *netdev,
572 			       struct ethtool_ringparam *ring)
573 {
574 	struct hinic_dev *nic_dev = netdev_priv(netdev);
575 	u16 new_sq_depth, new_rq_depth;
576 	int err;
577 
578 	err = check_ringparam_valid(nic_dev, ring);
579 	if (err)
580 		return err;
581 
582 	new_sq_depth = (u16)(1U << (u16)ilog2(ring->tx_pending));
583 	new_rq_depth = (u16)(1U << (u16)ilog2(ring->rx_pending));
584 
585 	if (new_sq_depth == nic_dev->sq_depth &&
586 	    new_rq_depth == nic_dev->rq_depth)
587 		return 0;
588 
589 	netif_info(nic_dev, drv, netdev,
590 		   "Change Tx/Rx ring depth from %d/%d to %d/%d\n",
591 		   nic_dev->sq_depth, nic_dev->rq_depth,
592 		   new_sq_depth, new_rq_depth);
593 
594 	nic_dev->sq_depth = new_sq_depth;
595 	nic_dev->rq_depth = new_rq_depth;
596 
597 	if (netif_running(netdev)) {
598 		netif_info(nic_dev, drv, netdev, "Restarting netdev\n");
599 		err = hinic_close(netdev);
600 		if (err) {
601 			netif_err(nic_dev, drv, netdev,
602 				  "Failed to close netdev\n");
603 			return -EFAULT;
604 		}
605 
606 		err = hinic_open(netdev);
607 		if (err) {
608 			netif_err(nic_dev, drv, netdev,
609 				  "Failed to open netdev\n");
610 			return -EFAULT;
611 		}
612 	}
613 
614 	return 0;
615 }
616 static void hinic_get_channels(struct net_device *netdev,
617 			       struct ethtool_channels *channels)
618 {
619 	struct hinic_dev *nic_dev = netdev_priv(netdev);
620 	struct hinic_hwdev *hwdev = nic_dev->hwdev;
621 
622 	channels->max_combined = nic_dev->max_qps;
623 	channels->combined_count = hinic_hwdev_num_qps(hwdev);
624 }
625 
626 static int hinic_set_channels(struct net_device *netdev,
627 			      struct ethtool_channels *channels)
628 {
629 	struct hinic_dev *nic_dev = netdev_priv(netdev);
630 	unsigned int count = channels->combined_count;
631 	int err;
632 
633 	netif_info(nic_dev, drv, netdev, "Set max combined queue number from %d to %d\n",
634 		   hinic_hwdev_num_qps(nic_dev->hwdev), count);
635 
636 	if (netif_running(netdev)) {
637 		netif_info(nic_dev, drv, netdev, "Restarting netdev\n");
638 		hinic_close(netdev);
639 
640 		nic_dev->hwdev->nic_cap.num_qps = count;
641 
642 		err = hinic_open(netdev);
643 		if (err) {
644 			netif_err(nic_dev, drv, netdev,
645 				  "Failed to open netdev\n");
646 			return -EFAULT;
647 		}
648 	} else {
649 		nic_dev->hwdev->nic_cap.num_qps = count;
650 	}
651 
652 	return 0;
653 }
654 
655 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev,
656 				   struct ethtool_rxnfc *cmd)
657 {
658 	struct hinic_rss_type rss_type = { 0 };
659 	int err;
660 
661 	cmd->data = 0;
662 
663 	if (!(nic_dev->flags & HINIC_RSS_ENABLE))
664 		return 0;
665 
666 	err = hinic_get_rss_type(nic_dev, nic_dev->rss_tmpl_idx,
667 				 &rss_type);
668 	if (err)
669 		return err;
670 
671 	cmd->data = RXH_IP_SRC | RXH_IP_DST;
672 	switch (cmd->flow_type) {
673 	case TCP_V4_FLOW:
674 		if (rss_type.tcp_ipv4)
675 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
676 		break;
677 	case TCP_V6_FLOW:
678 		if (rss_type.tcp_ipv6)
679 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
680 		break;
681 	case UDP_V4_FLOW:
682 		if (rss_type.udp_ipv4)
683 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
684 		break;
685 	case UDP_V6_FLOW:
686 		if (rss_type.udp_ipv6)
687 			cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
688 		break;
689 	case IPV4_FLOW:
690 	case IPV6_FLOW:
691 		break;
692 	default:
693 		cmd->data = 0;
694 		return -EINVAL;
695 	}
696 
697 	return 0;
698 }
699 
700 static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd,
701 			       struct hinic_rss_type *rss_type)
702 {
703 	u8 rss_l4_en = 0;
704 
705 	switch (cmd->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
706 	case 0:
707 		rss_l4_en = 0;
708 		break;
709 	case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
710 		rss_l4_en = 1;
711 		break;
712 	default:
713 		return -EINVAL;
714 	}
715 
716 	switch (cmd->flow_type) {
717 	case TCP_V4_FLOW:
718 		rss_type->tcp_ipv4 = rss_l4_en;
719 		break;
720 	case TCP_V6_FLOW:
721 		rss_type->tcp_ipv6 = rss_l4_en;
722 		break;
723 	case UDP_V4_FLOW:
724 		rss_type->udp_ipv4 = rss_l4_en;
725 		break;
726 	case UDP_V6_FLOW:
727 		rss_type->udp_ipv6 = rss_l4_en;
728 		break;
729 	default:
730 		return -EINVAL;
731 	}
732 
733 	return 0;
734 }
735 
736 static int hinic_set_rss_hash_opts(struct hinic_dev *nic_dev,
737 				   struct ethtool_rxnfc *cmd)
738 {
739 	struct hinic_rss_type *rss_type = &nic_dev->rss_type;
740 	int err;
741 
742 	if (!(nic_dev->flags & HINIC_RSS_ENABLE)) {
743 		cmd->data = 0;
744 		return -EOPNOTSUPP;
745 	}
746 
747 	/* RSS does not support anything other than hashing
748 	 * to queues on src and dst IPs and ports
749 	 */
750 	if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 |
751 		RXH_L4_B_2_3))
752 		return -EINVAL;
753 
754 	/* We need at least the IP SRC and DEST fields for hashing */
755 	if (!(cmd->data & RXH_IP_SRC) || !(cmd->data & RXH_IP_DST))
756 		return -EINVAL;
757 
758 	err = hinic_get_rss_type(nic_dev,
759 				 nic_dev->rss_tmpl_idx, rss_type);
760 	if (err)
761 		return -EFAULT;
762 
763 	switch (cmd->flow_type) {
764 	case TCP_V4_FLOW:
765 	case TCP_V6_FLOW:
766 	case UDP_V4_FLOW:
767 	case UDP_V6_FLOW:
768 		err = set_l4_rss_hash_ops(cmd, rss_type);
769 		if (err)
770 			return err;
771 		break;
772 	case IPV4_FLOW:
773 		rss_type->ipv4 = 1;
774 		break;
775 	case IPV6_FLOW:
776 		rss_type->ipv6 = 1;
777 		break;
778 	default:
779 		return -EINVAL;
780 	}
781 
782 	err = hinic_set_rss_type(nic_dev, nic_dev->rss_tmpl_idx,
783 				 *rss_type);
784 	if (err)
785 		return -EFAULT;
786 
787 	return 0;
788 }
789 
790 static int __set_rss_rxfh(struct net_device *netdev,
791 			  const u32 *indir, const u8 *key)
792 {
793 	struct hinic_dev *nic_dev = netdev_priv(netdev);
794 	int err;
795 
796 	if (indir) {
797 		if (!nic_dev->rss_indir_user) {
798 			nic_dev->rss_indir_user =
799 				kzalloc(sizeof(u32) * HINIC_RSS_INDIR_SIZE,
800 					GFP_KERNEL);
801 			if (!nic_dev->rss_indir_user)
802 				return -ENOMEM;
803 		}
804 
805 		memcpy(nic_dev->rss_indir_user, indir,
806 		       sizeof(u32) * HINIC_RSS_INDIR_SIZE);
807 
808 		err = hinic_rss_set_indir_tbl(nic_dev,
809 					      nic_dev->rss_tmpl_idx, indir);
810 		if (err)
811 			return -EFAULT;
812 	}
813 
814 	if (key) {
815 		if (!nic_dev->rss_hkey_user) {
816 			nic_dev->rss_hkey_user =
817 				kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL);
818 
819 			if (!nic_dev->rss_hkey_user)
820 				return -ENOMEM;
821 		}
822 
823 		memcpy(nic_dev->rss_hkey_user, key, HINIC_RSS_KEY_SIZE);
824 
825 		err = hinic_rss_set_template_tbl(nic_dev,
826 						 nic_dev->rss_tmpl_idx, key);
827 		if (err)
828 			return -EFAULT;
829 	}
830 
831 	return 0;
832 }
833 
834 static int hinic_get_rxnfc(struct net_device *netdev,
835 			   struct ethtool_rxnfc *cmd, u32 *rule_locs)
836 {
837 	struct hinic_dev *nic_dev = netdev_priv(netdev);
838 	int err = 0;
839 
840 	switch (cmd->cmd) {
841 	case ETHTOOL_GRXRINGS:
842 		cmd->data = nic_dev->num_qps;
843 		break;
844 	case ETHTOOL_GRXFH:
845 		err = hinic_get_rss_hash_opts(nic_dev, cmd);
846 		break;
847 	default:
848 		err = -EOPNOTSUPP;
849 		break;
850 	}
851 
852 	return err;
853 }
854 
855 static int hinic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
856 {
857 	struct hinic_dev *nic_dev = netdev_priv(netdev);
858 	int err = 0;
859 
860 	switch (cmd->cmd) {
861 	case ETHTOOL_SRXFH:
862 		err = hinic_set_rss_hash_opts(nic_dev, cmd);
863 		break;
864 	default:
865 		err = -EOPNOTSUPP;
866 		break;
867 	}
868 
869 	return err;
870 }
871 
872 static int hinic_get_rxfh(struct net_device *netdev,
873 			  u32 *indir, u8 *key, u8 *hfunc)
874 {
875 	struct hinic_dev *nic_dev = netdev_priv(netdev);
876 	u8 hash_engine_type = 0;
877 	int err = 0;
878 
879 	if (!(nic_dev->flags & HINIC_RSS_ENABLE))
880 		return -EOPNOTSUPP;
881 
882 	if (hfunc) {
883 		err = hinic_rss_get_hash_engine(nic_dev,
884 						nic_dev->rss_tmpl_idx,
885 						&hash_engine_type);
886 		if (err)
887 			return -EFAULT;
888 
889 		*hfunc = hash_engine_type ? ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR;
890 	}
891 
892 	if (indir) {
893 		err = hinic_rss_get_indir_tbl(nic_dev,
894 					      nic_dev->rss_tmpl_idx, indir);
895 		if (err)
896 			return -EFAULT;
897 	}
898 
899 	if (key)
900 		err = hinic_rss_get_template_tbl(nic_dev,
901 						 nic_dev->rss_tmpl_idx, key);
902 
903 	return err;
904 }
905 
906 static int hinic_set_rxfh(struct net_device *netdev, const u32 *indir,
907 			  const u8 *key, const u8 hfunc)
908 {
909 	struct hinic_dev *nic_dev = netdev_priv(netdev);
910 	int err = 0;
911 
912 	if (!(nic_dev->flags & HINIC_RSS_ENABLE))
913 		return -EOPNOTSUPP;
914 
915 	if (hfunc != ETH_RSS_HASH_NO_CHANGE) {
916 		if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR)
917 			return -EOPNOTSUPP;
918 
919 		nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ?
920 			HINIC_RSS_HASH_ENGINE_TYPE_XOR :
921 			HINIC_RSS_HASH_ENGINE_TYPE_TOEP;
922 		err = hinic_rss_set_hash_engine
923 			(nic_dev, nic_dev->rss_tmpl_idx,
924 			nic_dev->rss_hash_engine);
925 		if (err)
926 			return -EFAULT;
927 	}
928 
929 	err = __set_rss_rxfh(netdev, indir, key);
930 
931 	return err;
932 }
933 
934 static u32 hinic_get_rxfh_key_size(struct net_device *netdev)
935 {
936 	return HINIC_RSS_KEY_SIZE;
937 }
938 
939 static u32 hinic_get_rxfh_indir_size(struct net_device *netdev)
940 {
941 	return HINIC_RSS_INDIR_SIZE;
942 }
943 
944 #define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0])))
945 
946 #define HINIC_FUNC_STAT(_stat_item) {	\
947 	.name = #_stat_item, \
948 	.size = sizeof_field(struct hinic_vport_stats, _stat_item), \
949 	.offset = offsetof(struct hinic_vport_stats, _stat_item) \
950 }
951 
952 static struct hinic_stats hinic_function_stats[] = {
953 	HINIC_FUNC_STAT(tx_unicast_pkts_vport),
954 	HINIC_FUNC_STAT(tx_unicast_bytes_vport),
955 	HINIC_FUNC_STAT(tx_multicast_pkts_vport),
956 	HINIC_FUNC_STAT(tx_multicast_bytes_vport),
957 	HINIC_FUNC_STAT(tx_broadcast_pkts_vport),
958 	HINIC_FUNC_STAT(tx_broadcast_bytes_vport),
959 
960 	HINIC_FUNC_STAT(rx_unicast_pkts_vport),
961 	HINIC_FUNC_STAT(rx_unicast_bytes_vport),
962 	HINIC_FUNC_STAT(rx_multicast_pkts_vport),
963 	HINIC_FUNC_STAT(rx_multicast_bytes_vport),
964 	HINIC_FUNC_STAT(rx_broadcast_pkts_vport),
965 	HINIC_FUNC_STAT(rx_broadcast_bytes_vport),
966 
967 	HINIC_FUNC_STAT(tx_discard_vport),
968 	HINIC_FUNC_STAT(rx_discard_vport),
969 	HINIC_FUNC_STAT(tx_err_vport),
970 	HINIC_FUNC_STAT(rx_err_vport),
971 };
972 
973 #define HINIC_PORT_STAT(_stat_item) { \
974 	.name = #_stat_item, \
975 	.size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \
976 	.offset = offsetof(struct hinic_phy_port_stats, _stat_item) \
977 }
978 
979 static struct hinic_stats hinic_port_stats[] = {
980 	HINIC_PORT_STAT(mac_rx_total_pkt_num),
981 	HINIC_PORT_STAT(mac_rx_total_oct_num),
982 	HINIC_PORT_STAT(mac_rx_bad_pkt_num),
983 	HINIC_PORT_STAT(mac_rx_bad_oct_num),
984 	HINIC_PORT_STAT(mac_rx_good_pkt_num),
985 	HINIC_PORT_STAT(mac_rx_good_oct_num),
986 	HINIC_PORT_STAT(mac_rx_uni_pkt_num),
987 	HINIC_PORT_STAT(mac_rx_multi_pkt_num),
988 	HINIC_PORT_STAT(mac_rx_broad_pkt_num),
989 	HINIC_PORT_STAT(mac_tx_total_pkt_num),
990 	HINIC_PORT_STAT(mac_tx_total_oct_num),
991 	HINIC_PORT_STAT(mac_tx_bad_pkt_num),
992 	HINIC_PORT_STAT(mac_tx_bad_oct_num),
993 	HINIC_PORT_STAT(mac_tx_good_pkt_num),
994 	HINIC_PORT_STAT(mac_tx_good_oct_num),
995 	HINIC_PORT_STAT(mac_tx_uni_pkt_num),
996 	HINIC_PORT_STAT(mac_tx_multi_pkt_num),
997 	HINIC_PORT_STAT(mac_tx_broad_pkt_num),
998 	HINIC_PORT_STAT(mac_rx_fragment_pkt_num),
999 	HINIC_PORT_STAT(mac_rx_undersize_pkt_num),
1000 	HINIC_PORT_STAT(mac_rx_undermin_pkt_num),
1001 	HINIC_PORT_STAT(mac_rx_64_oct_pkt_num),
1002 	HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num),
1003 	HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num),
1004 	HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num),
1005 	HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num),
1006 	HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num),
1007 	HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num),
1008 	HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num),
1009 	HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num),
1010 	HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num),
1011 	HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num),
1012 	HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num),
1013 	HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num),
1014 	HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num),
1015 	HINIC_PORT_STAT(mac_rx_oversize_pkt_num),
1016 	HINIC_PORT_STAT(mac_rx_jabber_pkt_num),
1017 	HINIC_PORT_STAT(mac_rx_pause_num),
1018 	HINIC_PORT_STAT(mac_rx_pfc_pkt_num),
1019 	HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num),
1020 	HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num),
1021 	HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num),
1022 	HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num),
1023 	HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num),
1024 	HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num),
1025 	HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num),
1026 	HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num),
1027 	HINIC_PORT_STAT(mac_rx_control_pkt_num),
1028 	HINIC_PORT_STAT(mac_rx_sym_err_pkt_num),
1029 	HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num),
1030 	HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num),
1031 	HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num),
1032 	HINIC_PORT_STAT(mac_tx_fragment_pkt_num),
1033 	HINIC_PORT_STAT(mac_tx_undersize_pkt_num),
1034 	HINIC_PORT_STAT(mac_tx_undermin_pkt_num),
1035 	HINIC_PORT_STAT(mac_tx_64_oct_pkt_num),
1036 	HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num),
1037 	HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num),
1038 	HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num),
1039 	HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num),
1040 	HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num),
1041 	HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num),
1042 	HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num),
1043 	HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num),
1044 	HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num),
1045 	HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num),
1046 	HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num),
1047 	HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num),
1048 	HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num),
1049 	HINIC_PORT_STAT(mac_tx_oversize_pkt_num),
1050 	HINIC_PORT_STAT(mac_tx_jabber_pkt_num),
1051 	HINIC_PORT_STAT(mac_tx_pause_num),
1052 	HINIC_PORT_STAT(mac_tx_pfc_pkt_num),
1053 	HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num),
1054 	HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num),
1055 	HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num),
1056 	HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num),
1057 	HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num),
1058 	HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num),
1059 	HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num),
1060 	HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num),
1061 	HINIC_PORT_STAT(mac_tx_control_pkt_num),
1062 	HINIC_PORT_STAT(mac_tx_err_all_pkt_num),
1063 	HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num),
1064 	HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num),
1065 };
1066 
1067 #define HINIC_TXQ_STAT(_stat_item) { \
1068 	.name = "txq%d_"#_stat_item, \
1069 	.size = sizeof_field(struct hinic_txq_stats, _stat_item), \
1070 	.offset = offsetof(struct hinic_txq_stats, _stat_item) \
1071 }
1072 
1073 static struct hinic_stats hinic_tx_queue_stats[] = {
1074 	HINIC_TXQ_STAT(pkts),
1075 	HINIC_TXQ_STAT(bytes),
1076 	HINIC_TXQ_STAT(tx_busy),
1077 	HINIC_TXQ_STAT(tx_wake),
1078 	HINIC_TXQ_STAT(tx_dropped),
1079 	HINIC_TXQ_STAT(big_frags_pkts),
1080 };
1081 
1082 #define HINIC_RXQ_STAT(_stat_item) { \
1083 	.name = "rxq%d_"#_stat_item, \
1084 	.size = sizeof_field(struct hinic_rxq_stats, _stat_item), \
1085 	.offset = offsetof(struct hinic_rxq_stats, _stat_item) \
1086 }
1087 
1088 static struct hinic_stats hinic_rx_queue_stats[] = {
1089 	HINIC_RXQ_STAT(pkts),
1090 	HINIC_RXQ_STAT(bytes),
1091 	HINIC_RXQ_STAT(errors),
1092 	HINIC_RXQ_STAT(csum_errors),
1093 	HINIC_RXQ_STAT(other_errors),
1094 };
1095 
1096 static void get_drv_queue_stats(struct hinic_dev *nic_dev, u64 *data)
1097 {
1098 	struct hinic_txq_stats txq_stats;
1099 	struct hinic_rxq_stats rxq_stats;
1100 	u16 i = 0, j = 0, qid = 0;
1101 	char *p;
1102 
1103 	for (qid = 0; qid < nic_dev->num_qps; qid++) {
1104 		if (!nic_dev->txqs)
1105 			break;
1106 
1107 		hinic_txq_get_stats(&nic_dev->txqs[qid], &txq_stats);
1108 		for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++, i++) {
1109 			p = (char *)&txq_stats +
1110 				hinic_tx_queue_stats[j].offset;
1111 			data[i] = (hinic_tx_queue_stats[j].size ==
1112 					sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1113 		}
1114 	}
1115 
1116 	for (qid = 0; qid < nic_dev->num_qps; qid++) {
1117 		if (!nic_dev->rxqs)
1118 			break;
1119 
1120 		hinic_rxq_get_stats(&nic_dev->rxqs[qid], &rxq_stats);
1121 		for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++, i++) {
1122 			p = (char *)&rxq_stats +
1123 				hinic_rx_queue_stats[j].offset;
1124 			data[i] = (hinic_rx_queue_stats[j].size ==
1125 					sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1126 		}
1127 	}
1128 }
1129 
1130 static void hinic_get_ethtool_stats(struct net_device *netdev,
1131 				    struct ethtool_stats *stats, u64 *data)
1132 {
1133 	struct hinic_dev *nic_dev = netdev_priv(netdev);
1134 	struct hinic_vport_stats vport_stats = {0};
1135 	struct hinic_phy_port_stats *port_stats;
1136 	u16 i = 0, j = 0;
1137 	char *p;
1138 	int err;
1139 
1140 	err = hinic_get_vport_stats(nic_dev, &vport_stats);
1141 	if (err)
1142 		netif_err(nic_dev, drv, netdev,
1143 			  "Failed to get vport stats from firmware\n");
1144 
1145 	for (j = 0; j < ARRAY_LEN(hinic_function_stats); j++, i++) {
1146 		p = (char *)&vport_stats + hinic_function_stats[j].offset;
1147 		data[i] = (hinic_function_stats[j].size ==
1148 				sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1149 	}
1150 
1151 	port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL);
1152 	if (!port_stats) {
1153 		memset(&data[i], 0,
1154 		       ARRAY_LEN(hinic_port_stats) * sizeof(*data));
1155 		i += ARRAY_LEN(hinic_port_stats);
1156 		goto get_drv_stats;
1157 	}
1158 
1159 	err = hinic_get_phy_port_stats(nic_dev, port_stats);
1160 	if (err)
1161 		netif_err(nic_dev, drv, netdev,
1162 			  "Failed to get port stats from firmware\n");
1163 
1164 	for (j = 0; j < ARRAY_LEN(hinic_port_stats); j++, i++) {
1165 		p = (char *)port_stats + hinic_port_stats[j].offset;
1166 		data[i] = (hinic_port_stats[j].size ==
1167 				sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1168 	}
1169 
1170 	kfree(port_stats);
1171 
1172 get_drv_stats:
1173 	get_drv_queue_stats(nic_dev, data + i);
1174 }
1175 
1176 static int hinic_get_sset_count(struct net_device *netdev, int sset)
1177 {
1178 	struct hinic_dev *nic_dev = netdev_priv(netdev);
1179 	int count, q_num;
1180 
1181 	switch (sset) {
1182 	case ETH_SS_STATS:
1183 		q_num = nic_dev->num_qps;
1184 		count = ARRAY_LEN(hinic_function_stats) +
1185 			(ARRAY_LEN(hinic_tx_queue_stats) +
1186 			ARRAY_LEN(hinic_rx_queue_stats)) * q_num;
1187 
1188 		count += ARRAY_LEN(hinic_port_stats);
1189 
1190 		return count;
1191 	default:
1192 		return -EOPNOTSUPP;
1193 	}
1194 }
1195 
1196 static void hinic_get_strings(struct net_device *netdev,
1197 			      u32 stringset, u8 *data)
1198 {
1199 	struct hinic_dev *nic_dev = netdev_priv(netdev);
1200 	char *p = (char *)data;
1201 	u16 i, j;
1202 
1203 	switch (stringset) {
1204 	case ETH_SS_STATS:
1205 		for (i = 0; i < ARRAY_LEN(hinic_function_stats); i++) {
1206 			memcpy(p, hinic_function_stats[i].name,
1207 			       ETH_GSTRING_LEN);
1208 			p += ETH_GSTRING_LEN;
1209 		}
1210 
1211 		for (i = 0; i < ARRAY_LEN(hinic_port_stats); i++) {
1212 			memcpy(p, hinic_port_stats[i].name,
1213 			       ETH_GSTRING_LEN);
1214 			p += ETH_GSTRING_LEN;
1215 		}
1216 
1217 		for (i = 0; i < nic_dev->num_qps; i++) {
1218 			for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++) {
1219 				sprintf(p, hinic_tx_queue_stats[j].name, i);
1220 				p += ETH_GSTRING_LEN;
1221 			}
1222 		}
1223 
1224 		for (i = 0; i < nic_dev->num_qps; i++) {
1225 			for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++) {
1226 				sprintf(p, hinic_rx_queue_stats[j].name, i);
1227 				p += ETH_GSTRING_LEN;
1228 			}
1229 		}
1230 
1231 		return;
1232 	default:
1233 		return;
1234 	}
1235 }
1236 
1237 static const struct ethtool_ops hinic_ethtool_ops = {
1238 	.get_link_ksettings = hinic_get_link_ksettings,
1239 	.set_link_ksettings = hinic_set_link_ksettings,
1240 	.get_drvinfo = hinic_get_drvinfo,
1241 	.get_link = ethtool_op_get_link,
1242 	.get_ringparam = hinic_get_ringparam,
1243 	.set_ringparam = hinic_set_ringparam,
1244 	.get_channels = hinic_get_channels,
1245 	.set_channels = hinic_set_channels,
1246 	.get_rxnfc = hinic_get_rxnfc,
1247 	.set_rxnfc = hinic_set_rxnfc,
1248 	.get_rxfh_key_size = hinic_get_rxfh_key_size,
1249 	.get_rxfh_indir_size = hinic_get_rxfh_indir_size,
1250 	.get_rxfh = hinic_get_rxfh,
1251 	.set_rxfh = hinic_set_rxfh,
1252 	.get_sset_count = hinic_get_sset_count,
1253 	.get_ethtool_stats = hinic_get_ethtool_stats,
1254 	.get_strings = hinic_get_strings,
1255 };
1256 
1257 void hinic_set_ethtool_ops(struct net_device *netdev)
1258 {
1259 	netdev->ethtool_ops = &hinic_ethtool_ops;
1260 }
1261