123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- From: Gregory CLEMENT <gregory.clement@free-electrons.com>
- Date: Thu, 4 Feb 2016 22:09:27 +0100
- Subject: [PATCH] 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: Gregory CLEMENT <gregory.clement@free-electrons.com>
- Signed-off-by: David S. Miller <davem@davemloft.net>
- ---
- --- a/drivers/net/ethernet/marvell/mvneta.c
- +++ b/drivers/net/ethernet/marvell/mvneta.c
- @@ -1036,6 +1036,43 @@ static void mvneta_set_autoneg(struct mv
- }
- }
-
- +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:
- * Clears interrupt Cause and Mask registers.
- * Clears all MAC tables.
- @@ -1053,14 +1090,10 @@ static void mvneta_defaults_set(struct m
- int max_cpu = num_present_cpus();
-
- /* Clear all Cause registers */
- - mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
- - mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
- + on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
-
- /* Mask all interrupts */
- - mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
- + on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
- mvreg_write(pp, MVNETA_INTR_ENABLE, 0);
-
- /* Enable MBUS Retry bit16 */
- @@ -2526,31 +2559,6 @@ static int mvneta_setup_txqs(struct mvne
- 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)
- {
- int cpu;
- @@ -2601,13 +2609,10 @@ static void mvneta_stop_dev(struct mvnet
- mvneta_port_disable(pp);
-
- /* Clear all ethernet port interrupts */
- - mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
- + on_each_cpu(mvneta_percpu_clear_intr_cause, pp, true);
-
- /* Mask all ethernet port interrupts */
- - mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
- + on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
-
- mvneta_tx_reset(pp);
- mvneta_rx_reset(pp);
- @@ -2919,9 +2924,7 @@ static int mvneta_percpu_notifier(struct
- }
-
- /* Mask all ethernet port interrupts */
- - mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
- + on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
- napi_enable(&port->napi);
-
-
- @@ -2936,14 +2939,8 @@ static int mvneta_percpu_notifier(struct
- */
- mvneta_percpu_elect(pp);
-
- - /* Unmask all ethernet port interrupts, as this
- - * notifier is called for each CPU then the CPU to
- - * 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);
- + /* Unmask all ethernet port interrupts */
- + on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
- mvreg_write(pp, MVNETA_INTR_MISC_MASK,
- MVNETA_CAUSE_PHY_STATUS_CHANGE |
- MVNETA_CAUSE_LINK_CHANGE |
- @@ -2954,9 +2951,7 @@ static int mvneta_percpu_notifier(struct
- case CPU_DOWN_PREPARE_FROZEN:
- netif_tx_stop_all_queues(pp->dev);
- /* Mask all ethernet port interrupts */
- - mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
- - mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
- + on_each_cpu(mvneta_percpu_mask_interrupt, pp, true);
-
- napi_synchronize(&port->napi);
- napi_disable(&port->napi);
- @@ -2972,10 +2967,7 @@ static int mvneta_percpu_notifier(struct
- /* Check if a new CPU must be elected now this on is down */
- mvneta_percpu_elect(pp);
- /* Unmask all ethernet port interrupts */
- - mvreg_write(pp, MVNETA_INTR_NEW_MASK,
- - MVNETA_RX_INTR_MASK(rxq_number) |
- - MVNETA_TX_INTR_MASK(txq_number) |
- - MVNETA_MISCINTR_INTR_MASK);
- + on_each_cpu(mvneta_percpu_unmask_interrupt, pp, true);
- mvreg_write(pp, MVNETA_INTR_MISC_MASK,
- MVNETA_CAUSE_PHY_STATUS_CHANGE |
- MVNETA_CAUSE_LINK_CHANGE |
|