Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ll_temac: Add ethtool support for coalesce parameters

Please note that the delays are calculated based on typical
parameters. But as TEMAC is an HDL IP, designs may vary, and future
work might be needed to make this calculation configurable.

Signed-off-by: Esben Haabendal <esben@geanix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Esben Haabendal and committed by
David S. Miller
227d4617 f7b261bf

+81 -22
+3 -2
drivers/net/ethernet/xilinx/ll_temac.h
··· 379 379 int rx_bd_tail; 380 380 381 381 /* DMA channel control setup */ 382 - u32 tx_chnl_ctrl; 383 - u32 rx_chnl_ctrl; 382 + u8 coalesce_count_tx; 383 + u8 coalesce_delay_tx; 384 384 u8 coalesce_count_rx; 385 + u8 coalesce_delay_rx; 385 386 386 387 struct delayed_work restart_work; 387 388 };
+78 -20
drivers/net/ethernet/xilinx/ll_temac_main.c
··· 379 379 } 380 380 381 381 /* Configure DMA channel (irq setup) */ 382 - lp->dma_out(lp, TX_CHNL_CTRL, lp->tx_chnl_ctrl | 382 + lp->dma_out(lp, TX_CHNL_CTRL, 383 + lp->coalesce_delay_tx << 24 | lp->coalesce_count_tx << 16 | 383 384 0x00000400 | // Use 1 Bit Wide Counters. Currently Not Used! 384 385 CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN | 385 386 CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN); 386 - lp->dma_out(lp, RX_CHNL_CTRL, lp->rx_chnl_ctrl | 387 + lp->dma_out(lp, RX_CHNL_CTRL, 388 + lp->coalesce_delay_rx << 24 | lp->coalesce_count_rx << 16 | 387 389 CHNL_CTRL_IRQ_IOE | 388 390 CHNL_CTRL_IRQ_EN | CHNL_CTRL_IRQ_ERR_EN | 389 391 CHNL_CTRL_IRQ_DLY_EN | CHNL_CTRL_IRQ_COAL_EN); ··· 1291 1289 return 0; 1292 1290 } 1293 1291 1292 + static int ll_temac_ethtools_get_coalesce(struct net_device *ndev, 1293 + struct ethtool_coalesce *ec) 1294 + { 1295 + struct temac_local *lp = netdev_priv(ndev); 1296 + 1297 + ec->rx_max_coalesced_frames = lp->coalesce_count_rx; 1298 + ec->tx_max_coalesced_frames = lp->coalesce_count_tx; 1299 + ec->rx_coalesce_usecs = (lp->coalesce_delay_rx * 512) / 100; 1300 + ec->tx_coalesce_usecs = (lp->coalesce_delay_tx * 512) / 100; 1301 + return 0; 1302 + } 1303 + 1304 + static int ll_temac_ethtools_set_coalesce(struct net_device *ndev, 1305 + struct ethtool_coalesce *ec) 1306 + { 1307 + struct temac_local *lp = netdev_priv(ndev); 1308 + 1309 + if (netif_running(ndev)) { 1310 + netdev_err(ndev, 1311 + "Please stop netif before applying configuration\n"); 1312 + return -EFAULT; 1313 + } 1314 + 1315 + if (ec->rx_coalesce_usecs_irq || 1316 + ec->rx_max_coalesced_frames_irq || 1317 + ec->tx_coalesce_usecs_irq || 1318 + ec->tx_max_coalesced_frames_irq || 1319 + ec->stats_block_coalesce_usecs || 1320 + ec->use_adaptive_rx_coalesce || 1321 + ec->use_adaptive_tx_coalesce || 1322 + ec->pkt_rate_low || 1323 + ec->rx_coalesce_usecs_low || 1324 + ec->rx_max_coalesced_frames_low || 1325 + ec->tx_coalesce_usecs_low || 1326 + ec->tx_max_coalesced_frames_low || 1327 + ec->pkt_rate_high || 1328 + ec->rx_coalesce_usecs_high || 1329 + ec->rx_max_coalesced_frames_high || 1330 + ec->tx_coalesce_usecs_high || 1331 + ec->tx_max_coalesced_frames_high || 1332 + ec->rate_sample_interval) 1333 + return -EOPNOTSUPP; 1334 + if (ec->rx_max_coalesced_frames) 1335 + lp->coalesce_count_rx = ec->rx_max_coalesced_frames; 1336 + if (ec->tx_max_coalesced_frames) 1337 + lp->coalesce_count_tx = ec->tx_max_coalesced_frames; 1338 + /* With typical LocalLink clock speed of 200 MHz and 1339 + * C_PRESCALAR=1023, each delay count corresponds to 5.12 us. 1340 + */ 1341 + if (ec->rx_coalesce_usecs) 1342 + lp->coalesce_delay_rx = 1343 + min(255U, (ec->rx_coalesce_usecs * 100) / 512); 1344 + if (ec->tx_coalesce_usecs) 1345 + lp->coalesce_delay_tx = 1346 + min(255U, (ec->tx_coalesce_usecs * 100) / 512); 1347 + 1348 + return 0; 1349 + } 1350 + 1294 1351 static const struct ethtool_ops temac_ethtool_ops = { 1295 1352 .nway_reset = phy_ethtool_nway_reset, 1296 1353 .get_link = ethtool_op_get_link, ··· 1358 1297 .set_link_ksettings = phy_ethtool_set_link_ksettings, 1359 1298 .get_ringparam = ll_temac_ethtools_get_ringparam, 1360 1299 .set_ringparam = ll_temac_ethtools_set_ringparam, 1300 + .get_coalesce = ll_temac_ethtools_get_coalesce, 1301 + .set_coalesce = ll_temac_ethtools_set_coalesce, 1361 1302 }; 1362 1303 1363 1304 static int temac_probe(struct platform_device *pdev) ··· 1469 1406 /* Can checksum TCP/UDP over IPv4. */ 1470 1407 ndev->features |= NETIF_F_IP_CSUM; 1471 1408 1409 + /* Defaults for IRQ delay/coalescing setup. These are 1410 + * configuration values, so does not belong in device-tree. 1411 + */ 1412 + lp->coalesce_delay_tx = 0x10; 1413 + lp->coalesce_count_tx = 0x22; 1414 + lp->coalesce_delay_rx = 0xff; 1415 + lp->coalesce_count_rx = 0x07; 1416 + 1472 1417 /* Setup LocalLink DMA */ 1473 1418 if (temac_np) { 1474 1419 /* Find the DMA node, map the DMA registers, and ··· 1515 1444 lp->rx_irq = irq_of_parse_and_map(dma_np, 0); 1516 1445 lp->tx_irq = irq_of_parse_and_map(dma_np, 1); 1517 1446 1518 - /* Use defaults for IRQ delay/coalescing setup. These 1519 - * are configuration values, so does not belong in 1520 - * device-tree. 1521 - */ 1522 - lp->tx_chnl_ctrl = 0x10220000; 1523 - lp->rx_chnl_ctrl = 0xff070000; 1524 - lp->coalesce_count_rx = 0x07; 1525 - 1526 1447 /* Finished with the DMA node; drop the reference */ 1527 1448 of_node_put(dma_np); 1528 1449 } else if (pdata) { ··· 1540 1477 lp->tx_irq = platform_get_irq(pdev, 1); 1541 1478 1542 1479 /* IRQ delay/coalescing setup */ 1543 - if (pdata->tx_irq_timeout || pdata->tx_irq_count) 1544 - lp->tx_chnl_ctrl = (pdata->tx_irq_timeout << 24) | 1545 - (pdata->tx_irq_count << 16); 1546 - else 1547 - lp->tx_chnl_ctrl = 0x10220000; 1480 + if (pdata->tx_irq_timeout || pdata->tx_irq_count) { 1481 + lp->coalesce_delay_tx = pdata->tx_irq_timeout; 1482 + lp->coalesce_count_tx = pdata->tx_irq_count; 1483 + } 1548 1484 if (pdata->rx_irq_timeout || pdata->rx_irq_count) { 1549 - lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) | 1550 - (pdata->rx_irq_count << 16); 1485 + lp->coalesce_delay_rx = pdata->rx_irq_timeout; 1551 1486 lp->coalesce_count_rx = pdata->rx_irq_count; 1552 - } else { 1553 - lp->rx_chnl_ctrl = 0xff070000; 1554 - lp->coalesce_count_rx = 0x07; 1555 1487 } 1556 1488 } 1557 1489