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

mcp251xfd-ethtool.c (4370B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
      4//
      5// Copyright (c) 2021, 2022 Pengutronix,
      6//               Marc Kleine-Budde <kernel@pengutronix.de>
      7//
      8
      9#include <linux/ethtool.h>
     10
     11#include "mcp251xfd.h"
     12#include "mcp251xfd-ram.h"
     13
     14static void
     15mcp251xfd_ring_get_ringparam(struct net_device *ndev,
     16			     struct ethtool_ringparam *ring,
     17			     struct kernel_ethtool_ringparam *kernel_ring,
     18			     struct netlink_ext_ack *extack)
     19{
     20	const struct mcp251xfd_priv *priv = netdev_priv(ndev);
     21	const bool fd_mode = mcp251xfd_is_fd_mode(priv);
     22	struct can_ram_layout layout;
     23
     24	can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode);
     25	ring->rx_max_pending = layout.max_rx;
     26	ring->tx_max_pending = layout.max_tx;
     27
     28	ring->rx_pending = priv->rx_obj_num;
     29	ring->tx_pending = priv->tx->obj_num;
     30}
     31
     32static int
     33mcp251xfd_ring_set_ringparam(struct net_device *ndev,
     34			     struct ethtool_ringparam *ring,
     35			     struct kernel_ethtool_ringparam *kernel_ring,
     36			     struct netlink_ext_ack *extack)
     37{
     38	struct mcp251xfd_priv *priv = netdev_priv(ndev);
     39	const bool fd_mode = mcp251xfd_is_fd_mode(priv);
     40	struct can_ram_layout layout;
     41
     42	can_ram_get_layout(&layout, &mcp251xfd_ram_config, ring, NULL, fd_mode);
     43	if ((layout.cur_rx != priv->rx_obj_num ||
     44	     layout.cur_tx != priv->tx->obj_num) &&
     45	    netif_running(ndev))
     46		return -EBUSY;
     47
     48	priv->rx_obj_num = layout.cur_rx;
     49	priv->rx_obj_num_coalesce_irq = layout.rx_coalesce;
     50	priv->tx->obj_num = layout.cur_tx;
     51
     52	return 0;
     53}
     54
     55static int mcp251xfd_ring_get_coalesce(struct net_device *ndev,
     56				       struct ethtool_coalesce *ec,
     57				       struct kernel_ethtool_coalesce *kec,
     58				       struct netlink_ext_ack *ext_ack)
     59{
     60	struct mcp251xfd_priv *priv = netdev_priv(ndev);
     61	u32 rx_max_frames, tx_max_frames;
     62
     63	/* The ethtool doc says:
     64	 * To disable coalescing, set usecs = 0 and max_frames = 1.
     65	 */
     66	if (priv->rx_obj_num_coalesce_irq == 0)
     67		rx_max_frames = 1;
     68	else
     69		rx_max_frames = priv->rx_obj_num_coalesce_irq;
     70
     71	ec->rx_max_coalesced_frames_irq = rx_max_frames;
     72	ec->rx_coalesce_usecs_irq = priv->rx_coalesce_usecs_irq;
     73
     74	if (priv->tx_obj_num_coalesce_irq == 0)
     75		tx_max_frames = 1;
     76	else
     77		tx_max_frames = priv->tx_obj_num_coalesce_irq;
     78
     79	ec->tx_max_coalesced_frames_irq = tx_max_frames;
     80	ec->tx_coalesce_usecs_irq = priv->tx_coalesce_usecs_irq;
     81
     82	return 0;
     83}
     84
     85static int mcp251xfd_ring_set_coalesce(struct net_device *ndev,
     86				       struct ethtool_coalesce *ec,
     87				       struct kernel_ethtool_coalesce *kec,
     88				       struct netlink_ext_ack *ext_ack)
     89{
     90	struct mcp251xfd_priv *priv = netdev_priv(ndev);
     91	const bool fd_mode = mcp251xfd_is_fd_mode(priv);
     92	const struct ethtool_ringparam ring = {
     93		.rx_pending = priv->rx_obj_num,
     94		.tx_pending = priv->tx->obj_num,
     95	};
     96	struct can_ram_layout layout;
     97
     98	can_ram_get_layout(&layout, &mcp251xfd_ram_config, &ring, ec, fd_mode);
     99
    100	if ((layout.rx_coalesce != priv->rx_obj_num_coalesce_irq ||
    101	     ec->rx_coalesce_usecs_irq != priv->rx_coalesce_usecs_irq ||
    102	     layout.tx_coalesce != priv->tx_obj_num_coalesce_irq ||
    103	     ec->tx_coalesce_usecs_irq != priv->tx_coalesce_usecs_irq) &&
    104	    netif_running(ndev))
    105		return -EBUSY;
    106
    107	priv->rx_obj_num = layout.cur_rx;
    108	priv->rx_obj_num_coalesce_irq = layout.rx_coalesce;
    109	priv->rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq;
    110
    111	priv->tx->obj_num = layout.cur_tx;
    112	priv->tx_obj_num_coalesce_irq = layout.tx_coalesce;
    113	priv->tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq;
    114
    115	return 0;
    116}
    117
    118static const struct ethtool_ops mcp251xfd_ethtool_ops = {
    119	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ |
    120		ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ |
    121		ETHTOOL_COALESCE_TX_USECS_IRQ |
    122		ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,
    123	.get_ringparam = mcp251xfd_ring_get_ringparam,
    124	.set_ringparam = mcp251xfd_ring_set_ringparam,
    125	.get_coalesce = mcp251xfd_ring_get_coalesce,
    126	.set_coalesce = mcp251xfd_ring_set_coalesce,
    127};
    128
    129void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv)
    130{
    131	struct can_ram_layout layout;
    132
    133	priv->ndev->ethtool_ops = &mcp251xfd_ethtool_ops;
    134
    135	can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, false);
    136	priv->rx_obj_num = layout.default_rx;
    137	priv->tx->obj_num = layout.default_tx;
    138
    139	priv->rx_obj_num_coalesce_irq = 0;
    140	priv->tx_obj_num_coalesce_irq = 0;
    141	priv->rx_coalesce_usecs_irq = 0;
    142	priv->tx_coalesce_usecs_irq = 0;
    143}