@@ -324,7 +324,137 @@ static int tsnep_ethtool_get_ts_info(struct net_device *netdev,
324
324
return 0 ;
325
325
}
326
326
327
+ static struct tsnep_queue * tsnep_get_queue_with_tx (struct tsnep_adapter * adapter ,
328
+ int index )
329
+ {
330
+ int i ;
331
+
332
+ for (i = 0 ; i < adapter -> num_queues ; i ++ ) {
333
+ if (adapter -> queue [i ].tx ) {
334
+ if (index == 0 )
335
+ return & adapter -> queue [i ];
336
+
337
+ index -- ;
338
+ }
339
+ }
340
+
341
+ return NULL ;
342
+ }
343
+
344
+ static struct tsnep_queue * tsnep_get_queue_with_rx (struct tsnep_adapter * adapter ,
345
+ int index )
346
+ {
347
+ int i ;
348
+
349
+ for (i = 0 ; i < adapter -> num_queues ; i ++ ) {
350
+ if (adapter -> queue [i ].rx ) {
351
+ if (index == 0 )
352
+ return & adapter -> queue [i ];
353
+
354
+ index -- ;
355
+ }
356
+ }
357
+
358
+ return NULL ;
359
+ }
360
+
361
+ static int tsnep_ethtool_get_coalesce (struct net_device * netdev ,
362
+ struct ethtool_coalesce * ec ,
363
+ struct kernel_ethtool_coalesce * kernel_coal ,
364
+ struct netlink_ext_ack * extack )
365
+ {
366
+ struct tsnep_adapter * adapter = netdev_priv (netdev );
367
+ struct tsnep_queue * queue ;
368
+
369
+ queue = tsnep_get_queue_with_rx (adapter , 0 );
370
+ if (queue )
371
+ ec -> rx_coalesce_usecs = tsnep_get_irq_coalesce (queue );
372
+
373
+ queue = tsnep_get_queue_with_tx (adapter , 0 );
374
+ if (queue )
375
+ ec -> tx_coalesce_usecs = tsnep_get_irq_coalesce (queue );
376
+
377
+ return 0 ;
378
+ }
379
+
380
+ static int tsnep_ethtool_set_coalesce (struct net_device * netdev ,
381
+ struct ethtool_coalesce * ec ,
382
+ struct kernel_ethtool_coalesce * kernel_coal ,
383
+ struct netlink_ext_ack * extack )
384
+ {
385
+ struct tsnep_adapter * adapter = netdev_priv (netdev );
386
+ int i ;
387
+ int retval ;
388
+
389
+ for (i = 0 ; i < adapter -> num_queues ; i ++ ) {
390
+ /* RX coalesce has priority for queues with TX and RX */
391
+ if (adapter -> queue [i ].rx )
392
+ retval = tsnep_set_irq_coalesce (& adapter -> queue [i ],
393
+ ec -> rx_coalesce_usecs );
394
+ else
395
+ retval = tsnep_set_irq_coalesce (& adapter -> queue [i ],
396
+ ec -> tx_coalesce_usecs );
397
+ if (retval != 0 )
398
+ return retval ;
399
+ }
400
+
401
+ return 0 ;
402
+ }
403
+
404
+ static int tsnep_ethtool_get_per_queue_coalesce (struct net_device * netdev ,
405
+ u32 queue ,
406
+ struct ethtool_coalesce * ec )
407
+ {
408
+ struct tsnep_adapter * adapter = netdev_priv (netdev );
409
+ struct tsnep_queue * queue_with_rx ;
410
+ struct tsnep_queue * queue_with_tx ;
411
+
412
+ if (queue >= max (adapter -> num_tx_queues , adapter -> num_rx_queues ))
413
+ return - EINVAL ;
414
+
415
+ queue_with_rx = tsnep_get_queue_with_rx (adapter , queue );
416
+ if (queue_with_rx )
417
+ ec -> rx_coalesce_usecs = tsnep_get_irq_coalesce (queue_with_rx );
418
+
419
+ queue_with_tx = tsnep_get_queue_with_tx (adapter , queue );
420
+ if (queue_with_tx )
421
+ ec -> tx_coalesce_usecs = tsnep_get_irq_coalesce (queue_with_tx );
422
+
423
+ return 0 ;
424
+ }
425
+
426
+ static int tsnep_ethtool_set_per_queue_coalesce (struct net_device * netdev ,
427
+ u32 queue ,
428
+ struct ethtool_coalesce * ec )
429
+ {
430
+ struct tsnep_adapter * adapter = netdev_priv (netdev );
431
+ struct tsnep_queue * queue_with_rx ;
432
+ struct tsnep_queue * queue_with_tx ;
433
+ int retval ;
434
+
435
+ if (queue >= max (adapter -> num_tx_queues , adapter -> num_rx_queues ))
436
+ return - EINVAL ;
437
+
438
+ queue_with_rx = tsnep_get_queue_with_rx (adapter , queue );
439
+ if (queue_with_rx ) {
440
+ retval = tsnep_set_irq_coalesce (queue_with_rx , ec -> rx_coalesce_usecs );
441
+ if (retval != 0 )
442
+ return retval ;
443
+ }
444
+
445
+ /* RX coalesce has priority for queues with TX and RX */
446
+ queue_with_tx = tsnep_get_queue_with_tx (adapter , queue );
447
+ if (queue_with_tx && !queue_with_tx -> rx ) {
448
+ retval = tsnep_set_irq_coalesce (queue_with_tx , ec -> tx_coalesce_usecs );
449
+ if (retval != 0 )
450
+ return retval ;
451
+ }
452
+
453
+ return 0 ;
454
+ }
455
+
327
456
const struct ethtool_ops tsnep_ethtool_ops = {
457
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS ,
328
458
.get_drvinfo = tsnep_ethtool_get_drvinfo ,
329
459
.get_regs_len = tsnep_ethtool_get_regs_len ,
330
460
.get_regs = tsnep_ethtool_get_regs ,
@@ -340,6 +470,10 @@ const struct ethtool_ops tsnep_ethtool_ops = {
340
470
.set_rxnfc = tsnep_ethtool_set_rxnfc ,
341
471
.get_channels = tsnep_ethtool_get_channels ,
342
472
.get_ts_info = tsnep_ethtool_get_ts_info ,
473
+ .get_coalesce = tsnep_ethtool_get_coalesce ,
474
+ .set_coalesce = tsnep_ethtool_set_coalesce ,
475
+ .get_per_queue_coalesce = tsnep_ethtool_get_per_queue_coalesce ,
476
+ .set_per_queue_coalesce = tsnep_ethtool_set_per_queue_coalesce ,
343
477
.get_link_ksettings = phy_ethtool_get_link_ksettings ,
344
478
.set_link_ksettings = phy_ethtool_set_link_ksettings ,
345
479
};
0 commit comments