liquidio: VF interrupt initialization cleanup
authorRick Farrington <ricardo.farrington@cavium.com>
Wed, 31 May 2017 16:48:09 +0000 (09:48 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 2 Jun 2017 18:13:49 +0000 (14:13 -0400)
Set initialization state variable to (reflect interrupt initialization) at
correct time (immediately after having configured interrupts).  This fixes
problem of inconsistent IRQ allocation in case of [obscure] failure when
negotiating with PF driver during init.

Clean-up of interrupt enablement during initialization & avoid potential
race condition with chip-specific code (i.e. perform interrupt control in
main driver module).  Added explanatory comments regarding interrupt
enablement.

Signed-off-by: Rick Farrington <ricardo.farrington@cavium.com>
Signed-off-by: Satanand Burla <satananda.burla@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/liquidio/cn23xx_vf_device.c
drivers/net/ethernet/cavium/liquidio/lio_vf_main.c

index b6117b6a1de20d4a711a1371fa2c7558f24cd55d..20f3d2adf0c282e5383a7a051643e179a2c3700b 100644 (file)
@@ -431,11 +431,6 @@ int cn23xx_octeon_pfvf_handshake(struct octeon_device *oct)
        mbox_cmd.fn = (octeon_mbox_callback_t)octeon_pfvf_hs_callback;
        mbox_cmd.fn_arg = &status;
 
-       /* Interrupts are not enabled at this point.
-        * Enable them with default oq ticks
-        */
-       oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
-
        octeon_mbox_write(oct, &mbox_cmd);
 
        atomic_set(&status, 0);
@@ -444,11 +439,6 @@ int cn23xx_octeon_pfvf_handshake(struct octeon_device *oct)
                schedule_timeout_uninterruptible(1);
        } while ((!atomic_read(&status)) && (count++ < 100000));
 
-       /* Disable the interrupt so that the interrupsts will be reenabled
-        * with the oq ticks received from the PF
-        */
-       oct->fn_list.disable_interrupt(oct, OCTEON_ALL_INTR);
-
        ret = atomic_read(&status);
        if (!ret) {
                dev_err(&oct->pci_dev->dev, "octeon_pfvf_handshake timeout\n");
index 31d737c22648b71c119b38d8f8122a555dd6a5b6..07124096db48b8bb399155003f7e23a8ff5098c4 100644 (file)
@@ -3188,13 +3188,28 @@ static int octeon_device_init(struct octeon_device *oct)
        if (octeon_setup_interrupt(oct))
                return 1;
 
+       atomic_set(&oct->status, OCT_DEV_INTR_SET_DONE);
+
+       /* ***************************************************************
+        * The interrupts need to be enabled for the PF<-->VF handshake.
+        * They are [re]-enabled after the PF<-->VF handshake so that the
+        * correct OQ tick value is used (i.e. the value retrieved from
+        * the PF as part of the handshake).
+        */
+
+       /* Enable Octeon device interrupts */
+       oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
+
        if (cn23xx_octeon_pfvf_handshake(oct))
                return 1;
 
+       /* Here we [re]-enable the interrupts so that the correct OQ tick value
+        * is used (i.e. the value that was retrieved during the handshake)
+        */
+
        /* Enable Octeon device interrupts */
        oct->fn_list.enable_interrupt(oct, OCTEON_ALL_INTR);
-
-       atomic_set(&oct->status, OCT_DEV_INTR_SET_DONE);
+       /* *************************************************************** */
 
        /* Enable the input and output queues for this Octeon device */
        if (oct->fn_list.enable_io_queues(oct)) {