33
33
#include <linux/of_irq.h>
34
34
#include <linux/of_address.h>
35
35
#include <linux/skbuff.h>
36
- #include <linux/spinlock .h>
36
+ #include <linux/math64 .h>
37
37
#include <linux/phy.h>
38
38
#include <linux/mii.h>
39
39
#include <linux/ethtool.h>
@@ -226,6 +226,28 @@ static void axienet_dma_bd_release(struct net_device *ndev)
226
226
lp -> rx_bd_p );
227
227
}
228
228
229
+ /**
230
+ * axienet_usec_to_timer - Calculate IRQ delay timer value
231
+ * @lp: Pointer to the axienet_local structure
232
+ * @coalesce_usec: Microseconds to convert into timer value
233
+ */
234
+ static u32 axienet_usec_to_timer (struct axienet_local * lp , u32 coalesce_usec )
235
+ {
236
+ u32 result ;
237
+ u64 clk_rate = 125000000 ; /* arbitrary guess if no clock rate set */
238
+
239
+ if (lp -> axi_clk )
240
+ clk_rate = clk_get_rate (lp -> axi_clk );
241
+
242
+ /* 1 Timeout Interval = 125 * (clock period of SG clock) */
243
+ result = DIV64_U64_ROUND_CLOSEST ((u64 )coalesce_usec * clk_rate ,
244
+ (u64 )125000000 );
245
+ if (result > 255 )
246
+ result = 255 ;
247
+
248
+ return result ;
249
+ }
250
+
229
251
/**
230
252
* axienet_dma_start - Set up DMA registers and start DMA operation
231
253
* @lp: Pointer to the axienet_local structure
@@ -241,7 +263,8 @@ static void axienet_dma_start(struct axienet_local *lp)
241
263
* the first RX packet. Otherwise leave at 0 to disable delay interrupt.
242
264
*/
243
265
if (lp -> coalesce_count_rx > 1 )
244
- lp -> rx_dma_cr |= (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT ) |
266
+ lp -> rx_dma_cr |= (axienet_usec_to_timer (lp , lp -> coalesce_usec_rx )
267
+ << XAXIDMA_DELAY_SHIFT ) |
245
268
XAXIDMA_IRQ_DELAY_MASK ;
246
269
axienet_dma_out32 (lp , XAXIDMA_RX_CR_OFFSET , lp -> rx_dma_cr );
247
270
@@ -252,7 +275,8 @@ static void axienet_dma_start(struct axienet_local *lp)
252
275
* the first TX packet. Otherwise leave at 0 to disable delay interrupt.
253
276
*/
254
277
if (lp -> coalesce_count_tx > 1 )
255
- tx_cr |= (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT ) |
278
+ tx_cr |= (axienet_usec_to_timer (lp , lp -> coalesce_usec_tx )
279
+ << XAXIDMA_DELAY_SHIFT ) |
256
280
XAXIDMA_IRQ_DELAY_MASK ;
257
281
axienet_dma_out32 (lp , XAXIDMA_TX_CR_OFFSET , tx_cr );
258
282
@@ -1469,14 +1493,12 @@ axienet_ethtools_get_coalesce(struct net_device *ndev,
1469
1493
struct kernel_ethtool_coalesce * kernel_coal ,
1470
1494
struct netlink_ext_ack * extack )
1471
1495
{
1472
- u32 regval = 0 ;
1473
1496
struct axienet_local * lp = netdev_priv (ndev );
1474
- regval = axienet_dma_in32 (lp , XAXIDMA_RX_CR_OFFSET );
1475
- ecoalesce -> rx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK )
1476
- >> XAXIDMA_COALESCE_SHIFT ;
1477
- regval = axienet_dma_in32 (lp , XAXIDMA_TX_CR_OFFSET );
1478
- ecoalesce -> tx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK )
1479
- >> XAXIDMA_COALESCE_SHIFT ;
1497
+
1498
+ ecoalesce -> rx_max_coalesced_frames = lp -> coalesce_count_rx ;
1499
+ ecoalesce -> rx_coalesce_usecs = lp -> coalesce_usec_rx ;
1500
+ ecoalesce -> tx_max_coalesced_frames = lp -> coalesce_count_tx ;
1501
+ ecoalesce -> tx_coalesce_usecs = lp -> coalesce_usec_tx ;
1480
1502
return 0 ;
1481
1503
}
1482
1504
@@ -1509,8 +1531,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
1509
1531
1510
1532
if (ecoalesce -> rx_max_coalesced_frames )
1511
1533
lp -> coalesce_count_rx = ecoalesce -> rx_max_coalesced_frames ;
1534
+ if (ecoalesce -> rx_coalesce_usecs )
1535
+ lp -> coalesce_usec_rx = ecoalesce -> rx_coalesce_usecs ;
1512
1536
if (ecoalesce -> tx_max_coalesced_frames )
1513
1537
lp -> coalesce_count_tx = ecoalesce -> tx_max_coalesced_frames ;
1538
+ if (ecoalesce -> tx_coalesce_usecs )
1539
+ lp -> coalesce_usec_tx = ecoalesce -> tx_coalesce_usecs ;
1514
1540
1515
1541
return 0 ;
1516
1542
}
@@ -1541,7 +1567,8 @@ static int axienet_ethtools_nway_reset(struct net_device *dev)
1541
1567
}
1542
1568
1543
1569
static const struct ethtool_ops axienet_ethtool_ops = {
1544
- .supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES ,
1570
+ .supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES |
1571
+ ETHTOOL_COALESCE_USECS ,
1545
1572
.get_drvinfo = axienet_ethtools_get_drvinfo ,
1546
1573
.get_regs_len = axienet_ethtools_get_regs_len ,
1547
1574
.get_regs = axienet_ethtools_get_regs ,
@@ -2028,7 +2055,9 @@ static int axienet_probe(struct platform_device *pdev)
2028
2055
}
2029
2056
2030
2057
lp -> coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD ;
2058
+ lp -> coalesce_usec_rx = XAXIDMA_DFT_RX_USEC ;
2031
2059
lp -> coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD ;
2060
+ lp -> coalesce_usec_tx = XAXIDMA_DFT_TX_USEC ;
2032
2061
2033
2062
/* Reset core now that clocks are enabled, prior to accessing MDIO */
2034
2063
ret = __axienet_device_reset (lp );
0 commit comments