Commit db488c10 authored by Gregory CLEMENT's avatar Gregory CLEMENT Committed by David S. Miller

net: mvneta: Modify the queue related fields from each cpu

In the MVNETA_INTR_* registers, the queues related fields are per cpu,
according to the datasheet (comment in [] are added by me):
"In a multi-CPU system, bits of RX[or TX] queues for which the access by
the reading[or writing] CPU is disabled are read as 0, and cannot be
cleared[or written]."

That means that each time we want to manipulate these bits we had to do
it on each cpu and not only on the current cpu.
Signed-off-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cde4c0fe
...@@ -1038,6 +1038,43 @@ static void mvneta_set_autoneg(struct mvneta_port *pp, int enable) ...@@ -1038,6 +1038,43 @@ static void mvneta_set_autoneg(struct mvneta_port *pp, int enable)
} }
} }
static void mvneta_percpu_unmask_interrupt(void *arg)
{
struct mvneta_port *pp = arg;
/* All the queue are unmasked, but actually only the ones
* mapped to this CPU will be unmasked
*/
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
MVNETA_RX_INTR_MASK_ALL |
MVNETA_TX_INTR_MASK_ALL |
MVNETA_MISCINTR_INTR_MASK);
}
static void mvneta_percpu_mask_interrupt(void *arg)
{
struct mvneta_port *pp = arg;
/* All the queue are masked, but actually only the ones
* mapped to this CPU will be masked
*/
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
}
static void mvneta_percpu_clear_intr_cause(void *arg)
{
struct mvneta_port *pp = arg;
/* All the queue are cleared, but actually only the ones
* mapped to this CPU will be cleared
*/
mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
}
/* This method sets defaults to the NETA port: /* This method sets defaults to the NETA port:
* Clears interrupt Cause and Mask registers. * Clears interrupt Cause and Mask registers.
* Clears all MAC tables. * Clears all MAC tables.
...@@ -1055,14 +1092,10 @@ static void mvneta_defaults_set(struct mvneta_port *pp) ...@@ -1055,14 +1092,10 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
int max_cpu = num_present_cpus(); int max_cpu = num_present_cpus();
/* Clear all Cause registers */ /* Clear all Cause registers */
mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0); on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
/* Mask all interrupts */ /* Mask all interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
mvreg_write(pp, MVNETA_INTR_ENABLE, 0); mvreg_write(pp, MVNETA_INTR_ENABLE, 0);
/* Enable MBUS Retry bit16 */ /* Enable MBUS Retry bit16 */
...@@ -2528,31 +2561,6 @@ static int mvneta_setup_txqs(struct mvneta_port *pp) ...@@ -2528,31 +2561,6 @@ static int mvneta_setup_txqs(struct mvneta_port *pp)
return 0; return 0;
} }
static void mvneta_percpu_unmask_interrupt(void *arg)
{
struct mvneta_port *pp = arg;
/* All the queue are unmasked, but actually only the ones
* maped to this CPU will be unmasked
*/
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
MVNETA_RX_INTR_MASK_ALL |
MVNETA_TX_INTR_MASK_ALL |
MVNETA_MISCINTR_INTR_MASK);
}
static void mvneta_percpu_mask_interrupt(void *arg)
{
struct mvneta_port *pp = arg;
/* All the queue are masked, but actually only the ones
* maped to this CPU will be masked
*/
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
}
static void mvneta_start_dev(struct mvneta_port *pp) static void mvneta_start_dev(struct mvneta_port *pp)
{ {
int cpu; int cpu;
...@@ -2603,13 +2611,10 @@ static void mvneta_stop_dev(struct mvneta_port *pp) ...@@ -2603,13 +2611,10 @@ static void mvneta_stop_dev(struct mvneta_port *pp)
mvneta_port_disable(pp); mvneta_port_disable(pp);
/* Clear all ethernet port interrupts */ /* Clear all ethernet port interrupts */
mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0); on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
/* Mask all ethernet port interrupts */ /* Mask all ethernet port interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
mvneta_tx_reset(pp); mvneta_tx_reset(pp);
mvneta_rx_reset(pp); mvneta_rx_reset(pp);
...@@ -2921,9 +2926,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, ...@@ -2921,9 +2926,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
} }
/* Mask all ethernet port interrupts */ /* Mask all ethernet port interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
napi_enable(&port->napi); napi_enable(&port->napi);
...@@ -2938,14 +2941,8 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, ...@@ -2938,14 +2941,8 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
*/ */
mvneta_percpu_elect(pp); mvneta_percpu_elect(pp);
/* Unmask all ethernet port interrupts, as this /* Unmask all ethernet port interrupts */
* notifier is called for each CPU then the CPU to on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
* Queue mapping is applied
*/
mvreg_write(pp, MVNETA_INTR_NEW_MASK,
MVNETA_RX_INTR_MASK(rxq_number) |
MVNETA_TX_INTR_MASK(txq_number) |
MVNETA_MISCINTR_INTR_MASK);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, mvreg_write(pp, MVNETA_INTR_MISC_MASK,
MVNETA_CAUSE_PHY_STATUS_CHANGE | MVNETA_CAUSE_PHY_STATUS_CHANGE |
MVNETA_CAUSE_LINK_CHANGE | MVNETA_CAUSE_LINK_CHANGE |
...@@ -2956,9 +2953,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, ...@@ -2956,9 +2953,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
case CPU_DOWN_PREPARE_FROZEN: case CPU_DOWN_PREPARE_FROZEN:
netif_tx_stop_all_queues(pp->dev); netif_tx_stop_all_queues(pp->dev);
/* Mask all ethernet port interrupts */ /* Mask all ethernet port interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0); on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
napi_synchronize(&port->napi); napi_synchronize(&port->napi);
napi_disable(&port->napi); napi_disable(&port->napi);
...@@ -2974,10 +2969,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb, ...@@ -2974,10 +2969,7 @@ static int mvneta_percpu_notifier(struct notifier_block *nfb,
/* Check if a new CPU must be elected now this on is down */ /* Check if a new CPU must be elected now this on is down */
mvneta_percpu_elect(pp); mvneta_percpu_elect(pp);
/* Unmask all ethernet port interrupts */ /* Unmask all ethernet port interrupts */
mvreg_write(pp, MVNETA_INTR_NEW_MASK, on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
MVNETA_RX_INTR_MASK(rxq_number) |
MVNETA_TX_INTR_MASK(txq_number) |
MVNETA_MISCINTR_INTR_MASK);
mvreg_write(pp, MVNETA_INTR_MISC_MASK, mvreg_write(pp, MVNETA_INTR_MISC_MASK,
MVNETA_CAUSE_PHY_STATUS_CHANGE | MVNETA_CAUSE_PHY_STATUS_CHANGE |
MVNETA_CAUSE_LINK_CHANGE | MVNETA_CAUSE_LINK_CHANGE |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment