X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Ftxgbe%2Ftxgbe_ethdev.c;h=006399468841e87a5091b1bbf605d4f13e884e9c;hb=b43045eedeebb15354d85babdb84171a1073aa9d;hp=a1d90ad89bda8c121e7c5efa95c21d197d8808b1;hpb=f611dada1af8d32a0264c4b8c2066c8cdc12edb8;p=dpdk.git diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index a1d90ad89b..0063994688 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2020 + * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd. + * Copyright(c) 2010-2017 Intel Corporation */ #include @@ -106,6 +107,7 @@ static void txgbe_vlan_hw_strip_disable(struct rte_eth_dev *dev, static void txgbe_dev_link_status_print(struct rte_eth_dev *dev); static int txgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on); static int txgbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev); +static int txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev); static int txgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev); static int txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev); static int txgbe_dev_interrupt_action(struct rte_eth_dev *dev, @@ -494,6 +496,10 @@ txgbe_parse_devargs(struct txgbe_hw *hw, struct rte_devargs *devargs) u16 poll = 0; u16 present = 1; u16 sgmii = 0; + u16 ffe_set = 0; + u16 ffe_main = 27; + u16 ffe_pre = 8; + u16 ffe_post = 44; if (devargs == NULL) goto null; @@ -510,6 +516,14 @@ txgbe_parse_devargs(struct txgbe_hw *hw, struct rte_devargs *devargs) &txgbe_handle_devarg, &present); rte_kvargs_process(kvlist, TXGBE_DEVARG_KX_SGMII, &txgbe_handle_devarg, &sgmii); + rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_SET, + &txgbe_handle_devarg, &ffe_set); + rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_MAIN, + &txgbe_handle_devarg, &ffe_main); + rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_PRE, + &txgbe_handle_devarg, &ffe_pre); + rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_POST, + &txgbe_handle_devarg, &ffe_post); rte_kvargs_free(kvlist); null: @@ -517,6 +531,10 @@ null: hw->devarg.poll = poll; hw->devarg.present = present; hw->devarg.sgmii = sgmii; + hw->phy.ffe_set = ffe_set; + hw->phy.ffe_main = ffe_main; + hw->phy.ffe_pre = ffe_pre; + hw->phy.ffe_post = ffe_post; } static int @@ -913,34 +931,10 @@ static int eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { - struct rte_eth_dev *pf_ethdev; - struct rte_eth_devargs eth_da; - int retval; - - if (pci_dev->device.devargs) { - retval = rte_eth_devargs_parse(pci_dev->device.devargs->args, - ð_da); - if (retval) - return retval; - } else { - memset(ð_da, 0, sizeof(eth_da)); - } - - retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, + return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name, sizeof(struct txgbe_adapter), eth_dev_pci_specific_init, pci_dev, eth_txgbe_dev_init, NULL); - - if (retval || eth_da.nb_representor_ports < 1) - return retval; - if (eth_da.type != RTE_ETH_REPRESENTOR_VF) - return -ENOTSUP; - - pf_ethdev = rte_eth_dev_allocated(pci_dev->device.name); - if (pf_ethdev == NULL) - return -ENODEV; - - return 0; } static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev) @@ -949,7 +943,7 @@ static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev) ethdev = rte_eth_dev_allocated(pci_dev->device.name); if (!ethdev) - return -ENODEV; + return 0; return rte_eth_dev_destroy(ethdev, eth_txgbe_dev_uninit); } @@ -1192,7 +1186,6 @@ txgbe_vlan_hw_extend_disable(struct rte_eth_dev *dev) ctrl = rd32(hw, TXGBE_PORTCTL); ctrl &= ~TXGBE_PORTCTL_VLANEXT; - ctrl &= ~TXGBE_PORTCTL_QINQ; wr32(hw, TXGBE_PORTCTL, ctrl); } @@ -1200,17 +1193,38 @@ static void txgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev) { struct txgbe_hw *hw = TXGBE_DEV_HW(dev); - struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode; - struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode; uint32_t ctrl; PMD_INIT_FUNC_TRACE(); ctrl = rd32(hw, TXGBE_PORTCTL); ctrl |= TXGBE_PORTCTL_VLANEXT; - if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP || - txmode->offloads & DEV_TX_OFFLOAD_QINQ_INSERT) - ctrl |= TXGBE_PORTCTL_QINQ; + wr32(hw, TXGBE_PORTCTL, ctrl); +} + +static void +txgbe_qinq_hw_strip_disable(struct rte_eth_dev *dev) +{ + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + uint32_t ctrl; + + PMD_INIT_FUNC_TRACE(); + + ctrl = rd32(hw, TXGBE_PORTCTL); + ctrl &= ~TXGBE_PORTCTL_QINQ; + wr32(hw, TXGBE_PORTCTL, ctrl); +} + +static void +txgbe_qinq_hw_strip_enable(struct rte_eth_dev *dev) +{ + struct txgbe_hw *hw = TXGBE_DEV_HW(dev); + uint32_t ctrl; + + PMD_INIT_FUNC_TRACE(); + + ctrl = rd32(hw, TXGBE_PORTCTL); + ctrl |= TXGBE_PORTCTL_QINQ | TXGBE_PORTCTL_VLANEXT; wr32(hw, TXGBE_PORTCTL, ctrl); } @@ -1277,6 +1291,13 @@ txgbe_vlan_offload_config(struct rte_eth_dev *dev, int mask) txgbe_vlan_hw_extend_disable(dev); } + if (mask & ETH_QINQ_STRIP_MASK) { + if (rxmode->offloads & DEV_RX_OFFLOAD_QINQ_STRIP) + txgbe_qinq_hw_strip_enable(dev); + else + txgbe_qinq_hw_strip_disable(dev); + } + return 0; } @@ -1507,6 +1528,7 @@ txgbe_dev_phy_intr_setup(struct rte_eth_dev *dev) gpie |= TXGBE_GPIOBIT_6; wr32(hw, TXGBE_GPIOINTEN, gpie); intr->mask_misc |= TXGBE_ICRMISC_GPIO; + intr->mask_misc |= TXGBE_ICRMISC_ANDONE; } int @@ -1642,6 +1664,7 @@ txgbe_dev_start(struct rte_eth_dev *dev) return -1; hw->mac.start_hw(hw); hw->mac.get_link_status = true; + hw->dev_start = true; /* configure PF module if SRIOV enabled */ txgbe_pf_host_configure(dev); @@ -1740,7 +1763,8 @@ txgbe_dev_start(struct rte_eth_dev *dev) hw->mac.enable_tx_laser(hw); } - err = hw->mac.check_link(hw, &speed, &link_up, 0); + if ((hw->subsystem_device_id & 0xFF) != TXGBE_DEV_ID_KR_KX_KX4) + err = hw->mac.check_link(hw, &speed, &link_up, 0); if (err) goto error; dev->data->dev_link.link_status = link_up; @@ -1783,6 +1807,7 @@ txgbe_dev_start(struct rte_eth_dev *dev) skip_link_setup: if (rte_intr_allow_others(intr_handle)) { + txgbe_dev_misc_interrupt_setup(dev); /* check if lsc interrupt is enabled */ if (dev->data->dev_conf.intr_conf.lsc != 0) txgbe_dev_lsc_interrupt_setup(dev, TRUE); @@ -1909,6 +1934,7 @@ txgbe_dev_stop(struct rte_eth_dev *dev) hw->adapter_stopped = true; dev->data->dev_started = 0; + hw->dev_start = false; return 0; } @@ -2562,9 +2588,11 @@ txgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) hw->phy.get_fw_version(hw, &etrack_id); ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; @@ -2700,12 +2728,17 @@ txgbe_dev_link_update_share(struct rte_eth_dev *dev, } if (link_up == 0) { - if (hw->phy.media_type == txgbe_media_type_fiber) { + if ((hw->subsystem_device_id & 0xFF) == + TXGBE_DEV_ID_KR_KX_KX4) { + hw->mac.bp_down_event(hw); + } else if (hw->phy.media_type == txgbe_media_type_fiber) { intr->flags |= TXGBE_FLAG_NEED_LINK_CONFIG; rte_eal_alarm_set(10, txgbe_dev_setup_link_alarm_handler, dev); } return rte_eth_linkstatus_set(dev, &link); + } else if (!hw->dev_start) { + return rte_eth_linkstatus_set(dev, &link); } intr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG; @@ -2835,6 +2868,20 @@ txgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on) return 0; } +static int +txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev) +{ + struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev); + u64 mask; + + mask = TXGBE_ICR_MASK; + mask &= (1ULL << TXGBE_MISC_VEC_ID); + intr->mask |= mask; + intr->mask_misc |= TXGBE_ICRMISC_GPIO; + intr->mask_misc |= TXGBE_ICRMISC_ANDONE; + return 0; +} + /** * It clears the interrupt causes and enables the interrupt. * It will be called once only during nic initialized. @@ -2850,9 +2897,11 @@ static int txgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev) { struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev); + u64 mask; - intr->mask[0] |= TXGBE_ICR_MASK; - intr->mask[1] |= TXGBE_ICR_MASK; + mask = TXGBE_ICR_MASK; + mask &= ~((1ULL << TXGBE_RX_VEC_START) - 1); + intr->mask |= mask; return 0; } @@ -2908,6 +2957,9 @@ txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev) if (eicr & TXGBE_ICRMISC_LSC) intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE; + if (eicr & TXGBE_ICRMISC_ANDONE) + intr->flags |= TXGBE_FLAG_NEED_AN_CONFIG; + if (eicr & TXGBE_ICRMISC_VFMBX) intr->flags |= TXGBE_FLAG_MAILBOX; @@ -2985,6 +3037,13 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev, intr->flags &= ~TXGBE_FLAG_PHY_INTERRUPT; } + if (intr->flags & TXGBE_FLAG_NEED_AN_CONFIG) { + if (hw->devarg.auto_neg == 1 && hw->devarg.poll == 0) { + hw->mac.kr_handle(hw); + intr->flags &= ~TXGBE_FLAG_NEED_AN_CONFIG; + } + } + if (intr->flags & TXGBE_FLAG_NEED_LINK_UPDATE) { struct rte_eth_link link; @@ -2998,6 +3057,11 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev, /* handle it 1 sec later, wait it being stable */ timeout = TXGBE_LINK_UP_CHECK_TIMEOUT; /* likely to down */ + else if ((hw->subsystem_device_id & 0xFF) == + TXGBE_DEV_ID_KR_KX_KX4 && + hw->devarg.auto_neg == 1) + /* handle it 2 sec later for backplane AN73 */ + timeout = 2000; else /* handle it 4 sec later, wait it being stable */ timeout = TXGBE_LINK_DOWN_CHECK_TIMEOUT; @@ -3008,10 +3072,12 @@ txgbe_dev_interrupt_action(struct rte_eth_dev *dev, (void *)dev) < 0) { PMD_DRV_LOG(ERR, "Error setting alarm"); } else { - /* remember original mask */ - intr->mask_misc_orig = intr->mask_misc; /* only disable lsc interrupt */ intr->mask_misc &= ~TXGBE_ICRMISC_LSC; + + intr->mask_orig = intr->mask; + /* only disable all misc interrupts */ + intr->mask &= ~(1ULL << TXGBE_MISC_VEC_ID); } } @@ -3072,8 +3138,10 @@ txgbe_dev_interrupt_delayed_handler(void *param) } /* restore original mask */ - intr->mask_misc = intr->mask_misc_orig; - intr->mask_misc_orig = 0; + intr->mask_misc |= TXGBE_ICRMISC_LSC; + + intr->mask = intr->mask_orig; + intr->mask_orig = 0; PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr); txgbe_enable_intr(dev); @@ -4935,7 +5003,6 @@ txgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, break; } wr32(hw, TXGBE_VXLANPORT, udp_tunnel->udp_port); - wr32(hw, TXGBE_VXLANPORTGPE, udp_tunnel->udp_port); break; case RTE_TUNNEL_TYPE_GENEVE: if (udp_tunnel->udp_port == 0) { @@ -4953,6 +5020,14 @@ txgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, } wr32(hw, TXGBE_TEREDOPORT, udp_tunnel->udp_port); break; + case RTE_TUNNEL_TYPE_VXLAN_GPE: + if (udp_tunnel->udp_port == 0) { + PMD_DRV_LOG(ERR, "Add VxLAN port 0 is not allowed."); + ret = -EINVAL; + break; + } + wr32(hw, TXGBE_VXLANPORTGPE, udp_tunnel->udp_port); + break; default: PMD_DRV_LOG(ERR, "Invalid tunnel type"); ret = -EINVAL; @@ -4986,7 +5061,6 @@ txgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, break; } wr32(hw, TXGBE_VXLANPORT, 0); - wr32(hw, TXGBE_VXLANPORTGPE, 0); break; case RTE_TUNNEL_TYPE_GENEVE: cur_port = (uint16_t)rd32(hw, TXGBE_GENEVEPORT); @@ -5008,6 +5082,16 @@ txgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, } wr32(hw, TXGBE_TEREDOPORT, 0); break; + case RTE_TUNNEL_TYPE_VXLAN_GPE: + cur_port = (uint16_t)rd32(hw, TXGBE_VXLANPORTGPE); + if (cur_port != udp_tunnel->udp_port) { + PMD_DRV_LOG(ERR, "Port %u does not exist.", + udp_tunnel->udp_port); + ret = -EINVAL; + break; + } + wr32(hw, TXGBE_VXLANPORTGPE, 0); + break; default: PMD_DRV_LOG(ERR, "Invalid tunnel type"); ret = -EINVAL; @@ -5273,19 +5357,23 @@ RTE_PMD_REGISTER_PARAM_STRING(net_txgbe, TXGBE_DEVARG_BP_AUTO "=<0|1>" TXGBE_DEVARG_KR_POLL "=<0|1>" TXGBE_DEVARG_KR_PRESENT "=<0|1>" - TXGBE_DEVARG_KX_SGMII "=<0|1>"); + TXGBE_DEVARG_KX_SGMII "=<0|1>" + TXGBE_DEVARG_FFE_SET "=<0-4>" + TXGBE_DEVARG_FFE_MAIN "=" + TXGBE_DEVARG_FFE_PRE "=" + TXGBE_DEVARG_FFE_POST "="); -RTE_LOG_REGISTER(txgbe_logtype_init, pmd.net.txgbe.init, NOTICE); -RTE_LOG_REGISTER(txgbe_logtype_driver, pmd.net.txgbe.driver, NOTICE); -RTE_LOG_REGISTER(txgbe_logtype_bp, pmd.net.txgbe.bp, NOTICE); +RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_init, init, NOTICE); +RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_driver, driver, NOTICE); +RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_bp, bp, NOTICE); #ifdef RTE_LIBRTE_TXGBE_DEBUG_RX - RTE_LOG_REGISTER(txgbe_logtype_rx, pmd.net.txgbe.rx, DEBUG); + RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_rx, rx, DEBUG); #endif #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX - RTE_LOG_REGISTER(txgbe_logtype_tx, pmd.net.txgbe.tx, DEBUG); + RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_tx, tx, DEBUG); #endif #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX_FREE - RTE_LOG_REGISTER(txgbe_logtype_tx_free, pmd.net.txgbe.tx_free, DEBUG); + RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_tx_free, tx_free, DEBUG); #endif