0001
0002
0003
0004
0005
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
0192
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
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
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
0467 cpsw_intr_disable(cpsw);
0468
0469
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
0479 smp_mb__after_atomic();
0480 }
0481
0482
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
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
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
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
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
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
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