Commit 23e500e8 authored by Nikita Danilov's avatar Nikita Danilov Committed by David S. Miller

net: atlantic: disable PTP on AQC111, AQC112

This patch disables PTP on AQC111 and AQC112 due to a known HW issue,
which can cause datapath issues.

Ideally PTP block should have been disabled via PHY provisioning, but
unfortunately many units have been shipped with enabled PTP block.
Thus, we have to work around this in the driver.

Fixes: dbcd6806 ("net: aquantia: add support for Phy access")
Signed-off-by: default avatarNikita Danilov <ndanilov@marvell.com>
Signed-off-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0b4a66a3
......@@ -64,6 +64,7 @@ struct aq_hw_caps_s {
u8 rx_rings;
bool flow_control;
bool is_64_dma;
u32 quirks;
u32 priv_data_len;
};
......
......@@ -415,6 +415,15 @@ int aq_nic_init(struct aq_nic_s *self)
self->aq_nic_cfg.aq_hw_caps->media_type == AQ_HW_MEDIA_TYPE_TP) {
self->aq_hw->phy_id = HW_ATL_PHY_ID_MAX;
err = aq_phy_init(self->aq_hw);
/* Disable the PTP on NICs where it's known to cause datapath
* problems.
* Ideally this should have been done by PHY provisioning, but
* many units have been shipped with enabled PTP block already.
*/
if (self->aq_nic_cfg.aq_hw_caps->quirks & AQ_NIC_QUIRK_BAD_PTP)
if (self->aq_hw->phy_id != HW_ATL_PHY_ID_MAX)
aq_phy_disable_ptp(self->aq_hw);
}
for (i = 0U; i < self->aq_vecs; i++) {
......
......@@ -81,6 +81,8 @@ struct aq_nic_cfg_s {
#define AQ_NIC_FLAG_ERR_UNPLUG 0x40000000U
#define AQ_NIC_FLAG_ERR_HW 0x80000000U
#define AQ_NIC_QUIRK_BAD_PTP BIT(0)
#define AQ_NIC_WOL_MODES (WAKE_MAGIC |\
WAKE_PHY)
......
// SPDX-License-Identifier: GPL-2.0-only
/* aQuantia Corporation Network Driver
* Copyright (C) 2018-2019 aQuantia Corporation. All rights reserved
/* Atlantic Network Driver
*
* Copyright (C) 2018-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
#include "aq_phy.h"
#define HW_ATL_PTP_DISABLE_MSK BIT(10)
bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw)
{
int err = 0;
......@@ -145,3 +149,24 @@ bool aq_phy_init(struct aq_hw_s *aq_hw)
return true;
}
void aq_phy_disable_ptp(struct aq_hw_s *aq_hw)
{
static const u16 ptp_registers[] = {
0x031e,
0x031d,
0x031c,
0x031b,
};
u16 val;
int i;
for (i = 0; i < ARRAY_SIZE(ptp_registers); i++) {
val = aq_phy_read_reg(aq_hw, MDIO_MMD_VEND1,
ptp_registers[i]);
aq_phy_write_reg(aq_hw, MDIO_MMD_VEND1,
ptp_registers[i],
val & ~HW_ATL_PTP_DISABLE_MSK);
}
}
/* SPDX-License-Identifier: GPL-2.0-only */
/* aQuantia Corporation Network Driver
* Copyright (C) 2018-2019 aQuantia Corporation. All rights reserved
/* Atlantic Network Driver
*
* Copyright (C) 2018-2019 aQuantia Corporation
* Copyright (C) 2019-2020 Marvell International Ltd.
*/
#ifndef AQ_PHY_H
......@@ -29,4 +31,6 @@ bool aq_phy_init_phy_id(struct aq_hw_s *aq_hw);
bool aq_phy_init(struct aq_hw_s *aq_hw);
void aq_phy_disable_ptp(struct aq_hw_s *aq_hw);
#endif /* AQ_PHY_H */
......@@ -93,6 +93,25 @@ const struct aq_hw_caps_s hw_atl_b0_caps_aqc109 = {
AQ_NIC_RATE_100M,
};
const struct aq_hw_caps_s hw_atl_b0_caps_aqc111 = {
DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_5G |
AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_BAD_PTP,
};
const struct aq_hw_caps_s hw_atl_b0_caps_aqc112 = {
DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
.media_type = AQ_HW_MEDIA_TYPE_TP,
.link_speed_msk = AQ_NIC_RATE_2G5 |
AQ_NIC_RATE_1G |
AQ_NIC_RATE_100M,
.quirks = AQ_NIC_QUIRK_BAD_PTP,
};
static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
{
int err = 0;
......
......@@ -18,17 +18,15 @@ extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc100;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc107;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc108;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc109;
#define hw_atl_b0_caps_aqc111 hw_atl_b0_caps_aqc108
#define hw_atl_b0_caps_aqc112 hw_atl_b0_caps_aqc109
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc111;
extern const struct aq_hw_caps_s hw_atl_b0_caps_aqc112;
#define hw_atl_b0_caps_aqc100s hw_atl_b0_caps_aqc100
#define hw_atl_b0_caps_aqc107s hw_atl_b0_caps_aqc107
#define hw_atl_b0_caps_aqc108s hw_atl_b0_caps_aqc108
#define hw_atl_b0_caps_aqc109s hw_atl_b0_caps_aqc109
#define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc108
#define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc109
#define hw_atl_b0_caps_aqc111s hw_atl_b0_caps_aqc111
#define hw_atl_b0_caps_aqc112s hw_atl_b0_caps_aqc112
extern const struct aq_hw_ops hw_atl_ops_b0;
......
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