diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 8a37b9f604e2..d5f452e4aca8 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1545,6 +1545,133 @@ static void iavf_watchdog_timer(struct timer_list *t) /* timer will be rescheduled in watchdog task */ } +/** + * iavf_process_aq_command - process aq_required flags + * and sends aq command + * @adapter: pointer to iavf adapter structure + * + * Returns 0 on success + * Returns error code if no command was sent + * or error code if the command failed. + **/ +static int iavf_process_aq_command(struct iavf_adapter *adapter) +{ + if (adapter->aq_required & IAVF_FLAG_AQ_GET_CONFIG) + return iavf_send_vf_config_msg(adapter); + if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_QUEUES) { + iavf_disable_queues(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_MAP_VECTORS) { + iavf_map_queues(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_ADD_MAC_FILTER) { + iavf_add_ether_addrs(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_ADD_VLAN_FILTER) { + iavf_add_vlans(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_DEL_MAC_FILTER) { + iavf_del_ether_addrs(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_DEL_VLAN_FILTER) { + iavf_del_vlans(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING) { + iavf_enable_vlan_stripping(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING) { + iavf_disable_vlan_stripping(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_QUEUES) { + iavf_configure_queues(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_QUEUES) { + iavf_enable_queues(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_RSS) { + /* This message goes straight to the firmware, not the + * PF, so we don't have to set current_op as we will + * not get a response through the ARQ. + */ + adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_RSS; + return 0; + } + if (adapter->aq_required & IAVF_FLAG_AQ_GET_HENA) { + iavf_get_hena(adapter); + return 0; + } + if (adapter->aq_required & IAVF_FLAG_AQ_SET_HENA) { + iavf_set_hena(adapter); + return 0; + } + if (adapter->aq_required & IAVF_FLAG_AQ_SET_RSS_KEY) { + iavf_set_rss_key(adapter); + return 0; + } + if (adapter->aq_required & IAVF_FLAG_AQ_SET_RSS_LUT) { + iavf_set_rss_lut(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_PROMISC) { + iavf_set_promiscuous(adapter, FLAG_VF_UNICAST_PROMISC | + FLAG_VF_MULTICAST_PROMISC); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_ALLMULTI) { + iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); + return 0; + } + + if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) && + (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { + iavf_set_promiscuous(adapter, 0); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_CHANNELS) { + iavf_enable_channels(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_CHANNELS) { + iavf_disable_channels(adapter); + return 0; + } + if (adapter->aq_required & IAVF_FLAG_AQ_ADD_CLOUD_FILTER) { + iavf_add_cloud_filter(adapter); + return 0; + } + + if (adapter->aq_required & IAVF_FLAG_AQ_DEL_CLOUD_FILTER) { + iavf_del_cloud_filter(adapter); + return 0; + } + + return -EAGAIN; +} + /** * iavf_watchdog_task - Periodic call-back task * @work: pointer to work_struct @@ -1552,8 +1679,8 @@ static void iavf_watchdog_timer(struct timer_list *t) static void iavf_watchdog_task(struct work_struct *work) { struct iavf_adapter *adapter = container_of(work, - struct iavf_adapter, - watchdog_task); + struct iavf_adapter, + watchdog_task); struct iavf_hw *hw = &adapter->hw; u32 reg_val; @@ -1563,10 +1690,10 @@ static void iavf_watchdog_task(struct work_struct *work) if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) { reg_val = rd32(hw, IAVF_VFGEN_RSTAT) & IAVF_VFGEN_RSTAT_VFR_STATE_MASK; - if ((reg_val == VIRTCHNL_VFR_VFACTIVE) || - (reg_val == VIRTCHNL_VFR_COMPLETED)) { + if (reg_val == VIRTCHNL_VFR_VFACTIVE || + reg_val == VIRTCHNL_VFR_COMPLETED) { /* A chance for redemption! */ - dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attempting reinit.\n"); + dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attemptingreinit.\n"); adapter->state = __IAVF_STARTUP; adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED; schedule_delayed_work(&adapter->init_task, 10); @@ -1584,7 +1711,7 @@ static void iavf_watchdog_task(struct work_struct *work) goto watchdog_done; } - if ((adapter->state < __IAVF_DOWN) || + if (adapter->state < __IAVF_DOWN || (adapter->flags & IAVF_FLAG_RESET_PENDING)) goto watchdog_done; @@ -1602,136 +1729,22 @@ static void iavf_watchdog_task(struct work_struct *work) /* Process admin queue tasks. After init, everything gets done * here so we don't race on the admin queue. + * The check is made against -EAGAIN, as it's the error code that + * would be returned on no op to run. Failures of called functions + * return other values. */ if (adapter->current_op) { if (!iavf_asq_done(hw)) { dev_dbg(&adapter->pdev->dev, "Admin queue timeout\n"); iavf_send_api_ver(adapter); } - goto watchdog_done; - } - if (adapter->aq_required & IAVF_FLAG_AQ_GET_CONFIG) { - iavf_send_vf_config_msg(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_QUEUES) { - iavf_disable_queues(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_MAP_VECTORS) { - iavf_map_queues(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ADD_MAC_FILTER) { - iavf_add_ether_addrs(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ADD_VLAN_FILTER) { - iavf_add_vlans(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DEL_MAC_FILTER) { - iavf_del_ether_addrs(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DEL_VLAN_FILTER) { - iavf_del_vlans(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_VLAN_STRIPPING) { - iavf_enable_vlan_stripping(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_VLAN_STRIPPING) { - iavf_disable_vlan_stripping(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_QUEUES) { - iavf_configure_queues(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_QUEUES) { - iavf_enable_queues(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_CONFIGURE_RSS) { - /* This message goes straight to the firmware, not the - * PF, so we don't have to set current_op as we will - * not get a response through the ARQ. - */ - iavf_init_rss(adapter); - adapter->aq_required &= ~IAVF_FLAG_AQ_CONFIGURE_RSS; - goto watchdog_done; - } - if (adapter->aq_required & IAVF_FLAG_AQ_GET_HENA) { - iavf_get_hena(adapter); - goto watchdog_done; - } - if (adapter->aq_required & IAVF_FLAG_AQ_SET_HENA) { - iavf_set_hena(adapter); - goto watchdog_done; - } - if (adapter->aq_required & IAVF_FLAG_AQ_SET_RSS_KEY) { - iavf_set_rss_key(adapter); - goto watchdog_done; - } - if (adapter->aq_required & IAVF_FLAG_AQ_SET_RSS_LUT) { - iavf_set_rss_lut(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_PROMISC) { - iavf_set_promiscuous(adapter, FLAG_VF_UNICAST_PROMISC | - FLAG_VF_MULTICAST_PROMISC); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_REQUEST_ALLMULTI) { - iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); - goto watchdog_done; - } - - if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) && - (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { - iavf_set_promiscuous(adapter, 0); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ENABLE_CHANNELS) { - iavf_enable_channels(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DISABLE_CHANNELS) { - iavf_disable_channels(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_ADD_CLOUD_FILTER) { - iavf_add_cloud_filter(adapter); - goto watchdog_done; - } - - if (adapter->aq_required & IAVF_FLAG_AQ_DEL_CLOUD_FILTER) { - iavf_del_cloud_filter(adapter); - goto watchdog_done; + } else if (iavf_process_aq_command(adapter) == -EAGAIN && + adapter->state == __IAVF_RUNNING) { + iavf_request_stats(adapter); } schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5)); - if (adapter->state == __IAVF_RUNNING) - iavf_request_stats(adapter); watchdog_done: if (adapter->state == __IAVF_RUNNING) iavf_detect_recover_hung(&adapter->vsi);