@@ -591,9 +591,117 @@ static int tc_setup_cls(struct stmmac_priv *priv,
591
591
return ret ;
592
592
}
593
593
594
+ static int tc_setup_taprio (struct stmmac_priv * priv ,
595
+ struct tc_taprio_qopt_offload * qopt )
596
+ {
597
+ u32 size , wid = priv -> dma_cap .estwid , dep = priv -> dma_cap .estdep ;
598
+ struct plat_stmmacenet_data * plat = priv -> plat ;
599
+ struct timespec64 time ;
600
+ int i , ret = 0 ;
601
+
602
+ if (!priv -> dma_cap .estsel )
603
+ return - EOPNOTSUPP ;
604
+
605
+ switch (wid ) {
606
+ case 0x1 :
607
+ wid = 16 ;
608
+ break ;
609
+ case 0x2 :
610
+ wid = 20 ;
611
+ break ;
612
+ case 0x3 :
613
+ wid = 24 ;
614
+ break ;
615
+ default :
616
+ return - EOPNOTSUPP ;
617
+ }
618
+
619
+ switch (dep ) {
620
+ case 0x1 :
621
+ dep = 64 ;
622
+ break ;
623
+ case 0x2 :
624
+ dep = 128 ;
625
+ break ;
626
+ case 0x3 :
627
+ dep = 256 ;
628
+ break ;
629
+ case 0x4 :
630
+ dep = 512 ;
631
+ break ;
632
+ case 0x5 :
633
+ dep = 1024 ;
634
+ break ;
635
+ default :
636
+ return - EOPNOTSUPP ;
637
+ }
638
+
639
+ if (!qopt -> enable )
640
+ goto disable ;
641
+ if (qopt -> num_entries >= dep )
642
+ return - EINVAL ;
643
+ if (!qopt -> base_time )
644
+ return - ERANGE ;
645
+ if (!qopt -> cycle_time )
646
+ return - ERANGE ;
647
+
648
+ if (!plat -> est ) {
649
+ plat -> est = devm_kzalloc (priv -> device , sizeof (* plat -> est ),
650
+ GFP_KERNEL );
651
+ if (!plat -> est )
652
+ return - ENOMEM ;
653
+ } else {
654
+ memset (plat -> est , 0 , sizeof (* plat -> est ));
655
+ }
656
+
657
+ size = qopt -> num_entries ;
658
+
659
+ priv -> plat -> est -> gcl_size = size ;
660
+ priv -> plat -> est -> enable = qopt -> enable ;
661
+
662
+ for (i = 0 ; i < size ; i ++ ) {
663
+ s64 delta_ns = qopt -> entries [i ].interval ;
664
+ u32 gates = qopt -> entries [i ].gate_mask ;
665
+
666
+ if (delta_ns > GENMASK (wid , 0 ))
667
+ return - ERANGE ;
668
+ if (gates > GENMASK (31 - wid , 0 ))
669
+ return - ERANGE ;
670
+ if (qopt -> entries [i ].command != TC_TAPRIO_CMD_SET_GATES )
671
+ return - EOPNOTSUPP ;
672
+
673
+ priv -> plat -> est -> gcl [i ] = delta_ns | (gates << wid );
674
+ }
675
+
676
+ /* Adjust for real system time */
677
+ time = ktime_to_timespec64 (qopt -> base_time );
678
+ priv -> plat -> est -> btr [0 ] = (u32 )time .tv_nsec ;
679
+ priv -> plat -> est -> btr [1 ] = (u32 )time .tv_sec ;
680
+
681
+ priv -> plat -> est -> ctr [0 ] = (u32 )(qopt -> cycle_time % NSEC_PER_SEC );
682
+ priv -> plat -> est -> ctr [1 ] = (u32 )(qopt -> cycle_time / NSEC_PER_SEC );
683
+
684
+ ret = stmmac_est_configure (priv , priv -> ioaddr , priv -> plat -> est ,
685
+ priv -> plat -> clk_ptp_rate );
686
+ if (ret ) {
687
+ netdev_err (priv -> dev , "failed to configure EST\n" );
688
+ goto disable ;
689
+ }
690
+
691
+ netdev_info (priv -> dev , "configured EST\n" );
692
+ return 0 ;
693
+
694
+ disable :
695
+ priv -> plat -> est -> enable = false;
696
+ stmmac_est_configure (priv , priv -> ioaddr , priv -> plat -> est ,
697
+ priv -> plat -> clk_ptp_rate );
698
+ return ret ;
699
+ }
700
+
594
701
const struct stmmac_tc_ops dwmac510_tc_ops = {
595
702
.init = tc_init ,
596
703
.setup_cls_u32 = tc_setup_cls_u32 ,
597
704
.setup_cbs = tc_setup_cbs ,
598
705
.setup_cls = tc_setup_cls ,
706
+ .setup_taprio = tc_setup_taprio ,
599
707
};
0 commit comments