Linux Audio

Check our new training course

Loading...
   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 */
  32static 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 */
  53static 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 */
  81static 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 */
 105static 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 */
 143static 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 */
 174static 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 */
 193static 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
 207static 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
 578static 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
1068static 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
1075static 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
1094static 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
1113static 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
1129void vxge_initialize_ethtool_ops(struct net_device *ndev)
1130{
1131	SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
1132}