@@ -201,6 +201,93 @@ static void emac_get_rmon_stats(struct net_device *ndev,
201201 rmon_stats -> hist_tx [4 ] = emac_get_stat_by_name (emac , "tx_bucket5_frames" );
202202}
203203
204+ static int emac_get_coalesce (struct net_device * ndev ,
205+ struct ethtool_coalesce * coal ,
206+ struct kernel_ethtool_coalesce * kernel_coal ,
207+ struct netlink_ext_ack * extack )
208+ {
209+ struct prueth_emac * emac = netdev_priv (ndev );
210+ struct prueth_tx_chn * tx_chn ;
211+
212+ tx_chn = & emac -> tx_chns [0 ];
213+
214+ coal -> rx_coalesce_usecs = emac -> rx_pace_timeout_ns / 1000 ;
215+ coal -> tx_coalesce_usecs = tx_chn -> tx_pace_timeout_ns / 1000 ;
216+
217+ return 0 ;
218+ }
219+
220+ static int emac_get_per_queue_coalesce (struct net_device * ndev , u32 queue ,
221+ struct ethtool_coalesce * coal )
222+ {
223+ struct prueth_emac * emac = netdev_priv (ndev );
224+ struct prueth_tx_chn * tx_chn ;
225+
226+ if (queue >= PRUETH_MAX_TX_QUEUES )
227+ return - EINVAL ;
228+
229+ tx_chn = & emac -> tx_chns [queue ];
230+
231+ coal -> tx_coalesce_usecs = tx_chn -> tx_pace_timeout_ns / 1000 ;
232+
233+ return 0 ;
234+ }
235+
236+ static int emac_set_coalesce (struct net_device * ndev ,
237+ struct ethtool_coalesce * coal ,
238+ struct kernel_ethtool_coalesce * kernel_coal ,
239+ struct netlink_ext_ack * extack )
240+ {
241+ struct prueth_emac * emac = netdev_priv (ndev );
242+ struct prueth * prueth = emac -> prueth ;
243+ struct prueth_tx_chn * tx_chn ;
244+
245+ tx_chn = & emac -> tx_chns [0 ];
246+
247+ if (coal -> rx_coalesce_usecs &&
248+ coal -> rx_coalesce_usecs < ICSSG_MIN_COALESCE_USECS ) {
249+ dev_info (prueth -> dev , "defaulting to min value of %dus for rx-usecs\n" ,
250+ ICSSG_MIN_COALESCE_USECS );
251+ coal -> rx_coalesce_usecs = ICSSG_MIN_COALESCE_USECS ;
252+ }
253+
254+ if (coal -> tx_coalesce_usecs &&
255+ coal -> tx_coalesce_usecs < ICSSG_MIN_COALESCE_USECS ) {
256+ dev_info (prueth -> dev , "defaulting to min value of %dus for tx-usecs\n" ,
257+ ICSSG_MIN_COALESCE_USECS );
258+ coal -> tx_coalesce_usecs = ICSSG_MIN_COALESCE_USECS ;
259+ }
260+
261+ emac -> rx_pace_timeout_ns = coal -> rx_coalesce_usecs * 1000 ;
262+ tx_chn -> tx_pace_timeout_ns = coal -> tx_coalesce_usecs * 1000 ;
263+
264+ return 0 ;
265+ }
266+
267+ static int emac_set_per_queue_coalesce (struct net_device * ndev , u32 queue ,
268+ struct ethtool_coalesce * coal )
269+ {
270+ struct prueth_emac * emac = netdev_priv (ndev );
271+ struct prueth * prueth = emac -> prueth ;
272+ struct prueth_tx_chn * tx_chn ;
273+
274+ if (queue >= PRUETH_MAX_TX_QUEUES )
275+ return - EINVAL ;
276+
277+ tx_chn = & emac -> tx_chns [queue ];
278+
279+ if (coal -> tx_coalesce_usecs &&
280+ coal -> tx_coalesce_usecs < ICSSG_MIN_COALESCE_USECS ) {
281+ dev_info (prueth -> dev , "defaulting to min value of %dus for tx-usecs for tx-%u\n" ,
282+ ICSSG_MIN_COALESCE_USECS , queue );
283+ coal -> tx_coalesce_usecs = ICSSG_MIN_COALESCE_USECS ;
284+ }
285+
286+ tx_chn -> tx_pace_timeout_ns = coal -> tx_coalesce_usecs * 1000 ;
287+
288+ return 0 ;
289+ }
290+
204291const struct ethtool_ops icssg_ethtool_ops = {
205292 .get_drvinfo = emac_get_drvinfo ,
206293 .get_msglevel = emac_get_msglevel ,
@@ -209,6 +296,12 @@ const struct ethtool_ops icssg_ethtool_ops = {
209296 .get_ethtool_stats = emac_get_ethtool_stats ,
210297 .get_strings = emac_get_strings ,
211298 .get_ts_info = emac_get_ts_info ,
299+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS |
300+ ETHTOOL_COALESCE_TX_USECS ,
301+ .get_coalesce = emac_get_coalesce ,
302+ .set_coalesce = emac_set_coalesce ,
303+ .get_per_queue_coalesce = emac_get_per_queue_coalesce ,
304+ .set_per_queue_coalesce = emac_set_per_queue_coalesce ,
212305 .get_channels = emac_get_channels ,
213306 .set_channels = emac_set_channels ,
214307 .get_link_ksettings = emac_get_link_ksettings ,
0 commit comments