1/******************************************************************************
2 * This software may be used and distributed according to the terms of
3 * the GNU General Public License (GPL), incorporated herein by reference.
4 * Drivers based on or derived from this code fall under the GPL and must
5 * retain the authorship, copyright and license notice.  This file is not
6 * a complete program and may only be used when the entire operating
7 * system is licensed under the GPL.
8 * See the file COPYING in this distribution for more information.
9 *
10 * vxge-ethtool.c: Driver for Exar Corp's X3100 Series 10GbE PCIe I/O
11 *                 Virtualized Server Adapter.
12 * Copyright(c) 2002-2010 Exar Corp.
13 ******************************************************************************/
14#include <linux/ethtool.h>
15#include <linux/slab.h>
16#include <linux/pci.h>
17#include <linux/etherdevice.h>
18
19#include "vxge-ethtool.h"
20
21/**
22 * vxge_ethtool_sset - Sets different link parameters.
23 * @dev: device pointer.
24 * @info: pointer to the structure with parameters given by ethtool to set
25 * link information.
26 *
27 * The function sets different link parameters provided by the user onto
28 * the NIC.
29 * Return value:
30 * 0 on success.
31 */
32static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
33{
34	/* We currently only support 10Gb/FULL */
35	if ((info->autoneg == AUTONEG_ENABLE) ||
36	    (ethtool_cmd_speed(info) != SPEED_10000) ||
37	    (info->duplex != DUPLEX_FULL))
38		return -EINVAL;
39
40	return 0;
41}
42
43/**
44 * vxge_ethtool_gset - Return link specific information.
45 * @dev: device pointer.
46 * @info: pointer to the structure with parameters given by ethtool
47 * to return link information.
48 *
49 * Returns link specific information like speed, duplex etc.. to ethtool.
50 * Return value :
51 * return 0 on success.
52 */
53static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
54{
55	info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
56	info->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
57	info->port = PORT_FIBRE;
58
59	info->transceiver = XCVR_EXTERNAL;
60
61	if (netif_carrier_ok(dev)) {
62		ethtool_cmd_speed_set(info, SPEED_10000);
63		info->duplex = DUPLEX_FULL;
64	} else {
65		ethtool_cmd_speed_set(info, -1);
66		info->duplex = -1;
67	}
68
69	info->autoneg = AUTONEG_DISABLE;
70	return 0;
71}
72
73/**
74 * vxge_ethtool_gdrvinfo - Returns driver specific information.
75 * @dev: device pointer.
76 * @info: pointer to the structure with parameters given by ethtool to
77 * return driver information.
78 *
79 * Returns driver specefic information like name, version etc.. to ethtool.
80 */
81static void vxge_ethtool_gdrvinfo(struct net_device *dev,
82				  struct ethtool_drvinfo *info)
83{
84	struct vxgedev *vdev = netdev_priv(dev);
85	strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME));
86	strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
87	strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN);
88	strlcpy(info->bus_info, pci_name(vdev->pdev), sizeof(info->bus_info));
89	info->regdump_len = sizeof(struct vxge_hw_vpath_reg)
90				* vdev->no_of_vpath;
91
92	info->n_stats = STAT_LEN;
93}
94
95/**
96 * vxge_ethtool_gregs - dumps the entire space of Titan into the buffer.
97 * @dev: device pointer.
98 * @regs: pointer to the structure with parameters given by ethtool for
99 * dumping the registers.
100 * @reg_space: The input argumnet into which all the registers are dumped.
101 *
102 * Dumps the vpath register space of Titan NIC into the user given
103 * buffer area.
104 */
105static void vxge_ethtool_gregs(struct net_device *dev,
106			       struct ethtool_regs *regs, void *space)
107{
108	int index, offset;
109	enum vxge_hw_status status;
110	u64 reg;
111	u64 *reg_space = (u64 *)space;
112	struct vxgedev *vdev = netdev_priv(dev);
113	struct __vxge_hw_device *hldev = vdev->devh;
114
115	regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
116	regs->version = vdev->pdev->subsystem_device;
117	for (index = 0; index < vdev->no_of_vpath; index++) {
118		for (offset = 0; offset < sizeof(struct vxge_hw_vpath_reg);
119				offset += 8) {
120			status = vxge_hw_mgmt_reg_read(hldev,
121					vxge_hw_mgmt_reg_type_vpath,
122					vdev->vpaths[index].device_id,
123					offset, &reg);
124			if (status != VXGE_HW_OK) {
125				vxge_debug_init(VXGE_ERR,
126					"%s:%d Getting reg dump Failed",
127						__func__, __LINE__);
128				return;
129			}
130			*reg_space++ = reg;
131		}
132	}
133}
134
135/**
136 * vxge_ethtool_idnic - To physically identify the nic on the system.
137 * @dev : device pointer.
138 * @state : requested LED state
139 *
140 * Used to physically identify the NIC on the system.
141 * 0 on success
142 */
143static int vxge_ethtool_idnic(struct net_device *dev,
144			      enum ethtool_phys_id_state state)
145{
146	struct vxgedev *vdev = netdev_priv(dev);
147	struct __vxge_hw_device *hldev = vdev->devh;
148
149	switch (state) {
150	case ETHTOOL_ID_ACTIVE:
151		vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
152		break;
153
154	case ETHTOOL_ID_INACTIVE:
155		vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
156		break;
157
158	default:
159		return -EINVAL;
160	}
161
162	return 0;
163}
164
165/**
166 * vxge_ethtool_getpause_data - Pause frame frame generation and reception.
167 * @dev : device pointer.
168 * @ep : pointer to the structure with pause parameters given by ethtool.
169 * Description:
170 * Returns the Pause frame generation and reception capability of the NIC.
171 * Return value:
172 *  void
173 */
174static void vxge_ethtool_getpause_data(struct net_device *dev,
175				       struct ethtool_pauseparam *ep)
176{
177	struct vxgedev *vdev = netdev_priv(dev);
178	struct __vxge_hw_device *hldev = vdev->devh;
179
180	vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause);
181}
182
183/**
184 * vxge_ethtool_setpause_data -  set/reset pause frame generation.
185 * @dev : device pointer.
186 * @ep : pointer to the structure with pause parameters given by ethtool.
187 * Description:
188 * It can be used to set or reset Pause frame generation or reception
189 * support of the NIC.
190 * Return value:
191 * int, returns 0 on Success
192 */
193static int vxge_ethtool_setpause_data(struct net_device *dev,
194				      struct ethtool_pauseparam *ep)
195{
196	struct vxgedev *vdev = netdev_priv(dev);
197	struct __vxge_hw_device *hldev = vdev->devh;
198
199	vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause);
200
201	vdev->config.tx_pause_enable = ep->tx_pause;
202	vdev->config.rx_pause_enable = ep->rx_pause;
203
204	return 0;
205}
206
207static void vxge_get_ethtool_stats(struct net_device *dev,
208				   struct ethtool_stats *estats, u64 *tmp_stats)
209{
210	int j, k;
211	enum vxge_hw_status status;
212	enum vxge_hw_status swstatus;
213	struct vxge_vpath *vpath = NULL;
214	struct vxgedev *vdev = netdev_priv(dev);
215	struct __vxge_hw_device *hldev = vdev->devh;
216	struct vxge_hw_xmac_stats *xmac_stats;
217	struct vxge_hw_device_stats_sw_info *sw_stats;
218	struct vxge_hw_device_stats_hw_info *hw_stats;
219
220	u64 *ptr = tmp_stats;
221
222	memset(tmp_stats, 0,
223		vxge_ethtool_get_sset_count(dev, ETH_SS_STATS) * sizeof(u64));
224
225	xmac_stats = kzalloc(sizeof(struct vxge_hw_xmac_stats), GFP_KERNEL);
226	if (xmac_stats == NULL) {
227		vxge_debug_init(VXGE_ERR,
228			"%s : %d Memory Allocation failed for xmac_stats",
229				 __func__, __LINE__);
230		return;
231	}
232
233	sw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_sw_info),
234				GFP_KERNEL);
235	if (sw_stats == NULL) {
236		kfree(xmac_stats);
237		vxge_debug_init(VXGE_ERR,
238			"%s : %d Memory Allocation failed for sw_stats",
239			__func__, __LINE__);
240		return;
241	}
242
243	hw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_hw_info),
244				GFP_KERNEL);
245	if (hw_stats == NULL) {
246		kfree(xmac_stats);
247		kfree(sw_stats);
248		vxge_debug_init(VXGE_ERR,
249			"%s : %d Memory Allocation failed for hw_stats",
250			__func__, __LINE__);
251		return;
252	}
253
254	*ptr++ = 0;
255	status = vxge_hw_device_xmac_stats_get(hldev, xmac_stats);
256	if (status != VXGE_HW_OK) {
257		if (status != VXGE_HW_ERR_PRIVILAGED_OPEARATION) {
258			vxge_debug_init(VXGE_ERR,
259				"%s : %d Failure in getting xmac stats",
260				__func__, __LINE__);
261		}
262	}
263	swstatus = vxge_hw_driver_stats_get(hldev, sw_stats);
264	if (swstatus != VXGE_HW_OK) {
265		vxge_debug_init(VXGE_ERR,
266			"%s : %d Failure in getting sw stats",
267			__func__, __LINE__);
268	}
269
270	status = vxge_hw_device_stats_get(hldev, hw_stats);
271	if (status != VXGE_HW_OK) {
272		vxge_debug_init(VXGE_ERR,
273			"%s : %d hw_stats_get error", __func__, __LINE__);
274	}
275
276	for (k = 0; k < vdev->no_of_vpath; k++) {
277		struct vxge_hw_vpath_stats_hw_info *vpath_info;
278
279		vpath = &vdev->vpaths[k];
280		j = vpath->device_id;
281		vpath_info = hw_stats->vpath_info[j];
282		if (!vpath_info) {
283			memset(ptr, 0, (VXGE_HW_VPATH_TX_STATS_LEN +
284				VXGE_HW_VPATH_RX_STATS_LEN) * sizeof(u64));
285			ptr += (VXGE_HW_VPATH_TX_STATS_LEN +
286				VXGE_HW_VPATH_RX_STATS_LEN);
287			continue;
288		}
289
290		*ptr++ = vpath_info->tx_stats.tx_ttl_eth_frms;
291		*ptr++ = vpath_info->tx_stats.tx_ttl_eth_octets;
292		*ptr++ = vpath_info->tx_stats.tx_data_octets;
293		*ptr++ = vpath_info->tx_stats.tx_mcast_frms;
294		*ptr++ = vpath_info->tx_stats.tx_bcast_frms;
295		*ptr++ = vpath_info->tx_stats.tx_ucast_frms;
296		*ptr++ = vpath_info->tx_stats.tx_tagged_frms;
297		*ptr++ = vpath_info->tx_stats.tx_vld_ip;
298		*ptr++ = vpath_info->tx_stats.tx_vld_ip_octets;
299		*ptr++ = vpath_info->tx_stats.tx_icmp;
300		*ptr++ = vpath_info->tx_stats.tx_tcp;
301		*ptr++ = vpath_info->tx_stats.tx_rst_tcp;
302		*ptr++ = vpath_info->tx_stats.tx_udp;
303		*ptr++ = vpath_info->tx_stats.tx_unknown_protocol;
304		*ptr++ = vpath_info->tx_stats.tx_lost_ip;
305		*ptr++ = vpath_info->tx_stats.tx_parse_error;
306		*ptr++ = vpath_info->tx_stats.tx_tcp_offload;
307		*ptr++ = vpath_info->tx_stats.tx_retx_tcp_offload;
308		*ptr++ = vpath_info->tx_stats.tx_lost_ip_offload;
309		*ptr++ = vpath_info->rx_stats.rx_ttl_eth_frms;
310		*ptr++ = vpath_info->rx_stats.rx_vld_frms;
311		*ptr++ = vpath_info->rx_stats.rx_offload_frms;
312		*ptr++ = vpath_info->rx_stats.rx_ttl_eth_octets;
313		*ptr++ = vpath_info->rx_stats.rx_data_octets;
314		*ptr++ = vpath_info->rx_stats.rx_offload_octets;
315		*ptr++ = vpath_info->rx_stats.rx_vld_mcast_frms;
316		*ptr++ = vpath_info->rx_stats.rx_vld_bcast_frms;
317		*ptr++ = vpath_info->rx_stats.rx_accepted_ucast_frms;
318		*ptr++ = vpath_info->rx_stats.rx_accepted_nucast_frms;
319		*ptr++ = vpath_info->rx_stats.rx_tagged_frms;
320		*ptr++ = vpath_info->rx_stats.rx_long_frms;
321		*ptr++ = vpath_info->rx_stats.rx_usized_frms;
322		*ptr++ = vpath_info->rx_stats.rx_osized_frms;
323		*ptr++ = vpath_info->rx_stats.rx_frag_frms;
324		*ptr++ = vpath_info->rx_stats.rx_jabber_frms;
325		*ptr++ = vpath_info->rx_stats.rx_ttl_64_frms;
326		*ptr++ = vpath_info->rx_stats.rx_ttl_65_127_frms;
327		*ptr++ = vpath_info->rx_stats.rx_ttl_128_255_frms;
328		*ptr++ = vpath_info->rx_stats.rx_ttl_256_511_frms;
329		*ptr++ = vpath_info->rx_stats.rx_ttl_512_1023_frms;
330		*ptr++ = vpath_info->rx_stats.rx_ttl_1024_1518_frms;
331		*ptr++ = vpath_info->rx_stats.rx_ttl_1519_4095_frms;
332		*ptr++ = vpath_info->rx_stats.rx_ttl_4096_8191_frms;
333		*ptr++ = vpath_info->rx_stats.rx_ttl_8192_max_frms;
334		*ptr++ = vpath_info->rx_stats.rx_ttl_gt_max_frms;
335		*ptr++ = vpath_info->rx_stats.rx_ip;
336		*ptr++ = vpath_info->rx_stats.rx_accepted_ip;
337		*ptr++ = vpath_info->rx_stats.rx_ip_octets;
338		*ptr++ = vpath_info->rx_stats.rx_err_ip;
339		*ptr++ = vpath_info->rx_stats.rx_icmp;
340		*ptr++ = vpath_info->rx_stats.rx_tcp;
341		*ptr++ = vpath_info->rx_stats.rx_udp;
342		*ptr++ = vpath_info->rx_stats.rx_err_tcp;
343		*ptr++ = vpath_info->rx_stats.rx_lost_frms;
344		*ptr++ = vpath_info->rx_stats.rx_lost_ip;
345		*ptr++ = vpath_info->rx_stats.rx_lost_ip_offload;
346		*ptr++ = vpath_info->rx_stats.rx_various_discard;
347		*ptr++ = vpath_info->rx_stats.rx_sleep_discard;
348		*ptr++ = vpath_info->rx_stats.rx_red_discard;
349		*ptr++ = vpath_info->rx_stats.rx_queue_full_discard;
350		*ptr++ = vpath_info->rx_stats.rx_mpa_ok_frms;
351	}
352	*ptr++ = 0;
353	for (k = 0; k < vdev->max_config_port; k++) {
354		*ptr++ = xmac_stats->aggr_stats[k].tx_frms;
355		*ptr++ = xmac_stats->aggr_stats[k].tx_data_octets;
356		*ptr++ = xmac_stats->aggr_stats[k].tx_mcast_frms;
357		*ptr++ = xmac_stats->aggr_stats[k].tx_bcast_frms;
358		*ptr++ = xmac_stats->aggr_stats[k].tx_discarded_frms;
359		*ptr++ = xmac_stats->aggr_stats[k].tx_errored_frms;
360		*ptr++ = xmac_stats->aggr_stats[k].rx_frms;
361		*ptr++ = xmac_stats->aggr_stats[k].rx_data_octets;
362		*ptr++ = xmac_stats->aggr_stats[k].rx_mcast_frms;
363		*ptr++ = xmac_stats->aggr_stats[k].rx_bcast_frms;
364		*ptr++ = xmac_stats->aggr_stats[k].rx_discarded_frms;
365		*ptr++ = xmac_stats->aggr_stats[k].rx_errored_frms;
366		*ptr++ = xmac_stats->aggr_stats[k].rx_unknown_slow_proto_frms;
367	}
368	*ptr++ = 0;
369	for (k = 0; k < vdev->max_config_port; k++) {
370		*ptr++ = xmac_stats->port_stats[k].tx_ttl_frms;
371		*ptr++ = xmac_stats->port_stats[k].tx_ttl_octets;
372		*ptr++ = xmac_stats->port_stats[k].tx_data_octets;
373		*ptr++ = xmac_stats->port_stats[k].tx_mcast_frms;
374		*ptr++ = xmac_stats->port_stats[k].tx_bcast_frms;
375		*ptr++ = xmac_stats->port_stats[k].tx_ucast_frms;
376		*ptr++ = xmac_stats->port_stats[k].tx_tagged_frms;
377		*ptr++ = xmac_stats->port_stats[k].tx_vld_ip;
378		*ptr++ = xmac_stats->port_stats[k].tx_vld_ip_octets;
379		*ptr++ = xmac_stats->port_stats[k].tx_icmp;
380		*ptr++ = xmac_stats->port_stats[k].tx_tcp;
381		*ptr++ = xmac_stats->port_stats[k].tx_rst_tcp;
382		*ptr++ = xmac_stats->port_stats[k].tx_udp;
383		*ptr++ = xmac_stats->port_stats[k].tx_parse_error;
384		*ptr++ = xmac_stats->port_stats[k].tx_unknown_protocol;
385		*ptr++ = xmac_stats->port_stats[k].tx_pause_ctrl_frms;
386		*ptr++ = xmac_stats->port_stats[k].tx_marker_pdu_frms;
387		*ptr++ = xmac_stats->port_stats[k].tx_lacpdu_frms;
388		*ptr++ = xmac_stats->port_stats[k].tx_drop_ip;
389		*ptr++ = xmac_stats->port_stats[k].tx_marker_resp_pdu_frms;
390		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_char2_match;
391		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_char1_match;
392		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_column2_match;
393		*ptr++ = xmac_stats->port_stats[k].tx_xgmii_column1_match;
394		*ptr++ = xmac_stats->port_stats[k].tx_any_err_frms;
395		*ptr++ = xmac_stats->port_stats[k].tx_drop_frms;
396		*ptr++ = xmac_stats->port_stats[k].rx_ttl_frms;
397		*ptr++ = xmac_stats->port_stats[k].rx_vld_frms;
398		*ptr++ = xmac_stats->port_stats[k].rx_offload_frms;
399		*ptr++ = xmac_stats->port_stats[k].rx_ttl_octets;
400		*ptr++ = xmac_stats->port_stats[k].rx_data_octets;
401		*ptr++ = xmac_stats->port_stats[k].rx_offload_octets;
402		*ptr++ = xmac_stats->port_stats[k].rx_vld_mcast_frms;
403		*ptr++ = xmac_stats->port_stats[k].rx_vld_bcast_frms;
404		*ptr++ = xmac_stats->port_stats[k].rx_accepted_ucast_frms;
405		*ptr++ = xmac_stats->port_stats[k].rx_accepted_nucast_frms;
406		*ptr++ = xmac_stats->port_stats[k].rx_tagged_frms;
407		*ptr++ = xmac_stats->port_stats[k].rx_long_frms;
408		*ptr++ = xmac_stats->port_stats[k].rx_usized_frms;
409		*ptr++ = xmac_stats->port_stats[k].rx_osized_frms;
410		*ptr++ = xmac_stats->port_stats[k].rx_frag_frms;
411		*ptr++ = xmac_stats->port_stats[k].rx_jabber_frms;
412		*ptr++ = xmac_stats->port_stats[k].rx_ttl_64_frms;
413		*ptr++ = xmac_stats->port_stats[k].rx_ttl_65_127_frms;
414		*ptr++ = xmac_stats->port_stats[k].rx_ttl_128_255_frms;
415		*ptr++ = xmac_stats->port_stats[k].rx_ttl_256_511_frms;
416		*ptr++ = xmac_stats->port_stats[k].rx_ttl_512_1023_frms;
417		*ptr++ = xmac_stats->port_stats[k].rx_ttl_1024_1518_frms;
418		*ptr++ = xmac_stats->port_stats[k].rx_ttl_1519_4095_frms;
419		*ptr++ = xmac_stats->port_stats[k].rx_ttl_4096_8191_frms;
420		*ptr++ = xmac_stats->port_stats[k].rx_ttl_8192_max_frms;
421		*ptr++ = xmac_stats->port_stats[k].rx_ttl_gt_max_frms;
422		*ptr++ = xmac_stats->port_stats[k].rx_ip;
423		*ptr++ = xmac_stats->port_stats[k].rx_accepted_ip;
424		*ptr++ = xmac_stats->port_stats[k].rx_ip_octets;
425		*ptr++ = xmac_stats->port_stats[k].rx_err_ip;
426		*ptr++ = xmac_stats->port_stats[k].rx_icmp;
427		*ptr++ = xmac_stats->port_stats[k].rx_tcp;
428		*ptr++ = xmac_stats->port_stats[k].rx_udp;
429		*ptr++ = xmac_stats->port_stats[k].rx_err_tcp;
430		*ptr++ = xmac_stats->port_stats[k].rx_pause_count;
431		*ptr++ = xmac_stats->port_stats[k].rx_pause_ctrl_frms;
432		*ptr++ = xmac_stats->port_stats[k].rx_unsup_ctrl_frms;
433		*ptr++ = xmac_stats->port_stats[k].rx_fcs_err_frms;
434		*ptr++ = xmac_stats->port_stats[k].rx_in_rng_len_err_frms;
435		*ptr++ = xmac_stats->port_stats[k].rx_out_rng_len_err_frms;
436		*ptr++ = xmac_stats->port_stats[k].rx_drop_frms;
437		*ptr++ = xmac_stats->port_stats[k].rx_discarded_frms;
438		*ptr++ = xmac_stats->port_stats[k].rx_drop_ip;
439		*ptr++ = xmac_stats->port_stats[k].rx_drop_udp;
440		*ptr++ = xmac_stats->port_stats[k].rx_marker_pdu_frms;
441		*ptr++ = xmac_stats->port_stats[k].rx_lacpdu_frms;
442		*ptr++ = xmac_stats->port_stats[k].rx_unknown_pdu_frms;
443		*ptr++ = xmac_stats->port_stats[k].rx_marker_resp_pdu_frms;
444		*ptr++ = xmac_stats->port_stats[k].rx_fcs_discard;
445		*ptr++ = xmac_stats->port_stats[k].rx_illegal_pdu_frms;
446		*ptr++ = xmac_stats->port_stats[k].rx_switch_discard;
447		*ptr++ = xmac_stats->port_stats[k].rx_len_discard;
448		*ptr++ = xmac_stats->port_stats[k].rx_rpa_discard;
449		*ptr++ = xmac_stats->port_stats[k].rx_l2_mgmt_discard;
450		*ptr++ = xmac_stats->port_stats[k].rx_rts_discard;
451		*ptr++ = xmac_stats->port_stats[k].rx_trash_discard;
452		*ptr++ = xmac_stats->port_stats[k].rx_buff_full_discard;
453		*ptr++ = xmac_stats->port_stats[k].rx_red_discard;
454		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_ctrl_err_cnt;
455		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_data_err_cnt;
456		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_char1_match;
457		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_err_sym;
458		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_column1_match;
459		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_char2_match;
460		*ptr++ = xmac_stats->port_stats[k].rx_local_fault;
461		*ptr++ = xmac_stats->port_stats[k].rx_xgmii_column2_match;
462		*ptr++ = xmac_stats->port_stats[k].rx_jettison;
463		*ptr++ = xmac_stats->port_stats[k].rx_remote_fault;
464	}
465
466	*ptr++ = 0;
467	for (k = 0; k < vdev->no_of_vpath; k++) {
468		struct vxge_hw_vpath_stats_sw_info *vpath_info;
469
470		vpath = &vdev->vpaths[k];
471		j = vpath->device_id;
472		vpath_info = (struct vxge_hw_vpath_stats_sw_info *)
473				&sw_stats->vpath_info[j];
474		*ptr++ = vpath_info->soft_reset_cnt;
475		*ptr++ = vpath_info->error_stats.unknown_alarms;
476		*ptr++ = vpath_info->error_stats.network_sustained_fault;
477		*ptr++ = vpath_info->error_stats.network_sustained_ok;
478		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_overwrite;
479		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_poison;
480		*ptr++ = vpath_info->error_stats.kdfcctl_fifo0_dma_error;
481		*ptr++ = vpath_info->error_stats.dblgen_fifo0_overflow;
482		*ptr++ = vpath_info->error_stats.statsb_pif_chain_error;
483		*ptr++ = vpath_info->error_stats.statsb_drop_timeout;
484		*ptr++ = vpath_info->error_stats.target_illegal_access;
485		*ptr++ = vpath_info->error_stats.ini_serr_det;
486		*ptr++ = vpath_info->error_stats.prc_ring_bumps;
487		*ptr++ = vpath_info->error_stats.prc_rxdcm_sc_err;
488		*ptr++ = vpath_info->error_stats.prc_rxdcm_sc_abort;
489		*ptr++ = vpath_info->error_stats.prc_quanta_size_err;
490		*ptr++ = vpath_info->ring_stats.common_stats.full_cnt;
491		*ptr++ = vpath_info->ring_stats.common_stats.usage_cnt;
492		*ptr++ = vpath_info->ring_stats.common_stats.usage_max;
493		*ptr++ = vpath_info->ring_stats.common_stats.
494					reserve_free_swaps_cnt;
495		*ptr++ = vpath_info->ring_stats.common_stats.total_compl_cnt;
496		for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
497			*ptr++ = vpath_info->ring_stats.rxd_t_code_err_cnt[j];
498		*ptr++ = vpath_info->fifo_stats.common_stats.full_cnt;
499		*ptr++ = vpath_info->fifo_stats.common_stats.usage_cnt;
500		*ptr++ = vpath_info->fifo_stats.common_stats.usage_max;
501		*ptr++ = vpath_info->fifo_stats.common_stats.
502						reserve_free_swaps_cnt;
503		*ptr++ = vpath_info->fifo_stats.common_stats.total_compl_cnt;
504		*ptr++ = vpath_info->fifo_stats.total_posts;
505		*ptr++ = vpath_info->fifo_stats.total_buffers;
506		for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
507			*ptr++ = vpath_info->fifo_stats.txd_t_code_err_cnt[j];
508	}
509
510	*ptr++ = 0;
511	for (k = 0; k < vdev->no_of_vpath; k++) {
512		struct vxge_hw_vpath_stats_hw_info *vpath_info;
513		vpath = &vdev->vpaths[k];
514		j = vpath->device_id;
515		vpath_info = hw_stats->vpath_info[j];
516		if (!vpath_info) {
517			memset(ptr, 0, VXGE_HW_VPATH_STATS_LEN * sizeof(u64));
518			ptr += VXGE_HW_VPATH_STATS_LEN;
519			continue;
520		}
521		*ptr++ = vpath_info->ini_num_mwr_sent;
522		*ptr++ = vpath_info->ini_num_mrd_sent;
523		*ptr++ = vpath_info->ini_num_cpl_rcvd;
524		*ptr++ = vpath_info->ini_num_mwr_byte_sent;
525		*ptr++ = vpath_info->ini_num_cpl_byte_rcvd;
526		*ptr++ = vpath_info->wrcrdtarb_xoff;
527		*ptr++ = vpath_info->rdcrdtarb_xoff;
528		*ptr++ = vpath_info->vpath_genstats_count0;
529		*ptr++ = vpath_info->vpath_genstats_count1;
530		*ptr++ = vpath_info->vpath_genstats_count2;
531		*ptr++ = vpath_info->vpath_genstats_count3;
532		*ptr++ = vpath_info->vpath_genstats_count4;
533		*ptr++ = vpath_info->vpath_genstats_count5;
534		*ptr++ = vpath_info->prog_event_vnum0;
535		*ptr++ = vpath_info->prog_event_vnum1;
536		*ptr++ = vpath_info->prog_event_vnum2;
537		*ptr++ = vpath_info->prog_event_vnum3;
538		*ptr++ = vpath_info->rx_multi_cast_frame_discard;
539		*ptr++ = vpath_info->rx_frm_transferred;
540		*ptr++ = vpath_info->rxd_returned;
541		*ptr++ = vpath_info->rx_mpa_len_fail_frms;
542		*ptr++ = vpath_info->rx_mpa_mrk_fail_frms;
543		*ptr++ = vpath_info->rx_mpa_crc_fail_frms;
544		*ptr++ = vpath_info->rx_permitted_frms;
545		*ptr++ = vpath_info->rx_vp_reset_discarded_frms;
546		*ptr++ = vpath_info->rx_wol_frms;
547		*ptr++ = vpath_info->tx_vp_reset_discarded_frms;
548	}
549
550	*ptr++ = 0;
551	*ptr++ = vdev->stats.vpaths_open;
552	*ptr++ = vdev->stats.vpath_open_fail;
553	*ptr++ = vdev->stats.link_up;
554	*ptr++ = vdev->stats.link_down;
555
556	for (k = 0; k < vdev->no_of_vpath; k++) {
557		*ptr += vdev->vpaths[k].fifo.stats.tx_frms;
558		*(ptr + 1) += vdev->vpaths[k].fifo.stats.tx_errors;
559		*(ptr + 2) += vdev->vpaths[k].fifo.stats.tx_bytes;
560		*(ptr + 3) += vdev->vpaths[k].fifo.stats.txd_not_free;
561		*(ptr + 4) += vdev->vpaths[k].fifo.stats.txd_out_of_desc;
562		*(ptr + 5) += vdev->vpaths[k].ring.stats.rx_frms;
563		*(ptr + 6) += vdev->vpaths[k].ring.stats.rx_errors;
564		*(ptr + 7) += vdev->vpaths[k].ring.stats.rx_bytes;
565		*(ptr + 8) += vdev->vpaths[k].ring.stats.rx_mcast;
566		*(ptr + 9) += vdev->vpaths[k].fifo.stats.pci_map_fail +
567				vdev->vpaths[k].ring.stats.pci_map_fail;
568		*(ptr + 10) += vdev->vpaths[k].ring.stats.skb_alloc_fail;
569	}
570
571	ptr += 12;
572
573	kfree(xmac_stats);
574	kfree(sw_stats);
575	kfree(hw_stats);
576}
577
578static void vxge_ethtool_get_strings(struct net_device *dev, u32 stringset,
579				     u8 *data)
580{
581	int stat_size = 0;
582	int i, j;
583	struct vxgedev *vdev = netdev_priv(dev);
584	switch (stringset) {
585	case ETH_SS_STATS:
586		vxge_add_string("VPATH STATISTICS%s\t\t\t",
587			&stat_size, data, "");
588		for (i = 0; i < vdev->no_of_vpath; i++) {
589			vxge_add_string("tx_ttl_eth_frms_%d\t\t\t",
590					&stat_size, data, i);
591			vxge_add_string("tx_ttl_eth_octects_%d\t\t",
592					&stat_size, data, i);
593			vxge_add_string("tx_data_octects_%d\t\t\t",
594					&stat_size, data, i);
595			vxge_add_string("tx_mcast_frms_%d\t\t\t",
596					&stat_size, data, i);
597			vxge_add_string("tx_bcast_frms_%d\t\t\t",
598					&stat_size, data, i);
599			vxge_add_string("tx_ucast_frms_%d\t\t\t",
600					&stat_size, data, i);
601			vxge_add_string("tx_tagged_frms_%d\t\t\t",
602					&stat_size, data, i);
603			vxge_add_string("tx_vld_ip_%d\t\t\t",
604					&stat_size, data, i);
605			vxge_add_string("tx_vld_ip_octects_%d\t\t",
606					&stat_size, data, i);
607			vxge_add_string("tx_icmp_%d\t\t\t\t",
608					&stat_size, data, i);
609			vxge_add_string("tx_tcp_%d\t\t\t\t",
610					&stat_size, data, i);
611			vxge_add_string("tx_rst_tcp_%d\t\t\t",
612					&stat_size, data, i);
613			vxge_add_string("tx_udp_%d\t\t\t\t",
614					&stat_size, data, i);
615			vxge_add_string("tx_unknown_proto_%d\t\t\t",
616					&stat_size, data, i);
617			vxge_add_string("tx_lost_ip_%d\t\t\t",
618					&stat_size, data, i);
619			vxge_add_string("tx_parse_error_%d\t\t\t",
620					&stat_size, data, i);
621			vxge_add_string("tx_tcp_offload_%d\t\t\t",
622					&stat_size, data, i);
623			vxge_add_string("tx_retx_tcp_offload_%d\t\t",
624					&stat_size, data, i);
625			vxge_add_string("tx_lost_ip_offload_%d\t\t",
626					&stat_size, data, i);
627			vxge_add_string("rx_ttl_eth_frms_%d\t\t\t",
628					&stat_size, data, i);
629			vxge_add_string("rx_vld_frms_%d\t\t\t",
630					&stat_size, data, i);
631			vxge_add_string("rx_offload_frms_%d\t\t\t",
632					&stat_size, data, i);
633			vxge_add_string("rx_ttl_eth_octects_%d\t\t",
634					&stat_size, data, i);
635			vxge_add_string("rx_data_octects_%d\t\t\t",
636					&stat_size, data, i);
637			vxge_add_string("rx_offload_octects_%d\t\t",
638					&stat_size, data, i);
639			vxge_add_string("rx_vld_mcast_frms_%d\t\t",
640					&stat_size, data, i);
641			vxge_add_string("rx_vld_bcast_frms_%d\t\t",
642					&stat_size, data, i);
643			vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
644					&stat_size, data, i);
645			vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
646					&stat_size, data, i);
647			vxge_add_string("rx_tagged_frms_%d\t\t\t",
648					&stat_size, data, i);
649			vxge_add_string("rx_long_frms_%d\t\t\t",
650					&stat_size, data, i);
651			vxge_add_string("rx_usized_frms_%d\t\t\t",
652					&stat_size, data, i);
653			vxge_add_string("rx_osized_frms_%d\t\t\t",
654					&stat_size, data, i);
655			vxge_add_string("rx_frag_frms_%d\t\t\t",
656					&stat_size, data, i);
657			vxge_add_string("rx_jabber_frms_%d\t\t\t",
658					&stat_size, data, i);
659			vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
660					&stat_size, data, i);
661			vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
662					&stat_size, data, i);
663			vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
664					&stat_size, data, i);
665			vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
666					&stat_size, data, i);
667			vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
668					&stat_size, data, i);
669			vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
670					&stat_size, data, i);
671			vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
672					&stat_size, data, i);
673			vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
674					&stat_size, data, i);
675			vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
676					&stat_size, data, i);
677			vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
678					&stat_size, data, i);
679			vxge_add_string("rx_ip%d\t\t\t\t",
680					&stat_size, data, i);
681			vxge_add_string("rx_accepted_ip_%d\t\t\t",
682					&stat_size, data, i);
683			vxge_add_string("rx_ip_octects_%d\t\t\t",
684					&stat_size, data, i);
685			vxge_add_string("rx_err_ip_%d\t\t\t",
686					&stat_size, data, i);
687			vxge_add_string("rx_icmp_%d\t\t\t\t",
688					&stat_size, data, i);
689			vxge_add_string("rx_tcp_%d\t\t\t\t",
690					&stat_size, data, i);
691			vxge_add_string("rx_udp_%d\t\t\t\t",
692					&stat_size, data, i);
693			vxge_add_string("rx_err_tcp_%d\t\t\t",
694					&stat_size, data, i);
695			vxge_add_string("rx_lost_frms_%d\t\t\t",
696					&stat_size, data, i);
697			vxge_add_string("rx_lost_ip_%d\t\t\t",
698					&stat_size, data, i);
699			vxge_add_string("rx_lost_ip_offload_%d\t\t",
700					&stat_size, data, i);
701			vxge_add_string("rx_various_discard_%d\t\t",
702					&stat_size, data, i);
703			vxge_add_string("rx_sleep_discard_%d\t\t\t",
704					&stat_size, data, i);
705			vxge_add_string("rx_red_discard_%d\t\t\t",
706					&stat_size, data, i);
707			vxge_add_string("rx_queue_full_discard_%d\t\t",
708					&stat_size, data, i);
709			vxge_add_string("rx_mpa_ok_frms_%d\t\t\t",
710					&stat_size, data, i);
711		}
712
713		vxge_add_string("\nAGGR STATISTICS%s\t\t\t\t",
714			&stat_size, data, "");
715		for (i = 0; i < vdev->max_config_port; i++) {
716			vxge_add_string("tx_frms_%d\t\t\t\t",
717				&stat_size, data, i);
718			vxge_add_string("tx_data_octects_%d\t\t\t",
719				&stat_size, data, i);
720			vxge_add_string("tx_mcast_frms_%d\t\t\t",
721				&stat_size, data, i);
722			vxge_add_string("tx_bcast_frms_%d\t\t\t",
723				&stat_size, data, i);
724			vxge_add_string("tx_discarded_frms_%d\t\t",
725				&stat_size, data, i);
726			vxge_add_string("tx_errored_frms_%d\t\t\t",
727				&stat_size, data, i);
728			vxge_add_string("rx_frms_%d\t\t\t\t",
729				&stat_size, data, i);
730			vxge_add_string("rx_data_octects_%d\t\t\t",
731				&stat_size, data, i);
732			vxge_add_string("rx_mcast_frms_%d\t\t\t",
733				&stat_size, data, i);
734			vxge_add_string("rx_bcast_frms_%d\t\t\t",
735				&stat_size, data, i);
736			vxge_add_string("rx_discarded_frms_%d\t\t",
737				&stat_size, data, i);
738			vxge_add_string("rx_errored_frms_%d\t\t\t",
739				&stat_size, data, i);
740			vxge_add_string("rx_unknown_slow_proto_frms_%d\t",
741				&stat_size, data, i);
742		}
743
744		vxge_add_string("\nPORT STATISTICS%s\t\t\t\t",
745			&stat_size, data, "");
746		for (i = 0; i < vdev->max_config_port; i++) {
747			vxge_add_string("tx_ttl_frms_%d\t\t\t",
748				&stat_size, data, i);
749			vxge_add_string("tx_ttl_octects_%d\t\t\t",
750				&stat_size, data, i);
751			vxge_add_string("tx_data_octects_%d\t\t\t",
752				&stat_size, data, i);
753			vxge_add_string("tx_mcast_frms_%d\t\t\t",
754				&stat_size, data, i);
755			vxge_add_string("tx_bcast_frms_%d\t\t\t",
756				&stat_size, data, i);
757			vxge_add_string("tx_ucast_frms_%d\t\t\t",
758				&stat_size, data, i);
759			vxge_add_string("tx_tagged_frms_%d\t\t\t",
760				&stat_size, data, i);
761			vxge_add_string("tx_vld_ip_%d\t\t\t",
762				&stat_size, data, i);
763			vxge_add_string("tx_vld_ip_octects_%d\t\t",
764				&stat_size, data, i);
765			vxge_add_string("tx_icmp_%d\t\t\t\t",
766				&stat_size, data, i);
767			vxge_add_string("tx_tcp_%d\t\t\t\t",
768				&stat_size, data, i);
769			vxge_add_string("tx_rst_tcp_%d\t\t\t",
770				&stat_size, data, i);
771			vxge_add_string("tx_udp_%d\t\t\t\t",
772				&stat_size, data, i);
773			vxge_add_string("tx_parse_error_%d\t\t\t",
774				&stat_size, data, i);
775			vxge_add_string("tx_unknown_protocol_%d\t\t",
776				&stat_size, data, i);
777			vxge_add_string("tx_pause_ctrl_frms_%d\t\t",
778				&stat_size, data, i);
779			vxge_add_string("tx_marker_pdu_frms_%d\t\t",
780				&stat_size, data, i);
781			vxge_add_string("tx_lacpdu_frms_%d\t\t\t",
782				&stat_size, data, i);
783			vxge_add_string("tx_drop_ip_%d\t\t\t",
784				&stat_size, data, i);
785			vxge_add_string("tx_marker_resp_pdu_frms_%d\t\t",
786				&stat_size, data, i);
787			vxge_add_string("tx_xgmii_char2_match_%d\t\t",
788				&stat_size, data, i);
789			vxge_add_string("tx_xgmii_char1_match_%d\t\t",
790				&stat_size, data, i);
791			vxge_add_string("tx_xgmii_column2_match_%d\t\t",
792				&stat_size, data, i);
793			vxge_add_string("tx_xgmii_column1_match_%d\t\t",
794				&stat_size, data, i);
795			vxge_add_string("tx_any_err_frms_%d\t\t\t",
796				&stat_size, data, i);
797			vxge_add_string("tx_drop_frms_%d\t\t\t",
798				&stat_size, data, i);
799			vxge_add_string("rx_ttl_frms_%d\t\t\t",
800				&stat_size, data, i);
801			vxge_add_string("rx_vld_frms_%d\t\t\t",
802				&stat_size, data, i);
803			vxge_add_string("rx_offload_frms_%d\t\t\t",
804				&stat_size, data, i);
805			vxge_add_string("rx_ttl_octects_%d\t\t\t",
806				&stat_size, data, i);
807			vxge_add_string("rx_data_octects_%d\t\t\t",
808				&stat_size, data, i);
809			vxge_add_string("rx_offload_octects_%d\t\t",
810				&stat_size, data, i);
811			vxge_add_string("rx_vld_mcast_frms_%d\t\t",
812				&stat_size, data, i);
813			vxge_add_string("rx_vld_bcast_frms_%d\t\t",
814				&stat_size, data, i);
815			vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
816				&stat_size, data, i);
817			vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
818				&stat_size, data, i);
819			vxge_add_string("rx_tagged_frms_%d\t\t\t",
820				&stat_size, data, i);
821			vxge_add_string("rx_long_frms_%d\t\t\t",
822				&stat_size, data, i);
823			vxge_add_string("rx_usized_frms_%d\t\t\t",
824				&stat_size, data, i);
825			vxge_add_string("rx_osized_frms_%d\t\t\t",
826				&stat_size, data, i);
827			vxge_add_string("rx_frag_frms_%d\t\t\t",
828				&stat_size, data, i);
829			vxge_add_string("rx_jabber_frms_%d\t\t\t",
830				&stat_size, data, i);
831			vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
832				&stat_size, data, i);
833			vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
834				&stat_size, data, i);
835			vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
836				&stat_size, data, i);
837			vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
838				&stat_size, data, i);
839			vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
840				&stat_size, data, i);
841			vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
842				&stat_size, data, i);
843			vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
844				&stat_size, data, i);
845			vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
846				&stat_size, data, i);
847			vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
848				&stat_size, data, i);
849			vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
850				&stat_size, data, i);
851			vxge_add_string("rx_ip_%d\t\t\t\t",
852				&stat_size, data, i);
853			vxge_add_string("rx_accepted_ip_%d\t\t\t",
854				&stat_size, data, i);
855			vxge_add_string("rx_ip_octets_%d\t\t\t",
856				&stat_size, data, i);
857			vxge_add_string("rx_err_ip_%d\t\t\t",
858				&stat_size, data, i);
859			vxge_add_string("rx_icmp_%d\t\t\t\t",
860				&stat_size, data, i);
861			vxge_add_string("rx_tcp_%d\t\t\t\t",
862				&stat_size, data, i);
863			vxge_add_string("rx_udp_%d\t\t\t\t",
864				&stat_size, data, i);
865			vxge_add_string("rx_err_tcp_%d\t\t\t",
866				&stat_size, data, i);
867			vxge_add_string("rx_pause_count_%d\t\t\t",
868				&stat_size, data, i);
869			vxge_add_string("rx_pause_ctrl_frms_%d\t\t",
870				&stat_size, data, i);
871			vxge_add_string("rx_unsup_ctrl_frms_%d\t\t",
872				&stat_size, data, i);
873			vxge_add_string("rx_fcs_err_frms_%d\t\t\t",
874				&stat_size, data, i);
875			vxge_add_string("rx_in_rng_len_err_frms_%d\t\t",
876				&stat_size, data, i);
877			vxge_add_string("rx_out_rng_len_err_frms_%d\t\t",
878				&stat_size, data, i);
879			vxge_add_string("rx_drop_frms_%d\t\t\t",
880				&stat_size, data, i);
881			vxge_add_string("rx_discard_frms_%d\t\t\t",
882				&stat_size, data, i);
883			vxge_add_string("rx_drop_ip_%d\t\t\t",
884				&stat_size, data, i);
885			vxge_add_string("rx_drop_udp_%d\t\t\t",
886				&stat_size, data, i);
887			vxge_add_string("rx_marker_pdu_frms_%d\t\t",
888				&stat_size, data, i);
889			vxge_add_string("rx_lacpdu_frms_%d\t\t\t",
890				&stat_size, data, i);
891			vxge_add_string("rx_unknown_pdu_frms_%d\t\t",
892				&stat_size, data, i);
893			vxge_add_string("rx_marker_resp_pdu_frms_%d\t\t",
894				&stat_size, data, i);
895			vxge_add_string("rx_fcs_discard_%d\t\t\t",
896				&stat_size, data, i);
897			vxge_add_string("rx_illegal_pdu_frms_%d\t\t",
898				&stat_size, data, i);
899			vxge_add_string("rx_switch_discard_%d\t\t",
900				&stat_size, data, i);
901			vxge_add_string("rx_len_discard_%d\t\t\t",
902				&stat_size, data, i);
903			vxge_add_string("rx_rpa_discard_%d\t\t\t",
904				&stat_size, data, i);
905			vxge_add_string("rx_l2_mgmt_discard_%d\t\t",
906				&stat_size, data, i);
907			vxge_add_string("rx_rts_discard_%d\t\t\t",
908				&stat_size, data, i);
909			vxge_add_string("rx_trash_discard_%d\t\t\t",
910				&stat_size, data, i);
911			vxge_add_string("rx_buff_full_discard_%d\t\t",
912				&stat_size, data, i);
913			vxge_add_string("rx_red_discard_%d\t\t\t",
914				&stat_size, data, i);
915			vxge_add_string("rx_xgmii_ctrl_err_cnt_%d\t\t",
916				&stat_size, data, i);
917			vxge_add_string("rx_xgmii_data_err_cnt_%d\t\t",
918				&stat_size, data, i);
919			vxge_add_string("rx_xgmii_char1_match_%d\t\t",
920				&stat_size, data, i);
921			vxge_add_string("rx_xgmii_err_sym_%d\t\t\t",
922				&stat_size, data, i);
923			vxge_add_string("rx_xgmii_column1_match_%d\t\t",
924				&stat_size, data, i);
925			vxge_add_string("rx_xgmii_char2_match_%d\t\t",
926				&stat_size, data, i);
927			vxge_add_string("rx_local_fault_%d\t\t\t",
928				&stat_size, data, i);
929			vxge_add_string("rx_xgmii_column2_match_%d\t\t",
930				&stat_size, data, i);
931			vxge_add_string("rx_jettison_%d\t\t\t",
932				&stat_size, data, i);
933			vxge_add_string("rx_remote_fault_%d\t\t\t",
934				&stat_size, data, i);
935		}
936
937		vxge_add_string("\n SOFTWARE STATISTICS%s\t\t\t",
938			&stat_size, data, "");
939		for (i = 0; i < vdev->no_of_vpath; i++) {
940			vxge_add_string("soft_reset_cnt_%d\t\t\t",
941				&stat_size, data, i);
942			vxge_add_string("unknown_alarms_%d\t\t\t",
943				&stat_size, data, i);
944			vxge_add_string("network_sustained_fault_%d\t\t",
945				&stat_size, data, i);
946			vxge_add_string("network_sustained_ok_%d\t\t",
947				&stat_size, data, i);
948			vxge_add_string("kdfcctl_fifo0_overwrite_%d\t\t",
949				&stat_size, data, i);
950			vxge_add_string("kdfcctl_fifo0_poison_%d\t\t",
951				&stat_size, data, i);
952			vxge_add_string("kdfcctl_fifo0_dma_error_%d\t\t",
953				&stat_size, data, i);
954			vxge_add_string("dblgen_fifo0_overflow_%d\t\t",
955				&stat_size, data, i);
956			vxge_add_string("statsb_pif_chain_error_%d\t\t",
957				&stat_size, data, i);
958			vxge_add_string("statsb_drop_timeout_%d\t\t",
959				&stat_size, data, i);
960			vxge_add_string("target_illegal_access_%d\t\t",
961				&stat_size, data, i);
962			vxge_add_string("ini_serr_det_%d\t\t\t",
963				&stat_size, data, i);
964			vxge_add_string("prc_ring_bumps_%d\t\t\t",
965				&stat_size, data, i);
966			vxge_add_string("prc_rxdcm_sc_err_%d\t\t\t",
967				&stat_size, data, i);
968			vxge_add_string("prc_rxdcm_sc_abort_%d\t\t",
969				&stat_size, data, i);
970			vxge_add_string("prc_quanta_size_err_%d\t\t",
971				&stat_size, data, i);
972			vxge_add_string("ring_full_cnt_%d\t\t\t",
973				&stat_size, data, i);
974			vxge_add_string("ring_usage_cnt_%d\t\t\t",
975				&stat_size, data, i);
976			vxge_add_string("ring_usage_max_%d\t\t\t",
977				&stat_size, data, i);
978			vxge_add_string("ring_reserve_free_swaps_cnt_%d\t",
979				&stat_size, data, i);
980			vxge_add_string("ring_total_compl_cnt_%d\t\t",
981				&stat_size, data, i);
982			for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
983				vxge_add_string("rxd_t_code_err_cnt%d_%d\t\t",
984					&stat_size, data, j, i);
985			vxge_add_string("fifo_full_cnt_%d\t\t\t",
986				&stat_size, data, i);
987			vxge_add_string("fifo_usage_cnt_%d\t\t\t",
988				&stat_size, data, i);
989			vxge_add_string("fifo_usage_max_%d\t\t\t",
990				&stat_size, data, i);
991			vxge_add_string("fifo_reserve_free_swaps_cnt_%d\t",
992				&stat_size, data, i);
993			vxge_add_string("fifo_total_compl_cnt_%d\t\t",
994				&stat_size, data, i);
995			vxge_add_string("fifo_total_posts_%d\t\t\t",
996				&stat_size, data, i);
997			vxge_add_string("fifo_total_buffers_%d\t\t",
998				&stat_size, data, i);
999			for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
1000				vxge_add_string("txd_t_code_err_cnt%d_%d\t\t",
1001					&stat_size, data, j, i);
1002		}
1003
1004		vxge_add_string("\n HARDWARE STATISTICS%s\t\t\t",
1005				&stat_size, data, "");
1006		for (i = 0; i < vdev->no_of_vpath; i++) {
1007			vxge_add_string("ini_num_mwr_sent_%d\t\t\t",
1008					&stat_size, data, i);
1009			vxge_add_string("ini_num_mrd_sent_%d\t\t\t",
1010					&stat_size, data, i);
1011			vxge_add_string("ini_num_cpl_rcvd_%d\t\t\t",
1012					&stat_size, data, i);
1013			vxge_add_string("ini_num_mwr_byte_sent_%d\t\t",
1014					&stat_size, data, i);
1015			vxge_add_string("ini_num_cpl_byte_rcvd_%d\t\t",
1016					&stat_size, data, i);
1017			vxge_add_string("wrcrdtarb_xoff_%d\t\t\t",
1018					&stat_size, data, i);
1019			vxge_add_string("rdcrdtarb_xoff_%d\t\t\t",
1020					&stat_size, data, i);
1021			vxge_add_string("vpath_genstats_count0_%d\t\t",
1022					&stat_size, data, i);
1023			vxge_add_string("vpath_genstats_count1_%d\t\t",
1024					&stat_size, data, i);
1025			vxge_add_string("vpath_genstats_count2_%d\t\t",
1026					&stat_size, data, i);
1027			vxge_add_string("vpath_genstats_count3_%d\t\t",
1028					&stat_size, data, i);
1029			vxge_add_string("vpath_genstats_count4_%d\t\t",
1030					&stat_size, data, i);
1031			vxge_add_string("vpath_genstats_count5_%d\t\t",
1032					&stat_size, data, i);
1033			vxge_add_string("prog_event_vnum0_%d\t\t\t",
1034					&stat_size, data, i);
1035			vxge_add_string("prog_event_vnum1_%d\t\t\t",
1036					&stat_size, data, i);
1037			vxge_add_string("prog_event_vnum2_%d\t\t\t",
1038					&stat_size, data, i);
1039			vxge_add_string("prog_event_vnum3_%d\t\t\t",
1040					&stat_size, data, i);
1041			vxge_add_string("rx_multi_cast_frame_discard_%d\t",
1042					&stat_size, data, i);
1043			vxge_add_string("rx_frm_transferred_%d\t\t",
1044					&stat_size, data, i);
1045			vxge_add_string("rxd_returned_%d\t\t\t",
1046					&stat_size, data, i);
1047			vxge_add_string("rx_mpa_len_fail_frms_%d\t\t",
1048					&stat_size, data, i);
1049			vxge_add_string("rx_mpa_mrk_fail_frms_%d\t\t",
1050					&stat_size, data, i);
1051			vxge_add_string("rx_mpa_crc_fail_frms_%d\t\t",
1052					&stat_size, data, i);
1053			vxge_add_string("rx_permitted_frms_%d\t\t",
1054					&stat_size, data, i);
1055			vxge_add_string("rx_vp_reset_discarded_frms_%d\t",
1056					&stat_size, data, i);
1057			vxge_add_string("rx_wol_frms_%d\t\t\t",
1058					&stat_size, data, i);
1059			vxge_add_string("tx_vp_reset_discarded_frms_%d\t",
1060					&stat_size, data, i);
1061		}
1062
1063		memcpy(data + stat_size, &ethtool_driver_stats_keys,
1064			sizeof(ethtool_driver_stats_keys));
1065	}
1066}
1067
1068static int vxge_ethtool_get_regs_len(struct net_device *dev)
1069{
1070	struct vxgedev *vdev = netdev_priv(dev);
1071
1072	return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
1073}
1074
1075static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
1076{
1077	struct vxgedev *vdev = netdev_priv(dev);
1078
1079	switch (sset) {
1080	case ETH_SS_STATS:
1081		return VXGE_TITLE_LEN +
1082			(vdev->no_of_vpath * VXGE_HW_VPATH_STATS_LEN) +
1083			(vdev->max_config_port * VXGE_HW_AGGR_STATS_LEN) +
1084			(vdev->max_config_port * VXGE_HW_PORT_STATS_LEN) +
1085			(vdev->no_of_vpath * VXGE_HW_VPATH_TX_STATS_LEN) +
1086			(vdev->no_of_vpath * VXGE_HW_VPATH_RX_STATS_LEN) +
1087			(vdev->no_of_vpath * VXGE_SW_STATS_LEN) +
1088			DRIVER_STAT_LEN;
1089	default:
1090		return -EOPNOTSUPP;
1091	}
1092}
1093
1094static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
1095{
1096	struct vxgedev *vdev = netdev_priv(dev);
1097
1098	if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) {
1099		printk(KERN_INFO "Single Function Mode is required to flash the"
1100		       " firmware\n");
1101		return -EINVAL;
1102	}
1103
1104	if (netif_running(dev)) {
1105		printk(KERN_INFO "Interface %s must be down to flash the "
1106		       "firmware\n", dev->name);
1107		return -EBUSY;
1108	}
1109
1110	return vxge_fw_upgrade(vdev, parms->data, 1);
1111}
1112
1113static const struct ethtool_ops vxge_ethtool_ops = {
1114	.get_settings		= vxge_ethtool_gset,
1115	.set_settings		= vxge_ethtool_sset,
1116	.get_drvinfo		= vxge_ethtool_gdrvinfo,
1117	.get_regs_len		= vxge_ethtool_get_regs_len,
1118	.get_regs		= vxge_ethtool_gregs,
1119	.get_link		= ethtool_op_get_link,
1120	.get_pauseparam		= vxge_ethtool_getpause_data,
1121	.set_pauseparam		= vxge_ethtool_setpause_data,
1122	.get_strings		= vxge_ethtool_get_strings,
1123	.set_phys_id		= vxge_ethtool_idnic,
1124	.get_sset_count		= vxge_ethtool_get_sset_count,
1125	.get_ethtool_stats	= vxge_get_ethtool_stats,
1126	.flash_device		= vxge_fw_flash,
1127};
1128
1129void vxge_initialize_ethtool_ops(struct net_device *ndev)
1130{
1131	SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
1132}
1133