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/phylink.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 "txgbe_type.h" 12 #include "txgbe_ethtool.h" 13 14 static int txgbe_set_ringparam(struct net_device *netdev, 15 struct ethtool_ringparam *ring, 16 struct kernel_ethtool_ringparam *kernel_ring, 17 struct netlink_ext_ack *extack) 18 { 19 struct wx *wx = netdev_priv(netdev); 20 u32 new_rx_count, new_tx_count; 21 struct wx_ring *temp_ring; 22 int i, err = 0; 23 24 new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD); 25 new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE); 26 27 new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD); 28 new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE); 29 30 if (new_tx_count == wx->tx_ring_count && 31 new_rx_count == wx->rx_ring_count) 32 return 0; 33 34 err = wx_set_state_reset(wx); 35 if (err) 36 return err; 37 38 if (!netif_running(wx->netdev)) { 39 for (i = 0; i < wx->num_tx_queues; i++) 40 wx->tx_ring[i]->count = new_tx_count; 41 for (i = 0; i < wx->num_rx_queues; i++) 42 wx->rx_ring[i]->count = new_rx_count; 43 wx->tx_ring_count = new_tx_count; 44 wx->rx_ring_count = new_rx_count; 45 46 goto clear_reset; 47 } 48 49 /* allocate temporary buffer to store rings in */ 50 i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); 51 temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL); 52 if (!temp_ring) { 53 err = -ENOMEM; 54 goto clear_reset; 55 } 56 57 txgbe_down(wx); 58 59 wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring); 60 kvfree(temp_ring); 61 62 txgbe_up(wx); 63 64 clear_reset: 65 clear_bit(WX_STATE_RESETTING, wx->state); 66 return err; 67 } 68 69 static int txgbe_set_channels(struct net_device *dev, 70 struct ethtool_channels *ch) 71 { 72 int err; 73 74 err = wx_set_channels(dev, ch); 75 if (err < 0) 76 return err; 77 78 /* use setup TC to update any traffic class queue mapping */ 79 return txgbe_setup_tc(dev, netdev_get_num_tc(dev)); 80 } 81 82 static const struct ethtool_ops txgbe_ethtool_ops = { 83 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 84 ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ, 85 .get_drvinfo = wx_get_drvinfo, 86 .nway_reset = wx_nway_reset, 87 .get_link = ethtool_op_get_link, 88 .get_link_ksettings = wx_get_link_ksettings, 89 .set_link_ksettings = wx_set_link_ksettings, 90 .get_sset_count = wx_get_sset_count, 91 .get_strings = wx_get_strings, 92 .get_ethtool_stats = wx_get_ethtool_stats, 93 .get_eth_mac_stats = wx_get_mac_stats, 94 .get_pause_stats = wx_get_pause_stats, 95 .get_pauseparam = wx_get_pauseparam, 96 .set_pauseparam = wx_set_pauseparam, 97 .get_ringparam = wx_get_ringparam, 98 .set_ringparam = txgbe_set_ringparam, 99 .get_coalesce = wx_get_coalesce, 100 .set_coalesce = wx_set_coalesce, 101 .get_channels = wx_get_channels, 102 .set_channels = txgbe_set_channels, 103 .get_msglevel = wx_get_msglevel, 104 .set_msglevel = wx_set_msglevel, 105 }; 106 107 void txgbe_set_ethtool_ops(struct net_device *netdev) 108 { 109 netdev->ethtool_ops = &txgbe_ethtool_ops; 110 } 111