net/bnxt: handle reset notify async event from FW
[dpdk.git] / drivers / net / fm10k / base / fm10k_pf.c
index 4c075b6..439dd22 100644 (file)
@@ -1,35 +1,6 @@
-/*******************************************************************************
-
-Copyright (c) 2013 - 2015, Intel Corporation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
-    this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of the Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-***************************************************************************/
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2013 - 2015 Intel Corporation
+ */
 
 #include "fm10k_pf.h"
 #include "fm10k_vf.h"
@@ -66,21 +37,21 @@ STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
 
        /* shut down all rings */
        err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);
-       if (err)
+       if (err == FM10K_ERR_REQUESTS_PENDING) {
+               hw->mac.reset_while_pending++;
+               goto force_reset;
+       } else if (err) {
                return err;
+       }
 
        /* Verify that DMA is no longer active */
        reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL);
        if (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE))
                return FM10K_ERR_DMA_PENDING;
 
-       /* verify the switch is ready for reset */
-       reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);
-       if (!(reg & FM10K_DMA_CTRL2_SWITCH_READY))
-               goto out;
-
+force_reset:
        /* Inititate data path reset */
-       reg |= FM10K_DMA_CTRL_DATAPATH_RESET;
+       reg = FM10K_DMA_CTRL_DATAPATH_RESET;
        FM10K_WRITE_REG(hw, FM10K_DMA_CTRL, reg);
 
        /* Flush write and allow 100us for reset to complete */
@@ -90,10 +61,9 @@ STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
        /* Verify we made it out of reset */
        reg = FM10K_READ_REG(hw, FM10K_IP);
        if (!(reg & FM10K_IP_NOTINRESET))
-               err = FM10K_ERR_RESET_FAILED;
+               return FM10K_ERR_RESET_FAILED;
 
-out:
-       return err;
+       return FM10K_SUCCESS;
 }
 
 /**
@@ -412,7 +382,7 @@ STATIC s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort,
        DEBUGFUNC("fm10k_update_uc_addr_pf");
 
        /* verify MAC address is valid */
-       if (!FM10K_IS_VALID_ETHER_ADDR(mac))
+       if (!IS_VALID_ETHER_ADDR(mac))
                return FM10K_ERR_PARAM;
 
        return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags);
@@ -435,7 +405,7 @@ STATIC s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort,
        DEBUGFUNC("fm10k_update_mc_addr_pf");
 
        /* verify multicast address is valid */
-       if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac))
+       if (!IS_MULTICAST_ETHER_ADDR(mac))
                return FM10K_ERR_PARAM;
 
        return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0);
@@ -927,9 +897,35 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
        fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
                                    vf_info->mac, vf_vid);
 
-       /* load onto outgoing mailbox, ignore any errors on enqueue */
-       if (vf_info->mbx.ops.enqueue_tx)
-               vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
+       /* Configure Queue control register with new VLAN ID. The TXQCTL
+        * register is RO from the VF, so the PF must do this even in the
+        * case of notifying the VF of a new VID via the mailbox.
+        */
+       txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
+                FM10K_TXQCTL_VID_MASK;
+       txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
+                 FM10K_TXQCTL_VF | vf_idx;
+
+       for (i = 0; i < queues_per_pool; i++)
+               FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
+
+       /* try loading a message onto outgoing mailbox first */
+       if (vf_info->mbx.ops.enqueue_tx) {
+               err = vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
+               if (err != FM10K_MBX_ERR_NO_MBX)
+                       return err;
+               err = FM10K_SUCCESS;
+       }
+
+       /* If we aren't connected to a mailbox, this is most likely because
+        * the VF driver is not running. It should thus be safe to re-map
+        * queues and use the registers to pass the MAC address so that the VF
+        * driver gets correct information during its initialization.
+        */
+
+       /* MAP Tx queue back to 0 temporarily, and disable it */
+       FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
+       FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
 
        /* verify ring has disabled before modifying base address registers */
        txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
@@ -945,7 +941,7 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
        }
 
        /* Update base address registers to contain MAC address */
-       if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
+       if (IS_VALID_ETHER_ADDR(vf_info->mac)) {
                tdbal = (((u32)vf_info->mac[3]) << 24) |
                        (((u32)vf_info->mac[4]) << 16) |
                        (((u32)vf_info->mac[5]) << 8);
@@ -968,16 +964,6 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
                                                   FM10K_TDLEN_ITR_SCALE_SHIFT);
 
 err_out:
