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