1/*
2 * Copyright (C) 2005 - 2014 Emulex
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation.  The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
11 * linux-drivers@emulex.com
12 *
13 * Emulex
14 * 3333 Susan Street
15 * Costa Mesa, CA 92626
16 */
17
18#include "be.h"
19#include "be_cmds.h"
20#include <linux/ethtool.h>
21
22struct be_ethtool_stat {
23	char desc[ETH_GSTRING_LEN];
24	int type;
25	int size;
26	int offset;
27};
28
29enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
30#define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
31					offsetof(_struct, field)
32#define DRVSTAT_TX_INFO(field)	#field, DRVSTAT_TX,\
33					FIELDINFO(struct be_tx_stats, field)
34#define DRVSTAT_RX_INFO(field)	#field, DRVSTAT_RX,\
35					FIELDINFO(struct be_rx_stats, field)
36#define	DRVSTAT_INFO(field)	#field, DRVSTAT,\
37					FIELDINFO(struct be_drv_stats, field)
38
39static const struct be_ethtool_stat et_stats[] = {
40	{DRVSTAT_INFO(rx_crc_errors)},
41	{DRVSTAT_INFO(rx_alignment_symbol_errors)},
42	{DRVSTAT_INFO(rx_pause_frames)},
43	{DRVSTAT_INFO(rx_control_frames)},
44	/* Received packets dropped when the Ethernet length field
45	 * is not equal to the actual Ethernet data length.
46	 */
47	{DRVSTAT_INFO(rx_in_range_errors)},
48	/* Received packets dropped when their length field is >= 1501 bytes
49	 * and <= 1535 bytes.
50	 */
51	{DRVSTAT_INFO(rx_out_range_errors)},
52	/* Received packets dropped when they are longer than 9216 bytes */
53	{DRVSTAT_INFO(rx_frame_too_long)},
54	/* Received packets dropped when they don't pass the unicast or
55	 * multicast address filtering.
56	 */
57	{DRVSTAT_INFO(rx_address_filtered)},
58	/* Received packets dropped when IP packet length field is less than
59	 * the IP header length field.
60	 */
61	{DRVSTAT_INFO(rx_dropped_too_small)},
62	/* Received packets dropped when IP length field is greater than
63	 * the actual packet length.
64	 */
65	{DRVSTAT_INFO(rx_dropped_too_short)},
66	/* Received packets dropped when the IP header length field is less
67	 * than 5.
68	 */
69	{DRVSTAT_INFO(rx_dropped_header_too_small)},
70	/* Received packets dropped when the TCP header length field is less
71	 * than 5 or the TCP header length + IP header length is more
72	 * than IP packet length.
73	 */
74	{DRVSTAT_INFO(rx_dropped_tcp_length)},
75	{DRVSTAT_INFO(rx_dropped_runt)},
76	/* Number of received packets dropped when a fifo for descriptors going
77	 * into the packet demux block overflows. In normal operation, this
78	 * fifo must never overflow.
79	 */
80	{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
81	/* Received packets dropped when the RX block runs out of space in
82	 * one of its input FIFOs. This could happen due a long burst of
83	 * minimum-sized (64b) frames in the receive path.
84	 * This counter may also be erroneously incremented rarely.
85	 */
86	{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
87	{DRVSTAT_INFO(rx_ip_checksum_errs)},
88	{DRVSTAT_INFO(rx_tcp_checksum_errs)},
89	{DRVSTAT_INFO(rx_udp_checksum_errs)},
90	{DRVSTAT_INFO(tx_pauseframes)},
91	{DRVSTAT_INFO(tx_controlframes)},
92	{DRVSTAT_INFO(rx_priority_pause_frames)},
93	{DRVSTAT_INFO(tx_priority_pauseframes)},
94	/* Received packets dropped when an internal fifo going into
95	 * main packet buffer tank (PMEM) overflows.
96	 */
97	{DRVSTAT_INFO(pmem_fifo_overflow_drop)},
98	{DRVSTAT_INFO(jabber_events)},
99	/* Received packets dropped due to lack of available HW packet buffers
100	 * used to temporarily hold the received packets.
101	 */
102	{DRVSTAT_INFO(rx_drops_no_pbuf)},
103	/* Received packets dropped due to input receive buffer
104	 * descriptor fifo overflowing.
105	 */
106	{DRVSTAT_INFO(rx_drops_no_erx_descr)},
107	/* Packets dropped because the internal FIFO to the offloaded TCP
108	 * receive processing block is full. This could happen only for
109	 * offloaded iSCSI or FCoE trarffic.
110	 */
111	{DRVSTAT_INFO(rx_drops_no_tpre_descr)},
112	/* Received packets dropped when they need more than 8
113	 * receive buffers. This cannot happen as the driver configures
114	 * 2048 byte receive buffers.
115	 */
116	{DRVSTAT_INFO(rx_drops_too_many_frags)},
117	{DRVSTAT_INFO(forwarded_packets)},
118	/* Received packets dropped when the frame length
119	 * is more than 9018 bytes
120	 */
121	{DRVSTAT_INFO(rx_drops_mtu)},
122	/* Number of dma mapping errors */
123	{DRVSTAT_INFO(dma_map_errors)},
124	/* Number of packets dropped due to random early drop function */
125	{DRVSTAT_INFO(eth_red_drops)},
126	{DRVSTAT_INFO(be_on_die_temperature)},
127	{DRVSTAT_INFO(rx_roce_bytes_lsd)},
128	{DRVSTAT_INFO(rx_roce_bytes_msd)},
129	{DRVSTAT_INFO(rx_roce_frames)},
130	{DRVSTAT_INFO(roce_drops_payload_len)},
131	{DRVSTAT_INFO(roce_drops_crc)}
132};
133
134#define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
135
136/* Stats related to multi RX queues: get_stats routine assumes bytes, pkts
137 * are first and second members respectively.
138 */
139static const struct be_ethtool_stat et_rx_stats[] = {
140	{DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
141	{DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
142	{DRVSTAT_RX_INFO(rx_compl)},
143	{DRVSTAT_RX_INFO(rx_compl_err)},
144	{DRVSTAT_RX_INFO(rx_mcast_pkts)},
145	/* Number of page allocation failures while posting receive buffers
146	 * to HW.
147	 */
148	{DRVSTAT_RX_INFO(rx_post_fail)},
149	/* Recevied packets dropped due to skb allocation failure */
150	{DRVSTAT_RX_INFO(rx_drops_no_skbs)},
151	/* Received packets dropped due to lack of available fetched buffers
152	 * posted by the driver.
153	 */
154	{DRVSTAT_RX_INFO(rx_drops_no_frags)}
155};
156
157#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
158
159/* Stats related to multi TX queues: get_stats routine assumes compl is the
160 * first member
161 */
162static const struct be_ethtool_stat et_tx_stats[] = {
163	{DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
164	/* This counter is incremented when the HW encounters an error while
165	 * parsing the packet header of an outgoing TX request. This counter is
166	 * applicable only for BE2, BE3 and Skyhawk based adapters.
167	 */
168	{DRVSTAT_TX_INFO(tx_hdr_parse_err)},
169	/* This counter is incremented when an error occurs in the DMA
170	 * operation associated with the TX request from the host to the device.
171	 */
172	{DRVSTAT_TX_INFO(tx_dma_err)},
173	/* This counter is incremented when MAC or VLAN spoof checking is
174	 * enabled on the interface and the TX request fails the spoof check
175	 * in HW.
176	 */
177	{DRVSTAT_TX_INFO(tx_spoof_check_err)},
178	/* This counter is incremented when the HW encounters an error while
179	 * performing TSO offload. This counter is applicable only for Lancer
180	 * adapters.
181	 */
182	{DRVSTAT_TX_INFO(tx_tso_err)},
183	/* This counter is incremented when the HW detects Q-in-Q style VLAN
184	 * tagging in a packet and such tagging is not expected on the outgoing
185	 * interface. This counter is applicable only for Lancer adapters.
186	 */
187	{DRVSTAT_TX_INFO(tx_qinq_err)},
188	/* This counter is incremented when the HW detects parity errors in the
189	 * packet data. This counter is applicable only for Lancer adapters.
190	 */
191	{DRVSTAT_TX_INFO(tx_internal_parity_err)},
192	{DRVSTAT_TX_INFO(tx_bytes)},
193	{DRVSTAT_TX_INFO(tx_pkts)},
194	/* Number of skbs queued for trasmission by the driver */
195	{DRVSTAT_TX_INFO(tx_reqs)},
196	/* Number of times the TX queue was stopped due to lack
197	 * of spaces in the TXQ.
198	 */
199	{DRVSTAT_TX_INFO(tx_stops)},
200	/* Pkts dropped in the driver's transmit path */
201	{DRVSTAT_TX_INFO(tx_drv_drops)}
202};
203
204#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
205
206static const char et_self_tests[][ETH_GSTRING_LEN] = {
207	"MAC Loopback test",
208	"PHY Loopback test",
209	"External Loopback test",
210	"DDR DMA test",
211	"Link test"
212};
213
214#define ETHTOOL_TESTS_NUM ARRAY_SIZE(et_self_tests)
215#define BE_MAC_LOOPBACK 0x0
216#define BE_PHY_LOOPBACK 0x1
217#define BE_ONE_PORT_EXT_LOOPBACK 0x2
218#define BE_NO_LOOPBACK 0xff
219
220static void be_get_drvinfo(struct net_device *netdev,
221			   struct ethtool_drvinfo *drvinfo)
222{
223	struct be_adapter *adapter = netdev_priv(netdev);
224
225	strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
226	strlcpy(drvinfo->version, DRV_VER, sizeof(drvinfo->version));
227	if (!memcmp(adapter->fw_ver, adapter->fw_on_flash, FW_VER_LEN))
228		strlcpy(drvinfo->fw_version, adapter->fw_ver,
229			sizeof(drvinfo->fw_version));
230	else
231		snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
232			 "%s [%s]", adapter->fw_ver, adapter->fw_on_flash);
233
234	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
235		sizeof(drvinfo->bus_info));
236	drvinfo->testinfo_len = 0;
237	drvinfo->regdump_len = 0;
238	drvinfo->eedump_len = 0;
239}
240
241static u32 lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name)
242{
243	u32 data_read = 0, eof;
244	u8 addn_status;
245	struct be_dma_mem data_len_cmd;
246	int status;
247
248	memset(&data_len_cmd, 0, sizeof(data_len_cmd));
249	/* data_offset and data_size should be 0 to get reg len */
250	status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0,
251					file_name, &data_read, &eof,
252					&addn_status);
253
254	return data_read;
255}
256
257static int lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name,
258				u32 buf_len, void *buf)
259{
260	struct be_dma_mem read_cmd;
261	u32 read_len = 0, total_read_len = 0, chunk_size;
262	u32 eof = 0;
263	u8 addn_status;
264	int status = 0;
265
266	read_cmd.size = LANCER_READ_FILE_CHUNK;
267	read_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, read_cmd.size,
268					  &read_cmd.dma, GFP_ATOMIC);
269
270	if (!read_cmd.va) {
271		dev_err(&adapter->pdev->dev,
272			"Memory allocation failure while reading dump\n");
273		return -ENOMEM;
274	}
275
276	while ((total_read_len < buf_len) && !eof) {
277		chunk_size = min_t(u32, (buf_len - total_read_len),
278				   LANCER_READ_FILE_CHUNK);
279		chunk_size = ALIGN(chunk_size, 4);
280		status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size,
281						total_read_len, file_name,
282						&read_len, &eof, &addn_status);
283		if (!status) {
284			memcpy(buf + total_read_len, read_cmd.va, read_len);
285			total_read_len += read_len;
286			eof &= LANCER_READ_FILE_EOF_MASK;
287		} else {
288			status = -EIO;
289			break;
290		}
291	}
292	dma_free_coherent(&adapter->pdev->dev, read_cmd.size, read_cmd.va,
293			  read_cmd.dma);
294
295	return status;
296}
297
298static int be_get_reg_len(struct net_device *netdev)
299{
300	struct be_adapter *adapter = netdev_priv(netdev);
301	u32 log_size = 0;
302
303	if (!check_privilege(adapter, MAX_PRIVILEGES))
304		return 0;
305
306	if (be_physfn(adapter)) {
307		if (lancer_chip(adapter))
308			log_size = lancer_cmd_get_file_len(adapter,
309							   LANCER_FW_DUMP_FILE);
310		else
311			be_cmd_get_reg_len(adapter, &log_size);
312	}
313	return log_size;
314}
315
316static void
317be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
318{
319	struct be_adapter *adapter = netdev_priv(netdev);
320
321	if (be_physfn(adapter)) {
322		memset(buf, 0, regs->len);
323		if (lancer_chip(adapter))
324			lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE,
325					     regs->len, buf);
326		else
327			be_cmd_get_regs(adapter, regs->len, buf);
328	}
329}
330
331static int be_get_coalesce(struct net_device *netdev,
332			   struct ethtool_coalesce *et)
333{
334	struct be_adapter *adapter = netdev_priv(netdev);
335	struct be_aic_obj *aic = &adapter->aic_obj[0];
336
337	et->rx_coalesce_usecs = aic->prev_eqd;
338	et->rx_coalesce_usecs_high = aic->max_eqd;
339	et->rx_coalesce_usecs_low = aic->min_eqd;
340
341	et->tx_coalesce_usecs = aic->prev_eqd;
342	et->tx_coalesce_usecs_high = aic->max_eqd;
343	et->tx_coalesce_usecs_low = aic->min_eqd;
344
345	et->use_adaptive_rx_coalesce = aic->enable;
346	et->use_adaptive_tx_coalesce = aic->enable;
347
348	return 0;
349}
350
351/* TX attributes are ignored. Only RX attributes are considered
352 * eqd cmd is issued in the worker thread.
353 */
354static int be_set_coalesce(struct net_device *netdev,
355			   struct ethtool_coalesce *et)
356{
357	struct be_adapter *adapter = netdev_priv(netdev);
358	struct be_aic_obj *aic = &adapter->aic_obj[0];
359	struct be_eq_obj *eqo;
360	int i;
361
362	for_all_evt_queues(adapter, eqo, i) {
363		aic->enable = et->use_adaptive_rx_coalesce;
364		aic->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD);
365		aic->min_eqd = min(et->rx_coalesce_usecs_low, aic->max_eqd);
366		aic->et_eqd = min(et->rx_coalesce_usecs, aic->max_eqd);
367		aic->et_eqd = max(aic->et_eqd, aic->min_eqd);
368		aic++;
369	}
370
371	return 0;
372}
373
374static void be_get_ethtool_stats(struct net_device *netdev,
375				 struct ethtool_stats *stats, uint64_t *data)
376{
377	struct be_adapter *adapter = netdev_priv(netdev);
378	struct be_rx_obj *rxo;
379	struct be_tx_obj *txo;
380	void *p;
381	unsigned int i, j, base = 0, start;
382
383	for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
384		p = (u8 *)&adapter->drv_stats + et_stats[i].offset;
385		data[i] = *(u32 *)p;
386	}
387	base += ETHTOOL_STATS_NUM;
388
389	for_all_rx_queues(adapter, rxo, j) {
390		struct be_rx_stats *stats = rx_stats(rxo);
391
392		do {
393			start = u64_stats_fetch_begin_irq(&stats->sync);
394			data[base] = stats->rx_bytes;
395			data[base + 1] = stats->rx_pkts;
396		} while (u64_stats_fetch_retry_irq(&stats->sync, start));
397
398		for (i = 2; i < ETHTOOL_RXSTATS_NUM; i++) {
399			p = (u8 *)stats + et_rx_stats[i].offset;
400			data[base + i] = *(u32 *)p;
401		}
402		base += ETHTOOL_RXSTATS_NUM;
403	}
404
405	for_all_tx_queues(adapter, txo, j) {
406		struct be_tx_stats *stats = tx_stats(txo);
407
408		do {
409			start = u64_stats_fetch_begin_irq(&stats->sync_compl);
410			data[base] = stats->tx_compl;
411		} while (u64_stats_fetch_retry_irq(&stats->sync_compl, start));
412
413		do {
414			start = u64_stats_fetch_begin_irq(&stats->sync);
415			for (i = 1; i < ETHTOOL_TXSTATS_NUM; i++) {
416				p = (u8 *)stats + et_tx_stats[i].offset;
417				data[base + i] =
418					(et_tx_stats[i].size == sizeof(u64)) ?
419						*(u64 *)p : *(u32 *)p;
420			}
421		} while (u64_stats_fetch_retry_irq(&stats->sync, start));
422		base += ETHTOOL_TXSTATS_NUM;
423	}
424}
425
426static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
427				uint8_t *data)
428{
429	struct be_adapter *adapter = netdev_priv(netdev);
430	int i, j;
431
432	switch (stringset) {
433	case ETH_SS_STATS:
434		for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
435			memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN);
436			data += ETH_GSTRING_LEN;
437		}
438		for (i = 0; i < adapter->num_rx_qs; i++) {
439			for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) {
440				sprintf(data, "rxq%d: %s", i,
441					et_rx_stats[j].desc);
442				data += ETH_GSTRING_LEN;
443			}
444		}
445		for (i = 0; i < adapter->num_tx_qs; i++) {
446			for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) {
447				sprintf(data, "txq%d: %s", i,
448					et_tx_stats[j].desc);
449				data += ETH_GSTRING_LEN;
450			}
451		}
452		break;
453	case ETH_SS_TEST:
454		for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
455			memcpy(data, et_self_tests[i], ETH_GSTRING_LEN);
456			data += ETH_GSTRING_LEN;
457		}
458		break;
459	}
460}
461
462static int be_get_sset_count(struct net_device *netdev, int stringset)
463{
464	struct be_adapter *adapter = netdev_priv(netdev);
465
466	switch (stringset) {
467	case ETH_SS_TEST:
468		return ETHTOOL_TESTS_NUM;
469	case ETH_SS_STATS:
470		return ETHTOOL_STATS_NUM +
471			adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
472			adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
473	default:
474		return -EINVAL;
475	}
476}
477
478static u32 be_get_port_type(struct be_adapter *adapter)
479{
480	u32 port;
481
482	switch (adapter->phy.interface_type) {
483	case PHY_TYPE_BASET_1GB:
484	case PHY_TYPE_BASEX_1GB:
485	case PHY_TYPE_SGMII:
486		port = PORT_TP;
487		break;
488	case PHY_TYPE_SFP_PLUS_10GB:
489		if (adapter->phy.cable_type & SFP_PLUS_COPPER_CABLE)
490			port = PORT_DA;
491		else
492			port = PORT_FIBRE;
493		break;
494	case PHY_TYPE_QSFP:
495		if (adapter->phy.cable_type & QSFP_PLUS_CR4_CABLE)
496			port = PORT_DA;
497		else
498			port = PORT_FIBRE;
499		break;
500	case PHY_TYPE_XFP_10GB:
501	case PHY_TYPE_SFP_1GB:
502		port = PORT_FIBRE;
503		break;
504	case PHY_TYPE_BASET_10GB:
505		port = PORT_TP;
506		break;
507	default:
508		port = PORT_OTHER;
509	}
510
511	return port;
512}
513
514static u32 convert_to_et_setting(struct be_adapter *adapter, u32 if_speeds)
515{
516	u32 val = 0;
517
518	switch (adapter->phy.interface_type) {
519	case PHY_TYPE_BASET_1GB:
520	case PHY_TYPE_BASEX_1GB:
521	case PHY_TYPE_SGMII:
522		val |= SUPPORTED_TP;
523		if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
524			val |= SUPPORTED_1000baseT_Full;
525		if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
526			val |= SUPPORTED_100baseT_Full;
527		if (if_speeds & BE_SUPPORTED_SPEED_10MBPS)
528			val |= SUPPORTED_10baseT_Full;
529		break;
530	case PHY_TYPE_KX4_10GB:
531		val |= SUPPORTED_Backplane;
532		if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
533			val |= SUPPORTED_1000baseKX_Full;
534		if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
535			val |= SUPPORTED_10000baseKX4_Full;
536		break;
537	case PHY_TYPE_KR2_20GB:
538		val |= SUPPORTED_Backplane;
539		if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
540			val |= SUPPORTED_10000baseKR_Full;
541		if (if_speeds & BE_SUPPORTED_SPEED_20GBPS)
542			val |= SUPPORTED_20000baseKR2_Full;
543		break;
544	case PHY_TYPE_KR_10GB:
545		val |= SUPPORTED_Backplane |
546				SUPPORTED_10000baseKR_Full;
547		break;
548	case PHY_TYPE_KR4_40GB:
549		val |= SUPPORTED_Backplane;
550		if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
551			val |= SUPPORTED_10000baseKR_Full;
552		if (if_speeds & BE_SUPPORTED_SPEED_40GBPS)
553			val |= SUPPORTED_40000baseKR4_Full;
554		break;
555	case PHY_TYPE_QSFP:
556		if (if_speeds & BE_SUPPORTED_SPEED_40GBPS) {
557			switch (adapter->phy.cable_type) {
558			case QSFP_PLUS_CR4_CABLE:
559				val |= SUPPORTED_40000baseCR4_Full;
560				break;
561			case QSFP_PLUS_LR4_CABLE:
562				val |= SUPPORTED_40000baseLR4_Full;
563				break;
564			default:
565				val |= SUPPORTED_40000baseSR4_Full;
566				break;
567			}
568		}
569	case PHY_TYPE_SFP_PLUS_10GB:
570	case PHY_TYPE_XFP_10GB:
571	case PHY_TYPE_SFP_1GB:
572		val |= SUPPORTED_FIBRE;
573		if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
574			val |= SUPPORTED_10000baseT_Full;
575		if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
576			val |= SUPPORTED_1000baseT_Full;
577		break;
578	case PHY_TYPE_BASET_10GB:
579		val |= SUPPORTED_TP;
580		if (if_speeds & BE_SUPPORTED_SPEED_10GBPS)
581			val |= SUPPORTED_10000baseT_Full;
582		if (if_speeds & BE_SUPPORTED_SPEED_1GBPS)
583			val |= SUPPORTED_1000baseT_Full;
584		if (if_speeds & BE_SUPPORTED_SPEED_100MBPS)
585			val |= SUPPORTED_100baseT_Full;
586		break;
587	default:
588		val |= SUPPORTED_TP;
589	}
590
591	return val;
592}
593
594bool be_pause_supported(struct be_adapter *adapter)
595{
596	return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB ||
597		adapter->phy.interface_type == PHY_TYPE_XFP_10GB) ?
598		false : true;
599}
600
601static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
602{
603	struct be_adapter *adapter = netdev_priv(netdev);
604	u8 link_status;
605	u16 link_speed = 0;
606	int status;
607	u32 auto_speeds;
608	u32 fixed_speeds;
609
610	if (adapter->phy.link_speed < 0) {
611		status = be_cmd_link_status_query(adapter, &link_speed,
612						  &link_status, 0);
613		if (!status)
614			be_link_status_update(adapter, link_status);
615		ethtool_cmd_speed_set(ecmd, link_speed);
616
617		status = be_cmd_get_phy_info(adapter);
618		if (!status) {
619			auto_speeds = adapter->phy.auto_speeds_supported;
620			fixed_speeds = adapter->phy.fixed_speeds_supported;
621
622			be_cmd_query_cable_type(adapter);
623
624			ecmd->supported =
625				convert_to_et_setting(adapter,
626						      auto_speeds |
627						      fixed_speeds);
628			ecmd->advertising =
629				convert_to_et_setting(adapter, auto_speeds);
630
631			ecmd->port = be_get_port_type(adapter);
632
633			if (adapter->phy.auto_speeds_supported) {
634				ecmd->supported |= SUPPORTED_Autoneg;
635				ecmd->autoneg = AUTONEG_ENABLE;
636				ecmd->advertising |= ADVERTISED_Autoneg;
637			}
638
639			ecmd->supported |= SUPPORTED_Pause;
640			if (be_pause_supported(adapter))
641				ecmd->advertising |= ADVERTISED_Pause;
642
643			switch (adapter->phy.interface_type) {
644			case PHY_TYPE_KR_10GB:
645			case PHY_TYPE_KX4_10GB:
646				ecmd->transceiver = XCVR_INTERNAL;
647				break;
648			default:
649				ecmd->transceiver = XCVR_EXTERNAL;
650				break;
651			}
652		} else {
653			ecmd->port = PORT_OTHER;
654			ecmd->autoneg = AUTONEG_DISABLE;
655			ecmd->transceiver = XCVR_DUMMY1;
656		}
657
658		/* Save for future use */
659		adapter->phy.link_speed = ethtool_cmd_speed(ecmd);
660		adapter->phy.port_type = ecmd->port;
661		adapter->phy.transceiver = ecmd->transceiver;
662		adapter->phy.autoneg = ecmd->autoneg;
663		adapter->phy.advertising = ecmd->advertising;
664		adapter->phy.supported = ecmd->supported;
665	} else {
666		ethtool_cmd_speed_set(ecmd, adapter->phy.link_speed);
667		ecmd->port = adapter->phy.port_type;
668		ecmd->transceiver = adapter->phy.transceiver;
669		ecmd->autoneg = adapter->phy.autoneg;
670		ecmd->advertising = adapter->phy.advertising;
671		ecmd->supported = adapter->phy.supported;
672	}
673
674	ecmd->duplex = netif_carrier_ok(netdev) ? DUPLEX_FULL : DUPLEX_UNKNOWN;
675	ecmd->phy_address = adapter->port_num;
676
677	return 0;
678}
679
680static void be_get_ringparam(struct net_device *netdev,
681			     struct ethtool_ringparam *ring)
682{
683	struct be_adapter *adapter = netdev_priv(netdev);
684
685	ring->rx_max_pending = adapter->rx_obj[0].q.len;
686	ring->rx_pending = adapter->rx_obj[0].q.len;
687	ring->tx_max_pending = adapter->tx_obj[0].q.len;
688	ring->tx_pending = adapter->tx_obj[0].q.len;
689}
690
691static void
692be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
693{
694	struct be_adapter *adapter = netdev_priv(netdev);
695
696	be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
697	ecmd->autoneg = adapter->phy.fc_autoneg;
698}
699
700static int
701be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
702{
703	struct be_adapter *adapter = netdev_priv(netdev);
704	int status;
705
706	if (ecmd->autoneg != adapter->phy.fc_autoneg)
707		return -EINVAL;
708
709	status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
710					 ecmd->rx_pause);
711	if (status) {
712		dev_warn(&adapter->pdev->dev, "Pause param set failed\n");
713		return be_cmd_status(status);
714	}
715
716	adapter->tx_fc = ecmd->tx_pause;
717	adapter->rx_fc = ecmd->rx_pause;
718	return 0;
719}
720
721static int be_set_phys_id(struct net_device *netdev,
722			  enum ethtool_phys_id_state state)
723{
724	struct be_adapter *adapter = netdev_priv(netdev);
725
726	switch (state) {
727	case ETHTOOL_ID_ACTIVE:
728		be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
729					&adapter->beacon_state);
730		return 1;	/* cycle on/off once per second */
731
732	case ETHTOOL_ID_ON:
733		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
734					BEACON_STATE_ENABLED);
735		break;
736
737	case ETHTOOL_ID_OFF:
738		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
739					BEACON_STATE_DISABLED);
740		break;
741
742	case ETHTOOL_ID_INACTIVE:
743		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
744					adapter->beacon_state);
745	}
746
747	return 0;
748}
749
750static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
751{
752	struct be_adapter *adapter = netdev_priv(netdev);
753	struct device *dev = &adapter->pdev->dev;
754	int status;
755
756	if (!lancer_chip(adapter) ||
757	    !check_privilege(adapter, MAX_PRIVILEGES))
758		return -EOPNOTSUPP;
759
760	switch (dump->flag) {
761	case LANCER_INITIATE_FW_DUMP:
762		status = lancer_initiate_dump(adapter);
763		if (!status)
764			dev_info(dev, "FW dump initiated successfully\n");
765		break;
766	case LANCER_DELETE_FW_DUMP:
767		status = lancer_delete_dump(adapter);
768		if (!status)
769			dev_info(dev, "FW dump deleted successfully\n");
770	break;
771	default:
772		dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag);
773		return -EINVAL;
774	}
775	return status;
776}
777
778static void be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
779{
780	struct be_adapter *adapter = netdev_priv(netdev);
781
782	if (adapter->wol_cap & BE_WOL_CAP) {
783		wol->supported |= WAKE_MAGIC;
784		if (adapter->wol_en)
785			wol->wolopts |= WAKE_MAGIC;
786	} else {
787		wol->wolopts = 0;
788	}
789	memset(&wol->sopass, 0, sizeof(wol->sopass));
790}
791
792static int be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
793{
794	struct be_adapter *adapter = netdev_priv(netdev);
795
796	if (wol->wolopts & ~WAKE_MAGIC)
797		return -EOPNOTSUPP;
798
799	if (!(adapter->wol_cap & BE_WOL_CAP)) {
800		dev_warn(&adapter->pdev->dev, "WOL not supported\n");
801		return -EOPNOTSUPP;
802	}
803
804	if (wol->wolopts & WAKE_MAGIC)
805		adapter->wol_en = true;
806	else
807		adapter->wol_en = false;
808
809	return 0;
810}
811
812static int be_test_ddr_dma(struct be_adapter *adapter)
813{
814	int ret, i;
815	struct be_dma_mem ddrdma_cmd;
816	static const u64 pattern[2] = {
817		0x5a5a5a5a5a5a5a5aULL, 0xa5a5a5a5a5a5a5a5ULL
818	};
819
820	ddrdma_cmd.size = sizeof(struct be_cmd_req_ddrdma_test);
821	ddrdma_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
822					    ddrdma_cmd.size, &ddrdma_cmd.dma,
823					    GFP_KERNEL);
824	if (!ddrdma_cmd.va)
825		return -ENOMEM;
826
827	for (i = 0; i < 2; i++) {
828		ret = be_cmd_ddr_dma_test(adapter, pattern[i],
829					  4096, &ddrdma_cmd);
830		if (ret != 0)
831			goto err;
832	}
833
834err:
835	dma_free_coherent(&adapter->pdev->dev, ddrdma_cmd.size, ddrdma_cmd.va,
836			  ddrdma_cmd.dma);
837	return be_cmd_status(ret);
838}
839
840static u64 be_loopback_test(struct be_adapter *adapter, u8 loopback_type,
841			    u64 *status)
842{
843	be_cmd_set_loopback(adapter, adapter->hba_port_num, loopback_type, 1);
844	*status = be_cmd_loopback_test(adapter, adapter->hba_port_num,
845				       loopback_type, 1500, 2, 0xabc);
846	be_cmd_set_loopback(adapter, adapter->hba_port_num, BE_NO_LOOPBACK, 1);
847	return *status;
848}
849
850static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
851			 u64 *data)
852{
853	struct be_adapter *adapter = netdev_priv(netdev);
854	int status;
855	u8 link_status = 0;
856
857	if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
858		dev_err(&adapter->pdev->dev, "Self test not supported\n");
859		test->flags |= ETH_TEST_FL_FAILED;
860		return;
861	}
862
863	memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
864
865	if (test->flags & ETH_TEST_FL_OFFLINE) {
866		if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0)
867			test->flags |= ETH_TEST_FL_FAILED;
868
869		if (be_loopback_test(adapter, BE_PHY_LOOPBACK, &data[1]) != 0)
870			test->flags |= ETH_TEST_FL_FAILED;
871
872		if (test->flags & ETH_TEST_FL_EXTERNAL_LB) {
873			if (be_loopback_test(adapter, BE_ONE_PORT_EXT_LOOPBACK,
874					     &data[2]) != 0)
875				test->flags |= ETH_TEST_FL_FAILED;
876			test->flags |= ETH_TEST_FL_EXTERNAL_LB_DONE;
877		}
878	}
879
880	if (!lancer_chip(adapter) && be_test_ddr_dma(adapter) != 0) {
881		data[3] = 1;
882		test->flags |= ETH_TEST_FL_FAILED;
883	}
884
885	status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
886	if (status) {
887		test->flags |= ETH_TEST_FL_FAILED;
888		data[4] = -1;
889	} else if (!link_status) {
890		test->flags |= ETH_TEST_FL_FAILED;
891		data[4] = 1;
892	}
893}
894
895static int be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
896{
897	struct be_adapter *adapter = netdev_priv(netdev);
898
899	return be_load_fw(adapter, efl->data);
900}
901
902static int be_get_eeprom_len(struct net_device *netdev)
903{
904	struct be_adapter *adapter = netdev_priv(netdev);
905
906	if (!check_privilege(adapter, MAX_PRIVILEGES))
907		return 0;
908
909	if (lancer_chip(adapter)) {
910		if (be_physfn(adapter))
911			return lancer_cmd_get_file_len(adapter,
912						       LANCER_VPD_PF_FILE);
913		else
914			return lancer_cmd_get_file_len(adapter,
915						       LANCER_VPD_VF_FILE);
916	} else {
917		return BE_READ_SEEPROM_LEN;
918	}
919}
920
921static int be_read_eeprom(struct net_device *netdev,
922			  struct ethtool_eeprom *eeprom, uint8_t *data)
923{
924	struct be_adapter *adapter = netdev_priv(netdev);
925	struct be_dma_mem eeprom_cmd;
926	struct be_cmd_resp_seeprom_read *resp;
927	int status;
928
929	if (!eeprom->len)
930		return -EINVAL;
931
932	if (lancer_chip(adapter)) {
933		if (be_physfn(adapter))
934			return lancer_cmd_read_file(adapter, LANCER_VPD_PF_FILE,
935						    eeprom->len, data);
936		else
937			return lancer_cmd_read_file(adapter, LANCER_VPD_VF_FILE,
938						    eeprom->len, data);
939	}
940
941	eeprom->magic = BE_VENDOR_ID | (adapter->pdev->device<<16);
942
943	memset(&eeprom_cmd, 0, sizeof(struct be_dma_mem));
944	eeprom_cmd.size = sizeof(struct be_cmd_req_seeprom_read);
945	eeprom_cmd.va = dma_zalloc_coherent(&adapter->pdev->dev,
946					    eeprom_cmd.size, &eeprom_cmd.dma,
947					    GFP_KERNEL);
948
949	if (!eeprom_cmd.va)
950		return -ENOMEM;
951
952	status = be_cmd_get_seeprom_data(adapter, &eeprom_cmd);
953
954	if (!status) {
955		resp = eeprom_cmd.va;
956		memcpy(data, resp->seeprom_data + eeprom->offset, eeprom->len);
957	}
958	dma_free_coherent(&adapter->pdev->dev, eeprom_cmd.size, eeprom_cmd.va,
959			  eeprom_cmd.dma);
960
961	return be_cmd_status(status);
962}
963
964static u32 be_get_msg_level(struct net_device *netdev)
965{
966	struct be_adapter *adapter = netdev_priv(netdev);
967
968	return adapter->msg_enable;
969}
970
971static void be_set_msg_level(struct net_device *netdev, u32 level)
972{
973	struct be_adapter *adapter = netdev_priv(netdev);
974
975	if (adapter->msg_enable == level)
976		return;
977
978	if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW))
979		if (BEx_chip(adapter))
980			be_cmd_set_fw_log_level(adapter, level & NETIF_MSG_HW ?
981						FW_LOG_LEVEL_DEFAULT :
982						FW_LOG_LEVEL_FATAL);
983	adapter->msg_enable = level;
984}
985
986static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type)
987{
988	u64 data = 0;
989
990	switch (flow_type) {
991	case TCP_V4_FLOW:
992		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
993			data |= RXH_IP_DST | RXH_IP_SRC;
994		if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV4)
995			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
996		break;
997	case UDP_V4_FLOW:
998		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
999			data |= RXH_IP_DST | RXH_IP_SRC;
1000		if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV4)
1001			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1002		break;
1003	case TCP_V6_FLOW:
1004		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
1005			data |= RXH_IP_DST | RXH_IP_SRC;
1006		if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV6)
1007			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1008		break;
1009	case UDP_V6_FLOW:
1010		if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
1011			data |= RXH_IP_DST | RXH_IP_SRC;
1012		if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV6)
1013			data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1014		break;
1015	}
1016
1017	return data;
1018}
1019
1020static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
1021			u32 *rule_locs)
1022{
1023	struct be_adapter *adapter = netdev_priv(netdev);
1024
1025	if (!be_multi_rxq(adapter)) {
1026		dev_info(&adapter->pdev->dev,
1027			 "ethtool::get_rxnfc: RX flow hashing is disabled\n");
1028		return -EINVAL;
1029	}
1030
1031	switch (cmd->cmd) {
1032	case ETHTOOL_GRXFH:
1033		cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
1034		break;
1035	case ETHTOOL_GRXRINGS:
1036		cmd->data = adapter->num_rx_qs - 1;
1037		break;
1038	default:
1039		return -EINVAL;
1040	}
1041
1042	return 0;
1043}
1044
1045static int be_set_rss_hash_opts(struct be_adapter *adapter,
1046				struct ethtool_rxnfc *cmd)
1047{
1048	struct be_rx_obj *rxo;
1049	int status = 0, i, j;
1050	u8 rsstable[128];
1051	u32 rss_flags = adapter->rss_info.rss_flags;
1052
1053	if (cmd->data != L3_RSS_FLAGS &&
1054	    cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS))
1055		return -EINVAL;
1056
1057	switch (cmd->flow_type) {
1058	case TCP_V4_FLOW:
1059		if (cmd->data == L3_RSS_FLAGS)
1060			rss_flags &= ~RSS_ENABLE_TCP_IPV4;
1061		else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1062			rss_flags |= RSS_ENABLE_IPV4 |
1063					RSS_ENABLE_TCP_IPV4;
1064		break;
1065	case TCP_V6_FLOW:
1066		if (cmd->data == L3_RSS_FLAGS)
1067			rss_flags &= ~RSS_ENABLE_TCP_IPV6;
1068		else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1069			rss_flags |= RSS_ENABLE_IPV6 |
1070					RSS_ENABLE_TCP_IPV6;
1071		break;
1072	case UDP_V4_FLOW:
1073		if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1074		    BEx_chip(adapter))
1075			return -EINVAL;
1076
1077		if (cmd->data == L3_RSS_FLAGS)
1078			rss_flags &= ~RSS_ENABLE_UDP_IPV4;
1079		else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1080			rss_flags |= RSS_ENABLE_IPV4 |
1081					RSS_ENABLE_UDP_IPV4;
1082		break;
1083	case UDP_V6_FLOW:
1084		if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1085		    BEx_chip(adapter))
1086			return -EINVAL;
1087
1088		if (cmd->data == L3_RSS_FLAGS)
1089			rss_flags &= ~RSS_ENABLE_UDP_IPV6;
1090		else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1091			rss_flags |= RSS_ENABLE_IPV6 |
1092					RSS_ENABLE_UDP_IPV6;
1093		break;
1094	default:
1095		return -EINVAL;
1096	}
1097
1098	if (rss_flags == adapter->rss_info.rss_flags)
1099		return status;
1100
1101	if (be_multi_rxq(adapter)) {
1102		for (j = 0; j < 128; j += adapter->num_rss_qs) {
1103			for_all_rss_queues(adapter, rxo, i) {
1104				if ((j + i) >= 128)
1105					break;
1106				rsstable[j + i] = rxo->rss_id;
1107			}
1108		}
1109	}
1110
1111	status = be_cmd_rss_config(adapter, adapter->rss_info.rsstable,
1112				   rss_flags, 128, adapter->rss_info.rss_hkey);
1113	if (!status)
1114		adapter->rss_info.rss_flags = rss_flags;
1115
1116	return be_cmd_status(status);
1117}
1118
1119static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1120{
1121	struct be_adapter *adapter = netdev_priv(netdev);
1122	int status = 0;
1123
1124	if (!be_multi_rxq(adapter)) {
1125		dev_err(&adapter->pdev->dev,
1126			"ethtool::set_rxnfc: RX flow hashing is disabled\n");
1127		return -EINVAL;
1128	}
1129
1130	switch (cmd->cmd) {
1131	case ETHTOOL_SRXFH:
1132		status = be_set_rss_hash_opts(adapter, cmd);
1133		break;
1134	default:
1135		return -EINVAL;
1136	}
1137
1138	return status;
1139}
1140
1141static void be_get_channels(struct net_device *netdev,
1142			    struct ethtool_channels *ch)
1143{
1144	struct be_adapter *adapter = netdev_priv(netdev);
1145
1146	ch->combined_count = adapter->num_evt_qs;
1147	ch->max_combined = be_max_qs(adapter);
1148}
1149
1150static int be_set_channels(struct net_device  *netdev,
1151			   struct ethtool_channels *ch)
1152{
1153	struct be_adapter *adapter = netdev_priv(netdev);
1154	int status;
1155
1156	if (ch->rx_count || ch->tx_count || ch->other_count ||
1157	    !ch->combined_count || ch->combined_count > be_max_qs(adapter))
1158		return -EINVAL;
1159
1160	adapter->cfg_num_qs = ch->combined_count;
1161
1162	status = be_update_queues(adapter);
1163	return be_cmd_status(status);
1164}
1165
1166static u32 be_get_rxfh_indir_size(struct net_device *netdev)
1167{
1168	return RSS_INDIR_TABLE_LEN;
1169}
1170
1171static u32 be_get_rxfh_key_size(struct net_device *netdev)
1172{
1173	return RSS_HASH_KEY_LEN;
1174}
1175
1176static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
1177		       u8 *hfunc)
1178{
1179	struct be_adapter *adapter = netdev_priv(netdev);
1180	int i;
1181	struct rss_info *rss = &adapter->rss_info;
1182
1183	if (indir) {
1184		for (i = 0; i < RSS_INDIR_TABLE_LEN; i++)
1185			indir[i] = rss->rss_queue[i];
1186	}
1187
1188	if (hkey)
1189		memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN);
1190
1191	if (hfunc)
1192		*hfunc = ETH_RSS_HASH_TOP;
1193
1194	return 0;
1195}
1196
1197static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
1198		       const u8 *hkey, const u8 hfunc)
1199{
1200	int rc = 0, i, j;
1201	struct be_adapter *adapter = netdev_priv(netdev);
1202	u8 rsstable[RSS_INDIR_TABLE_LEN];
1203
1204	/* We do not allow change in unsupported parameters */
1205	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1206		return -EOPNOTSUPP;
1207
1208	if (indir) {
1209		struct be_rx_obj *rxo;
1210
1211		for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) {
1212			j = indir[i];
1213			rxo = &adapter->rx_obj[j];
1214			rsstable[i] = rxo->rss_id;
1215			adapter->rss_info.rss_queue[i] = j;
1216		}
1217	} else {
1218		memcpy(rsstable, adapter->rss_info.rsstable,
1219		       RSS_INDIR_TABLE_LEN);
1220	}
1221
1222	if (!hkey)
1223		hkey =  adapter->rss_info.rss_hkey;
1224
1225	rc = be_cmd_rss_config(adapter, rsstable,
1226			       adapter->rss_info.rss_flags,
1227			       RSS_INDIR_TABLE_LEN, hkey);
1228	if (rc) {
1229		adapter->rss_info.rss_flags = RSS_ENABLE_NONE;
1230		return -EIO;
1231	}
1232	memcpy(adapter->rss_info.rss_hkey, hkey, RSS_HASH_KEY_LEN);
1233	memcpy(adapter->rss_info.rsstable, rsstable,
1234	       RSS_INDIR_TABLE_LEN);
1235	return 0;
1236}
1237
1238static int be_get_module_info(struct net_device *netdev,
1239			      struct ethtool_modinfo *modinfo)
1240{
1241	struct be_adapter *adapter = netdev_priv(netdev);
1242	u8 page_data[PAGE_DATA_LEN];
1243	int status;
1244
1245	if (!check_privilege(adapter, MAX_PRIVILEGES))
1246		return -EOPNOTSUPP;
1247
1248	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
1249						   page_data);
1250	if (!status) {
1251		if (!page_data[SFP_PLUS_SFF_8472_COMP]) {
1252			modinfo->type = ETH_MODULE_SFF_8079;
1253			modinfo->eeprom_len = PAGE_DATA_LEN;
1254		} else {
1255			modinfo->type = ETH_MODULE_SFF_8472;
1256			modinfo->eeprom_len = 2 * PAGE_DATA_LEN;
1257		}
1258	}
1259	return be_cmd_status(status);
1260}
1261
1262static int be_get_module_eeprom(struct net_device *netdev,
1263				struct ethtool_eeprom *eeprom, u8 *data)
1264{
1265	struct be_adapter *adapter = netdev_priv(netdev);
1266	int status;
1267
1268	if (!check_privilege(adapter, MAX_PRIVILEGES))
1269		return -EOPNOTSUPP;
1270
1271	status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0,
1272						   data);
1273	if (status)
1274		goto err;
1275
1276	if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) {
1277		status = be_cmd_read_port_transceiver_data(adapter,
1278							   TR_PAGE_A2,
1279							   data +
1280							   PAGE_DATA_LEN);
1281		if (status)
1282			goto err;
1283	}
1284	if (eeprom->offset)
1285		memcpy(data, data + eeprom->offset, eeprom->len);
1286err:
1287	return be_cmd_status(status);
1288}
1289
1290const struct ethtool_ops be_ethtool_ops = {
1291	.get_settings = be_get_settings,
1292	.get_drvinfo = be_get_drvinfo,
1293	.get_wol = be_get_wol,
1294	.set_wol = be_set_wol,
1295	.get_link = ethtool_op_get_link,
1296	.get_eeprom_len = be_get_eeprom_len,
1297	.get_eeprom = be_read_eeprom,
1298	.get_coalesce = be_get_coalesce,
1299	.set_coalesce = be_set_coalesce,
1300	.get_ringparam = be_get_ringparam,
1301	.get_pauseparam = be_get_pauseparam,
1302	.set_pauseparam = be_set_pauseparam,
1303	.get_strings = be_get_stat_strings,
1304	.set_phys_id = be_set_phys_id,
1305	.set_dump = be_set_dump,
1306	.get_msglevel = be_get_msg_level,
1307	.set_msglevel = be_set_msg_level,
1308	.get_sset_count = be_get_sset_count,
1309	.get_ethtool_stats = be_get_ethtool_stats,
1310	.get_regs_len = be_get_reg_len,
1311	.get_regs = be_get_regs,
1312	.flash_device = be_do_flash,
1313	.self_test = be_self_test,
1314	.get_rxnfc = be_get_rxnfc,
1315	.set_rxnfc = be_set_rxnfc,
1316	.get_rxfh_indir_size = be_get_rxfh_indir_size,
1317	.get_rxfh_key_size = be_get_rxfh_key_size,
1318	.get_rxfh = be_get_rxfh,
1319	.set_rxfh = be_set_rxfh,
1320	.get_channels = be_get_channels,
1321	.set_channels = be_set_channels,
1322	.get_module_info = be_get_module_info,
1323	.get_module_eeprom = be_get_module_eeprom
1324};
1325