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 15 static int ngbe_set_ringparam(struct net_device *netdev, 16 struct ethtool_ringparam *ring, 17 struct kernel_ethtool_ringparam *kernel_ring, 18 struct netlink_ext_ack *extack) 19 { 20 struct wx *wx = netdev_priv(netdev); 21 u32 new_rx_count, new_tx_count; 22 struct wx_ring *temp_ring; 23 int i, err = 0; 24 25 new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD); 26 new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE); 27 28 new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD); 29 new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE); 30 31 if (new_tx_count == wx->tx_ring_count && 32 new_rx_count == wx->rx_ring_count) 33 return 0; 34 35 mutex_lock(&wx->reset_lock); 36 set_bit(WX_STATE_RESETTING, wx->state); 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_objs(struct wx_ring, i); 52 if (!temp_ring) { 53 err = -ENOMEM; 54 goto clear_reset; 55 } 56 57 ngbe_down(wx); 58 59 wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring); 60 kvfree(temp_ring); 61 62 ngbe_up(wx); 63 64 clear_reset: 65 clear_bit(WX_STATE_RESETTING, wx->state); 66 mutex_unlock(&wx->reset_lock); 67 return err; 68 } 69 70 static const struct ethtool_ops ngbe_ethtool_ops = { 71 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 72 ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ | 73 ETHTOOL_COALESCE_USE_ADAPTIVE, 74 .get_drvinfo = wx_get_drvinfo, 75 .get_link = ethtool_op_get_link, 76 .get_link_ksettings = wx_get_link_ksettings, 77 .set_link_ksettings = wx_set_link_ksettings, 78 .nway_reset = wx_nway_reset, 79 .get_wol = wx_get_wol, 80 .set_wol = wx_set_wol, 81 .get_sset_count = wx_get_sset_count, 82 .get_strings = wx_get_strings, 83 .get_ethtool_stats = wx_get_ethtool_stats, 84 .get_eth_mac_stats = wx_get_mac_stats, 85 .get_pause_stats = wx_get_pause_stats, 86 .get_pauseparam = wx_get_pauseparam, 87 .set_pauseparam = wx_set_pauseparam, 88 .get_ringparam = wx_get_ringparam, 89 .set_ringparam = ngbe_set_ringparam, 90 .get_coalesce = wx_get_coalesce, 91 .set_coalesce = wx_set_coalesce, 92 .get_channels = wx_get_channels, 93 .set_channels = wx_set_channels, 94 .get_rxfh_fields = wx_get_rxfh_fields, 95 .set_rxfh_fields = wx_set_rxfh_fields, 96 .get_rxfh_indir_size = wx_rss_indir_size, 97 .get_rxfh_key_size = wx_get_rxfh_key_size, 98 .get_rxfh = wx_get_rxfh, 99 .set_rxfh = wx_set_rxfh, 100 .get_msglevel = wx_get_msglevel, 101 .set_msglevel = wx_set_msglevel, 102 .get_ts_info = wx_get_ts_info, 103 .get_ts_stats = wx_get_ptp_stats, 104 }; 105 106 void ngbe_set_ethtool_ops(struct net_device *netdev) 107 { 108 netdev->ethtool_ops = &ngbe_ethtool_ops; 109 } 110