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