177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/*
277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Copyright (C) 1999 - 2010 Intel Corporation.
377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *
577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * This code was derived from the Intel e1000e Linux driver.
677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *
777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * This program is free software; you can redistribute it and/or modify
877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * it under the terms of the GNU General Public License as published by
977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * the Free Software Foundation; version 2 of the License.
1077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *
1177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * This program is distributed in the hope that it will be useful,
1277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * but WITHOUT ANY WARRANTY; without even the implied warranty of
1377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * GNU General Public License for more details.
1577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *
1677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * You should have received a copy of the GNU General Public License
1777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * along with this program; if not, write to the Free Software
1877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
1977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
2077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#include "pch_gbe.h"
2177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#include "pch_gbe_api.h"
2277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
2377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
2425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * pch_gbe_stats - Stats item information
2577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
2677555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestruct pch_gbe_stats {
2777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	char string[ETH_GSTRING_LEN];
2877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	size_t size;
2977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	size_t offset;
3077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake};
3177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
3277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_STAT(m)						\
3377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{								\
3477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.string = #m,						\
3577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m),	\
3677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.offset = offsetof(struct pch_gbe_hw_stats, m),		\
3777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
3877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
3977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
4077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_gstrings_stats - ethtool information status name list
4177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
4277555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {
4377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_packets),
4477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_packets),
4577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_bytes),
4677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_bytes),
4777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_errors),
4877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_errors),
4977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_dropped),
5077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_dropped),
5177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(multicast),
5277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(collisions),
5377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_crc_errors),
5477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_frame_errors),
5577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(rx_alloc_buff_failed),
5677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_length_errors),
5777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_aborted_errors),
5877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_carrier_errors),
5977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_timeout_count),
6077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(tx_restart_count),
6177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_rx_dsc_empty_count),
6277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_rx_frame_err_count),
6377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_rx_fifo_err_count),
6477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_rx_dma_err_count),
6577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_tx_fifo_err_count),
6677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_tx_dma_err_count),
6777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	PCH_GBE_STAT(intr_tcpip_err_count)
6877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake};
6977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
7077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_QUEUE_STATS_LEN 0
7177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_GLOBAL_STATS_LEN	ARRAY_SIZE(pch_gbe_gstrings_stats)
7277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
7377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
7477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_MAC_REGS_LEN    (sizeof(struct pch_gbe_regs) / 4)
7577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#define PCH_GBE_REGS_LEN        (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
7677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
7777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_settings - Get device-specific settings
7877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
7977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @ecmd:   Ethtool command
8077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
8177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
8277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
8377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
8477555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_get_settings(struct net_device *netdev,
8577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				 struct ethtool_cmd *ecmd)
8677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
8777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
8877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int ret;
8977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
9077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ret = mii_ethtool_gset(&adapter->mii, ecmd);
9177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);
9277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
9377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
9477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (!netif_carrier_ok(adapter->netdev))
9525db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny		ethtool_cmd_speed_set(ecmd, -1);
9677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return ret;
9777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
9877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
9977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
10077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_set_settings - Set device-specific settings
10177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
10277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @ecmd:   Ethtool command
10377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
10477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
10577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
10677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
10777555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_set_settings(struct net_device *netdev,
10877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				 struct ethtool_cmd *ecmd)
10977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
11077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
11177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_hw *hw = &adapter->hw;
11225db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	u32 speed = ethtool_cmd_speed(ecmd);
11377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int ret;
11477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
11577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
11677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
11725db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	/* when set_settings() is called with a ethtool_cmd previously
11825db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	 * filled by get_settings() on a down link, speed is -1: */
11925db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	if (speed == UINT_MAX) {
12025db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny		speed = SPEED_1000;
12177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		ecmd->duplex = DUPLEX_FULL;
12289980827c7a1e3c2b36895c22c6ef0e92aea6b0cDan Carpenter	}
12377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ret = mii_ethtool_sset(&adapter->mii, ecmd);
12477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (ret) {
12577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pr_err("Error: mii_ethtool_sset\n");
12677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		return ret;
12777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
12825db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	hw->mac.link_speed = speed;
12977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	hw->mac.link_duplex = ecmd->duplex;
13077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	hw->phy.autoneg_advertised = ecmd->advertising;
13177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	hw->mac.autoneg = ecmd->autoneg;
13277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	pch_gbe_hal_phy_sw_reset(hw);
13377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
13477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	/* reset the link */
13577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (netif_running(adapter->netdev)) {
13677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_down(adapter);
13777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		ret = pch_gbe_up(adapter);
13877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	} else {
13977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_reset(adapter);
14077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
14177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return ret;
14277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
14377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
14477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
14577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_regs_len - Report the size of device registers
14677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
14777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns: the size of device registers.
14877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
14977555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_get_regs_len(struct net_device *netdev)
15077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
15177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return PCH_GBE_REGS_LEN * (int)sizeof(u32);
15277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
15377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
15477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
15577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_drvinfo - Report driver information
15677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:  Network interface device structure
15777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @drvinfo: Driver information structure
15877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
15977555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_drvinfo(struct net_device *netdev,
16077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				 struct ethtool_drvinfo *drvinfo)
16177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
16277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
16377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
16423020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones	strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
16523020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones	strlcpy(drvinfo->version, pch_driver_version, sizeof(drvinfo->version));
16623020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
16723020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones		sizeof(drvinfo->bus_info));
16877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	drvinfo->regdump_len = pch_gbe_get_regs_len(netdev);
16977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
17077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
17177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
17277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_regs - Get device registers
17377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
17477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @regs:   Ethtool register structure
17577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @p:      Buffer pointer of read device register date
17677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
17777555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_regs(struct net_device *netdev,
17877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				struct ethtool_regs *regs, void *p)
17977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
18077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
18177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_hw *hw = &adapter->hw;
18277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pci_dev *pdev = adapter->pdev;
18377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	u32 *regs_buff = p;
18477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	u16 i, tmp;
18577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
18677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;
18777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)
18877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		*regs_buff++ = ioread32(&hw->reg->INT_ST + i);
18977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	/* PHY register */
19077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {
19177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp);
19277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		*regs_buff++ = tmp;
19377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
19477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
19577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
19677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
19777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
19877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
19977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @wol:    Wake-on-Lan information
20077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
20177555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_wol(struct net_device *netdev,
20277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				struct ethtool_wolinfo *wol)
20377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
20477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
20577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
20677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
20777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	wol->wolopts = 0;
20877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
20977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))
21077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		wol->wolopts |= WAKE_UCAST;
21177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))
21277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		wol->wolopts |= WAKE_MCAST;
21377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))
21477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		wol->wolopts |= WAKE_BCAST;
21577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))
21677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		wol->wolopts |= WAKE_MAGIC;
21777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
21877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
21977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
22077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_set_wol - Turn Wake-on-Lan on or off
22177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
22277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @wol:    Pointer of wake-on-Lan information straucture
22377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
22477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
22577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
22677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
22777555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_set_wol(struct net_device *netdev,
22877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				struct ethtool_wolinfo *wol)
22977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
23077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
23177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
23277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))
23377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		return -EOPNOTSUPP;
23477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	/* these settings will always override what we currently have */
23577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	adapter->wake_up_evt = 0;
23677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
23777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((wol->wolopts & WAKE_UCAST))
23877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->wake_up_evt |= PCH_GBE_WLC_IND;
23977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((wol->wolopts & WAKE_MCAST))
24077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->wake_up_evt |= PCH_GBE_WLC_MLT;
24177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((wol->wolopts & WAKE_BCAST))
24277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->wake_up_evt |= PCH_GBE_WLC_BR;
24377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((wol->wolopts & WAKE_MAGIC))
24477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->wake_up_evt |= PCH_GBE_WLC_MP;
24577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return 0;
24677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
24777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
24877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
24977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_nway_reset - Restart autonegotiation
25077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
25177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
25277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
25377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
25477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
25577555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_nway_reset(struct net_device *netdev)
25677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
25777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
25877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
25977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return mii_nway_restart(&adapter->mii);
26077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
26177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
26277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
26377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_ringparam - Report ring sizes
26477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:  Network interface device structure
26577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @ring:    Ring param structure
26677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
26777555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_ringparam(struct net_device *netdev,
26877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake					struct ethtool_ringparam *ring)
26977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
27077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
27177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_tx_ring *txdr = adapter->tx_ring;
27277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;
27377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
27477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ring->rx_max_pending = PCH_GBE_MAX_RXD;
27577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ring->tx_max_pending = PCH_GBE_MAX_TXD;
27677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ring->rx_pending = rxdr->count;
27777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	ring->tx_pending = txdr->count;
27877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
27977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
28077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
28177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_set_ringparam - Set ring sizes
28277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:  Network interface device structure
28377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @ring:    Ring param structure
28477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
28577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
28677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
28777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
28877555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_set_ringparam(struct net_device *netdev,
28977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake					struct ethtool_ringparam *ring)
29077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
29177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
29277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_tx_ring *txdr, *tx_old;
29377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_rx_ring *rxdr, *rx_old;
29477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int tx_ring_size, rx_ring_size;
29577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int err = 0;
29677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
29777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
29877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		return -EINVAL;
29977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);
30077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);
30177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
30277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((netif_running(adapter->netdev)))
30377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_down(adapter);
30477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	tx_old = adapter->tx_ring;
30577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	rx_old = adapter->rx_ring;
30677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
30777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	txdr = kzalloc(tx_ring_size, GFP_KERNEL);
30877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (!txdr) {
30977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		err = -ENOMEM;
31077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		goto err_alloc_tx;
31177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
31277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
31377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (!rxdr) {
31477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		err = -ENOMEM;
31577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		goto err_alloc_rx;
31677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
31777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	adapter->tx_ring = txdr;
31877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	adapter->rx_ring = rxdr;
31977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
32077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	rxdr->count =
32177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
32277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);
32377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
32477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	txdr->count =
32577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
32677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);
32777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
32877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((netif_running(adapter->netdev))) {
32977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		/* Try to get new resources before deleting old */
33077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
33177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		if (err)
33277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			goto err_setup_rx;
33377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
33477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		if (err)
33577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			goto err_setup_tx;
33677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		/* save the new, restore the old in order to free it,
33777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		 * then restore the new back again */
33877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#ifdef RINGFREE
33977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->rx_ring = rx_old;
34077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->tx_ring = tx_old;
34177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
34277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_free_tx_resources(adapter, adapter->tx_ring);
34377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		kfree(tx_old);
34477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		kfree(rx_old);
34577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->rx_ring = rxdr;
34677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->tx_ring = txdr;
34777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#else
34877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_free_rx_resources(adapter, rx_old);
34977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_free_tx_resources(adapter, tx_old);
35077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		kfree(tx_old);
35177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		kfree(rx_old);
35277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->rx_ring = rxdr;
35377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		adapter->tx_ring = txdr;
35477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake#endif
35577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		err = pch_gbe_up(adapter);
35677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
35777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return err;
35877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
35977555ee7228234257957fd54daa0b69178906320Masayuki Ohtakeerr_setup_tx:
36077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
36177555ee7228234257957fd54daa0b69178906320Masayuki Ohtakeerr_setup_rx:
36277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	adapter->rx_ring = rx_old;
36377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	adapter->tx_ring = tx_old;
36477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	kfree(rxdr);
36577555ee7228234257957fd54daa0b69178906320Masayuki Ohtakeerr_alloc_rx:
36677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	kfree(txdr);
36777555ee7228234257957fd54daa0b69178906320Masayuki Ohtakeerr_alloc_tx:
36877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (netif_running(adapter->netdev))
36977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pch_gbe_up(adapter);
37077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return err;
37177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
37277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
37377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
37477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_pauseparam - Report pause parameters
37577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:  Network interface device structure
37677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @pause:   Pause parameters structure
37777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
37877555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_pauseparam(struct net_device *netdev,
37977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				       struct ethtool_pauseparam *pause)
38077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
38177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
38277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_hw *hw = &adapter->hw;
38377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
38477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	pause->autoneg =
38577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	    ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
38677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
38777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {
38877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pause->rx_pause = 1;
38977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	} else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {
39077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pause->tx_pause = 1;
39177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	} else if (hw->mac.fc == PCH_GBE_FC_FULL) {
39277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pause->rx_pause = 1;
39377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		pause->tx_pause = 1;
39477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
39577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
39677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
39777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
39877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_set_pauseparam - Set pause paramters
39977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:  Network interface device structure
40077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @pause:   Pause parameters structure
40177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * Returns
40277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	0:			Successful.
40377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *	Negative value:		Failed.
40477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
40577555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_set_pauseparam(struct net_device *netdev,
40677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				       struct ethtool_pauseparam *pause)
40777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
40877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
40977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_hw *hw = &adapter->hw;
41077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int ret = 0;
41177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
41277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	hw->mac.fc_autoneg = pause->autoneg;
41377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if ((pause->rx_pause) && (pause->tx_pause))
41477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		hw->mac.fc = PCH_GBE_FC_FULL;
41577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	else if ((pause->rx_pause) && (!pause->tx_pause))
41677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		hw->mac.fc = PCH_GBE_FC_RX_PAUSE;
41777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	else if ((!pause->rx_pause) && (pause->tx_pause))
41877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		hw->mac.fc = PCH_GBE_FC_TX_PAUSE;
41977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	else if ((!pause->rx_pause) && (!pause->tx_pause))
42077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		hw->mac.fc = PCH_GBE_FC_NONE;
42177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
42277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
42377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		if ((netif_running(adapter->netdev))) {
42477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			pch_gbe_down(adapter);
42577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			ret = pch_gbe_up(adapter);
42677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		} else {
42777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			pch_gbe_reset(adapter);
42877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		}
42977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	} else {
43077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		ret = pch_gbe_mac_force_mac_fc(hw);
43177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
43277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	return ret;
43377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
43477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
43577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
43677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_strings - Return a set of strings that describe the requested
43777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake *			 objects
43877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev:    Network interface device structure
43977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
44077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @data:      Pointer of read string data.
44177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
44277555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,
44377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake					u8 *data)
44477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
44577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	u8 *p = data;
44677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int i;
44777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
44877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	switch (stringset) {
44977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	case (u32) ETH_SS_STATS:
45077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
45177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			memcpy(p, pch_gbe_gstrings_stats[i].string,
45277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			       ETH_GSTRING_LEN);
45377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake			p += ETH_GSTRING_LEN;
45477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		}
45577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		break;
45677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
45777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
45877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
45977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake/**
46077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * pch_gbe_get_ethtool_stats - Return statistics about the device
46177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @netdev: Network interface device structure
46277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @stats:  Ethtool statue structure
46377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake * @data:   Pointer of read status area
46477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake */
46577555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic void pch_gbe_get_ethtool_stats(struct net_device *netdev,
46677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake				  struct ethtool_stats *stats, u64 *data)
46777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
46877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
46977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	int i;
47077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;
47177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	char *hw_stats = (char *)&adapter->stats;
47277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
47377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	pch_gbe_update_stats(adapter);
47477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
47577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		char *p = hw_stats + gstats->offset;
47677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);
47777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		gstats++;
47877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
47977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
48077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
48177555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic int pch_gbe_get_sset_count(struct net_device *netdev, int sset)
48277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
48377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	switch (sset) {
48477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	case ETH_SS_STATS:
48577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		return PCH_GBE_STATS_LEN;
48677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	default:
48777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake		return -EOPNOTSUPP;
48877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	}
48977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
49077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
49177555ee7228234257957fd54daa0b69178906320Masayuki Ohtakestatic const struct ethtool_ops pch_gbe_ethtool_ops = {
49277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_settings = pch_gbe_get_settings,
49377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.set_settings = pch_gbe_set_settings,
49477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_drvinfo = pch_gbe_get_drvinfo,
49577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_regs_len = pch_gbe_get_regs_len,
49677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_regs = pch_gbe_get_regs,
49777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_wol = pch_gbe_get_wol,
49877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.set_wol = pch_gbe_set_wol,
49977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.nway_reset = pch_gbe_nway_reset,
50077555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_link = ethtool_op_get_link,
50177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_ringparam = pch_gbe_get_ringparam,
50277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.set_ringparam = pch_gbe_set_ringparam,
50377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_pauseparam = pch_gbe_get_pauseparam,
50477555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.set_pauseparam = pch_gbe_set_pauseparam,
50577555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_strings = pch_gbe_get_strings,
50677555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_ethtool_stats = pch_gbe_get_ethtool_stats,
50777555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	.get_sset_count = pch_gbe_get_sset_count,
50877555ee7228234257957fd54daa0b69178906320Masayuki Ohtake};
50977555ee7228234257957fd54daa0b69178906320Masayuki Ohtake
51077555ee7228234257957fd54daa0b69178906320Masayuki Ohtakevoid pch_gbe_set_ethtool_ops(struct net_device *netdev)
51177555ee7228234257957fd54daa0b69178906320Masayuki Ohtake{
51277555ee7228234257957fd54daa0b69178906320Masayuki Ohtake	SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops);
51377555ee7228234257957fd54daa0b69178906320Masayuki Ohtake}
514