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