From patchwork Tue May 1 01:38:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Huang, Xiong" X-Patchwork-Id: 155989 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B6929B6FA7 for ; Tue, 1 May 2012 11:42:25 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757810Ab2EABj3 (ORCPT ); Mon, 30 Apr 2012 21:39:29 -0400 Received: from wolverine01.qualcomm.com ([199.106.114.254]:30376 "EHLO wolverine01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757758Ab2EABjX (ORCPT ); Mon, 30 Apr 2012 21:39:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=qca.qualcomm.com; i=xiong@qca.qualcomm.com; q=dns/txt; s=qcdkim; t=1335836363; x=1367372363; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=5RGGd7/ZHRB+viI7uEXUx2GqZLuKyGZBubZp4mbSqaY=; b=Ysq5IZpnw2wdFSP37EkXlxB6OvJBYVTeMgW+k04E8kyjcEU1R56AHMzt pjG5PNN9QnK4dCpFAoa4GifvlBddV5qzl3/0UJj7/yMv6NcLDwi2KyAUo Au4038mW1ylEpXFpEqJXoFeB6Gp3s3dR9tkrfwepkrHpVWTUk5DgvMNZa c=; X-IronPort-AV: E=McAfee;i="5400,1158,6697"; a="186394289" Received: from ironmsg03-l.qualcomm.com ([172.30.48.18]) by wolverine01.qualcomm.com with ESMTP; 30 Apr 2012 18:39:23 -0700 X-IronPort-AV: E=Sophos;i="4.75,507,1330934400"; d="scan'208";a="234248658" Received: from nasanexhc05.na.qualcomm.com ([172.30.48.2]) by Ironmsg03-L.qualcomm.com with ESMTP/TLS/RC4-SHA; 30 Apr 2012 18:39:23 -0700 Received: from qcmail1.qualcomm.com (172.30.48.1) by qcmail1.qualcomm.com (172.30.48.2) with Microsoft SMTP Server (TLS) id 14.2.283.3; Mon, 30 Apr 2012 18:39:20 -0700 Received: by qcmail1.qualcomm.com (sSMTP sendmail emulation); Tue, 01 May 2012 09:39:17 +0800 From: xiong To: , , CC: , , xiong Subject: [PATCH 02/10] atl1c: add PHY link event(up/down) patch Date: Tue, 1 May 2012 09:38:50 +0800 Message-ID: <1335836338-9425-3-git-send-email-xiong@qca.qualcomm.com> X-Mailer: git-send-email 1.7.7 In-Reply-To: <1335836338-9425-1-git-send-email-xiong@qca.qualcomm.com> References: <1335836338-9425-1-git-send-email-xiong@qca.qualcomm.com> MIME-Version: 1.0 X-Originating-IP: [172.30.48.1] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On some platforms the PHY settings need to change depending on the cable link status to get better stability. Signed-off-by: xiong Tested-by: Liu David --- drivers/net/ethernet/atheros/atl1c/atl1c.h | 1 + drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | 37 ++++++++++++++++ drivers/net/ethernet/atheros/atl1c/atl1c_hw.h | 1 + drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 53 +++++++++++++++++++++++ 4 files changed, 92 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c.h b/drivers/net/ethernet/atheros/atl1c/atl1c.h index acc2956..b2bf324 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c.h +++ b/drivers/net/ethernet/atheros/atl1c/atl1c.h @@ -436,6 +436,7 @@ struct atl1c_hw { bool phy_configured; bool re_autoneg; bool emi_ca; + bool msi_lnkpatch; /* link patch for specific platforms */ }; /* diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index 07f017f..209c179 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c @@ -848,3 +848,40 @@ int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc) return 0; } + + +/* configure phy after Link change Event */ +void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed) +{ + u16 phy_val; + bool adj_thresh = false; + + if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 || + hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2) + adj_thresh = true; + + if (link_speed != SPEED_0) { /* link up */ + /* az with brcm, half-amp */ + if (hw->nic_type == athr_l1d_2) { + atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6, + &phy_val); + phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN); + phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ? + AZ_ANADECT_LONG : AZ_ANADECT_DEF; + atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val); + } + /* threshold adjust */ + if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) { + atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP); + atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL, + L1D_SYSMODCTRL_IECHOADJ_DEF); + } + } else { /* link down */ + if (adj_thresh && hw->msi_lnkpatch) { + atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL, + SYSMODCTRL_IECHOADJ_DEF); + atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, + L1D_MSE16DB_DOWN); + } + } +} diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h index 0adb341..ea3f520 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.h @@ -63,6 +63,7 @@ int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr, u16 reg_addr, u16 phy_data); int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data); int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data); +void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed); /* hw-ids */ #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 25b7b00..6d5b374 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -258,6 +258,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) if (netif_msg_hw(adapter)) dev_warn(&pdev->dev, "stop mac failed\n"); atl1c_set_aspm(hw, SPEED_0); + atl1c_post_phy_linkchg(hw, SPEED_0); netif_carrier_off(netdev); netif_stop_queue(netdev); } else { @@ -274,6 +275,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) adapter->link_speed = speed; adapter->link_duplex = duplex; atl1c_set_aspm(hw, speed); + atl1c_post_phy_linkchg(hw, speed); atl1c_start_mac(adapter); if (netif_msg_link(adapter)) dev_info(&pdev->dev, @@ -697,6 +699,55 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) hw->link_cap_flags |= ATL1C_LINK_CAP_1000M; return 0; } + +struct atl1c_platform_patch { + u16 pci_did; + u8 pci_revid; + u16 subsystem_vid; + u16 subsystem_did; + u32 patch_flag; +#define ATL1C_LINK_PATCH 0x1 +}; +static const struct atl1c_platform_patch plats[] __devinitdata = { +{0x2060, 0xC1, 0x1019, 0x8152, 0x1}, +{0x2060, 0xC1, 0x1019, 0x2060, 0x1}, +{0x2060, 0xC1, 0x1019, 0xE000, 0x1}, +{0x2062, 0xC0, 0x1019, 0x8152, 0x1}, +{0x2062, 0xC0, 0x1019, 0x2062, 0x1}, +{0x2062, 0xC0, 0x1458, 0xE000, 0x1}, +{0x2062, 0xC1, 0x1019, 0x8152, 0x1}, +{0x2062, 0xC1, 0x1019, 0x2062, 0x1}, +{0x2062, 0xC1, 0x1458, 0xE000, 0x1}, +{0x2062, 0xC1, 0x1565, 0x2802, 0x1}, +{0x2062, 0xC1, 0x1565, 0x2801, 0x1}, +{0x1073, 0xC0, 0x1019, 0x8151, 0x1}, +{0x1073, 0xC0, 0x1019, 0x1073, 0x1}, +{0x1073, 0xC0, 0x1458, 0xE000, 0x1}, +{0x1083, 0xC0, 0x1458, 0xE000, 0x1}, +{0x1083, 0xC0, 0x1019, 0x8151, 0x1}, +{0x1083, 0xC0, 0x1019, 0x1083, 0x1}, +{0x1083, 0xC0, 0x1462, 0x7680, 0x1}, +{0x1083, 0xC0, 0x1565, 0x2803, 0x1}, +{0}, +}; + +static void __devinit atl1c_patch_assign(struct atl1c_hw *hw) +{ + int i = 0; + + hw->msi_lnkpatch = false; + + while (plats[i].pci_did != 0) { + if (plats[i].pci_did == hw->device_id && + plats[i].pci_revid == hw->revision_id && + plats[i].subsystem_vid == hw->subsystem_vendor_id && + plats[i].subsystem_did == hw->subsystem_id) { + if (plats[i].patch_flag & ATL1C_LINK_PATCH) + hw->msi_lnkpatch = true; + } + i++; + } +} /* * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter) * @adapter: board private structure to initialize @@ -732,6 +783,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) dev_err(&pdev->dev, "set mac function pointers failed\n"); return -1; } + atl1c_patch_assign(hw); + hw->intr_mask = IMR_NORMAL_MASK; hw->phy_configured = false; hw->preamble_len = 7;