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