Files
linux-nv-oot/drivers/net/ethernet/marvell/oak/oak_ethtool.c
Sheetal Tigadoli 748fa9c699 marvell:Add compilation support to driver
- Renamed the directory to oak
- Updated the make files to compile the source
- Removed unused script

ESDP-16549
Bug 3882239
Bug 3824037

Change-Id: I1dee5def85b6e25f88dff999f1051bfe62d5613b
Signed-off-by: Sheetal Tigadoli <stigadoli@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2856988
Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-03-21 02:27:20 -07:00

336 lines
9.4 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
*
* If you received this File from Marvell, you may opt to use, redistribute and/or
* modify this File in accordance with the terms and conditions of the General
* Public License Version 2, June 1991 (the "GPL License"), a copy of which is
* available along with the File in the license.txt file or by writing to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
* on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
* THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
* DISCLAIMED. The GPL License provides additional details about this warranty
* disclaimer.
*
*/
#include "oak_ethtool.h"
#include "oak_net.h"
static const char umac_strings[][ETH_GSTRING_LEN] = {
{"rx_good_frames"},
{"rx_bad_frames"},
{"rx_stall_fifo"},
{"rx_stall_desc"},
{"rx_discard_desc"},
{"tx_pause"},
{"tx_stall_fifo"},
};
static const u8 rx_strings[][ETH_GSTRING_LEN] = {
{"Rx Channel"},
{"rx_alloc_pages"},
{"rx_unmap_pages"},
{"rx_alloc_error"},
{"rx_frame_error"},
{"rx_errors"},
{"rx_interrupts"},
{"rx_good_frames"},
{"rx_byte_count"},
{"rx_vlan"},
{"rx_bad_frames"},
{"rx_no_sof"},
{"rx_no_eof"},
{"rx_bad_crc"},
{"rx_bad_csum"},
{"rx_l4p_ok"},
{"rx_ip4_ok"},
{"rx_bad_nores"},
{"rx_64"},
{"rx_128"},
{"rx_256"},
{"rx_512"},
{"rx_1024"},
{"rx_2048"},
{"rx_fragments"},
};
static const u8 tx_strings[][ETH_GSTRING_LEN] = {
{"Tx Channel"},
{"tx_frame_count"},
{"tx_frame_compl"},
{"tx_byte_count"},
{"tx_fragm_count"},
{"tx_drop"},
{"tx_errors"},
{"tx_interrupts"},
{"tx_stall_count"},
{"tx_64"},
{"tx_128"},
{"tx_256"},
{"tx_512"},
{"tx_1024"},
{"tx_2048"},
};
/* private function prototypes */
static void oak_ethtool_get_txc_stats(oak_t *np, u64 **data);
static void oak_ethtool_get_rxc_stats(oak_t *np, u64 **data);
static void oak_ethtool_get_stall_stats(oak_t *np);
static void oak_ethtool_get_misc_stats(oak_t *np);
/* Name : oak_ethtool_get_rxc_stats
* Returns : void
* Parameters : oak_t *np, u64 **data
* Description : This function copy Rx channel stats
*/
static void oak_ethtool_get_rxc_stats(oak_t *np, u64 **data)
{
u32 i;
**data = 0;
for (i = 0; i < np->num_rx_chan; i++) {
oak_rx_chan_t *rxc = &np->rx_channel[i];
/* Copy rx channel statistics */
memcpy(*data, &rxc->stat, sizeof(oak_driver_rx_stat));
**data = i + 1;
*data += (sizeof(oak_driver_rx_stat) / sizeof(u64));
}
}
/* Name : oak_ethtool_get_txc_stats
* Returns : void
* Parameters : oak_t *np, u64 **data
* Description : This function copy Tx channel stats
*/
static void oak_ethtool_get_txc_stats(oak_t *np, u64 **data)
{
u32 i;
**data = 0;
for (i = 0; i < np->num_tx_chan; i++) {
oak_tx_chan_t *txc = &np->tx_channel[i];
/* Copy tx channel statistics */
memcpy(*data, &txc->stat, sizeof(oak_driver_tx_stat));
**data = i + 1;
*data += (sizeof(oak_driver_tx_stat) / sizeof(u64));
}
}
/* Name : oak_ethtool_get_stall_stats
* Returns : void
* Parameters : oak_t *np
* Description : This function get the tx or rx stall counter statistics of the
* Ethernet interface.
*/
static void oak_ethtool_get_stall_stats(oak_t *np)
{
np->unimac_stat.tx_stall_fifo =
oak_unimac_io_read_32(np, OAK_UNI_STAT_TX_STALL_FIFO);
np->unimac_stat.rx_stall_desc =
oak_unimac_io_read_32(np, OAK_UNI_STAT_RX_STALL_DESC);
np->unimac_stat.rx_stall_fifo =
oak_unimac_io_read_32(np, OAK_UNI_STAT_RX_STALL_FIFO);
}
/* Name : oak_ethtool_get_misc_stats
* Returns : void
* Parameters : oak_t *np
* Description : This function get the tx/rx good, bad, pause, disc descriptor
* statistics of the Ethernet interface.
*/
static void oak_ethtool_get_misc_stats(oak_t *np)
{
np->unimac_stat.tx_pause =
oak_unimac_io_read_32(np, OAK_UNI_STAT_TX_PAUSE);
np->unimac_stat.rx_good_frames =
oak_unimac_io_read_32(np, OAK_UNI_STAT_RX_GOOD_FRAMES);
np->unimac_stat.rx_bad_frames =
oak_unimac_io_read_32(np, OAK_UNI_STAT_RX_BAD_FRAMES);
np->unimac_stat.rx_discard_desc =
oak_unimac_io_read_32(np, OAK_UNI_STAT_RX_DISC_DESC);
}
/* Name : oak_ethtool_get_stats
* Returns : void
* Parameters : struct net_device *dev, struct ethtool_stats *stats,
* u64 *data
* Description : This function reads the statistics of the Ethernet interface.
*/
void oak_ethtool_get_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
oak_t *np = netdev_priv(dev);
/* Get tx/rx channels stall and misc counters statistics */
oak_ethtool_get_stall_stats(np);
oak_ethtool_get_misc_stats(np);
memcpy(data, &np->unimac_stat, sizeof(np->unimac_stat));
data += sizeof(np->unimac_stat) / sizeof(u64);
/* Get rx/tx channel statistics */
oak_ethtool_get_rxc_stats(np, &data);
oak_ethtool_get_txc_stats(np, &data);
}
/* Name : oak_ethtool_get_sscnt
* Returns : int
* Parameters : struct net_device *dev, int stringset
* Description : This function read the String Set Count value of the
* Ethernet interface.
*/
int oak_ethtool_get_sscnt(struct net_device *dev, int stringset)
{
int retval;
oak_t *np = netdev_priv(dev);
/* Get the string set count statistics */
if (stringset == ETH_SS_STATS) {
retval = sizeof(np->unimac_stat) / sizeof(u64);
retval += (np->num_rx_chan *
sizeof(oak_driver_rx_stat) / sizeof(u64));
retval += (np->num_tx_chan *
sizeof(oak_driver_tx_stat) / sizeof(u64));
} else {
retval = -EINVAL;
}
return retval;
}
/* Name : oak_ethtool_get_strings
* Returns : void
* Parameters : struct net_device *dev, u32 stringset, u8 *data
* Description : This function get the Tx and Rx channel strings value of the
* Ethernet interface.
*/
void oak_ethtool_get_strings(struct net_device *dev, u32 stringset,
u8 *data)
{
*data = 0;
if (stringset == ETH_SS_STATS) {
u32 off = 0;
u32 i;
oak_t *np = netdev_priv(dev);
memcpy(&data[off], umac_strings, sizeof(umac_strings));
off += sizeof(umac_strings);
/* Copy statistics data into rx channel structure */
for (i = 0; i < np->num_rx_chan; i++) {
memcpy(&data[off], rx_strings, sizeof(rx_strings));
off += sizeof(rx_strings);
}
/* Copy statistics data into tx channel structure */
for (i = 0; i < np->num_tx_chan; i++) {
memcpy(&data[off], tx_strings, sizeof(tx_strings));
off += sizeof(tx_strings);
}
}
}
/* Name : oak_ethtool_get_cur_speed
* Returns : int
* Parameters : oak_t *np, int pspeed
* Description : This function caps the current PCIe speed for the Oak/Spruce
* switch.
*/
u32 oak_ethtool_cap_cur_speed(oak_t *np, u32 pspeed)
{
enum pcie_link_width wdth;
wdth = oak_net_pcie_get_width_cap(np->pdev);
if (wdth == PCIE_LNK_X1) { /* Oak */
if (pspeed > OAK_MAX_SPEED)
pspeed = OAK_MAX_SPEED;
} else if (wdth == PCIE_LNK_X2) {
if (pspeed > SPRUCE_MAX_SPEED)
pspeed = SPRUCE_MAX_SPEED;
}
return pspeed;
}
/* Name : ethtool_get_link_ksettings
* Returns : int
* Parameters : struct net_device *dev, struct ethtool_link_ksettings *ecmd
* Description : This function get the current port link settings of the
* Ethernet interface.
*/
int oak_ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *ecmd)
{
oak_t *oak;
u32 supported, advertising;
oak = netdev_priv(dev);
supported = 0;
advertising = 0;
memset(ecmd, 0, sizeof(*ecmd));
if (oak->speed == OAK_SPEED_1000) {
ecmd->base.speed = SPEED_1000;
supported |= SUPPORTED_1000baseT_Full |
SUPPORTED_1000baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_10baseT_Half;
supported |= SUPPORTED_Autoneg;
advertising |= ADVERTISED_1000baseT_Full |
ADVERTISED_1000baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_10baseT_Half;
} else if (oak->speed == OAK_SPEED_2500) {
ecmd->base.speed = SPEED_2500;
supported = SUPPORTED_10000baseT_Full;
advertising = ADVERTISED_2500baseX_Full;
} else if (oak->speed == OAK_SPEED_5000) {
ecmd->base.speed = SPEED_5000;
supported = SUPPORTED_10000baseT_Full;
advertising = ADVERTISED_10000baseT_Full;
} else {
ecmd->base.speed = SPEED_10000;
supported = SUPPORTED_10000baseT_Full;
supported |= SUPPORTED_TP;
advertising = ADVERTISED_10000baseT_Full;
}
ecmd->base.port = PORT_TP;
ecmd->base.duplex = DUPLEX_FULL;
ecmd->base.autoneg = AUTONEG_ENABLE;
/* This function was added in kernel 4.7 in commit 6d62b4d5fac62 ("net:
* ethtool: export conversion function between u32 and link mode")
*/
ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
supported);
ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
advertising);
return 0;
}
/* Name : oak_ethtool_get_drvinfo
* Returns : void
* Parameters : struct net_device *dev, struct ethtool_drvinfo *drvinfo
* Description : This function copy driver name, version and PCI bus
* information into ethtool driver information structure.
*/
void oak_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
oak_t *adapter = netdev_priv(netdev);
/* Copy a C-string into a sized buffer
* Copy driver name, version and bus information
*/
strscpy(drvinfo->driver, oak_driver_name, sizeof(drvinfo->driver));
strscpy(drvinfo->version, oak_driver_version,
sizeof(drvinfo->version));
strscpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
}