1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Alibaba Elastic Ethernet Adapter. 4 * 5 * Copyright (C) 2025 Alibaba Inc. 6 */ 7 8 #include <linux/ethtool.h> 9 #include <linux/ethtool_netlink.h> 10 #include <linux/rtnetlink.h> 11 12 #include "eea_adminq.h" 13 #include "eea_net.h" 14 #include "eea_pci.h" 15 16 struct eea_stat_desc { 17 char desc[ETH_GSTRING_LEN]; 18 size_t offset; 19 }; 20 21 #define EEA_TX_STAT(m) {#m, offsetof(struct eea_tx_stats, m)} 22 #define EEA_RX_STAT(m) {#m, offsetof(struct eea_rx_stats, m)} 23 24 static const struct eea_stat_desc eea_rx_stats_desc[] = { 25 EEA_RX_STAT(descs), 26 EEA_RX_STAT(kicks), 27 }; 28 29 static const struct eea_stat_desc eea_tx_stats_desc[] = { 30 EEA_TX_STAT(descs), 31 EEA_TX_STAT(kicks), 32 }; 33 34 #define EEA_TX_STATS_LEN ARRAY_SIZE(eea_tx_stats_desc) 35 #define EEA_RX_STATS_LEN ARRAY_SIZE(eea_rx_stats_desc) 36 37 static void eea_get_drvinfo(struct net_device *netdev, 38 struct ethtool_drvinfo *info) 39 { 40 struct eea_net *enet = netdev_priv(netdev); 41 struct eea_device *edev = enet->edev; 42 43 strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 44 strscpy(info->bus_info, eea_pci_name(edev), sizeof(info->bus_info)); 45 } 46 47 static void eea_get_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 eea_net *enet = netdev_priv(netdev); 53 54 ring->rx_max_pending = enet->cfg_hw.rx_ring_depth; 55 ring->tx_max_pending = enet->cfg_hw.tx_ring_depth; 56 ring->rx_pending = enet->cfg.rx_ring_depth; 57 ring->tx_pending = enet->cfg.tx_ring_depth; 58 59 kernel_ring->tcp_data_split = enet->cfg.split_hdr ? 60 ETHTOOL_TCP_DATA_SPLIT_ENABLED : 61 ETHTOOL_TCP_DATA_SPLIT_DISABLED; 62 } 63 64 static int eea_set_ringparam(struct net_device *netdev, 65 struct ethtool_ringparam *ring, 66 struct kernel_ethtool_ringparam *kernel_ring, 67 struct netlink_ext_ack *extack) 68 { 69 struct eea_net *enet = netdev_priv(netdev); 70 struct eea_net_init_ctx ctx; 71 bool need_update = false; 72 struct eea_net_cfg *cfg; 73 bool sh; 74 75 if (ring->rx_pending < EEA_NET_IO_RING_DEPTH_MIN || 76 ring->tx_pending < EEA_NET_IO_RING_DEPTH_MIN) 77 return -EINVAL; 78 79 if (!is_power_of_2(ring->rx_pending) || 80 !is_power_of_2(ring->tx_pending)) 81 return -EINVAL; 82 83 eea_init_ctx(enet, &ctx); 84 85 cfg = &ctx.cfg; 86 87 if (ring->rx_pending != cfg->rx_ring_depth) 88 need_update = true; 89 90 if (ring->tx_pending != cfg->tx_ring_depth) 91 need_update = true; 92 93 sh = false; 94 95 switch (kernel_ring->tcp_data_split) { 96 case ETHTOOL_TCP_DATA_SPLIT_ENABLED: 97 sh = true; 98 break; 99 100 case ETHTOOL_TCP_DATA_SPLIT_DISABLED: 101 sh = false; 102 break; 103 104 case ETHTOOL_TCP_DATA_SPLIT_UNKNOWN: 105 sh = !!cfg->split_hdr; 106 break; 107 } 108 109 if (sh != !!(cfg->split_hdr)) 110 need_update = true; 111 112 if (!need_update) 113 return 0; 114 115 cfg->rx_ring_depth = ring->rx_pending; 116 cfg->tx_ring_depth = ring->tx_pending; 117 118 /* By default, enet->cfg_hw.split_hdr is 128. */ 119 cfg->split_hdr = sh ? enet->cfg_hw.split_hdr : 0; 120 121 return eea_reset_hw_resources(enet, &ctx); 122 } 123 124 static int eea_set_channels(struct net_device *netdev, 125 struct ethtool_channels *channels) 126 { 127 struct eea_net *enet = netdev_priv(netdev); 128 u16 queue_pairs = channels->combined_count; 129 struct eea_net_init_ctx ctx; 130 struct eea_net_cfg *cfg; 131 132 eea_init_ctx(enet, &ctx); 133 134 cfg = &ctx.cfg; 135 136 cfg->rx_ring_num = queue_pairs; 137 cfg->tx_ring_num = queue_pairs; 138 139 return eea_reset_hw_resources(enet, &ctx); 140 } 141 142 static void eea_get_channels(struct net_device *netdev, 143 struct ethtool_channels *channels) 144 { 145 struct eea_net *enet = netdev_priv(netdev); 146 147 channels->combined_count = enet->cfg.rx_ring_num; 148 channels->max_combined = enet->cfg_hw.rx_ring_num; 149 } 150 151 static void eea_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 152 { 153 struct eea_net *enet = netdev_priv(netdev); 154 u8 *p = data; 155 u32 i, j; 156 157 if (stringset != ETH_SS_STATS) 158 return; 159 160 for (i = 0; i < enet->cfg.rx_ring_num; i++) { 161 for (j = 0; j < EEA_RX_STATS_LEN; j++) 162 ethtool_sprintf(&p, "rx%u_%s", i, 163 eea_rx_stats_desc[j].desc); 164 } 165 166 for (i = 0; i < enet->cfg.tx_ring_num; i++) { 167 for (j = 0; j < EEA_TX_STATS_LEN; j++) 168 ethtool_sprintf(&p, "tx%u_%s", i, 169 eea_tx_stats_desc[j].desc); 170 } 171 } 172 173 static int eea_get_sset_count(struct net_device *netdev, int sset) 174 { 175 struct eea_net *enet = netdev_priv(netdev); 176 177 if (sset != ETH_SS_STATS) 178 return -EOPNOTSUPP; 179 180 return enet->cfg.rx_ring_num * EEA_RX_STATS_LEN + 181 enet->cfg.tx_ring_num * EEA_TX_STATS_LEN; 182 } 183 184 static void eea_stats_fill_for_q(struct u64_stats_sync *syncp, u32 num, 185 const struct eea_stat_desc *desc, 186 u64 *data, u32 idx) 187 { 188 void *stats_base = syncp; 189 u32 start, i; 190 191 do { 192 start = u64_stats_fetch_begin(syncp); 193 for (i = 0; i < num; i++) 194 data[idx + i] = 195 u64_stats_read(stats_base + desc[i].offset); 196 197 } while (u64_stats_fetch_retry(syncp, start)); 198 199 BUILD_BUG_ON(offsetof(struct eea_tx_stats, syncp)); 200 BUILD_BUG_ON(offsetof(struct eea_rx_stats, syncp)); 201 } 202 203 static void eea_get_ethtool_stats(struct net_device *netdev, 204 struct ethtool_stats *stats, u64 *data) 205 { 206 struct eea_net *enet = netdev_priv(netdev); 207 u32 i, idx = 0; 208 209 ASSERT_RTNL(); 210 211 if (enet->rx) { 212 for (i = 0; i < enet->cfg.rx_ring_num; i++) { 213 struct eea_net_rx *rx = enet->rx[i]; 214 215 eea_stats_fill_for_q(&rx->stats.syncp, EEA_RX_STATS_LEN, 216 eea_rx_stats_desc, data, idx); 217 218 idx += EEA_RX_STATS_LEN; 219 } 220 } 221 222 if (enet->tx) { 223 for (i = 0; i < enet->cfg.tx_ring_num; i++) { 224 struct eea_net_tx *tx = &enet->tx[i]; 225 226 eea_stats_fill_for_q(&tx->stats.syncp, EEA_TX_STATS_LEN, 227 eea_tx_stats_desc, data, idx); 228 229 idx += EEA_TX_STATS_LEN; 230 } 231 } 232 } 233 234 void eea_update_rx_stats(struct eea_rx_stats *rx_stats, 235 struct eea_rx_ctx_stats *stats) 236 { 237 u64_stats_update_begin(&rx_stats->syncp); 238 u64_stats_add(&rx_stats->descs, stats->descs); 239 u64_stats_add(&rx_stats->packets, stats->packets); 240 u64_stats_add(&rx_stats->bytes, stats->bytes); 241 u64_stats_add(&rx_stats->drops, stats->drops); 242 u64_stats_add(&rx_stats->split_hdr_bytes, stats->split_hdr_bytes); 243 u64_stats_add(&rx_stats->split_hdr_packets, stats->split_hdr_packets); 244 u64_stats_add(&rx_stats->length_errors, stats->length_errors); 245 u64_stats_add(&rx_stats->kicks, stats->kicks); 246 u64_stats_update_end(&rx_stats->syncp); 247 } 248 249 static int eea_get_link_ksettings(struct net_device *netdev, 250 struct ethtool_link_ksettings *cmd) 251 { 252 struct eea_net *enet = netdev_priv(netdev); 253 254 cmd->base.speed = enet->speed; 255 cmd->base.duplex = enet->duplex; 256 cmd->base.port = PORT_OTHER; 257 258 return 0; 259 } 260 261 const struct ethtool_ops eea_ethtool_ops = { 262 .supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT, 263 .get_drvinfo = eea_get_drvinfo, 264 .get_link = ethtool_op_get_link, 265 .get_ringparam = eea_get_ringparam, 266 .set_ringparam = eea_set_ringparam, 267 .set_channels = eea_set_channels, 268 .get_channels = eea_get_channels, 269 .get_strings = eea_get_strings, 270 .get_sset_count = eea_get_sset_count, 271 .get_ethtool_stats = eea_get_ethtool_stats, 272 .get_link_ksettings = eea_get_link_ksettings, 273 }; 274