static void mvpp2_interrupts_mask(void *arg)
 {
        struct mvpp2_port *port = arg;
+       int cpu = smp_processor_id();
+       u32 thread;
 
        /* If the thread isn't used, don't do anything */
-       if (smp_processor_id() > port->priv->nthreads)
+       if (cpu > port->priv->nthreads)
                return;
 
-       mvpp2_thread_write(port->priv,
-                          mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
+       thread = mvpp2_cpu_to_thread(port->priv, cpu);
+
+       mvpp2_thread_write(port->priv, thread,
                           MVPP2_ISR_RX_TX_MASK_REG(port->id), 0);
+       mvpp2_thread_write(port->priv, thread,
+                          MVPP2_ISR_RX_ERR_CAUSE_REG(port->id), 0);
 }
 
 /* Unmask the current thread's Rx/Tx interrupts.
 static void mvpp2_interrupts_unmask(void *arg)
 {
        struct mvpp2_port *port = arg;
-       u32 val;
+       int cpu = smp_processor_id();
+       u32 val, thread;
 
        /* If the thread isn't used, don't do anything */
-       if (smp_processor_id() > port->priv->nthreads)
+       if (cpu > port->priv->nthreads)
                return;
 
+       thread = mvpp2_cpu_to_thread(port->priv, cpu);
+
        val = MVPP2_CAUSE_MISC_SUM_MASK |
                MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK(port->priv->hw_version);
        if (port->has_tx_irqs)
                val |= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
 
-       mvpp2_thread_write(port->priv,
-                          mvpp2_cpu_to_thread(port->priv, smp_processor_id()),
+       mvpp2_thread_write(port->priv, thread,
                           MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
+       mvpp2_thread_write(port->priv, thread,
+                          MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
+                          MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
 }
 
 static void
 
                mvpp2_thread_write(port->priv, v->sw_thread_id,
                                   MVPP2_ISR_RX_TX_MASK_REG(port->id), val);
+               mvpp2_thread_write(port->priv, v->sw_thread_id,
+                                  MVPP2_ISR_RX_ERR_CAUSE_REG(port->id),
+                                  MVPP2_ISR_RX_ERR_CAUSE_NONOCC_MASK);
        }
 }
 
        }
 }
 
+/* Set the number of non-occupied descriptors threshold */
+static void mvpp2_set_rxq_free_tresh(struct mvpp2_port *port,
+                                    struct mvpp2_rx_queue *rxq)
+{
+       u32 val;
+
+       mvpp2_write(port->priv, MVPP2_RXQ_NUM_REG, rxq->id);
+
+       val = mvpp2_read(port->priv, MVPP2_RXQ_THRESH_REG);
+       val &= ~MVPP2_RXQ_NON_OCCUPIED_MASK;
+       val |= MSS_THRESHOLD_STOP << MVPP2_RXQ_NON_OCCUPIED_OFFSET;
+       mvpp2_write(port->priv, MVPP2_RXQ_THRESH_REG, val);
+}
+
 /* Set the number of packets that will be received before Rx interrupt
  * will be generated by HW.
  */
        mvpp2_rx_pkts_coal_set(port, rxq);
        mvpp2_rx_time_coal_set(port, rxq);
 
+       /* Set the number of non occupied descriptors threshold */
+       mvpp2_set_rxq_free_tresh(port, rxq);
+
        /* Add number of descriptors ready for receiving packets */
        mvpp2_rxq_status_update(port, rxq->id, 0, rxq->size);