-       /* configure Queue control register */
-       txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
-                FM10K_TXQCTL_VID_MASK;
-       txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
-                 FM10K_TXQCTL_VF | vf_idx;
-
-       /* assign VLAN ID */
-       for (i = 0; i < queues_per_pool; i++)
-               FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
-
        /* restore the queue back to VF ownership */
        FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
        return err;
@@ -1085,7 +1071,7 @@ STATIC s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw,
        FM10K_WRITE_REG(hw, FM10K_MRQC(vf_info->vsi), 0);
 
        /* Update base address registers to contain MAC address */
-       if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) {
+       if (IS_VALID_ETHER_ADDR(vf_info->mac)) {
                tdbal = (((u32)vf_info->mac[3]) << 24) |
                        (((u32)vf_info->mac[4]) << 16) |
                        (((u32)vf_info->mac[5]) << 8);
@@ -1311,7 +1297,7 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results,
                        return err;
 
                /* block attempts to set MAC for a locked device */
-               if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac) &&
+               if (IS_VALID_ETHER_ADDR(vf_info->mac) &&
                    memcmp(mac, vf_info->mac, ETH_ALEN))
                        return FM10K_ERR_PARAM;
 
@@ -1496,7 +1482,7 @@ const struct fm10k_msg_data fm10k_iov_msg_data_pf[] = {
  *  This function collects and aggregates global and per queue hardware
  *  statistics.
  **/
-STATIC void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
+void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
                                     struct fm10k_hw_stats *stats)
 {
        u32 timeout, ur, ca, um, xec, vlan_drop, loopback_drop, nodesc_drop;
@@ -1569,7 +1555,7 @@ STATIC void fm10k_update_hw_stats_pf(struct fm10k_hw *hw,
  *  This function resets the base for global and per queue hardware
  *  statistics.
  **/
-STATIC void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
+void fm10k_rebind_hw_stats_pf(struct fm10k_hw *hw,
                                     struct fm10k_hw_stats *stats)
 {
        DEBUGFUNC("fm10k_rebind_hw_stats_pf");
@@ -1688,13 +1674,12 @@ STATIC s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw)
  *  @hw: pointer to hardware structure
  *  @switch_ready: pointer to boolean value that will record switch state
  *
- *  This funciton will check the DMA_CTRL2 register and mailbox in order
+ *  This function will check the DMA_CTRL2 register and mailbox in order
  *  to determine if the switch is ready for the PF to begin requesting
  *  addresses and mapping traffic to the local interface.
  **/
 STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
 {
-       s32 ret_val = FM10K_SUCCESS;
        u32 dma_ctrl2;
 
        DEBUGFUNC("fm10k_get_host_state_pf");
@@ -1702,19 +1687,10 @@ STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
        /* verify the switch is ready for interaction */
        dma_ctrl2 = FM10K_READ_REG(hw, FM10K_DMA_CTRL2);
        if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY))
-               goto out;
+               return FM10K_SUCCESS;
 
        /* retrieve generic host state info */
-       ret_val = fm10k_get_host_state_generic(hw, switch_ready);
-       if (ret_val)
-               goto out;
-
-       /* interface cannot receive traffic without logical ports */
-       if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
-               ret_val = fm10k_request_lport_map_pf(hw);
-
-out:
-       return ret_val;
+       return fm10k_get_host_state_generic(hw, switch_ready);
 }
 
 /* This structure defines the attibutes to be parsed below */
@@ -2102,6 +2078,7 @@ s32 fm10k_init_ops_pf(struct fm10k_hw *hw)
        mac->ops.set_dma_mask = &fm10k_set_dma_mask_pf;
        mac->ops.get_fault = &fm10k_get_fault_pf;
        mac->ops.get_host_state = &fm10k_get_host_state_pf;
+       mac->ops.request_lport_map = &fm10k_request_lport_map_pf;
        mac->ops.adjust_systime = &fm10k_adjust_systime_pf;
        mac->ops.notify_offset = &fm10k_notify_offset_pf;
        mac->ops.read_systime = &fm10k_read_systime_pf;