@@ -6609,57 +6609,110 @@ static void mvpp2_rx_fifo_init(struct mvpp2 *priv)
66096609 mvpp2_write (priv , MVPP2_RX_FIFO_INIT_REG , 0x1 );
66106610}
66116611
6612- static void mvpp22_rx_fifo_init (struct mvpp2 * priv )
6612+ static void mvpp22_rx_fifo_set_hw (struct mvpp2 * priv , int port , int data_size )
66136613{
6614- int port ;
6614+ int attr_size = MVPP2_RX_FIFO_PORT_ATTR_SIZE ( data_size ) ;
66156615
6616- /* The FIFO size parameters are set depending on the maximum speed a
6617- * given port can handle:
6618- * - Port 0: 10Gbps
6619- * - Port 1: 2.5Gbps
6620- * - Ports 2 and 3: 1Gbps
6621- */
6616+ mvpp2_write (priv , MVPP2_RX_DATA_FIFO_SIZE_REG (port ), data_size );
6617+ mvpp2_write (priv , MVPP2_RX_ATTR_FIFO_SIZE_REG (port ), attr_size );
6618+ }
66226619
6623- mvpp2_write (priv , MVPP2_RX_DATA_FIFO_SIZE_REG (0 ),
6624- MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB );
6625- mvpp2_write (priv , MVPP2_RX_ATTR_FIFO_SIZE_REG (0 ),
6626- MVPP2_RX_FIFO_PORT_ATTR_SIZE_32KB );
6620+ /* Initialize TX FIFO's: the total FIFO size is 48kB on PPv2.2.
6621+ * 4kB fixed space must be assigned for the loopback port.
6622+ * Redistribute remaining avialable 44kB space among all active ports.
6623+ * Guarantee minimum 32kB for 10G port and 8kB for port 1, capable of 2.5G
6624+ * SGMII link.
6625+ */
6626+ static void mvpp22_rx_fifo_init (struct mvpp2 * priv )
6627+ {
6628+ int remaining_ports_count ;
6629+ unsigned long port_map ;
6630+ int size_remainder ;
6631+ int port , size ;
6632+
6633+ /* The loopback requires fixed 4kB of the FIFO space assignment. */
6634+ mvpp22_rx_fifo_set_hw (priv , MVPP2_LOOPBACK_PORT_INDEX ,
6635+ MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB );
6636+ port_map = priv -> port_map & ~BIT (MVPP2_LOOPBACK_PORT_INDEX );
6637+
6638+ /* Set RX FIFO size to 0 for inactive ports. */
6639+ for_each_clear_bit (port , & port_map , MVPP2_LOOPBACK_PORT_INDEX )
6640+ mvpp22_rx_fifo_set_hw (priv , port , 0 );
6641+
6642+ /* Assign remaining RX FIFO space among all active ports. */
6643+ size_remainder = MVPP2_RX_FIFO_PORT_DATA_SIZE_44KB ;
6644+ remaining_ports_count = hweight_long (port_map );
6645+
6646+ for_each_set_bit (port , & port_map , MVPP2_LOOPBACK_PORT_INDEX ) {
6647+ if (remaining_ports_count == 1 )
6648+ size = size_remainder ;
6649+ else if (port == 0 )
6650+ size = max (size_remainder / remaining_ports_count ,
6651+ MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB );
6652+ else if (port == 1 )
6653+ size = max (size_remainder / remaining_ports_count ,
6654+ MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB );
6655+ else
6656+ size = size_remainder / remaining_ports_count ;
66276657
6628- mvpp2_write (priv , MVPP2_RX_DATA_FIFO_SIZE_REG (1 ),
6629- MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB );
6630- mvpp2_write (priv , MVPP2_RX_ATTR_FIFO_SIZE_REG (1 ),
6631- MVPP2_RX_FIFO_PORT_ATTR_SIZE_8KB );
6658+ size_remainder -= size ;
6659+ remaining_ports_count -- ;
66326660
6633- for (port = 2 ; port < MVPP2_MAX_PORTS ; port ++ ) {
6634- mvpp2_write (priv , MVPP2_RX_DATA_FIFO_SIZE_REG (port ),
6635- MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB );
6636- mvpp2_write (priv , MVPP2_RX_ATTR_FIFO_SIZE_REG (port ),
6637- MVPP2_RX_FIFO_PORT_ATTR_SIZE_4KB );
6661+ mvpp22_rx_fifo_set_hw (priv , port , size );
66386662 }
66396663
66406664 mvpp2_write (priv , MVPP2_RX_MIN_PKT_SIZE_REG ,
66416665 MVPP2_RX_FIFO_PORT_MIN_PKT );
66426666 mvpp2_write (priv , MVPP2_RX_FIFO_INIT_REG , 0x1 );
66436667}
66446668
6645- /* Initialize Tx FIFO's: the total FIFO size is 19kB on PPv2.2 and 10G
6646- * interfaces must have a Tx FIFO size of 10kB. As only port 0 can do 10G,
6647- * configure its Tx FIFO size to 10kB and the others ports Tx FIFO size to 3kB.
6669+ static void mvpp22_tx_fifo_set_hw (struct mvpp2 * priv , int port , int size )
6670+ {
6671+ int threshold = MVPP2_TX_FIFO_THRESHOLD (size );
6672+
6673+ mvpp2_write (priv , MVPP22_TX_FIFO_SIZE_REG (port ), size );
6674+ mvpp2_write (priv , MVPP22_TX_FIFO_THRESH_REG (port ), threshold );
6675+ }
6676+
6677+ /* Initialize TX FIFO's: the total FIFO size is 19kB on PPv2.2.
6678+ * 3kB fixed space must be assigned for the loopback port.
6679+ * Redistribute remaining avialable 16kB space among all active ports.
6680+ * The 10G interface should use 10kB (which is maximum possible size
6681+ * per single port).
66486682 */
66496683static void mvpp22_tx_fifo_init (struct mvpp2 * priv )
66506684{
6651- int port , size , thrs ;
6652-
6653- for (port = 0 ; port < MVPP2_MAX_PORTS ; port ++ ) {
6654- if (port == 0 ) {
6685+ int remaining_ports_count ;
6686+ unsigned long port_map ;
6687+ int size_remainder ;
6688+ int port , size ;
6689+
6690+ /* The loopback requires fixed 3kB of the FIFO space assignment. */
6691+ mvpp22_tx_fifo_set_hw (priv , MVPP2_LOOPBACK_PORT_INDEX ,
6692+ MVPP22_TX_FIFO_DATA_SIZE_3KB );
6693+ port_map = priv -> port_map & ~BIT (MVPP2_LOOPBACK_PORT_INDEX );
6694+
6695+ /* Set TX FIFO size to 0 for inactive ports. */
6696+ for_each_clear_bit (port , & port_map , MVPP2_LOOPBACK_PORT_INDEX )
6697+ mvpp22_tx_fifo_set_hw (priv , port , 0 );
6698+
6699+ /* Assign remaining TX FIFO space among all active ports. */
6700+ size_remainder = MVPP22_TX_FIFO_DATA_SIZE_16KB ;
6701+ remaining_ports_count = hweight_long (port_map );
6702+
6703+ for_each_set_bit (port , & port_map , MVPP2_LOOPBACK_PORT_INDEX ) {
6704+ if (remaining_ports_count == 1 )
6705+ size = min (size_remainder ,
6706+ MVPP22_TX_FIFO_DATA_SIZE_10KB );
6707+ else if (port == 0 )
66556708 size = MVPP22_TX_FIFO_DATA_SIZE_10KB ;
6656- thrs = MVPP2_TX_FIFO_THRESHOLD_10KB ;
6657- } else {
6658- size = MVPP22_TX_FIFO_DATA_SIZE_3KB ;
6659- thrs = MVPP2_TX_FIFO_THRESHOLD_3KB ;
6660- }
6661- mvpp2_write ( priv , MVPP22_TX_FIFO_SIZE_REG ( port ), size );
6662- mvpp2_write (priv , MVPP22_TX_FIFO_THRESH_REG ( port ), thrs );
6709+ else
6710+ size = size_remainder / remaining_ports_count ;
6711+
6712+ size_remainder -= size ;
6713+ remaining_ports_count -- ;
6714+
6715+ mvpp22_tx_fifo_set_hw (priv , port , size );
66636716 }
66646717}
66656718
@@ -6960,6 +7013,12 @@ static int mvpp2_probe(struct platform_device *pdev)
69607013 goto err_axi_clk ;
69617014 }
69627015
7016+ /* Map DTS-active ports. Should be done before FIFO mvpp2_init */
7017+ fwnode_for_each_available_child_node (fwnode , port_fwnode ) {
7018+ if (!fwnode_property_read_u32 (port_fwnode , "port-id" , & i ))
7019+ priv -> port_map |= BIT (i );
7020+ }
7021+
69637022 /* Initialize network controller */
69647023 err = mvpp2_init (pdev , priv );
69657024 if (err < 0 ) {
0 commit comments