@@ -741,6 +741,110 @@ static void *mvpp2_buf_alloc(struct mvpp2_port *port,
741
741
return data ;
742
742
}
743
743
744
+ /* Routine enable flow control for RXQs condition */
745
+ static void mvpp2_rxq_enable_fc (struct mvpp2_port * port )
746
+ {
747
+ int val , cm3_state , host_id , q ;
748
+ int fq = port -> first_rxq ;
749
+ unsigned long flags ;
750
+
751
+ spin_lock_irqsave (& port -> priv -> mss_spinlock , flags );
752
+
753
+ /* Remove Flow control enable bit to prevent race between FW and Kernel
754
+ * If Flow control was enabled, it would be re-enabled.
755
+ */
756
+ val = mvpp2_cm3_read (port -> priv , MSS_FC_COM_REG );
757
+ cm3_state = (val & FLOW_CONTROL_ENABLE_BIT );
758
+ val &= ~FLOW_CONTROL_ENABLE_BIT ;
759
+ mvpp2_cm3_write (port -> priv , MSS_FC_COM_REG , val );
760
+
761
+ /* Set same Flow control for all RXQs */
762
+ for (q = 0 ; q < port -> nrxqs ; q ++ ) {
763
+ /* Set stop and start Flow control RXQ thresholds */
764
+ val = MSS_THRESHOLD_START ;
765
+ val |= (MSS_THRESHOLD_STOP << MSS_RXQ_TRESH_STOP_OFFS );
766
+ mvpp2_cm3_write (port -> priv , MSS_RXQ_TRESH_REG (q , fq ), val );
767
+
768
+ val = mvpp2_cm3_read (port -> priv , MSS_RXQ_ASS_REG (q , fq ));
769
+ /* Set RXQ port ID */
770
+ val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE (q , fq ));
771
+ val |= (port -> id << MSS_RXQ_ASS_Q_BASE (q , fq ));
772
+ val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE (q , fq )
773
+ + MSS_RXQ_ASS_HOSTID_OFFS ));
774
+
775
+ /* Calculate RXQ host ID:
776
+ * In Single queue mode: Host ID equal to Host ID used for
777
+ * shared RX interrupt
778
+ * In Multi queue mode: Host ID equal to number of
779
+ * RXQ ID / number of CoS queues
780
+ * In Single resource mode: Host ID always equal to 0
781
+ */
782
+ if (queue_mode == MVPP2_QDIST_SINGLE_MODE )
783
+ host_id = port -> nqvecs ;
784
+ else if (queue_mode == MVPP2_QDIST_MULTI_MODE )
785
+ host_id = q ;
786
+ else
787
+ host_id = 0 ;
788
+
789
+ /* Set RXQ host ID */
790
+ val |= (host_id << (MSS_RXQ_ASS_Q_BASE (q , fq )
791
+ + MSS_RXQ_ASS_HOSTID_OFFS ));
792
+
793
+ mvpp2_cm3_write (port -> priv , MSS_RXQ_ASS_REG (q , fq ), val );
794
+ }
795
+
796
+ /* Notify Firmware that Flow control config space ready for update */
797
+ val = mvpp2_cm3_read (port -> priv , MSS_FC_COM_REG );
798
+ val |= FLOW_CONTROL_UPDATE_COMMAND_BIT ;
799
+ val |= cm3_state ;
800
+ mvpp2_cm3_write (port -> priv , MSS_FC_COM_REG , val );
801
+
802
+ spin_unlock_irqrestore (& port -> priv -> mss_spinlock , flags );
803
+ }
804
+
805
+ /* Routine disable flow control for RXQs condition */
806
+ static void mvpp2_rxq_disable_fc (struct mvpp2_port * port )
807
+ {
808
+ int val , cm3_state , q ;
809
+ unsigned long flags ;
810
+ int fq = port -> first_rxq ;
811
+
812
+ spin_lock_irqsave (& port -> priv -> mss_spinlock , flags );
813
+
814
+ /* Remove Flow control enable bit to prevent race between FW and Kernel
815
+ * If Flow control was enabled, it would be re-enabled.
816
+ */
817
+ val = mvpp2_cm3_read (port -> priv , MSS_FC_COM_REG );
818
+ cm3_state = (val & FLOW_CONTROL_ENABLE_BIT );
819
+ val &= ~FLOW_CONTROL_ENABLE_BIT ;
820
+ mvpp2_cm3_write (port -> priv , MSS_FC_COM_REG , val );
821
+
822
+ /* Disable Flow control for all RXQs */
823
+ for (q = 0 ; q < port -> nrxqs ; q ++ ) {
824
+ /* Set threshold 0 to disable Flow control */
825
+ val = 0 ;
826
+ val |= (0 << MSS_RXQ_TRESH_STOP_OFFS );
827
+ mvpp2_cm3_write (port -> priv , MSS_RXQ_TRESH_REG (q , fq ), val );
828
+
829
+ val = mvpp2_cm3_read (port -> priv , MSS_RXQ_ASS_REG (q , fq ));
830
+
831
+ val &= ~(MSS_RXQ_ASS_PORTID_MASK << MSS_RXQ_ASS_Q_BASE (q , fq ));
832
+
833
+ val &= ~(MSS_RXQ_ASS_HOSTID_MASK << (MSS_RXQ_ASS_Q_BASE (q , fq )
834
+ + MSS_RXQ_ASS_HOSTID_OFFS ));
835
+
836
+ mvpp2_cm3_write (port -> priv , MSS_RXQ_ASS_REG (q , fq ), val );
837
+ }
838
+
839
+ /* Notify Firmware that Flow control config space ready for update */
840
+ val = mvpp2_cm3_read (port -> priv , MSS_FC_COM_REG );
841
+ val |= FLOW_CONTROL_UPDATE_COMMAND_BIT ;
842
+ val |= cm3_state ;
843
+ mvpp2_cm3_write (port -> priv , MSS_FC_COM_REG , val );
844
+
845
+ spin_unlock_irqrestore (& port -> priv -> mss_spinlock , flags );
846
+ }
847
+
744
848
/* Release buffer to BM */
745
849
static inline void mvpp2_bm_pool_put (struct mvpp2_port * port , int pool ,
746
850
dma_addr_t buf_dma_addr ,
@@ -3013,6 +3117,9 @@ static void mvpp2_cleanup_rxqs(struct mvpp2_port *port)
3013
3117
3014
3118
for (queue = 0 ; queue < port -> nrxqs ; queue ++ )
3015
3119
mvpp2_rxq_deinit (port , port -> rxqs [queue ]);
3120
+
3121
+ if (port -> tx_fc )
3122
+ mvpp2_rxq_disable_fc (port );
3016
3123
}
3017
3124
3018
3125
/* Init all Rx queues for port */
@@ -3025,6 +3132,10 @@ static int mvpp2_setup_rxqs(struct mvpp2_port *port)
3025
3132
if (err )
3026
3133
goto err_cleanup ;
3027
3134
}
3135
+
3136
+ if (port -> tx_fc )
3137
+ mvpp2_rxq_enable_fc (port );
3138
+
3028
3139
return 0 ;
3029
3140
3030
3141
err_cleanup :
@@ -4324,6 +4435,8 @@ static int mvpp2_check_ringparam_valid(struct net_device *dev,
4324
4435
4325
4436
if (ring -> rx_pending > MVPP2_MAX_RXD_MAX )
4326
4437
new_rx_pending = MVPP2_MAX_RXD_MAX ;
4438
+ else if (ring -> rx_pending < MSS_THRESHOLD_START )
4439
+ new_rx_pending = MSS_THRESHOLD_START ;
4327
4440
else if (!IS_ALIGNED (ring -> rx_pending , 16 ))
4328
4441
new_rx_pending = ALIGN (ring -> rx_pending , 16 );
4329
4442
@@ -7156,6 +7269,9 @@ static int mvpp2_probe(struct platform_device *pdev)
7156
7269
priv -> hw_version = MVPP23 ;
7157
7270
}
7158
7271
7272
+ /* Init mss lock */
7273
+ spin_lock_init (& priv -> mss_spinlock );
7274
+
7159
7275
/* Initialize network controller */
7160
7276
err = mvpp2_init (pdev , priv );
7161
7277
if (err < 0 ) {
0 commit comments