From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lb0-x22e.google.com (mail-lb0-x22e.google.com [IPv6:2a00:1450:4010:c04::22e]) by dpdk.org (Postfix) with ESMTP id 5D9CE1F3 for ; Mon, 23 Sep 2013 21:16:19 +0200 (CEST) Received: by mail-lb0-f174.google.com with SMTP id w6so2925037lbh.19 for ; Mon, 23 Sep 2013 12:16:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=Pnpj93EufjUpHTRbnaRZO9OhxEyJCL7Vhs1TjZt50Ok=; b=s+lLaPo3Wlwp/TaLSSKeQ50RDr90W0v+43LBKZCn17UD1uZamJGX8K/fnfQ3EmJuOy Pf0K5aQN07hbX7JKjHUPBWjrh8aM/SSuj9ul/DBZY6dkskkln8qTD6KzDaHG/fU0/nnE 7IL2nRKa1Ytm+qPdFZ0gGNCm2YdvIyuvqm+IsJ0HNMIqIS70iR54caEWK00vjmFMcbkF ntrhA3WoZt4YMimAZsnZ3Ttuqr5HSGlkVegHKiZgSzfAeyILCPIhmp147BuO3a6uovcN IBk3LwFiu/rGJ2lMiMxlBIC6y0xnhS9na5+SXKXF4+1zgpW+074djrUvfJOBfZnwRixA aOuQ== X-Received: by 10.112.181.100 with SMTP id dv4mr2851247lbc.34.1379963818892; Mon, 23 Sep 2013 12:16:58 -0700 (PDT) Received: from localhost.localdomain (cs181018128.pp.htv.fi. [82.181.18.128]) by mx.google.com with ESMTPSA id b1sm13615278lah.6.1969.12.31.16.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 23 Sep 2013 12:16:58 -0700 (PDT) From: Qinglai Xiao To: dev@dpdk.org Date: Mon, 23 Sep 2013 22:16:20 +0300 Message-Id: <1379963780-5044-1-git-send-email-jigsaw@gmail.com> X-Mailer: git-send-email 1.7.10.4 Subject: [dpdk-dev] [PATCH] Add support for 82599 Tx->Rx loopback operation. X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Sep 2013 19:16:19 -0000 Signed-off-by: Qinglai Xiao --- lib/librte_ether/rte_ethdev.h | 1 + lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c | 122 +++++++++++++++++++++++++++++- lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h | 7 ++ lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 8 ++ lib/librte_pmd_ixgbe/ixgbe_rxtx.c | 6 ++ 5 files changed, 141 insertions(+), 3 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 2d7385f..f474e5b 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -670,6 +670,7 @@ struct rte_eth_conf { /**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */ uint16_t link_duplex; /**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */ + uint32_t lpbk; /**< Loopback operation. The value depends on ethernet controller. */ struct rte_eth_rxmode rxmode; /**< Port RX configuration. */ struct rte_eth_txmode txmode; /**< Port TX configuration. */ union { diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c index db07789..0416c01 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c @@ -48,6 +48,17 @@ STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, STATIC s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset, u16 words, u16 *data); + +STATIC s32 ixgbe_get_link_capabilities_82599_lpbk(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *negotiation); +STATIC s32 ixgbe_check_mac_link_82599_lpbk(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); +STATIC s32 ixgbe_setup_mac_link_82599_lpbk(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete); + + void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; @@ -68,7 +79,10 @@ void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) mac->ops.flap_tx_laser = NULL; } - if (hw->phy.multispeed_fiber) { + if (hw->lpbk == IXGBE_LPBK_82599_TX_RX) { + /* Support for Tx->Rx loopback operation */ + mac->ops.setup_link = &ixgbe_setup_mac_link_82599_lpbk; + } else if (hw->phy.multispeed_fiber) { /* Set up dual speed SFP+ support */ mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; } else { @@ -266,8 +280,23 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) mac->ops.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing; /* Link */ - mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599; - mac->ops.check_link = &ixgbe_check_mac_link_generic; + + /* 82599 has two loopback operations: Tx->Rx and Rx->Tx + * Only Tx->Rx is supported for now. + */ + switch (hw->lpbk) { + case IXGBE_LPBK_82599_TX_RX: + mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599_lpbk; + mac->ops.check_link = &ixgbe_check_mac_link_82599_lpbk; + break; + + case IXGBE_LPBK_82599_NONE: /* FALL THRU */ + default: + mac->ops.get_link_capabilities = &ixgbe_get_link_capabilities_82599; + mac->ops.check_link = &ixgbe_check_mac_link_generic; + break; + } + mac->ops.setup_rxpba = &ixgbe_set_rxpba_generic; ixgbe_init_mac_link_ops_82599(hw); @@ -2370,5 +2399,92 @@ reset_pipeline_out: return ret_val; } +/** + * ixgbe_get_link_capabilities_82599_lpbk - Determines link capabilities for Tx->Rx loopback setting + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @negotiation: always false + * + * For Tx->Rx loopback only. Rx->Tx loopback is not supported for now. + * + * @speed is always set to IXGBE_LINK_SPEED_10GB_FULL, + * @negotiation is always set to false. + **/ +STATIC s32 ixgbe_get_link_capabilities_82599_lpbk(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *negotiation) +{ + DEBUGFUNC("ixgbe_get_link_capabilities_82599_lpbk"); + + *speed = IXGBE_LINK_SPEED_10GB_FULL; + *negotiation = false; + + return IXGBE_SUCCESS; +} +/** + * ixgbe_check_mac_link_82599_lpbk - Determine link and speed status for loopback Tx->Rx setting + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * For Tx->Rx loopback only. Rx->Tx loopback is not supported for now. + * + * Regardless of link status (LINKS), always set @linkup to true, + * and @speed to IXGBE_LINK_SPEED_10GB_FULL. + **/ +STATIC s32 ixgbe_check_mac_link_82599_lpbk(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + DEBUGFUNC("ixgbe_check_mac_link_82599_lpbk"); + + *link_up = true; + *speed = IXGBE_LINK_SPEED_10GB_FULL; + + return 0; +} + +/** + * ixgbe_setup_mac_link_82599_loopback - Set MAC link speed for Tx->Rx loopback operation. + * @hw: pointer to hardware structure + * @speed: new link speed + * @autoneg: true if autonegotiation enabled + * @autoneg_wait_to_complete: true when waiting for completion is needed + * + * For Tx->Rx loopback only. Rx->Tx loopback is not supported for now. + * + * @speed, @autoneg and @autoneg_wait_to_complete are ignored. + * Just set AUTOC to IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU. + **/ +STATIC s32 ixgbe_setup_mac_link_82599_lpbk(struct ixgbe_hw *hw, + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete) +{ + u32 autoc; + u32 status = IXGBE_SUCCESS; + + DEBUGFUNC("ixgbe_setup_mac_link_82599_lpbk"); + autoc = IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; + + if (ixgbe_verify_lesm_fw_enabled_82599(hw)) { + status = hw->mac.ops.acquire_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + if (status != IXGBE_SUCCESS) { + status = IXGBE_ERR_SWFW_SYNC; + goto out; + } + } + + /* Restart link */ + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); + ixgbe_reset_pipeline_82599(hw); + + hw->mac.ops.release_swfw_sync(hw, + IXGBE_GSSR_MAC_CSR_SM); + msec_delay(50); + +out: + return status; +} diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h index 7fffd60..a31c9f7 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h @@ -2352,6 +2352,12 @@ enum ixgbe_fdir_pballoc_type { #define FW_CEM_MAX_RETRIES 3 #define FW_CEM_RESP_STATUS_SUCCESS 0x1 +/* Loopback operation types */ +/* 82599 specific loopback operation types */ +#define IXGBE_LPBK_82599_NONE 0x0 /* Default value. Loopback is disabled. */ +#define IXGBE_LPBK_82599_TX_RX 0x1 /* Tx->Rx loopback operation is enabled. */ +#define IXGBE_LPBK_82599_RX_TX 0x2 /* Rx->Tx loopback operation is enabled. */ + /* Host Interface Command Structures */ struct ixgbe_hic_hdr { @@ -3150,6 +3156,7 @@ struct ixgbe_hw { int api_version; bool force_full_reset; bool allow_unsupported_sfp; + uint32_t lpbk; }; #define ixgbe_call_func(hw, func, params, error) \ diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 9235f9d..09600bc 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -1137,6 +1137,14 @@ ixgbe_dev_configure(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); + if (dev->data->dev_conf.lpbk) { + struct ixgbe_hw *hw = + IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + hw->lpbk = dev->data->dev_conf.lpbk; + } + + /* set flag to update link status after init */ intr->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; diff --git a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c index 5fba01d..158da0e 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_rxtx.c +++ b/lib/librte_pmd_ixgbe/ixgbe_rxtx.c @@ -3252,6 +3252,12 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev) } else hlreg0 &= ~IXGBE_HLREG0_JUMBOEN; + /* + * Both Tx->Rx and Rx->Tx requres IXGBE_HLREG0_LPBK to be set. + */ + if (hw->lpbk) + hlreg0 |= IXGBE_HLREG0_LPBK; + IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); /* Setup RX queues */ -- 1.7.10.4