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

ethtool.c (5682B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (c) 2020 Facebook
      3
      4#include <linux/debugfs.h>
      5#include <linux/ethtool.h>
      6#include <linux/random.h>
      7
      8#include "netdevsim.h"
      9
     10static void
     11nsim_get_pause_stats(struct net_device *dev,
     12		     struct ethtool_pause_stats *pause_stats)
     13{
     14	struct netdevsim *ns = netdev_priv(dev);
     15
     16	if (ns->ethtool.pauseparam.report_stats_rx)
     17		pause_stats->rx_pause_frames = 1;
     18	if (ns->ethtool.pauseparam.report_stats_tx)
     19		pause_stats->tx_pause_frames = 2;
     20}
     21
     22static void
     23nsim_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
     24{
     25	struct netdevsim *ns = netdev_priv(dev);
     26
     27	pause->autoneg = 0; /* We don't support ksettings, so can't pretend */
     28	pause->rx_pause = ns->ethtool.pauseparam.rx;
     29	pause->tx_pause = ns->ethtool.pauseparam.tx;
     30}
     31
     32static int
     33nsim_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
     34{
     35	struct netdevsim *ns = netdev_priv(dev);
     36
     37	if (pause->autoneg)
     38		return -EINVAL;
     39
     40	ns->ethtool.pauseparam.rx = pause->rx_pause;
     41	ns->ethtool.pauseparam.tx = pause->tx_pause;
     42	return 0;
     43}
     44
     45static int nsim_get_coalesce(struct net_device *dev,
     46			     struct ethtool_coalesce *coal,
     47			     struct kernel_ethtool_coalesce *kernel_coal,
     48			     struct netlink_ext_ack *extack)
     49{
     50	struct netdevsim *ns = netdev_priv(dev);
     51
     52	memcpy(coal, &ns->ethtool.coalesce, sizeof(ns->ethtool.coalesce));
     53	return 0;
     54}
     55
     56static int nsim_set_coalesce(struct net_device *dev,
     57			     struct ethtool_coalesce *coal,
     58			     struct kernel_ethtool_coalesce *kernel_coal,
     59			     struct netlink_ext_ack *extack)
     60{
     61	struct netdevsim *ns = netdev_priv(dev);
     62
     63	memcpy(&ns->ethtool.coalesce, coal, sizeof(ns->ethtool.coalesce));
     64	return 0;
     65}
     66
     67static void nsim_get_ringparam(struct net_device *dev,
     68			       struct ethtool_ringparam *ring,
     69			       struct kernel_ethtool_ringparam *kernel_ring,
     70			       struct netlink_ext_ack *extack)
     71{
     72	struct netdevsim *ns = netdev_priv(dev);
     73
     74	memcpy(ring, &ns->ethtool.ring, sizeof(ns->ethtool.ring));
     75}
     76
     77static int nsim_set_ringparam(struct net_device *dev,
     78			      struct ethtool_ringparam *ring,
     79			      struct kernel_ethtool_ringparam *kernel_ring,
     80			      struct netlink_ext_ack *extack)
     81{
     82	struct netdevsim *ns = netdev_priv(dev);
     83
     84	ns->ethtool.ring.rx_pending = ring->rx_pending;
     85	ns->ethtool.ring.rx_jumbo_pending = ring->rx_jumbo_pending;
     86	ns->ethtool.ring.rx_mini_pending = ring->rx_mini_pending;
     87	ns->ethtool.ring.tx_pending = ring->tx_pending;
     88	return 0;
     89}
     90
     91static void
     92nsim_get_channels(struct net_device *dev, struct ethtool_channels *ch)
     93{
     94	struct netdevsim *ns = netdev_priv(dev);
     95
     96	ch->max_combined = ns->nsim_bus_dev->num_queues;
     97	ch->combined_count = ns->ethtool.channels;
     98}
     99
    100static int
    101nsim_set_channels(struct net_device *dev, struct ethtool_channels *ch)
    102{
    103	struct netdevsim *ns = netdev_priv(dev);
    104	int err;
    105
    106	err = netif_set_real_num_queues(dev, ch->combined_count,
    107					ch->combined_count);
    108	if (err)
    109		return err;
    110
    111	ns->ethtool.channels = ch->combined_count;
    112	return 0;
    113}
    114
    115static int
    116nsim_get_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
    117{
    118	struct netdevsim *ns = netdev_priv(dev);
    119
    120	if (ns->ethtool.get_err)
    121		return -ns->ethtool.get_err;
    122	memcpy(fecparam, &ns->ethtool.fec, sizeof(ns->ethtool.fec));
    123	return 0;
    124}
    125
    126static int
    127nsim_set_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
    128{
    129	struct netdevsim *ns = netdev_priv(dev);
    130	u32 fec;
    131
    132	if (ns->ethtool.set_err)
    133		return -ns->ethtool.set_err;
    134	memcpy(&ns->ethtool.fec, fecparam, sizeof(ns->ethtool.fec));
    135	fec = fecparam->fec;
    136	if (fec == ETHTOOL_FEC_AUTO)
    137		fec |= ETHTOOL_FEC_OFF;
    138	fec |= ETHTOOL_FEC_NONE;
    139	ns->ethtool.fec.active_fec = 1 << (fls(fec) - 1);
    140	return 0;
    141}
    142
    143static const struct ethtool_ops nsim_ethtool_ops = {
    144	.supported_coalesce_params	= ETHTOOL_COALESCE_ALL_PARAMS,
    145	.get_pause_stats	        = nsim_get_pause_stats,
    146	.get_pauseparam		        = nsim_get_pauseparam,
    147	.set_pauseparam		        = nsim_set_pauseparam,
    148	.set_coalesce			= nsim_set_coalesce,
    149	.get_coalesce			= nsim_get_coalesce,
    150	.get_ringparam			= nsim_get_ringparam,
    151	.set_ringparam			= nsim_set_ringparam,
    152	.get_channels			= nsim_get_channels,
    153	.set_channels			= nsim_set_channels,
    154	.get_fecparam			= nsim_get_fecparam,
    155	.set_fecparam			= nsim_set_fecparam,
    156};
    157
    158static void nsim_ethtool_ring_init(struct netdevsim *ns)
    159{
    160	ns->ethtool.ring.rx_max_pending = 4096;
    161	ns->ethtool.ring.rx_jumbo_max_pending = 4096;
    162	ns->ethtool.ring.rx_mini_max_pending = 4096;
    163	ns->ethtool.ring.tx_max_pending = 4096;
    164}
    165
    166void nsim_ethtool_init(struct netdevsim *ns)
    167{
    168	struct dentry *ethtool, *dir;
    169
    170	ns->netdev->ethtool_ops = &nsim_ethtool_ops;
    171
    172	nsim_ethtool_ring_init(ns);
    173
    174	ns->ethtool.fec.fec = ETHTOOL_FEC_NONE;
    175	ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
    176
    177	ns->ethtool.channels = ns->nsim_bus_dev->num_queues;
    178
    179	ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);
    180
    181	debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
    182	debugfs_create_u32("set_err", 0600, ethtool, &ns->ethtool.set_err);
    183
    184	dir = debugfs_create_dir("pause", ethtool);
    185	debugfs_create_bool("report_stats_rx", 0600, dir,
    186			    &ns->ethtool.pauseparam.report_stats_rx);
    187	debugfs_create_bool("report_stats_tx", 0600, dir,
    188			    &ns->ethtool.pauseparam.report_stats_tx);
    189
    190	dir = debugfs_create_dir("ring", ethtool);
    191	debugfs_create_u32("rx_max_pending", 0600, dir,
    192			   &ns->ethtool.ring.rx_max_pending);
    193	debugfs_create_u32("rx_jumbo_max_pending", 0600, dir,
    194			   &ns->ethtool.ring.rx_jumbo_max_pending);
    195	debugfs_create_u32("rx_mini_max_pending", 0600, dir,
    196			   &ns->ethtool.ring.rx_mini_max_pending);
    197	debugfs_create_u32("tx_max_pending", 0600, dir,
    198			   &ns->ethtool.ring.tx_max_pending);
    199}