0001
0002
0003
0004
0005
0006 #define KMSG_COMPONENT "qeth"
0007 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0008
0009 #include <linux/ethtool.h>
0010 #include "qeth_core.h"
0011
0012
0013 #define QETH_TXQ_STAT(_name, _stat) { \
0014 .name = _name, \
0015 .offset = offsetof(struct qeth_out_q_stats, _stat) \
0016 }
0017
0018 #define QETH_CARD_STAT(_name, _stat) { \
0019 .name = _name, \
0020 .offset = offsetof(struct qeth_card_stats, _stat) \
0021 }
0022
0023 struct qeth_stats {
0024 char name[ETH_GSTRING_LEN];
0025 unsigned int offset;
0026 };
0027
0028 static const struct qeth_stats txq_stats[] = {
0029 QETH_TXQ_STAT("IO buffers", bufs),
0030 QETH_TXQ_STAT("IO buffer elements", buf_elements),
0031 QETH_TXQ_STAT("packed IO buffers", bufs_pack),
0032 QETH_TXQ_STAT("skbs", tx_packets),
0033 QETH_TXQ_STAT("packed skbs", skbs_pack),
0034 QETH_TXQ_STAT("SG skbs", skbs_sg),
0035 QETH_TXQ_STAT("HW csum skbs", skbs_csum),
0036 QETH_TXQ_STAT("TSO skbs", skbs_tso),
0037 QETH_TXQ_STAT("linearized skbs", skbs_linearized),
0038 QETH_TXQ_STAT("linearized+error skbs", skbs_linearized_fail),
0039 QETH_TXQ_STAT("TSO bytes", tso_bytes),
0040 QETH_TXQ_STAT("Packing mode switches", packing_mode_switch),
0041 QETH_TXQ_STAT("Queue stopped", stopped),
0042 QETH_TXQ_STAT("Doorbell", doorbell),
0043 QETH_TXQ_STAT("IRQ for frames", coal_frames),
0044 QETH_TXQ_STAT("Completion IRQ", completion_irq),
0045 QETH_TXQ_STAT("Completion yield", completion_yield),
0046 QETH_TXQ_STAT("Completion timer", completion_timer),
0047 };
0048
0049 static const struct qeth_stats card_stats[] = {
0050 QETH_CARD_STAT("rx0 IO buffers", rx_bufs),
0051 QETH_CARD_STAT("rx0 HW csum skbs", rx_skb_csum),
0052 QETH_CARD_STAT("rx0 SG skbs", rx_sg_skbs),
0053 QETH_CARD_STAT("rx0 SG page frags", rx_sg_frags),
0054 QETH_CARD_STAT("rx0 SG page allocs", rx_sg_alloc_page),
0055 QETH_CARD_STAT("rx0 dropped, no memory", rx_dropped_nomem),
0056 QETH_CARD_STAT("rx0 dropped, bad format", rx_dropped_notsupp),
0057 QETH_CARD_STAT("rx0 dropped, runt", rx_dropped_runt),
0058 };
0059
0060 #define TXQ_STATS_LEN ARRAY_SIZE(txq_stats)
0061 #define CARD_STATS_LEN ARRAY_SIZE(card_stats)
0062
0063 static void qeth_add_stat_data(u64 **dst, void *src,
0064 const struct qeth_stats stats[],
0065 unsigned int size)
0066 {
0067 unsigned int i;
0068 char *stat;
0069
0070 for (i = 0; i < size; i++) {
0071 stat = (char *)src + stats[i].offset;
0072 **dst = *(u64 *)stat;
0073 (*dst)++;
0074 }
0075 }
0076
0077 static void qeth_add_stat_strings(u8 **data, const char *prefix,
0078 const struct qeth_stats stats[],
0079 unsigned int size)
0080 {
0081 unsigned int i;
0082
0083 for (i = 0; i < size; i++)
0084 ethtool_sprintf(data, "%s%s", prefix, stats[i].name);
0085 }
0086
0087 static int qeth_get_sset_count(struct net_device *dev, int stringset)
0088 {
0089 struct qeth_card *card = dev->ml_priv;
0090
0091 switch (stringset) {
0092 case ETH_SS_STATS:
0093 return CARD_STATS_LEN +
0094 card->qdio.no_out_queues * TXQ_STATS_LEN;
0095 default:
0096 return -EINVAL;
0097 }
0098 }
0099
0100 static void qeth_get_ethtool_stats(struct net_device *dev,
0101 struct ethtool_stats *stats, u64 *data)
0102 {
0103 struct qeth_card *card = dev->ml_priv;
0104 unsigned int i;
0105
0106 qeth_add_stat_data(&data, &card->stats, card_stats, CARD_STATS_LEN);
0107 for (i = 0; i < card->qdio.no_out_queues; i++)
0108 qeth_add_stat_data(&data, &card->qdio.out_qs[i]->stats,
0109 txq_stats, TXQ_STATS_LEN);
0110 }
0111
0112 static void __qeth_set_coalesce(struct net_device *dev,
0113 struct qeth_qdio_out_q *queue,
0114 struct ethtool_coalesce *coal)
0115 {
0116 WRITE_ONCE(queue->coalesce_usecs, coal->tx_coalesce_usecs);
0117 WRITE_ONCE(queue->max_coalesced_frames, coal->tx_max_coalesced_frames);
0118
0119 if (coal->tx_coalesce_usecs &&
0120 netif_running(dev) &&
0121 !qeth_out_queue_is_empty(queue))
0122 qeth_tx_arm_timer(queue, coal->tx_coalesce_usecs);
0123 }
0124
0125 static int qeth_set_coalesce(struct net_device *dev,
0126 struct ethtool_coalesce *coal,
0127 struct kernel_ethtool_coalesce *kernel_coal,
0128 struct netlink_ext_ack *extack)
0129 {
0130 struct qeth_card *card = dev->ml_priv;
0131 struct qeth_qdio_out_q *queue;
0132 unsigned int i;
0133
0134 if (!IS_IQD(card))
0135 return -EOPNOTSUPP;
0136
0137 if (!coal->tx_coalesce_usecs && !coal->tx_max_coalesced_frames)
0138 return -EINVAL;
0139
0140 qeth_for_each_output_queue(card, queue, i)
0141 __qeth_set_coalesce(dev, queue, coal);
0142
0143 return 0;
0144 }
0145
0146 static void qeth_get_ringparam(struct net_device *dev,
0147 struct ethtool_ringparam *param,
0148 struct kernel_ethtool_ringparam *kernel_param,
0149 struct netlink_ext_ack *extack)
0150 {
0151 struct qeth_card *card = dev->ml_priv;
0152
0153 param->rx_max_pending = QDIO_MAX_BUFFERS_PER_Q;
0154 param->rx_mini_max_pending = 0;
0155 param->rx_jumbo_max_pending = 0;
0156 param->tx_max_pending = QDIO_MAX_BUFFERS_PER_Q;
0157
0158 param->rx_pending = card->qdio.in_buf_pool.buf_count;
0159 param->rx_mini_pending = 0;
0160 param->rx_jumbo_pending = 0;
0161 param->tx_pending = QDIO_MAX_BUFFERS_PER_Q;
0162 }
0163
0164 static void qeth_get_strings(struct net_device *dev, u32 stringset, u8 *data)
0165 {
0166 struct qeth_card *card = dev->ml_priv;
0167 char prefix[ETH_GSTRING_LEN] = "";
0168 unsigned int i;
0169
0170 switch (stringset) {
0171 case ETH_SS_STATS:
0172 qeth_add_stat_strings(&data, prefix, card_stats,
0173 CARD_STATS_LEN);
0174 for (i = 0; i < card->qdio.no_out_queues; i++) {
0175 snprintf(prefix, ETH_GSTRING_LEN, "tx%u ", i);
0176 qeth_add_stat_strings(&data, prefix, txq_stats,
0177 TXQ_STATS_LEN);
0178 }
0179 break;
0180 default:
0181 WARN_ON(1);
0182 break;
0183 }
0184 }
0185
0186 static void qeth_get_drvinfo(struct net_device *dev,
0187 struct ethtool_drvinfo *info)
0188 {
0189 struct qeth_card *card = dev->ml_priv;
0190
0191 strlcpy(info->driver, IS_LAYER2(card) ? "qeth_l2" : "qeth_l3",
0192 sizeof(info->driver));
0193 strlcpy(info->fw_version, card->info.mcl_level,
0194 sizeof(info->fw_version));
0195 snprintf(info->bus_info, sizeof(info->bus_info), "%s/%s/%s",
0196 CARD_RDEV_ID(card), CARD_WDEV_ID(card), CARD_DDEV_ID(card));
0197 }
0198
0199 static void qeth_get_channels(struct net_device *dev,
0200 struct ethtool_channels *channels)
0201 {
0202 struct qeth_card *card = dev->ml_priv;
0203
0204 channels->max_rx = dev->num_rx_queues;
0205 channels->max_tx = card->qdio.no_out_queues;
0206 channels->max_other = 0;
0207 channels->max_combined = 0;
0208 channels->rx_count = dev->real_num_rx_queues;
0209 channels->tx_count = dev->real_num_tx_queues;
0210 channels->other_count = 0;
0211 channels->combined_count = 0;
0212 }
0213
0214 static int qeth_set_channels(struct net_device *dev,
0215 struct ethtool_channels *channels)
0216 {
0217 struct qeth_priv *priv = netdev_priv(dev);
0218 struct qeth_card *card = dev->ml_priv;
0219 int rc;
0220
0221 if (channels->rx_count == 0 || channels->tx_count == 0)
0222 return -EINVAL;
0223 if (channels->tx_count > card->qdio.no_out_queues)
0224 return -EINVAL;
0225
0226
0227 if (qeth_uses_tx_prio_queueing(card))
0228 return -EPERM;
0229
0230 if (IS_IQD(card)) {
0231 if (channels->tx_count < QETH_IQD_MIN_TXQ)
0232 return -EINVAL;
0233
0234
0235
0236
0237 if (netif_running(dev) &&
0238 channels->tx_count < dev->real_num_tx_queues)
0239 return -EPERM;
0240 }
0241
0242 rc = qeth_set_real_num_tx_queues(card, channels->tx_count);
0243 if (!rc)
0244 priv->tx_wanted_queues = channels->tx_count;
0245
0246 return rc;
0247 }
0248
0249 static int qeth_get_ts_info(struct net_device *dev,
0250 struct ethtool_ts_info *info)
0251 {
0252 struct qeth_card *card = dev->ml_priv;
0253
0254 if (!IS_IQD(card))
0255 return -EOPNOTSUPP;
0256
0257 return ethtool_op_get_ts_info(dev, info);
0258 }
0259
0260 static int qeth_get_tunable(struct net_device *dev,
0261 const struct ethtool_tunable *tuna, void *data)
0262 {
0263 struct qeth_priv *priv = netdev_priv(dev);
0264
0265 switch (tuna->id) {
0266 case ETHTOOL_RX_COPYBREAK:
0267 *(u32 *)data = priv->rx_copybreak;
0268 return 0;
0269 default:
0270 return -EOPNOTSUPP;
0271 }
0272 }
0273
0274 static int qeth_set_tunable(struct net_device *dev,
0275 const struct ethtool_tunable *tuna,
0276 const void *data)
0277 {
0278 struct qeth_priv *priv = netdev_priv(dev);
0279
0280 switch (tuna->id) {
0281 case ETHTOOL_RX_COPYBREAK:
0282 WRITE_ONCE(priv->rx_copybreak, *(u32 *)data);
0283 return 0;
0284 default:
0285 return -EOPNOTSUPP;
0286 }
0287 }
0288
0289 static int qeth_get_per_queue_coalesce(struct net_device *dev, u32 __queue,
0290 struct ethtool_coalesce *coal)
0291 {
0292 struct qeth_card *card = dev->ml_priv;
0293 struct qeth_qdio_out_q *queue;
0294
0295 if (!IS_IQD(card))
0296 return -EOPNOTSUPP;
0297
0298 if (__queue >= card->qdio.no_out_queues)
0299 return -EINVAL;
0300
0301 queue = card->qdio.out_qs[__queue];
0302
0303 coal->tx_coalesce_usecs = queue->coalesce_usecs;
0304 coal->tx_max_coalesced_frames = queue->max_coalesced_frames;
0305 return 0;
0306 }
0307
0308 static int qeth_set_per_queue_coalesce(struct net_device *dev, u32 queue,
0309 struct ethtool_coalesce *coal)
0310 {
0311 struct qeth_card *card = dev->ml_priv;
0312
0313 if (!IS_IQD(card))
0314 return -EOPNOTSUPP;
0315
0316 if (queue >= card->qdio.no_out_queues)
0317 return -EINVAL;
0318
0319 if (!coal->tx_coalesce_usecs && !coal->tx_max_coalesced_frames)
0320 return -EINVAL;
0321
0322 __qeth_set_coalesce(dev, card->qdio.out_qs[queue], coal);
0323 return 0;
0324 }
0325
0326
0327
0328
0329
0330 static void qeth_set_ethtool_link_modes(struct ethtool_link_ksettings *cmd,
0331 enum qeth_link_mode link_mode)
0332 {
0333 ethtool_link_ksettings_zero_link_mode(cmd, supported);
0334 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
0335 ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
0336
0337 ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
0338 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
0339
0340 switch (cmd->base.port) {
0341 case PORT_TP:
0342 ethtool_link_ksettings_add_link_mode(cmd, supported, TP);
0343 ethtool_link_ksettings_add_link_mode(cmd, advertising, TP);
0344
0345 switch (cmd->base.speed) {
0346 case SPEED_10000:
0347 ethtool_link_ksettings_add_link_mode(cmd, supported,
0348 10000baseT_Full);
0349 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0350 10000baseT_Full);
0351 fallthrough;
0352 case SPEED_1000:
0353 ethtool_link_ksettings_add_link_mode(cmd, supported,
0354 1000baseT_Full);
0355 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0356 1000baseT_Full);
0357 ethtool_link_ksettings_add_link_mode(cmd, supported,
0358 1000baseT_Half);
0359 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0360 1000baseT_Half);
0361 fallthrough;
0362 case SPEED_100:
0363 ethtool_link_ksettings_add_link_mode(cmd, supported,
0364 100baseT_Full);
0365 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0366 100baseT_Full);
0367 ethtool_link_ksettings_add_link_mode(cmd, supported,
0368 100baseT_Half);
0369 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0370 100baseT_Half);
0371 fallthrough;
0372 case SPEED_10:
0373 ethtool_link_ksettings_add_link_mode(cmd, supported,
0374 10baseT_Full);
0375 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0376 10baseT_Full);
0377 ethtool_link_ksettings_add_link_mode(cmd, supported,
0378 10baseT_Half);
0379 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0380 10baseT_Half);
0381 break;
0382 default:
0383 break;
0384 }
0385
0386 break;
0387 case PORT_FIBRE:
0388 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
0389 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
0390
0391 switch (cmd->base.speed) {
0392 case SPEED_25000:
0393 ethtool_link_ksettings_add_link_mode(cmd, supported,
0394 25000baseSR_Full);
0395 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0396 25000baseSR_Full);
0397 break;
0398 case SPEED_10000:
0399 if (link_mode == QETH_LINK_MODE_FIBRE_LONG) {
0400 ethtool_link_ksettings_add_link_mode(cmd, supported,
0401 10000baseLR_Full);
0402 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0403 10000baseLR_Full);
0404 } else if (link_mode == QETH_LINK_MODE_FIBRE_SHORT) {
0405 ethtool_link_ksettings_add_link_mode(cmd, supported,
0406 10000baseSR_Full);
0407 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0408 10000baseSR_Full);
0409 }
0410 break;
0411 case SPEED_1000:
0412 ethtool_link_ksettings_add_link_mode(cmd, supported,
0413 1000baseX_Full);
0414 ethtool_link_ksettings_add_link_mode(cmd, advertising,
0415 1000baseX_Full);
0416 break;
0417 default:
0418 break;
0419 }
0420
0421 break;
0422 default:
0423 break;
0424 }
0425 }
0426
0427 static int qeth_get_link_ksettings(struct net_device *netdev,
0428 struct ethtool_link_ksettings *cmd)
0429 {
0430 struct qeth_card *card = netdev->ml_priv;
0431
0432 QETH_CARD_TEXT(card, 4, "ethtglks");
0433 cmd->base.speed = card->info.link_info.speed;
0434 cmd->base.duplex = card->info.link_info.duplex;
0435 cmd->base.port = card->info.link_info.port;
0436 cmd->base.autoneg = AUTONEG_ENABLE;
0437 cmd->base.phy_address = 0;
0438 cmd->base.mdio_support = 0;
0439 cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID;
0440 cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID;
0441
0442 qeth_set_ethtool_link_modes(cmd, card->info.link_info.link_mode);
0443
0444 return 0;
0445 }
0446
0447 const struct ethtool_ops qeth_ethtool_ops = {
0448 .supported_coalesce_params = ETHTOOL_COALESCE_TX_USECS |
0449 ETHTOOL_COALESCE_TX_MAX_FRAMES,
0450 .get_link = ethtool_op_get_link,
0451 .set_coalesce = qeth_set_coalesce,
0452 .get_ringparam = qeth_get_ringparam,
0453 .get_strings = qeth_get_strings,
0454 .get_ethtool_stats = qeth_get_ethtool_stats,
0455 .get_sset_count = qeth_get_sset_count,
0456 .get_drvinfo = qeth_get_drvinfo,
0457 .get_channels = qeth_get_channels,
0458 .set_channels = qeth_set_channels,
0459 .get_ts_info = qeth_get_ts_info,
0460 .get_tunable = qeth_get_tunable,
0461 .set_tunable = qeth_set_tunable,
0462 .get_per_queue_coalesce = qeth_get_per_queue_coalesce,
0463 .set_per_queue_coalesce = qeth_set_per_queue_coalesce,
0464 .get_link_ksettings = qeth_get_link_ksettings,
0465 };