From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id D04E95A84 for ; Fri, 6 May 2016 08:08:28 +0200 (CEST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP; 05 May 2016 23:08:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,585,1455004800"; d="scan'208";a="697627360" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by FMSMGA003.fm.intel.com with ESMTP; 05 May 2016 23:08:28 -0700 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id u4668Pml016688; Fri, 6 May 2016 14:08:25 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id u4668McX029565; Fri, 6 May 2016 14:08:24 +0800 Received: (from beileixi@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id u4668M5Y029561; Fri, 6 May 2016 14:08:22 +0800 From: Beilei Xing To: helin.zhang@intel.com Cc: dev@dpdk.org, Beilei Xing Date: Fri, 6 May 2016 14:07:28 +0800 Message-Id: <1462514861-29419-17-git-send-email-beilei.xing@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1462514861-29419-1-git-send-email-beilei.xing@intel.com> References: <1462514861-29419-1-git-send-email-beilei.xing@intel.com> Subject: [dpdk-dev] [PATCH 16/29] ixgbe/base: add new phy definitions 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: Fri, 06 May 2016 06:08:29 -0000 It adds new phy definitions. Signed-off-by: Beilei Xing --- drivers/net/ixgbe/base/ixgbe_phy.c | 16 +- drivers/net/ixgbe/base/ixgbe_type.h | 14 +- drivers/net/ixgbe/base/ixgbe_x550.c | 303 ++++++++++++++++++++++++++++++++++-- drivers/net/ixgbe/base/ixgbe_x550.h | 43 +++++ 4 files changed, 355 insertions(+), 21 deletions(-) diff --git a/drivers/net/ixgbe/base/ixgbe_phy.c b/drivers/net/ixgbe/base/ixgbe_phy.c index 6ed685e..ed1b14f 100644 --- a/drivers/net/ixgbe/base/ixgbe_phy.c +++ b/drivers/net/ixgbe/base/ixgbe_phy.c @@ -454,6 +454,9 @@ enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) case X557_PHY_ID: phy_type = ixgbe_phy_x550em_ext_t; break; + case IXGBE_M88E1500_E_PHY_ID: + phy_type = ixgbe_phy_m88; + break; default: phy_type = ixgbe_phy_unknown; break; @@ -615,13 +618,12 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, DEBUGFUNC("ixgbe_read_phy_reg_generic"); - if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { - status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type, - phy_data); - hw->mac.ops.release_swfw_sync(hw, gssr); - } else { - status = IXGBE_ERR_SWFW_SYNC; - } + if (hw->mac.ops.acquire_swfw_sync(hw, gssr)) + return IXGBE_ERR_SWFW_SYNC; + + status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); + + hw->mac.ops.release_swfw_sync(hw, gssr); return status; } diff --git a/drivers/net/ixgbe/base/ixgbe_type.h b/drivers/net/ixgbe/base/ixgbe_type.h index da1fe16..f1379be 100644 --- a/drivers/net/ixgbe/base/ixgbe_type.h +++ b/drivers/net/ixgbe/base/ixgbe_type.h @@ -1607,7 +1607,8 @@ struct ixgbe_dmac_config { #define ATH_PHY_ID 0x03429050 /* PHY Types */ -#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 +#define IXGBE_M88E1500_E_PHY_ID 0x01410DD0 +#define IXGBE_M88E1543_E_PHY_ID 0x01410EA0 /* Special PHY Init Routine */ #define IXGBE_PHY_INIT_OFFSET_NL 0x002B @@ -3250,6 +3251,7 @@ typedef u32 ixgbe_autoneg_advertised; /* Link speed */ typedef u32 ixgbe_link_speed; #define IXGBE_LINK_SPEED_UNKNOWN 0 +#define IXGBE_LINK_SPEED_10_FULL 0x0004 #define IXGBE_LINK_SPEED_100_FULL 0x0008 #define IXGBE_LINK_SPEED_1GB_FULL 0x0020 #define IXGBE_LINK_SPEED_2_5GB_FULL 0x0400 @@ -3574,6 +3576,14 @@ enum ixgbe_fc_mode { ixgbe_fc_default }; +/* Master/slave control */ +enum ixgbe_ms_type { + ixgbe_ms_hw_default = 0, + ixgbe_ms_force_master, + ixgbe_ms_force_slave, + ixgbe_ms_auto +}; + /* Smart Speed Settings */ #define IXGBE_SMARTSPEED_MAX_RETRIES 3 enum ixgbe_smart_speed { @@ -3949,6 +3959,8 @@ struct ixgbe_phy_info { bool reset_disable; ixgbe_autoneg_advertised autoneg_advertised; ixgbe_link_speed speeds_supported; + enum ixgbe_ms_type ms_type; + enum ixgbe_ms_type original_ms_type; enum ixgbe_smart_speed smart_speed; bool smart_speed_active; bool multispeed_fiber; diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c index 993ef16..a4b444b 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.c +++ b/drivers/net/ixgbe/base/ixgbe_x550.c @@ -329,6 +329,100 @@ STATIC void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) } /** + * ixgbe_read_phy_reg_mdi_22 - Read from a clause 22 PHY register without lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit address of PHY register to read + * @dev_type: always unused + * @phy_data: Pointer to read data from PHY register + */ +static s32 ixgbe_read_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr, + u32 dev_type, u16 *phy_data) +{ + u32 i, data, command; + UNREFERENCED_1PARAMETER(dev_type); + + /* Setup and write the read command */ + command = (reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_READ | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + + if (command & IXGBE_MSCA_MDI_COMMAND) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY read command did not complete.\n"); + return IXGBE_ERR_PHY; + } + + /* Read operation is complete. Get the data from MSRWD */ + data = IXGBE_READ_REG(hw, IXGBE_MSRWD); + data >>= IXGBE_MSRWD_READ_DATA_SHIFT; + *phy_data = (u16)data; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_write_phy_reg_mdi_22 - Write to a clause 22 PHY register without lock + * @hw: pointer to hardware structure + * @reg_addr: 32 bit PHY register to write + * @dev_type: always unused + * @phy_data: Data to write to the PHY register + */ +static s32 ixgbe_write_phy_reg_mdi_22(struct ixgbe_hw *hw, u32 reg_addr, + u32 dev_type, u16 phy_data) +{ + u32 i, command; + UNREFERENCED_1PARAMETER(dev_type); + + /* Put the data in the MDI single read and write data register*/ + IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); + + /* Setup and write the write command */ + command = (reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | + (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + + if (command & IXGBE_MSCA_MDI_COMMAND) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY write cmd didn't complete\n"); + return IXGBE_ERR_PHY; + } + + return IXGBE_SUCCESS; +} + +/** * ixgbe_identify_phy_1g - Get 1g PHY type based on device id * @hw: pointer to hardware structure * @@ -336,28 +430,33 @@ STATIC void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw) */ static s32 ixgbe_identify_phy_1g(struct ixgbe_hw *hw) { + u32 swfw_mask = hw->phy.phy_semaphore_mask; u16 phy_id_high; u16 phy_id_low; - u32 val; + s32 rc; - val = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, - hw->phy.addr, &phy_id_high); - if (val || phy_id_high == 0xFFFF) { - hw->phy.type = ixgbe_phy_sgmii; - return 0; - } + rc = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (rc) + return rc; - val = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, - hw->phy.addr, &phy_id_low); - if (val) - return val; + rc = ixgbe_read_phy_reg_mdi_22(hw, IXGBE_MDIO_PHY_ID_HIGH, 0, + &phy_id_high); + if (rc) + goto rel_out; + + rc = ixgbe_read_phy_reg_mdi_22(hw, IXGBE_MDIO_PHY_ID_LOW, 0, + &phy_id_low); + if (rc) + goto rel_out; hw->phy.id = (u32)phy_id_high << 16; hw->phy.id |= phy_id_low & IXGBE_PHY_REVISION_MASK; hw->phy.revision = (u32)phy_id_low & ~IXGBE_PHY_REVISION_MASK; - hw->phy.type = ixgbe_phy_m88; - return 0; +rel_out: + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + + return rc; } /** @@ -400,6 +499,11 @@ STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) return ixgbe_identify_phy_generic(hw); case IXGBE_DEV_ID_X550EM_A_1G_T: case IXGBE_DEV_ID_X550EM_A_1G_T_L: + hw->phy.phy_semaphore_mask = IXGBE_GSSR_TOKEN_SM; + if (hw->bus.lan_id) + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask |= IXGBE_GSSR_PHY0_SM; return ixgbe_identify_phy_1g(hw); default: break; @@ -1842,6 +1946,175 @@ STATIC s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw, } /** + * ixgbe_set_master_slave_mode - Set up PHY for master/slave mode + * @hw: pointer to hardware structure + * + * Must be called while holding the PHY semaphore and token + */ +static s32 ixgbe_set_master_slave_mode(struct ixgbe_hw *hw) +{ + u16 phy_data; + s32 rc; + + /* Resolve master/slave mode */ + rc = ixgbe_read_phy_reg_mdi_22(hw, IXGBE_M88E1500_1000T_CTRL, 0, + &phy_data); + if (rc) + return rc; + + /* load defaults for future use */ + if (phy_data & IXGBE_M88E1500_1000T_CTRL_MS_ENABLE) { + if (phy_data & IXGBE_M88E1500_1000T_CTRL_MS_VALUE) + hw->phy.original_ms_type = ixgbe_ms_force_master; + else + hw->phy.original_ms_type = ixgbe_ms_force_slave; + } else { + hw->phy.original_ms_type = ixgbe_ms_auto; + } + + switch (hw->phy.ms_type) { + case ixgbe_ms_force_master: + phy_data |= IXGBE_M88E1500_1000T_CTRL_MS_ENABLE; + phy_data |= IXGBE_M88E1500_1000T_CTRL_MS_VALUE; + break; + case ixgbe_ms_force_slave: + phy_data |= IXGBE_M88E1500_1000T_CTRL_MS_ENABLE; + phy_data &= ~IXGBE_M88E1500_1000T_CTRL_MS_VALUE; + break; + case ixgbe_ms_auto: + phy_data &= ~IXGBE_M88E1500_1000T_CTRL_MS_ENABLE; + break; + default: + break; + } + + return ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_1000T_CTRL, 0, + phy_data); +} + +/** + * ixgbe_reset_phy_m88_nolock - Reset m88 PHY without locking + * @hw: pointer to hardware structure + * + * Must be called while holding the PHY semaphore and token + */ +static s32 ixgbe_reset_phy_m88_nolock(struct ixgbe_hw *hw) +{ + s32 rc; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 1); + if (rc) + return rc; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_FIBER_CTRL, 0, + IXGBE_M88E1500_FIBER_CTRL_RESET | + IXGBE_M88E1500_FIBER_CTRL_DUPLEX_FULL | + IXGBE_M88E1500_FIBER_CTRL_SPEED_MSB); + if (rc) + goto res_out; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 18); + if (rc) + goto res_out; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_GEN_CTRL, 0, + IXGBE_M88E1500_GEN_CTRL_RESET | + IXGBE_M88E1500_GEN_CTRL_SGMII_COPPER); + if (rc) + goto res_out; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0); + if (rc) + goto res_out; + + rc = ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_COPPER_CTRL, 0, + IXGBE_M88E1500_COPPER_CTRL_RESET | + IXGBE_M88E1500_COPPER_CTRL_AN_EN | + IXGBE_M88E1500_COPPER_CTRL_RESTART_AN | + IXGBE_M88E1500_COPPER_CTRL_FULL_DUPLEX | + IXGBE_M88E1500_COPPER_CTRL_SPEED_MSB); + +res_out: + ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0); + return rc; +} + +/** + * ixgbe_reset_phy_m88 - Reset m88 PHY + * @hw: pointer to hardware structure + */ +static s32 ixgbe_reset_phy_m88(struct ixgbe_hw *hw) +{ + u32 swfw_mask = hw->phy.phy_semaphore_mask; + s32 rc; + + if (hw->phy.reset_disable || ixgbe_check_reset_blocked(hw)) + return IXGBE_SUCCESS; + + rc = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (rc) + return rc; + + rc = ixgbe_reset_phy_m88_nolock(hw); + + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return rc; +} + +/** + * ixgbe_setup_m88 - setup m88 PHY + * @hw: pointer to hardware structure + */ +static s32 ixgbe_setup_m88(struct ixgbe_hw *hw) +{ + u32 swfw_mask = hw->phy.phy_semaphore_mask; + struct ixgbe_phy_info *phy = &hw->phy; + u16 phy_data; + s32 rc; + + if (phy->reset_disable || ixgbe_check_reset_blocked(hw)) + return IXGBE_SUCCESS; + + rc = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); + if (rc) + return rc; + + rc = ixgbe_read_phy_reg_mdi_22(hw, IXGBE_M88E1500_PHY_SPEC_CTRL, 0, + &phy_data); + if (rc) + goto rel_out; + + /* Enable downshift and setting it to X6 */ + phy_data &= ~IXGBE_M88E1500_PSCR_DOWNSHIFT_ENABLE; + phy_data |= IXGBE_M88E1500_PSCR_DOWNSHIFT_6X; + phy_data |= IXGBE_M88E1500_PSCR_DOWNSHIFT_ENABLE; + rc = ixgbe_write_phy_reg_mdi_22(hw, + IXGBE_M88E1500_PHY_SPEC_CTRL, 0, + phy_data); + if (rc) + goto rel_out; + + ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0); + + /* Commit the changes */ + rc = ixgbe_reset_phy_m88_nolock(hw); + if (rc) { + DEBUGOUT("Error committing the PHY changes\n"); + goto rel_out; + } + + rc = ixgbe_set_master_slave_mode(hw); + + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return rc; + +rel_out: + ixgbe_write_phy_reg_mdi_22(hw, IXGBE_M88E1500_PAGE_ADDR, 0, 0); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return rc; +} + +/** * ixgbe_read_mng_if_sel_x550em - Read NW_MNG_IF_SEL register * @hw: pointer to hardware structure * @@ -1935,6 +2208,10 @@ s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) phy->ops.setup_link = NULL; break; case ixgbe_phy_m88: + phy->ops.setup_link = ixgbe_setup_m88; + phy->ops.read_reg_mdi = ixgbe_read_phy_reg_mdi_22; + phy->ops.write_reg_mdi = ixgbe_write_phy_reg_mdi_22; + phy->ops.reset = ixgbe_reset_phy_m88; break; default: break; diff --git a/drivers/net/ixgbe/base/ixgbe_x550.h b/drivers/net/ixgbe/base/ixgbe_x550.h index 2966c7b..a6ec3cb 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.h +++ b/drivers/net/ixgbe/base/ixgbe_x550.h @@ -36,6 +36,49 @@ POSSIBILITY OF SUCH DAMAGE. #include "ixgbe_type.h" +/* More phy definitions */ +#define IXGBE_M88E1500_COPPER_CTRL 0x0/* Page 0 reg */ +#define IXGBE_M88E1500_COPPER_CTRL_RESET 0x8000 +#define IXGBE_M88E1500_COPPER_CTRL_AN_EN 0x1000 +#define IXGBE_M88E1500_COPPER_CTRL_RESTART_AN 0x0200 +#define IXGBE_M88E1500_COPPER_CTRL_FULL_DUPLEX 0x0100 +#define IXGBE_M88E1500_COPPER_CTRL_SPEED_MSB 0x0040 +#define IXGBE_M88E1500_1000T_CTRL 0x09 /* 1000Base-T Ctrl Reg */ +/* 1=Configure PHY as Master 0=Configure PHY as Slave */ +#define IXGBE_M88E1500_1000T_CTRL_MS_VALUE 0x0800 +/* 1=Master/Slave manual config value 0=Automatic Master/Slave config */ +#define IXGBE_M88E1500_1000T_CTRL_MS_ENABLE 0x1000 +#define IXGBE_M88E1500_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ +#define IXGBE_M88E1500_AUTO_COPPER_SGMII 0x2 +#define IXGBE_M88E1500_AUTO_COPPER_BASEX 0x3 +#define IXGBE_M88E1500_STATUS_LINK 0x0004 /* Interface Link Bit */ +#define IXGBE_M88E1500_MAC_CTRL_1 0x10 +#define IXGBE_M88E1500_MAC_CTRL_1_MODE_MASK 0x0380 /* Mode Select */ +#define IXGBE_M88E1500_CFG_REG_1 0x0010 +#define IXGBE_M88E1500_CFG_REG_2 0x0011 +#define IXGBE_M88E1500_CFG_REG_3 0x0007 +#define IXGBE_M88E1500_MODE 0x0014 +#define IXGBE_M88E1500_PAGE_ADDR 0x16/* Page Offset reg */ +#define IXGBE_M88E1500_FIBER_CTRL 0x0/* Page 1 reg */ +#define IXGBE_M88E1500_FIBER_CTRL_RESET 0x8000 +#define IXGBE_M88E1500_FIBER_CTRL_SPEED_LSB 0x2000 +#define IXGBE_M88E1500_FIBER_CTRL_POWER_DOWN 0x0800 +#define IXGBE_M88E1500_FIBER_CTRL_DUPLEX_FULL 0x0100 +#define IXGBE_M88E1500_FIBER_CTRL_SPEED_MSB 0x0040 +#define IXGBE_M88E1500_EEE_CTRL_1 0x0/* Page 18 reg */ +#define IXGBE_M88E1500_EEE_CTRL_1_MS 0x0001/* EEE Master/Slave */ +#define IXGBE_M88E1500_GEN_CTRL 0x14/* Page 18 reg */ +#define IXGBE_M88E1500_GEN_CTRL_RESET 0x8000 +#define IXGBE_M88E1500_GEN_CTRL_SGMII_COPPER 0x0001/* Mode bits 0-2 */ + +/* M88E1500 Specific Registers */ +#define IXGBE_M88E1500_PHY_SPEC_CTRL 0x10 /* PHY Specific Ctrl Reg */ +#define IXGBE_M88E1500_PHY_SPEC_STATUS 0x11 /* PHY Specific Stat Reg */ + +#define IXGBE_M88E1500_PSCR_DOWNSHIFT_ENABLE 0x0800 +#define IXGBE_M88E1500_PSCR_DOWNSHIFT_MASK 0x7000 +#define IXGBE_M88E1500_PSCR_DOWNSHIFT_6X 0x5000 + s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw); s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw); s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw); -- 2.5.0