cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

emac-ethtool.c (6523B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
      3 */
      4
      5#include <linux/ethtool.h>
      6#include <linux/phy.h>
      7
      8#include "emac.h"
      9
     10static const char * const emac_ethtool_stat_strings[] = {
     11	"rx_ok",
     12	"rx_bcast",
     13	"rx_mcast",
     14	"rx_pause",
     15	"rx_ctrl",
     16	"rx_fcs_err",
     17	"rx_len_err",
     18	"rx_byte_cnt",
     19	"rx_runt",
     20	"rx_frag",
     21	"rx_sz_64",
     22	"rx_sz_65_127",
     23	"rx_sz_128_255",
     24	"rx_sz_256_511",
     25	"rx_sz_512_1023",
     26	"rx_sz_1024_1518",
     27	"rx_sz_1519_max",
     28	"rx_sz_ov",
     29	"rx_rxf_ov",
     30	"rx_align_err",
     31	"rx_bcast_byte_cnt",
     32	"rx_mcast_byte_cnt",
     33	"rx_err_addr",
     34	"rx_crc_align",
     35	"rx_jabbers",
     36	"tx_ok",
     37	"tx_bcast",
     38	"tx_mcast",
     39	"tx_pause",
     40	"tx_exc_defer",
     41	"tx_ctrl",
     42	"tx_defer",
     43	"tx_byte_cnt",
     44	"tx_sz_64",
     45	"tx_sz_65_127",
     46	"tx_sz_128_255",
     47	"tx_sz_256_511",
     48	"tx_sz_512_1023",
     49	"tx_sz_1024_1518",
     50	"tx_sz_1519_max",
     51	"tx_1_col",
     52	"tx_2_col",
     53	"tx_late_col",
     54	"tx_abort_col",
     55	"tx_underrun",
     56	"tx_rd_eop",
     57	"tx_len_err",
     58	"tx_trunc",
     59	"tx_bcast_byte",
     60	"tx_mcast_byte",
     61	"tx_col",
     62};
     63
     64#define EMAC_STATS_LEN	ARRAY_SIZE(emac_ethtool_stat_strings)
     65
     66static u32 emac_get_msglevel(struct net_device *netdev)
     67{
     68	struct emac_adapter *adpt = netdev_priv(netdev);
     69
     70	return adpt->msg_enable;
     71}
     72
     73static void emac_set_msglevel(struct net_device *netdev, u32 data)
     74{
     75	struct emac_adapter *adpt = netdev_priv(netdev);
     76
     77	adpt->msg_enable = data;
     78}
     79
     80static int emac_get_sset_count(struct net_device *netdev, int sset)
     81{
     82	switch (sset) {
     83	case ETH_SS_PRIV_FLAGS:
     84		return 1;
     85	case ETH_SS_STATS:
     86		return EMAC_STATS_LEN;
     87	default:
     88		return -EOPNOTSUPP;
     89	}
     90}
     91
     92static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
     93{
     94	unsigned int i;
     95
     96	switch (stringset) {
     97	case ETH_SS_PRIV_FLAGS:
     98		strcpy(data, "single-pause-mode");
     99		break;
    100
    101	case ETH_SS_STATS:
    102		for (i = 0; i < EMAC_STATS_LEN; i++) {
    103			strscpy(data, emac_ethtool_stat_strings[i],
    104				ETH_GSTRING_LEN);
    105			data += ETH_GSTRING_LEN;
    106		}
    107		break;
    108	}
    109}
    110
    111static void emac_get_ethtool_stats(struct net_device *netdev,
    112				   struct ethtool_stats *stats,
    113				   u64 *data)
    114{
    115	struct emac_adapter *adpt = netdev_priv(netdev);
    116
    117	spin_lock(&adpt->stats.lock);
    118
    119	emac_update_hw_stats(adpt);
    120	memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
    121
    122	spin_unlock(&adpt->stats.lock);
    123}
    124
    125static int emac_nway_reset(struct net_device *netdev)
    126{
    127	struct phy_device *phydev = netdev->phydev;
    128
    129	if (!phydev)
    130		return -ENODEV;
    131
    132	return genphy_restart_aneg(phydev);
    133}
    134
    135static void emac_get_ringparam(struct net_device *netdev,
    136			       struct ethtool_ringparam *ring,
    137			       struct kernel_ethtool_ringparam *kernel_ring,
    138			       struct netlink_ext_ack *extack)
    139{
    140	struct emac_adapter *adpt = netdev_priv(netdev);
    141
    142	ring->rx_max_pending = EMAC_MAX_RX_DESCS;
    143	ring->tx_max_pending = EMAC_MAX_TX_DESCS;
    144	ring->rx_pending = adpt->rx_desc_cnt;
    145	ring->tx_pending = adpt->tx_desc_cnt;
    146}
    147
    148static int emac_set_ringparam(struct net_device *netdev,
    149			      struct ethtool_ringparam *ring,
    150			      struct kernel_ethtool_ringparam *kernel_ring,
    151			      struct netlink_ext_ack *extack)
    152{
    153	struct emac_adapter *adpt = netdev_priv(netdev);
    154
    155	/* We don't have separate queues/rings for small/large frames, so
    156	 * reject any attempt to specify those values separately.
    157	 */
    158	if (ring->rx_mini_pending || ring->rx_jumbo_pending)
    159		return -EINVAL;
    160
    161	adpt->tx_desc_cnt =
    162		clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
    163
    164	adpt->rx_desc_cnt =
    165		clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
    166
    167	if (netif_running(netdev))
    168		return emac_reinit_locked(adpt);
    169
    170	return 0;
    171}
    172
    173static void emac_get_pauseparam(struct net_device *netdev,
    174				struct ethtool_pauseparam *pause)
    175{
    176	struct emac_adapter *adpt = netdev_priv(netdev);
    177
    178	pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
    179	pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
    180	pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
    181}
    182
    183static int emac_set_pauseparam(struct net_device *netdev,
    184			       struct ethtool_pauseparam *pause)
    185{
    186	struct emac_adapter *adpt = netdev_priv(netdev);
    187
    188	adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
    189	adpt->rx_flow_control = pause->rx_pause != 0;
    190	adpt->tx_flow_control = pause->tx_pause != 0;
    191
    192	if (netif_running(netdev))
    193		return emac_reinit_locked(adpt);
    194
    195	return 0;
    196}
    197
    198/* Selected registers that might want to track during runtime. */
    199static const u16 emac_regs[] = {
    200	EMAC_DMA_MAS_CTRL,
    201	EMAC_MAC_CTRL,
    202	EMAC_TXQ_CTRL_0,
    203	EMAC_RXQ_CTRL_0,
    204	EMAC_DMA_CTRL,
    205	EMAC_INT_MASK,
    206	EMAC_AXI_MAST_CTRL,
    207	EMAC_CORE_HW_VERSION,
    208	EMAC_MISC_CTRL,
    209};
    210
    211/* Every time emac_regs[] above is changed, increase this version number. */
    212#define EMAC_REGS_VERSION	0
    213
    214#define EMAC_MAX_REG_SIZE	ARRAY_SIZE(emac_regs)
    215
    216static void emac_get_regs(struct net_device *netdev,
    217			  struct ethtool_regs *regs, void *buff)
    218{
    219	struct emac_adapter *adpt = netdev_priv(netdev);
    220	u32 *val = buff;
    221	unsigned int i;
    222
    223	regs->version = EMAC_REGS_VERSION;
    224	regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
    225
    226	for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
    227		val[i] = readl(adpt->base + emac_regs[i]);
    228}
    229
    230static int emac_get_regs_len(struct net_device *netdev)
    231{
    232	return EMAC_MAX_REG_SIZE * sizeof(u32);
    233}
    234
    235#define EMAC_PRIV_ENABLE_SINGLE_PAUSE	BIT(0)
    236
    237static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
    238{
    239	struct emac_adapter *adpt = netdev_priv(netdev);
    240
    241	adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
    242
    243	if (netif_running(netdev))
    244		return emac_reinit_locked(adpt);
    245
    246	return 0;
    247}
    248
    249static u32 emac_get_priv_flags(struct net_device *netdev)
    250{
    251	struct emac_adapter *adpt = netdev_priv(netdev);
    252
    253	return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
    254}
    255
    256static const struct ethtool_ops emac_ethtool_ops = {
    257	.get_link_ksettings = phy_ethtool_get_link_ksettings,
    258	.set_link_ksettings = phy_ethtool_set_link_ksettings,
    259
    260	.get_msglevel    = emac_get_msglevel,
    261	.set_msglevel    = emac_set_msglevel,
    262
    263	.get_sset_count  = emac_get_sset_count,
    264	.get_strings = emac_get_strings,
    265	.get_ethtool_stats = emac_get_ethtool_stats,
    266
    267	.get_ringparam = emac_get_ringparam,
    268	.set_ringparam = emac_set_ringparam,
    269
    270	.get_pauseparam = emac_get_pauseparam,
    271	.set_pauseparam = emac_set_pauseparam,
    272
    273	.nway_reset = emac_nway_reset,
    274
    275	.get_link = ethtool_op_get_link,
    276
    277	.get_regs_len    = emac_get_regs_len,
    278	.get_regs        = emac_get_regs,
    279
    280	.set_priv_flags = emac_set_priv_flags,
    281	.get_priv_flags = emac_get_priv_flags,
    282};
    283
    284void emac_set_ethtool_ops(struct net_device *netdev)
    285{
    286	netdev->ethtool_ops = &emac_ethtool_ops;
    287}