@@ -596,8 +596,10 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)
596596 msecs_to_jiffies (1000 ));
597597 if (!i )
598598 dev_err (common -> dev , "tx timeout\n" );
599- for (i = 0 ; i < common -> tx_ch_num ; i ++ )
599+ for (i = 0 ; i < common -> tx_ch_num ; i ++ ) {
600600 napi_disable (& common -> tx_chns [i ].napi_tx );
601+ hrtimer_cancel (& common -> tx_chns [i ].tx_hrtimer );
602+ }
601603
602604 for (i = 0 ; i < common -> tx_ch_num ; i ++ ) {
603605 k3_udma_glue_reset_tx_chn (common -> tx_chns [i ].tx_chn ,
@@ -616,6 +618,7 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)
616618 }
617619
618620 napi_disable (& common -> napi_rx );
621+ hrtimer_cancel (& common -> rx_hrtimer );
619622
620623 for (i = 0 ; i < AM65_CPSW_MAX_RX_FLOWS ; i ++ )
621624 k3_udma_glue_reset_rx_chn (common -> rx_chns .rx_chn , i ,
@@ -885,6 +888,15 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_common *common,
885888 return ret ;
886889}
887890
891+ static enum hrtimer_restart am65_cpsw_nuss_rx_timer_callback (struct hrtimer * timer )
892+ {
893+ struct am65_cpsw_common * common =
894+ container_of (timer , struct am65_cpsw_common , rx_hrtimer );
895+
896+ enable_irq (common -> rx_chns .irq );
897+ return HRTIMER_NORESTART ;
898+ }
899+
888900static int am65_cpsw_nuss_rx_poll (struct napi_struct * napi_rx , int budget )
889901{
890902 struct am65_cpsw_common * common = am65_cpsw_napi_to_common (napi_rx );
@@ -912,7 +924,13 @@ static int am65_cpsw_nuss_rx_poll(struct napi_struct *napi_rx, int budget)
912924 if (num_rx < budget && napi_complete_done (napi_rx , num_rx )) {
913925 if (common -> rx_irq_disabled ) {
914926 common -> rx_irq_disabled = false;
915- enable_irq (common -> rx_chns .irq );
927+ if (unlikely (common -> rx_pace_timeout )) {
928+ hrtimer_start (& common -> rx_hrtimer ,
929+ ns_to_ktime (common -> rx_pace_timeout ),
930+ HRTIMER_MODE_REL_PINNED );
931+ } else {
932+ enable_irq (common -> rx_chns .irq );
933+ }
916934 }
917935 }
918936
@@ -968,7 +986,7 @@ static void am65_cpsw_nuss_tx_wake(struct am65_cpsw_tx_chn *tx_chn, struct net_d
968986}
969987
970988static int am65_cpsw_nuss_tx_compl_packets (struct am65_cpsw_common * common ,
971- int chn , unsigned int budget )
989+ int chn , unsigned int budget , bool * tdown )
972990{
973991 struct device * dev = common -> dev ;
974992 struct am65_cpsw_tx_chn * tx_chn ;
@@ -991,6 +1009,7 @@ static int am65_cpsw_nuss_tx_compl_packets(struct am65_cpsw_common *common,
9911009 if (cppi5_desc_is_tdcm (desc_dma )) {
9921010 if (atomic_dec_and_test (& common -> tdown_cnt ))
9931011 complete (& common -> tdown_complete );
1012+ * tdown = true;
9941013 break ;
9951014 }
9961015
@@ -1013,7 +1032,7 @@ static int am65_cpsw_nuss_tx_compl_packets(struct am65_cpsw_common *common,
10131032}
10141033
10151034static int am65_cpsw_nuss_tx_compl_packets_2g (struct am65_cpsw_common * common ,
1016- int chn , unsigned int budget )
1035+ int chn , unsigned int budget , bool * tdown )
10171036{
10181037 struct device * dev = common -> dev ;
10191038 struct am65_cpsw_tx_chn * tx_chn ;
@@ -1034,6 +1053,7 @@ static int am65_cpsw_nuss_tx_compl_packets_2g(struct am65_cpsw_common *common,
10341053 if (cppi5_desc_is_tdcm (desc_dma )) {
10351054 if (atomic_dec_and_test (& common -> tdown_cnt ))
10361055 complete (& common -> tdown_complete );
1056+ * tdown = true;
10371057 break ;
10381058 }
10391059
@@ -1059,21 +1079,40 @@ static int am65_cpsw_nuss_tx_compl_packets_2g(struct am65_cpsw_common *common,
10591079 return num_tx ;
10601080}
10611081
1082+ static enum hrtimer_restart am65_cpsw_nuss_tx_timer_callback (struct hrtimer * timer )
1083+ {
1084+ struct am65_cpsw_tx_chn * tx_chns =
1085+ container_of (timer , struct am65_cpsw_tx_chn , tx_hrtimer );
1086+
1087+ enable_irq (tx_chns -> irq );
1088+ return HRTIMER_NORESTART ;
1089+ }
1090+
10621091static int am65_cpsw_nuss_tx_poll (struct napi_struct * napi_tx , int budget )
10631092{
10641093 struct am65_cpsw_tx_chn * tx_chn = am65_cpsw_napi_to_tx_chn (napi_tx );
1094+ bool tdown = false;
10651095 int num_tx ;
10661096
10671097 if (AM65_CPSW_IS_CPSW2G (tx_chn -> common ))
1068- num_tx = am65_cpsw_nuss_tx_compl_packets_2g (tx_chn -> common , tx_chn -> id , budget );
1098+ num_tx = am65_cpsw_nuss_tx_compl_packets_2g (tx_chn -> common , tx_chn -> id ,
1099+ budget , & tdown );
10691100 else
1070- num_tx = am65_cpsw_nuss_tx_compl_packets (tx_chn -> common , tx_chn -> id , budget );
1101+ num_tx = am65_cpsw_nuss_tx_compl_packets (tx_chn -> common ,
1102+ tx_chn -> id , budget , & tdown );
10711103
10721104 if (num_tx >= budget )
10731105 return budget ;
10741106
1075- if (napi_complete_done (napi_tx , num_tx ))
1076- enable_irq (tx_chn -> irq );
1107+ if (napi_complete_done (napi_tx , num_tx )) {
1108+ if (unlikely (tx_chn -> tx_pace_timeout && !tdown )) {
1109+ hrtimer_start (& tx_chn -> tx_hrtimer ,
1110+ ns_to_ktime (tx_chn -> tx_pace_timeout ),
1111+ HRTIMER_MODE_REL_PINNED );
1112+ } else {
1113+ enable_irq (tx_chn -> irq );
1114+ }
1115+ }
10771116
10781117 return 0 ;
10791118}
@@ -1705,6 +1744,8 @@ static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common)
17051744
17061745 netif_napi_add_tx (common -> dma_ndev , & tx_chn -> napi_tx ,
17071746 am65_cpsw_nuss_tx_poll );
1747+ hrtimer_init (& tx_chn -> tx_hrtimer , CLOCK_MONOTONIC , HRTIMER_MODE_REL_PINNED );
1748+ tx_chn -> tx_hrtimer .function = & am65_cpsw_nuss_tx_timer_callback ;
17081749
17091750 ret = devm_request_irq (dev , tx_chn -> irq ,
17101751 am65_cpsw_nuss_tx_irq ,
@@ -1930,6 +1971,8 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
19301971
19311972 netif_napi_add (common -> dma_ndev , & common -> napi_rx ,
19321973 am65_cpsw_nuss_rx_poll );
1974+ hrtimer_init (& common -> rx_hrtimer , CLOCK_MONOTONIC , HRTIMER_MODE_REL_PINNED );
1975+ common -> rx_hrtimer .function = & am65_cpsw_nuss_rx_timer_callback ;
19331976
19341977 ret = devm_request_irq (dev , rx_chn -> irq ,
19351978 am65_cpsw_nuss_rx_irq ,
0 commit comments