X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fhns3%2Fhns3_ethdev.c;h=9cbcc13de8dbdd651f4905bcd694aa9e45b22b29;hb=46413898cf1df5798b8d1ea04522da0f0ce97205;hp=21c3c59cdd6104bf9557e2dacc9167e8165c6739;hpb=25fb790f7868f8eee96f7f051a834dec01b8a369;p=dpdk.git diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 21c3c59cdd..9cbcc13de8 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -102,6 +102,7 @@ static int hns3_remove_mc_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr); static int hns3_restore_fec(struct hns3_hw *hw); static int hns3_query_dev_fec_info(struct hns3_hw *hw); +static int hns3_do_stop(struct hns3_adapter *hns); void hns3_ether_format_addr(char *buf, uint16_t size, const struct rte_ether_addr *ether_addr) @@ -216,9 +217,6 @@ hns3_check_event_cause(struct hns3_adapter *hns, uint32_t *clearval) goto out; } - if (clearval && (vector0_int_stats || cmdq_src_val || hw_err_src_reg)) - hns3_warn(hw, "vector0_int_stats:0x%x cmdq_src_val:0x%x hw_err_src_reg:0x%x", - vector0_int_stats, cmdq_src_val, hw_err_src_reg); val = vector0_int_stats; ret = HNS3_VECTOR0_EVENT_OTHER; out: @@ -256,6 +254,34 @@ hns3_clear_all_event_cause(struct hns3_hw *hw) hns3_clear_event_cause(hw, HNS3_VECTOR0_EVENT_MBX, 0); } +static void +hns3_handle_mac_tnl(struct hns3_hw *hw) +{ + struct hns3_cmd_desc desc; + uint32_t status; + int ret; + + /* query and clear mac tnl interruptions */ + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_MAC_TNL_INT, true); + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hns3_err(hw, "failed to query mac tnl int, ret = %d.", ret); + return; + } + + status = rte_le_to_cpu_32(desc.data[0]); + if (status) { + hns3_warn(hw, "mac tnl int occurs, status = 0x%x.", status); + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CLEAR_MAC_TNL_INT, + false); + desc.data[0] = rte_cpu_to_le_32(HNS3_MAC_TNL_INT_CLR); + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) + hns3_err(hw, "failed to clear mac tnl int, ret = %d.", + ret); + } +} + static void hns3_interrupt_handler(void *param) { @@ -264,24 +290,36 @@ hns3_interrupt_handler(void *param) struct hns3_hw *hw = &hns->hw; enum hns3_evt_cause event_cause; uint32_t clearval = 0; + uint32_t vector0_int; + uint32_t ras_int; + uint32_t cmdq_int; /* Disable interrupt */ hns3_pf_disable_irq0(hw); event_cause = hns3_check_event_cause(hns, &clearval); + vector0_int = hns3_read_dev(hw, HNS3_VECTOR0_OTHER_INT_STS_REG); + ras_int = hns3_read_dev(hw, HNS3_RAS_PF_OTHER_INT_STS_REG); + cmdq_int = hns3_read_dev(hw, HNS3_VECTOR0_CMDQ_SRC_REG); /* vector 0 interrupt is shared with reset and mailbox source events. */ if (event_cause == HNS3_VECTOR0_EVENT_ERR) { - hns3_warn(hw, "Received err interrupt"); + hns3_warn(hw, "received interrupt: vector0_int_stat:0x%x " + "ras_int_stat:0x%x cmdq_int_stat:0x%x", + vector0_int, ras_int, cmdq_int); hns3_handle_msix_error(hns, &hw->reset.request); hns3_handle_ras_error(hns, &hw->reset.request); + hns3_handle_mac_tnl(hw); hns3_schedule_reset(hns); } else if (event_cause == HNS3_VECTOR0_EVENT_RST) { - hns3_warn(hw, "Received reset interrupt"); + hns3_warn(hw, "received reset interrupt"); hns3_schedule_reset(hns); - } else if (event_cause == HNS3_VECTOR0_EVENT_MBX) + } else if (event_cause == HNS3_VECTOR0_EVENT_MBX) { hns3_dev_handle_mbx_msg(hw); - else - hns3_err(hw, "Received unknown event"); + } else { + hns3_warn(hw, "received unknown event: vector0_int_stat:0x%x " + "ras_int_stat:0x%x cmdq_int_stat:0x%x", + vector0_int, ras_int, cmdq_int); + } hns3_clear_event_cause(hw, event_cause, clearval); /* Enable interrupt if it is not cause by reset */ @@ -4638,6 +4676,8 @@ hns3_update_link_status(struct hns3_hw *hw) if (state != hw->mac.link_status) { hw->mac.link_status = state; hns3_warn(hw, "Link status change to %s!", state ? "up" : "down"); + hns3_config_mac_tnl_int(hw, + state == ETH_LINK_UP ? true : false); return true; } @@ -4956,6 +4996,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) (void)hns3_firmware_compat_config(hw, false); hns3_uninit_umv_space(hw); hns3_tqp_stats_uninit(hw); + hns3_config_mac_tnl_int(hw, false); hns3_pf_disable_irq0(hw); rte_intr_disable(&pci_dev->intr_handle); hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, @@ -5133,11 +5174,8 @@ hns3_dev_start(struct rte_eth_dev *dev) return ret; } ret = hns3_map_rx_interrupt(dev); - if (ret) { - hw->adapter_state = HNS3_NIC_CONFIGURED; - rte_spinlock_unlock(&hw->lock); - return ret; - } + if (ret) + goto map_rx_inter_err; /* * There are three register used to control the status of a TQP @@ -5151,19 +5189,12 @@ hns3_dev_start(struct rte_eth_dev *dev) * status of queue in the dpdk framework. */ ret = hns3_start_all_txqs(dev); - if (ret) { - hw->adapter_state = HNS3_NIC_CONFIGURED; - rte_spinlock_unlock(&hw->lock); - return ret; - } + if (ret) + goto map_rx_inter_err; ret = hns3_start_all_rxqs(dev); - if (ret) { - hns3_stop_all_txqs(dev); - hw->adapter_state = HNS3_NIC_CONFIGURED; - rte_spinlock_unlock(&hw->lock); - return ret; - } + if (ret) + goto start_all_rxqs_fail; hw->adapter_state = HNS3_NIC_STARTED; rte_spinlock_unlock(&hw->lock); @@ -5187,7 +5218,17 @@ hns3_dev_start(struct rte_eth_dev *dev) hns3_tm_dev_start_proc(hw); hns3_info(hw, "hns3 dev start successful!"); + return 0; + +start_all_rxqs_fail: + hns3_stop_all_txqs(dev); +map_rx_inter_err: + (void)hns3_do_stop(hns); + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + + return ret; } static int @@ -5196,6 +5237,17 @@ hns3_do_stop(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; int ret; + /* + * The "hns3_do_stop" function will also be called by .stop_service to + * prepare reset. At the time of global or IMP reset, the command cannot + * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be + * accessed during the reset process. So the mbuf can not be released + * during reset and is required to be released after the reset is + * completed. + */ + if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) + hns3_dev_release_mbufs(hns); + ret = hns3_cfg_mac_mode(hw, false); if (ret) return ret; @@ -5270,10 +5322,10 @@ hns3_dev_stop(struct rte_eth_dev *dev) rte_spinlock_lock(&hw->lock); if (__atomic_load_n(&hw->reset.resetting, __ATOMIC_RELAXED) == 0) { hns3_tm_dev_stop_proc(hw); + hns3_config_mac_tnl_int(hw, false); hns3_stop_tqps(hw); hns3_do_stop(hns); hns3_unmap_rx_interrupt(dev); - hns3_dev_release_mbufs(hns); hw->adapter_state = HNS3_NIC_CONFIGURED; } hns3_rx_scattered_reset(dev);