Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Texas Instruments Ethernet Switch Driver ethtool intf
0004  *
0005  * Copyright (C) 2019 Texas Instruments
0006  */
0007 
0008 #include <linux/if_ether.h>
0009 #include <linux/if_vlan.h>
0010 #include <linux/kmemleak.h>
0011 #include <linux/module.h>
0012 #include <linux/netdevice.h>
0013 #include <linux/net_tstamp.h>
0014 #include <linux/phy.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/skbuff.h>
0017 
0018 #include "cpsw.h"
0019 #include "cpts.h"
0020 #include "cpsw_ale.h"
0021 #include "cpsw_priv.h"
0022 #include "davinci_cpdma.h"
0023 
0024 struct cpsw_hw_stats {
0025     u32 rxgoodframes;
0026     u32 rxbroadcastframes;
0027     u32 rxmulticastframes;
0028     u32 rxpauseframes;
0029     u32 rxcrcerrors;
0030     u32 rxaligncodeerrors;
0031     u32 rxoversizedframes;
0032     u32 rxjabberframes;
0033     u32 rxundersizedframes;
0034     u32 rxfragments;
0035     u32 __pad_0[2];
0036     u32 rxoctets;
0037     u32 txgoodframes;
0038     u32 txbroadcastframes;
0039     u32 txmulticastframes;
0040     u32 txpauseframes;
0041     u32 txdeferredframes;
0042     u32 txcollisionframes;
0043     u32 txsinglecollframes;
0044     u32 txmultcollframes;
0045     u32 txexcessivecollisions;
0046     u32 txlatecollisions;
0047     u32 txunderrun;
0048     u32 txcarriersenseerrors;
0049     u32 txoctets;
0050     u32 octetframes64;
0051     u32 octetframes65t127;
0052     u32 octetframes128t255;
0053     u32 octetframes256t511;
0054     u32 octetframes512t1023;
0055     u32 octetframes1024tup;
0056     u32 netoctets;
0057     u32 rxsofoverruns;
0058     u32 rxmofoverruns;
0059     u32 rxdmaoverruns;
0060 };
0061 
0062 struct cpsw_stats {
0063     char stat_string[ETH_GSTRING_LEN];
0064     int type;
0065     int sizeof_stat;
0066     int stat_offset;
0067 };
0068 
0069 enum {
0070     CPSW_STATS,
0071     CPDMA_RX_STATS,
0072     CPDMA_TX_STATS,
0073 };
0074 
0075 #define CPSW_STAT(m)        CPSW_STATS,             \
0076                 sizeof_field(struct cpsw_hw_stats, m), \
0077                 offsetof(struct cpsw_hw_stats, m)
0078 #define CPDMA_RX_STAT(m)    CPDMA_RX_STATS,                \
0079                 sizeof_field(struct cpdma_chan_stats, m), \
0080                 offsetof(struct cpdma_chan_stats, m)
0081 #define CPDMA_TX_STAT(m)    CPDMA_TX_STATS,                \
0082                 sizeof_field(struct cpdma_chan_stats, m), \
0083                 offsetof(struct cpdma_chan_stats, m)
0084 
0085 static const struct cpsw_stats cpsw_gstrings_stats[] = {
0086     { "Good Rx Frames", CPSW_STAT(rxgoodframes) },
0087     { "Broadcast Rx Frames", CPSW_STAT(rxbroadcastframes) },
0088     { "Multicast Rx Frames", CPSW_STAT(rxmulticastframes) },
0089     { "Pause Rx Frames", CPSW_STAT(rxpauseframes) },
0090     { "Rx CRC Errors", CPSW_STAT(rxcrcerrors) },
0091     { "Rx Align/Code Errors", CPSW_STAT(rxaligncodeerrors) },
0092     { "Oversize Rx Frames", CPSW_STAT(rxoversizedframes) },
0093     { "Rx Jabbers", CPSW_STAT(rxjabberframes) },
0094     { "Undersize (Short) Rx Frames", CPSW_STAT(rxundersizedframes) },
0095     { "Rx Fragments", CPSW_STAT(rxfragments) },
0096     { "Rx Octets", CPSW_STAT(rxoctets) },
0097     { "Good Tx Frames", CPSW_STAT(txgoodframes) },
0098     { "Broadcast Tx Frames", CPSW_STAT(txbroadcastframes) },
0099     { "Multicast Tx Frames", CPSW_STAT(txmulticastframes) },
0100     { "Pause Tx Frames", CPSW_STAT(txpauseframes) },
0101     { "Deferred Tx Frames", CPSW_STAT(txdeferredframes) },
0102     { "Collisions", CPSW_STAT(txcollisionframes) },
0103     { "Single Collision Tx Frames", CPSW_STAT(txsinglecollframes) },
0104     { "Multiple Collision Tx Frames", CPSW_STAT(txmultcollframes) },
0105     { "Excessive Collisions", CPSW_STAT(txexcessivecollisions) },
0106     { "Late Collisions", CPSW_STAT(txlatecollisions) },
0107     { "Tx Underrun", CPSW_STAT(txunderrun) },
0108     { "Carrier Sense Errors", CPSW_STAT(txcarriersenseerrors) },
0109     { "Tx Octets", CPSW_STAT(txoctets) },
0110     { "Rx + Tx 64 Octet Frames", CPSW_STAT(octetframes64) },
0111     { "Rx + Tx 65-127 Octet Frames", CPSW_STAT(octetframes65t127) },
0112     { "Rx + Tx 128-255 Octet Frames", CPSW_STAT(octetframes128t255) },
0113     { "Rx + Tx 256-511 Octet Frames", CPSW_STAT(octetframes256t511) },
0114     { "Rx + Tx 512-1023 Octet Frames", CPSW_STAT(octetframes512t1023) },
0115     { "Rx + Tx 1024-Up Octet Frames", CPSW_STAT(octetframes1024tup) },
0116     { "Net Octets", CPSW_STAT(netoctets) },
0117     { "Rx Start of Frame Overruns", CPSW_STAT(rxsofoverruns) },
0118     { "Rx Middle of Frame Overruns", CPSW_STAT(rxmofoverruns) },
0119     { "Rx DMA Overruns", CPSW_STAT(rxdmaoverruns) },
0120 };
0121 
0122 static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
0123     { "head_enqueue", CPDMA_RX_STAT(head_enqueue) },
0124     { "tail_enqueue", CPDMA_RX_STAT(tail_enqueue) },
0125     { "pad_enqueue", CPDMA_RX_STAT(pad_enqueue) },
0126     { "misqueued", CPDMA_RX_STAT(misqueued) },
0127     { "desc_alloc_fail", CPDMA_RX_STAT(desc_alloc_fail) },
0128     { "pad_alloc_fail", CPDMA_RX_STAT(pad_alloc_fail) },
0129     { "runt_receive_buf", CPDMA_RX_STAT(runt_receive_buff) },
0130     { "runt_transmit_buf", CPDMA_RX_STAT(runt_transmit_buff) },
0131     { "empty_dequeue", CPDMA_RX_STAT(empty_dequeue) },
0132     { "busy_dequeue", CPDMA_RX_STAT(busy_dequeue) },
0133     { "good_dequeue", CPDMA_RX_STAT(good_dequeue) },
0134     { "requeue", CPDMA_RX_STAT(requeue) },
0135     { "teardown_dequeue", CPDMA_RX_STAT(teardown_dequeue) },
0136 };
0137 
0138 #define CPSW_STATS_COMMON_LEN   ARRAY_SIZE(cpsw_gstrings_stats)
0139 #define CPSW_STATS_CH_LEN   ARRAY_SIZE(cpsw_gstrings_ch_stats)
0140 
0141 u32 cpsw_get_msglevel(struct net_device *ndev)
0142 {
0143     struct cpsw_priv *priv = netdev_priv(ndev);
0144 
0145     return priv->msg_enable;
0146 }
0147 
0148 void cpsw_set_msglevel(struct net_device *ndev, u32 value)
0149 {
0150     struct cpsw_priv *priv = netdev_priv(ndev);
0151 
0152     priv->msg_enable = value;
0153 }
0154 
0155 int cpsw_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
0156               struct kernel_ethtool_coalesce *kernel_coal,
0157               struct netlink_ext_ack *extack)
0158 {
0159     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0160 
0161     coal->rx_coalesce_usecs = cpsw->coal_intvl;
0162     return 0;
0163 }
0164 
0165 int cpsw_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
0166               struct kernel_ethtool_coalesce *kernel_coal,
0167               struct netlink_ext_ack *extack)
0168 {
0169     struct cpsw_priv *priv = netdev_priv(ndev);
0170     u32 int_ctrl;
0171     u32 num_interrupts = 0;
0172     u32 prescale = 0;
0173     u32 addnl_dvdr = 1;
0174     u32 coal_intvl = 0;
0175     struct cpsw_common *cpsw = priv->cpsw;
0176 
0177     coal_intvl = coal->rx_coalesce_usecs;
0178 
0179     int_ctrl =  readl(&cpsw->wr_regs->int_control);
0180     prescale = cpsw->bus_freq_mhz * 4;
0181 
0182     if (!coal->rx_coalesce_usecs) {
0183         int_ctrl &= ~(CPSW_INTPRESCALE_MASK | CPSW_INTPACEEN);
0184         goto update_return;
0185     }
0186 
0187     if (coal_intvl < CPSW_CMINTMIN_INTVL)
0188         coal_intvl = CPSW_CMINTMIN_INTVL;
0189 
0190     if (coal_intvl > CPSW_CMINTMAX_INTVL) {
0191         /* Interrupt pacer works with 4us Pulse, we can
0192          * throttle further by dilating the 4us pulse.
0193          */
0194         addnl_dvdr = CPSW_INTPRESCALE_MASK / prescale;
0195 
0196         if (addnl_dvdr > 1) {
0197             prescale *= addnl_dvdr;
0198             if (coal_intvl > (CPSW_CMINTMAX_INTVL * addnl_dvdr))
0199                 coal_intvl = (CPSW_CMINTMAX_INTVL
0200                         * addnl_dvdr);
0201         } else {
0202             addnl_dvdr = 1;
0203             coal_intvl = CPSW_CMINTMAX_INTVL;
0204         }
0205     }
0206 
0207     num_interrupts = (1000 * addnl_dvdr) / coal_intvl;
0208     writel(num_interrupts, &cpsw->wr_regs->rx_imax);
0209     writel(num_interrupts, &cpsw->wr_regs->tx_imax);
0210 
0211     int_ctrl |= CPSW_INTPACEEN;
0212     int_ctrl &= (~CPSW_INTPRESCALE_MASK);
0213     int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK);
0214 
0215 update_return:
0216     writel(int_ctrl, &cpsw->wr_regs->int_control);
0217 
0218     cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl);
0219     cpsw->coal_intvl = coal_intvl;
0220 
0221     return 0;
0222 }
0223 
0224 int cpsw_get_sset_count(struct net_device *ndev, int sset)
0225 {
0226     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0227 
0228     switch (sset) {
0229     case ETH_SS_STATS:
0230         return (CPSW_STATS_COMMON_LEN +
0231                (cpsw->rx_ch_num + cpsw->tx_ch_num) *
0232                CPSW_STATS_CH_LEN);
0233     default:
0234         return -EOPNOTSUPP;
0235     }
0236 }
0237 
0238 static void cpsw_add_ch_strings(u8 **p, int ch_num, int rx_dir)
0239 {
0240     int ch_stats_len;
0241     int line;
0242     int i;
0243 
0244     ch_stats_len = CPSW_STATS_CH_LEN * ch_num;
0245     for (i = 0; i < ch_stats_len; i++) {
0246         line = i % CPSW_STATS_CH_LEN;
0247         snprintf(*p, ETH_GSTRING_LEN,
0248              "%s DMA chan %ld: %s", rx_dir ? "Rx" : "Tx",
0249              (long)(i / CPSW_STATS_CH_LEN),
0250              cpsw_gstrings_ch_stats[line].stat_string);
0251         *p += ETH_GSTRING_LEN;
0252     }
0253 }
0254 
0255 void cpsw_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
0256 {
0257     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0258     u8 *p = data;
0259     int i;
0260 
0261     switch (stringset) {
0262     case ETH_SS_STATS:
0263         for (i = 0; i < CPSW_STATS_COMMON_LEN; i++) {
0264             memcpy(p, cpsw_gstrings_stats[i].stat_string,
0265                    ETH_GSTRING_LEN);
0266             p += ETH_GSTRING_LEN;
0267         }
0268 
0269         cpsw_add_ch_strings(&p, cpsw->rx_ch_num, 1);
0270         cpsw_add_ch_strings(&p, cpsw->tx_ch_num, 0);
0271         break;
0272     }
0273 }
0274 
0275 void cpsw_get_ethtool_stats(struct net_device *ndev,
0276                 struct ethtool_stats *stats, u64 *data)
0277 {
0278     u8 *p;
0279     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0280     struct cpdma_chan_stats ch_stats;
0281     int i, l, ch;
0282 
0283     /* Collect Davinci CPDMA stats for Rx and Tx Channel */
0284     for (l = 0; l < CPSW_STATS_COMMON_LEN; l++)
0285         data[l] = readl(cpsw->hw_stats +
0286                 cpsw_gstrings_stats[l].stat_offset);
0287 
0288     for (ch = 0; ch < cpsw->rx_ch_num; ch++) {
0289         cpdma_chan_get_stats(cpsw->rxv[ch].ch, &ch_stats);
0290         for (i = 0; i < CPSW_STATS_CH_LEN; i++, l++) {
0291             p = (u8 *)&ch_stats +
0292                 cpsw_gstrings_ch_stats[i].stat_offset;
0293             data[l] = *(u32 *)p;
0294         }
0295     }
0296 
0297     for (ch = 0; ch < cpsw->tx_ch_num; ch++) {
0298         cpdma_chan_get_stats(cpsw->txv[ch].ch, &ch_stats);
0299         for (i = 0; i < CPSW_STATS_CH_LEN; i++, l++) {
0300             p = (u8 *)&ch_stats +
0301                 cpsw_gstrings_ch_stats[i].stat_offset;
0302             data[l] = *(u32 *)p;
0303         }
0304     }
0305 }
0306 
0307 void cpsw_get_pauseparam(struct net_device *ndev,
0308              struct ethtool_pauseparam *pause)
0309 {
0310     struct cpsw_priv *priv = netdev_priv(ndev);
0311 
0312     pause->autoneg = AUTONEG_DISABLE;
0313     pause->rx_pause = priv->rx_pause ? true : false;
0314     pause->tx_pause = priv->tx_pause ? true : false;
0315 }
0316 
0317 void cpsw_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
0318 {
0319     struct cpsw_priv *priv = netdev_priv(ndev);
0320     struct cpsw_common *cpsw = priv->cpsw;
0321     int slave_no = cpsw_slave_index(cpsw, priv);
0322 
0323     wol->supported = 0;
0324     wol->wolopts = 0;
0325 
0326     if (cpsw->slaves[slave_no].phy)
0327         phy_ethtool_get_wol(cpsw->slaves[slave_no].phy, wol);
0328 }
0329 
0330 int cpsw_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
0331 {
0332     struct cpsw_priv *priv = netdev_priv(ndev);
0333     struct cpsw_common *cpsw = priv->cpsw;
0334     int slave_no = cpsw_slave_index(cpsw, priv);
0335 
0336     if (cpsw->slaves[slave_no].phy)
0337         return phy_ethtool_set_wol(cpsw->slaves[slave_no].phy, wol);
0338     else
0339         return -EOPNOTSUPP;
0340 }
0341 
0342 int cpsw_get_regs_len(struct net_device *ndev)
0343 {
0344     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0345 
0346     return cpsw_ale_get_num_entries(cpsw->ale) *
0347            ALE_ENTRY_WORDS * sizeof(u32);
0348 }
0349 
0350 void cpsw_get_regs(struct net_device *ndev, struct ethtool_regs *regs, void *p)
0351 {
0352     u32 *reg = p;
0353     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0354 
0355     /* update CPSW IP version */
0356     regs->version = cpsw->version;
0357 
0358     cpsw_ale_dump(cpsw->ale, reg);
0359 }
0360 
0361 int cpsw_ethtool_op_begin(struct net_device *ndev)
0362 {
0363     struct cpsw_priv *priv = netdev_priv(ndev);
0364     struct cpsw_common *cpsw = priv->cpsw;
0365     int ret;
0366 
0367     ret = pm_runtime_resume_and_get(cpsw->dev);
0368     if (ret < 0)
0369         cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
0370 
0371     return ret;
0372 }
0373 
0374 void cpsw_ethtool_op_complete(struct net_device *ndev)
0375 {
0376     struct cpsw_priv *priv = netdev_priv(ndev);
0377     int ret;
0378 
0379     ret = pm_runtime_put(priv->cpsw->dev);
0380     if (ret < 0)
0381         cpsw_err(priv, drv, "ethtool complete failed %d\n", ret);
0382 }
0383 
0384 void cpsw_get_channels(struct net_device *ndev, struct ethtool_channels *ch)
0385 {
0386     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0387 
0388     ch->max_rx = cpsw->quirk_irq ? 1 : CPSW_MAX_QUEUES;
0389     ch->max_tx = cpsw->quirk_irq ? 1 : CPSW_MAX_QUEUES;
0390     ch->max_combined = 0;
0391     ch->max_other = 0;
0392     ch->other_count = 0;
0393     ch->rx_count = cpsw->rx_ch_num;
0394     ch->tx_count = cpsw->tx_ch_num;
0395     ch->combined_count = 0;
0396 }
0397 
0398 int cpsw_get_link_ksettings(struct net_device *ndev,
0399                 struct ethtool_link_ksettings *ecmd)
0400 {
0401     struct cpsw_priv *priv = netdev_priv(ndev);
0402     struct cpsw_common *cpsw = priv->cpsw;
0403     int slave_no = cpsw_slave_index(cpsw, priv);
0404 
0405     if (!cpsw->slaves[slave_no].phy)
0406         return -EOPNOTSUPP;
0407 
0408     phy_ethtool_ksettings_get(cpsw->slaves[slave_no].phy, ecmd);
0409     return 0;
0410 }
0411 
0412 int cpsw_set_link_ksettings(struct net_device *ndev,
0413                 const struct ethtool_link_ksettings *ecmd)
0414 {
0415     struct cpsw_priv *priv = netdev_priv(ndev);
0416     struct cpsw_common *cpsw = priv->cpsw;
0417     int slave_no = cpsw_slave_index(cpsw, priv);
0418 
0419     if (!cpsw->slaves[slave_no].phy)
0420         return -EOPNOTSUPP;
0421 
0422     return phy_ethtool_ksettings_set(cpsw->slaves[slave_no].phy, ecmd);
0423 }
0424 
0425 int cpsw_get_eee(struct net_device *ndev, struct ethtool_eee *edata)
0426 {
0427     struct cpsw_priv *priv = netdev_priv(ndev);
0428     struct cpsw_common *cpsw = priv->cpsw;
0429     int slave_no = cpsw_slave_index(cpsw, priv);
0430 
0431     if (cpsw->slaves[slave_no].phy)
0432         return phy_ethtool_get_eee(cpsw->slaves[slave_no].phy, edata);
0433     else
0434         return -EOPNOTSUPP;
0435 }
0436 
0437 int cpsw_set_eee(struct net_device *ndev, struct ethtool_eee *edata)
0438 {
0439     struct cpsw_priv *priv = netdev_priv(ndev);
0440     struct cpsw_common *cpsw = priv->cpsw;
0441     int slave_no = cpsw_slave_index(cpsw, priv);
0442 
0443     if (cpsw->slaves[slave_no].phy)
0444         return phy_ethtool_set_eee(cpsw->slaves[slave_no].phy, edata);
0445     else
0446         return -EOPNOTSUPP;
0447 }
0448 
0449 int cpsw_nway_reset(struct net_device *ndev)
0450 {
0451     struct cpsw_priv *priv = netdev_priv(ndev);
0452     struct cpsw_common *cpsw = priv->cpsw;
0453     int slave_no = cpsw_slave_index(cpsw, priv);
0454 
0455     if (cpsw->slaves[slave_no].phy)
0456         return genphy_restart_aneg(cpsw->slaves[slave_no].phy);
0457     else
0458         return -EOPNOTSUPP;
0459 }
0460 
0461 static void cpsw_suspend_data_pass(struct net_device *ndev)
0462 {
0463     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0464     int i;
0465 
0466     /* Disable NAPI scheduling */
0467     cpsw_intr_disable(cpsw);
0468 
0469     /* Stop all transmit queues for every network device.
0470      */
0471     for (i = 0; i < cpsw->data.slaves; i++) {
0472         ndev = cpsw->slaves[i].ndev;
0473         if (!(ndev && netif_running(ndev)))
0474             continue;
0475 
0476         netif_tx_stop_all_queues(ndev);
0477 
0478         /* Barrier, so that stop_queue visible to other cpus */
0479         smp_mb__after_atomic();
0480     }
0481 
0482     /* Handle rest of tx packets and stop cpdma channels */
0483     cpdma_ctlr_stop(cpsw->dma);
0484 }
0485 
0486 static int cpsw_resume_data_pass(struct net_device *ndev)
0487 {
0488     struct cpsw_priv *priv = netdev_priv(ndev);
0489     struct cpsw_common *cpsw = priv->cpsw;
0490     int i, ret;
0491 
0492     /* After this receive is started */
0493     if (cpsw->usage_count) {
0494         ret = cpsw_fill_rx_channels(priv);
0495         if (ret)
0496             return ret;
0497 
0498         cpdma_ctlr_start(cpsw->dma);
0499         cpsw_intr_enable(cpsw);
0500     }
0501 
0502     /* Resume transmit for every affected interface */
0503     for (i = 0; i < cpsw->data.slaves; i++) {
0504         ndev = cpsw->slaves[i].ndev;
0505         if (ndev && netif_running(ndev))
0506             netif_tx_start_all_queues(ndev);
0507     }
0508 
0509     return 0;
0510 }
0511 
0512 static int cpsw_check_ch_settings(struct cpsw_common *cpsw,
0513                   struct ethtool_channels *ch)
0514 {
0515     if (cpsw->quirk_irq) {
0516         dev_err(cpsw->dev, "Maximum one tx/rx queue is allowed");
0517         return -EOPNOTSUPP;
0518     }
0519 
0520     if (ch->combined_count)
0521         return -EINVAL;
0522 
0523     /* verify we have at least one channel in each direction */
0524     if (!ch->rx_count || !ch->tx_count)
0525         return -EINVAL;
0526 
0527     if (ch->rx_count > cpsw->data.channels ||
0528         ch->tx_count > cpsw->data.channels)
0529         return -EINVAL;
0530 
0531     return 0;
0532 }
0533 
0534 static int cpsw_update_channels_res(struct cpsw_priv *priv, int ch_num, int rx,
0535                     cpdma_handler_fn rx_handler)
0536 {
0537     struct cpsw_common *cpsw = priv->cpsw;
0538     void (*handler)(void *, int, int);
0539     struct netdev_queue *queue;
0540     struct cpsw_vector *vec;
0541     int ret, *ch, vch;
0542 
0543     if (rx) {
0544         ch = &cpsw->rx_ch_num;
0545         vec = cpsw->rxv;
0546         handler = rx_handler;
0547     } else {
0548         ch = &cpsw->tx_ch_num;
0549         vec = cpsw->txv;
0550         handler = cpsw_tx_handler;
0551     }
0552 
0553     while (*ch < ch_num) {
0554         vch = rx ? *ch : 7 - *ch;
0555         vec[*ch].ch = cpdma_chan_create(cpsw->dma, vch, handler, rx);
0556         queue = netdev_get_tx_queue(priv->ndev, *ch);
0557         queue->tx_maxrate = 0;
0558 
0559         if (IS_ERR(vec[*ch].ch))
0560             return PTR_ERR(vec[*ch].ch);
0561 
0562         if (!vec[*ch].ch)
0563             return -EINVAL;
0564 
0565         cpsw_info(priv, ifup, "created new %d %s channel\n", *ch,
0566               (rx ? "rx" : "tx"));
0567         (*ch)++;
0568     }
0569 
0570     while (*ch > ch_num) {
0571         (*ch)--;
0572 
0573         ret = cpdma_chan_destroy(vec[*ch].ch);
0574         if (ret)
0575             return ret;
0576 
0577         cpsw_info(priv, ifup, "destroyed %d %s channel\n", *ch,
0578               (rx ? "rx" : "tx"));
0579     }
0580 
0581     return 0;
0582 }
0583 
0584 static void cpsw_fail(struct cpsw_common *cpsw)
0585 {
0586     struct net_device *ndev;
0587     int i;
0588 
0589     for (i = 0; i < cpsw->data.slaves; i++) {
0590         ndev = cpsw->slaves[i].ndev;
0591         if (ndev)
0592             dev_close(ndev);
0593     }
0594 }
0595 
0596 int cpsw_set_channels_common(struct net_device *ndev,
0597                  struct ethtool_channels *chs,
0598                  cpdma_handler_fn rx_handler)
0599 {
0600     struct cpsw_priv *priv = netdev_priv(ndev);
0601     struct cpsw_common *cpsw = priv->cpsw;
0602     struct net_device *sl_ndev;
0603     int i, new_pools, ret;
0604 
0605     ret = cpsw_check_ch_settings(cpsw, chs);
0606     if (ret < 0)
0607         return ret;
0608 
0609     cpsw_suspend_data_pass(ndev);
0610 
0611     new_pools = (chs->rx_count != cpsw->rx_ch_num) && cpsw->usage_count;
0612 
0613     ret = cpsw_update_channels_res(priv, chs->rx_count, 1, rx_handler);
0614     if (ret)
0615         goto err;
0616 
0617     ret = cpsw_update_channels_res(priv, chs->tx_count, 0, rx_handler);
0618     if (ret)
0619         goto err;
0620 
0621     for (i = 0; i < cpsw->data.slaves; i++) {
0622         sl_ndev = cpsw->slaves[i].ndev;
0623         if (!(sl_ndev && netif_running(sl_ndev)))
0624             continue;
0625 
0626         /* Inform stack about new count of queues */
0627         ret = netif_set_real_num_tx_queues(sl_ndev, cpsw->tx_ch_num);
0628         if (ret) {
0629             dev_err(priv->dev, "cannot set real number of tx queues\n");
0630             goto err;
0631         }
0632 
0633         ret = netif_set_real_num_rx_queues(sl_ndev, cpsw->rx_ch_num);
0634         if (ret) {
0635             dev_err(priv->dev, "cannot set real number of rx queues\n");
0636             goto err;
0637         }
0638     }
0639 
0640     cpsw_split_res(cpsw);
0641 
0642     if (new_pools) {
0643         cpsw_destroy_xdp_rxqs(cpsw);
0644         ret = cpsw_create_xdp_rxqs(cpsw);
0645         if (ret)
0646             goto err;
0647     }
0648 
0649     ret = cpsw_resume_data_pass(ndev);
0650     if (!ret)
0651         return 0;
0652 err:
0653     dev_err(priv->dev, "cannot update channels number, closing device\n");
0654     cpsw_fail(cpsw);
0655     return ret;
0656 }
0657 
0658 void cpsw_get_ringparam(struct net_device *ndev,
0659             struct ethtool_ringparam *ering,
0660             struct kernel_ethtool_ringparam *kernel_ering,
0661             struct netlink_ext_ack *extack)
0662 {
0663     struct cpsw_priv *priv = netdev_priv(ndev);
0664     struct cpsw_common *cpsw = priv->cpsw;
0665 
0666     /* not supported */
0667     ering->tx_max_pending = cpsw->descs_pool_size - CPSW_MAX_QUEUES;
0668     ering->tx_pending = cpdma_get_num_tx_descs(cpsw->dma);
0669     ering->rx_max_pending = cpsw->descs_pool_size - CPSW_MAX_QUEUES;
0670     ering->rx_pending = cpdma_get_num_rx_descs(cpsw->dma);
0671 }
0672 
0673 int cpsw_set_ringparam(struct net_device *ndev,
0674                struct ethtool_ringparam *ering,
0675                struct kernel_ethtool_ringparam *kernel_ering,
0676                struct netlink_ext_ack *extack)
0677 {
0678     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0679     int descs_num, ret;
0680 
0681     /* ignore ering->tx_pending - only rx_pending adjustment is supported */
0682 
0683     if (ering->rx_mini_pending || ering->rx_jumbo_pending ||
0684         ering->rx_pending < CPSW_MAX_QUEUES ||
0685         ering->rx_pending > (cpsw->descs_pool_size - CPSW_MAX_QUEUES))
0686         return -EINVAL;
0687 
0688     descs_num = cpdma_get_num_rx_descs(cpsw->dma);
0689     if (ering->rx_pending == descs_num)
0690         return 0;
0691 
0692     cpsw_suspend_data_pass(ndev);
0693 
0694     ret = cpdma_set_num_rx_descs(cpsw->dma, ering->rx_pending);
0695     if (ret) {
0696         if (cpsw_resume_data_pass(ndev))
0697             goto err;
0698 
0699         return ret;
0700     }
0701 
0702     if (cpsw->usage_count) {
0703         cpsw_destroy_xdp_rxqs(cpsw);
0704         ret = cpsw_create_xdp_rxqs(cpsw);
0705         if (ret)
0706             goto err;
0707     }
0708 
0709     ret = cpsw_resume_data_pass(ndev);
0710     if (!ret)
0711         return 0;
0712 err:
0713     cpdma_set_num_rx_descs(cpsw->dma, descs_num);
0714     dev_err(cpsw->dev, "cannot set ring params, closing device\n");
0715     cpsw_fail(cpsw);
0716     return ret;
0717 }
0718 
0719 #if IS_ENABLED(CONFIG_TI_CPTS)
0720 int cpsw_get_ts_info(struct net_device *ndev, struct ethtool_ts_info *info)
0721 {
0722     struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
0723 
0724     info->so_timestamping =
0725         SOF_TIMESTAMPING_TX_HARDWARE |
0726         SOF_TIMESTAMPING_TX_SOFTWARE |
0727         SOF_TIMESTAMPING_RX_HARDWARE |
0728         SOF_TIMESTAMPING_RX_SOFTWARE |
0729         SOF_TIMESTAMPING_SOFTWARE |
0730         SOF_TIMESTAMPING_RAW_HARDWARE;
0731     info->phc_index = cpsw->cpts->phc_index;
0732     info->tx_types =
0733         (1 << HWTSTAMP_TX_OFF) |
0734         (1 << HWTSTAMP_TX_ON);
0735     info->rx_filters =
0736         (1 << HWTSTAMP_FILTER_NONE) |
0737         (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
0738     return 0;
0739 }
0740 #else
0741 int cpsw_get_ts_info(struct net_device *ndev, struct ethtool_ts_info *info)
0742 {
0743     info->so_timestamping =
0744         SOF_TIMESTAMPING_TX_SOFTWARE |
0745         SOF_TIMESTAMPING_RX_SOFTWARE |
0746         SOF_TIMESTAMPING_SOFTWARE;
0747     info->phc_index = -1;
0748     info->tx_types = 0;
0749     info->rx_filters = 0;
0750     return 0;
0751 }
0752 #endif