Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
  3
  4#include <linux/pci.h>
  5#include <linux/phy.h>
  6#include <linux/netdevice.h>
  7
  8#include "../libwx/wx_ethtool.h"
  9#include "../libwx/wx_type.h"
 10#include "../libwx/wx_lib.h"
 11#include "../libwx/wx_hw.h"
 12#include "ngbe_ethtool.h"
 13#include "ngbe_type.h"
 14
 15static void ngbe_get_wol(struct net_device *netdev,
 16			 struct ethtool_wolinfo *wol)
 17{
 18	struct wx *wx = netdev_priv(netdev);
 19
 20	if (!wx->wol_hw_supported)
 21		return;
 22	wol->supported = WAKE_MAGIC;
 23	wol->wolopts = 0;
 24	if (wx->wol & WX_PSR_WKUP_CTL_MAG)
 25		wol->wolopts |= WAKE_MAGIC;
 26}
 27
 28static int ngbe_set_wol(struct net_device *netdev,
 29			struct ethtool_wolinfo *wol)
 30{
 31	struct wx *wx = netdev_priv(netdev);
 32	struct pci_dev *pdev = wx->pdev;
 33
 34	if (!wx->wol_hw_supported)
 35		return -EOPNOTSUPP;
 36
 37	wx->wol = 0;
 38	if (wol->wolopts & WAKE_MAGIC)
 39		wx->wol = WX_PSR_WKUP_CTL_MAG;
 40	netdev->wol_enabled = !!(wx->wol);
 41	wr32(wx, WX_PSR_WKUP_CTL, wx->wol);
 42	device_set_wakeup_enable(&pdev->dev, netdev->wol_enabled);
 43
 44	return 0;
 45}
 46
 47static int ngbe_set_ringparam(struct net_device *netdev,
 48			      struct ethtool_ringparam *ring,
 49			      struct kernel_ethtool_ringparam *kernel_ring,
 50			      struct netlink_ext_ack *extack)
 51{
 52	struct wx *wx = netdev_priv(netdev);
 53	u32 new_rx_count, new_tx_count;
 54	struct wx_ring *temp_ring;
 55	int i;
 56
 57	new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
 58	new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
 59
 60	new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
 61	new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);
 62
 63	if (new_tx_count == wx->tx_ring_count &&
 64	    new_rx_count == wx->rx_ring_count)
 65		return 0;
 66
 67	if (!netif_running(wx->netdev)) {
 68		for (i = 0; i < wx->num_tx_queues; i++)
 69			wx->tx_ring[i]->count = new_tx_count;
 70		for (i = 0; i < wx->num_rx_queues; i++)
 71			wx->rx_ring[i]->count = new_rx_count;
 72		wx->tx_ring_count = new_tx_count;
 73		wx->rx_ring_count = new_rx_count;
 74
 75		return 0;
 76	}
 77
 78	/* allocate temporary buffer to store rings in */
 79	i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
 80	temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
 81	if (!temp_ring)
 82		return -ENOMEM;
 83
 84	ngbe_down(wx);
 85
 86	wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
 87	kvfree(temp_ring);
 88
 89	wx_configure(wx);
 90	ngbe_up(wx);
 91
 92	return 0;
 93}
 94
 95static int ngbe_set_channels(struct net_device *dev,
 96			     struct ethtool_channels *ch)
 97{
 98	int err;
 99
100	err = wx_set_channels(dev, ch);
101	if (err < 0)
102		return err;
103
104	/* use setup TC to update any traffic class queue mapping */
105	return ngbe_setup_tc(dev, netdev_get_num_tc(dev));
106}
107
108static const struct ethtool_ops ngbe_ethtool_ops = {
109	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
110				     ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,
111	.get_drvinfo		= wx_get_drvinfo,
112	.get_link		= ethtool_op_get_link,
113	.get_link_ksettings	= wx_get_link_ksettings,
114	.set_link_ksettings	= wx_set_link_ksettings,
115	.nway_reset		= wx_nway_reset,
116	.get_wol		= ngbe_get_wol,
117	.set_wol		= ngbe_set_wol,
118	.get_sset_count		= wx_get_sset_count,
119	.get_strings		= wx_get_strings,
120	.get_ethtool_stats	= wx_get_ethtool_stats,
121	.get_eth_mac_stats	= wx_get_mac_stats,
122	.get_pause_stats	= wx_get_pause_stats,
123	.get_pauseparam		= wx_get_pauseparam,
124	.set_pauseparam		= wx_set_pauseparam,
125	.get_ringparam		= wx_get_ringparam,
126	.set_ringparam		= ngbe_set_ringparam,
127	.get_coalesce		= wx_get_coalesce,
128	.set_coalesce		= wx_set_coalesce,
129	.get_channels		= wx_get_channels,
130	.set_channels		= ngbe_set_channels,
131	.get_msglevel		= wx_get_msglevel,
132	.set_msglevel		= wx_set_msglevel,
133};
134
135void ngbe_set_ethtool_ops(struct net_device *netdev)
136{
137	netdev->ethtool_ops = &ngbe_ethtool_ops;
138}