Commit 903d7ce0 authored by Huang, Xiong's avatar Huang, Xiong Committed by David S. Miller

atl1c: add PHY link event(up/down) patch

On some platforms the PHY settings need to change depending on the
cable link status to get better stability.
Signed-off-by: default avatarxiong <xiong@qca.qualcomm.com>
Tested-by: default avatarLiu David <dwliu@qca.qualcomm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7cb6a291
...@@ -436,6 +436,7 @@ struct atl1c_hw { ...@@ -436,6 +436,7 @@ struct atl1c_hw {
bool phy_configured; bool phy_configured;
bool re_autoneg; bool re_autoneg;
bool emi_ca; bool emi_ca;
bool msi_lnkpatch; /* link patch for specific platforms */
}; };
/* /*
......
...@@ -848,3 +848,40 @@ int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc) ...@@ -848,3 +848,40 @@ int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
return 0; 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);
}
}
}
...@@ -63,6 +63,7 @@ int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr, ...@@ -63,6 +63,7 @@ int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
u16 reg_addr, u16 phy_data); u16 reg_addr, u16 phy_data);
int atl1c_read_phy_dbg(struct atl1c_hw *hw, 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); 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 */ /* hw-ids */
#define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062
......
...@@ -258,6 +258,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) ...@@ -258,6 +258,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
if (netif_msg_hw(adapter)) if (netif_msg_hw(adapter))
dev_warn(&pdev->dev, "stop mac failed\n"); dev_warn(&pdev->dev, "stop mac failed\n");
atl1c_set_aspm(hw, SPEED_0); atl1c_set_aspm(hw, SPEED_0);
atl1c_post_phy_linkchg(hw, SPEED_0);
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_stop_queue(netdev); netif_stop_queue(netdev);
} else { } else {
...@@ -274,6 +275,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) ...@@ -274,6 +275,7 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
adapter->link_speed = speed; adapter->link_speed = speed;
adapter->link_duplex = duplex; adapter->link_duplex = duplex;
atl1c_set_aspm(hw, speed); atl1c_set_aspm(hw, speed);
atl1c_post_phy_linkchg(hw, speed);
atl1c_start_mac(adapter); atl1c_start_mac(adapter);
if (netif_msg_link(adapter)) if (netif_msg_link(adapter))
dev_info(&pdev->dev, dev_info(&pdev->dev,
...@@ -697,6 +699,55 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) ...@@ -697,6 +699,55 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw)
hw->link_cap_flags |= ATL1C_LINK_CAP_1000M; hw->link_cap_flags |= ATL1C_LINK_CAP_1000M;
return 0; 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) * atl1c_sw_init - Initialize general software structures (struct atl1c_adapter)
* @adapter: board private structure to initialize * @adapter: board private structure to initialize
...@@ -732,6 +783,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) ...@@ -732,6 +783,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter)
dev_err(&pdev->dev, "set mac function pointers failed\n"); dev_err(&pdev->dev, "set mac function pointers failed\n");
return -1; return -1;
} }
atl1c_patch_assign(hw);
hw->intr_mask = IMR_NORMAL_MASK; hw->intr_mask = IMR_NORMAL_MASK;
hw->phy_configured = false; hw->phy_configured = false;
hw->preamble_len = 7; hw->preamble_len = 7;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment