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 static 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  */
51 static int
vxge_ethtool_set_link_ksettings(struct net_device * dev,const struct ethtool_link_ksettings * cmd)52 vxge_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  */
vxge_ethtool_get_link_ksettings(struct net_device * dev,struct ethtool_link_ksettings * cmd)74 static 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  */
vxge_ethtool_gdrvinfo(struct net_device * dev,struct ethtool_drvinfo * info)107 static 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  */
vxge_ethtool_gregs(struct net_device * dev,struct ethtool_regs * regs,void * space)127 static 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  */
vxge_ethtool_idnic(struct net_device * dev,enum ethtool_phys_id_state state)165 static 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  */
vxge_ethtool_getpause_data(struct net_device * dev,struct ethtool_pauseparam * ep)196 static 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  */
vxge_ethtool_setpause_data(struct net_device * dev,struct ethtool_pauseparam * ep)215 static 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 
vxge_get_ethtool_stats(struct net_device * dev,struct ethtool_stats * estats,u64 * tmp_stats)229 static 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 
vxge_ethtool_get_strings(struct net_device * dev,u32 stringset,u8 * data)600 static 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 
vxge_ethtool_get_regs_len(struct net_device * dev)1090 static 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 
vxge_ethtool_get_sset_count(struct net_device * dev,int sset)1097 static 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 
vxge_fw_flash(struct net_device * dev,struct ethtool_flash * parms)1116 static 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 
1135 static 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 
vxge_initialize_ethtool_ops(struct net_device * ndev)1151 void vxge_initialize_ethtool_ops(struct net_device *ndev)
1152 {
1153 	ndev->ethtool_ops = &vxge_ethtool_ops;
1154 }
1155