@@ -596,8 +596,10 @@ static int am65_cpsw_nuss_common_stop(struct am65_cpsw_common *common)
596
596
msecs_to_jiffies (1000 ));
597
597
if (!i )
598
598
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 ++ ) {
600
600
napi_disable (& common -> tx_chns [i ].napi_tx );
601
+ hrtimer_cancel (& common -> tx_chns [i ].tx_hrtimer );
602
+ }
601
603
602
604
for (i = 0 ; i < common -> tx_ch_num ; i ++ ) {
603
605
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)
616
618
}
617
619
618
620
napi_disable (& common -> napi_rx );
621
+ hrtimer_cancel (& common -> rx_hrtimer );
619
622
620
623
for (i = 0 ; i < AM65_CPSW_MAX_RX_FLOWS ; i ++ )
621
624
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,
885
888
return ret ;
886
889
}
887
890
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
+
888
900
static int am65_cpsw_nuss_rx_poll (struct napi_struct * napi_rx , int budget )
889
901
{
890
902
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)
912
924
if (num_rx < budget && napi_complete_done (napi_rx , num_rx )) {
913
925
if (common -> rx_irq_disabled ) {
914
926
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
+ }
916
934
}
917
935
}
918
936
@@ -968,7 +986,7 @@ static void am65_cpsw_nuss_tx_wake(struct am65_cpsw_tx_chn *tx_chn, struct net_d
968
986
}
969
987
970
988
static 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 )
972
990
{
973
991
struct device * dev = common -> dev ;
974
992
struct am65_cpsw_tx_chn * tx_chn ;
@@ -991,6 +1009,7 @@ static int am65_cpsw_nuss_tx_compl_packets(struct am65_cpsw_common *common,
991
1009
if (cppi5_desc_is_tdcm (desc_dma )) {
992
1010
if (atomic_dec_and_test (& common -> tdown_cnt ))
993
1011
complete (& common -> tdown_complete );
1012
+ * tdown = true;
994
1013
break ;
995
1014
}
996
1015
@@ -1013,7 +1032,7 @@ static int am65_cpsw_nuss_tx_compl_packets(struct am65_cpsw_common *common,
1013
1032
}
1014
1033
1015
1034
static 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 )
1017
1036
{
1018
1037
struct device * dev = common -> dev ;
1019
1038
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,
1034
1053
if (cppi5_desc_is_tdcm (desc_dma )) {
1035
1054
if (atomic_dec_and_test (& common -> tdown_cnt ))
1036
1055
complete (& common -> tdown_complete );
1056
+ * tdown = true;
1037
1057
break ;
1038
1058
}
1039
1059
@@ -1059,21 +1079,40 @@ static int am65_cpsw_nuss_tx_compl_packets_2g(struct am65_cpsw_common *common,
1059
1079
return num_tx ;
1060
1080
}
1061
1081
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
+
1062
1091
static int am65_cpsw_nuss_tx_poll (struct napi_struct * napi_tx , int budget )
1063
1092
{
1064
1093
struct am65_cpsw_tx_chn * tx_chn = am65_cpsw_napi_to_tx_chn (napi_tx );
1094
+ bool tdown = false;
1065
1095
int num_tx ;
1066
1096
1067
1097
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 );
1069
1100
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 );
1071
1103
1072
1104
if (num_tx >= budget )
1073
1105
return budget ;
1074
1106
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
+ }
1077
1116
1078
1117
return 0 ;
1079
1118
}
@@ -1705,6 +1744,8 @@ static int am65_cpsw_nuss_ndev_add_tx_napi(struct am65_cpsw_common *common)
1705
1744
1706
1745
netif_napi_add_tx (common -> dma_ndev , & tx_chn -> napi_tx ,
1707
1746
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 ;
1708
1749
1709
1750
ret = devm_request_irq (dev , tx_chn -> irq ,
1710
1751
am65_cpsw_nuss_tx_irq ,
@@ -1930,6 +1971,8 @@ static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common)
1930
1971
1931
1972
netif_napi_add (common -> dma_ndev , & common -> napi_rx ,
1932
1973
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 ;
1933
1976
1934
1977
ret = devm_request_irq (dev , rx_chn -> irq ,
1935
1978
am65_cpsw_nuss_rx_irq ,
0 commit comments