You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
559 lines
20 KiB
559 lines
20 KiB
From 464e318856bdfae595c18f7ba50968174696a2dc Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:37:02 -0500
|
|
Subject: [PATCH 045/139] [netdrv] net: atlantic: loopback tests via private
|
|
flags
|
|
|
|
Message-id: <1604687916-15087-46-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338473
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 045/139] net: atlantic: loopback tests via private flags
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit ea4b4d7fc1065165874c27b8add252e04d104137
|
|
Author: Igor Russkikh <irusskikh@marvell.com>
|
|
Date: Thu Nov 7 22:41:58 2019 +0000
|
|
|
|
net: atlantic: loopback tests via private flags
|
|
|
|
Here we add a number of ethtool private flags
|
|
to allow enabling various loopbacks on HW.
|
|
|
|
Thats useful for verification and bringup works.
|
|
|
|
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
.../net/ethernet/aquantia/atlantic/aq_ethtool.c | 55 +++++++++++++++++++++-
|
|
.../net/ethernet/aquantia/atlantic/aq_ethtool.h | 1 +
|
|
drivers/net/ethernet/aquantia/atlantic/aq_hw.h | 18 +++++++
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 45 ++++++++++++++++++
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.h | 2 +
|
|
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 30 +++++++++++-
|
|
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c | 26 ++++++++++
|
|
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h | 11 +++++
|
|
.../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | 54 +++++++++++++++++++++
|
|
.../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 32 +++++++++++++
|
|
10 files changed, 272 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
index 2f877fb46615..963bf6e67573 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
|
|
@@ -92,6 +92,14 @@ static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
|
|
"Queue[%d] InErrors",
|
|
};
|
|
|
|
+static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
|
|
+ "DMASystemLoopback",
|
|
+ "PKTSystemLoopback",
|
|
+ "DMANetworkLoopback",
|
|
+ "PHYInternalLoopback",
|
|
+ "PHYExternalLoopback",
|
|
+};
|
|
+
|
|
static void aq_ethtool_stats(struct net_device *ndev,
|
|
struct ethtool_stats *stats, u64 *data)
|
|
{
|
|
@@ -137,7 +145,8 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
|
|
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
|
|
u8 *p = data;
|
|
|
|
- if (stringset == ETH_SS_STATS) {
|
|
+ switch (stringset) {
|
|
+ case ETH_SS_STATS:
|
|
memcpy(p, aq_ethtool_stat_names,
|
|
sizeof(aq_ethtool_stat_names));
|
|
p = p + sizeof(aq_ethtool_stat_names);
|
|
@@ -150,6 +159,11 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
|
|
p += ETH_GSTRING_LEN;
|
|
}
|
|
}
|
|
+ break;
|
|
+ case ETH_SS_PRIV_FLAGS:
|
|
+ memcpy(p, aq_ethtool_priv_flag_names,
|
|
+ sizeof(aq_ethtool_priv_flag_names));
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -193,6 +207,9 @@ static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
|
|
ret = ARRAY_SIZE(aq_ethtool_stat_names) +
|
|
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
|
break;
|
|
+ case ETH_SS_PRIV_FLAGS:
|
|
+ ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
|
|
+ break;
|
|
default:
|
|
ret = -EOPNOTSUPP;
|
|
}
|
|
@@ -650,6 +667,40 @@ static void aq_set_msg_level(struct net_device *ndev, u32 data)
|
|
aq_nic->msg_enable = data;
|
|
}
|
|
|
|
+u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
|
|
+{
|
|
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
|
+
|
|
+ return aq_nic->aq_nic_cfg.priv_flags;
|
|
+}
|
|
+
|
|
+int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
|
|
+{
|
|
+ struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
|
+ struct aq_nic_cfg_s *cfg;
|
|
+ u32 priv_flags;
|
|
+
|
|
+ cfg = aq_nic_get_cfg(aq_nic);
|
|
+ priv_flags = cfg->priv_flags;
|
|
+
|
|
+ if (flags & ~AQ_PRIV_FLAGS_MASK)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ cfg->priv_flags = flags;
|
|
+
|
|
+ if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
|
|
+ if (netif_running(ndev)) {
|
|
+ dev_close(ndev);
|
|
+
|
|
+ dev_open(ndev, NULL);
|
|
+ }
|
|
+ } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
|
|
+ aq_nic_set_loopback(aq_nic);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
const struct ethtool_ops aq_ethtool_ops = {
|
|
.get_link = aq_ethtool_get_link,
|
|
.get_regs_len = aq_ethtool_get_regs_len,
|
|
@@ -676,6 +727,8 @@ const struct ethtool_ops aq_ethtool_ops = {
|
|
.set_msglevel = aq_set_msg_level,
|
|
.get_sset_count = aq_ethtool_get_sset_count,
|
|
.get_ethtool_stats = aq_ethtool_stats,
|
|
+ .get_priv_flags = aq_ethtool_get_priv_flags,
|
|
+ .set_priv_flags = aq_ethtool_set_priv_flags,
|
|
.get_link_ksettings = aq_ethtool_get_link_ksettings,
|
|
.set_link_ksettings = aq_ethtool_set_link_ksettings,
|
|
.get_coalesce = aq_ethtool_get_coalesce,
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
|
|
index 632b5531db4a..6d5be5ebeb13 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.h
|
|
@@ -12,5 +12,6 @@
|
|
#include "aq_common.h"
|
|
|
|
extern const struct ethtool_ops aq_ethtool_ops;
|
|
+#define AQ_PRIV_FLAGS_MASK (AQ_HW_LOOPBACK_MASK)
|
|
|
|
#endif /* AQ_ETHTOOL_H */
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
|
|
index b2203f43e00a..e9cf5913b70a 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
|
|
@@ -122,6 +122,20 @@ struct aq_stats_s {
|
|
#define AQ_HW_LED_BLINK 0x2U
|
|
#define AQ_HW_LED_DEFAULT 0x0U
|
|
|
|
+enum aq_priv_flags {
|
|
+ AQ_HW_LOOPBACK_DMA_SYS,
|
|
+ AQ_HW_LOOPBACK_PKT_SYS,
|
|
+ AQ_HW_LOOPBACK_DMA_NET,
|
|
+ AQ_HW_LOOPBACK_PHYINT_SYS,
|
|
+ AQ_HW_LOOPBACK_PHYEXT_SYS,
|
|
+};
|
|
+
|
|
+#define AQ_HW_LOOPBACK_MASK (BIT(AQ_HW_LOOPBACK_DMA_SYS) |\
|
|
+ BIT(AQ_HW_LOOPBACK_PKT_SYS) |\
|
|
+ BIT(AQ_HW_LOOPBACK_DMA_NET) |\
|
|
+ BIT(AQ_HW_LOOPBACK_PHYINT_SYS) |\
|
|
+ BIT(AQ_HW_LOOPBACK_PHYEXT_SYS))
|
|
+
|
|
struct aq_hw_s {
|
|
atomic_t flags;
|
|
u8 rbl_enabled:1;
|
|
@@ -280,6 +294,8 @@ struct aq_hw_ops {
|
|
u64 *timestamp);
|
|
|
|
int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc);
|
|
+
|
|
+ int (*hw_set_loopback)(struct aq_hw_s *self, u32 mode, bool enable);
|
|
};
|
|
|
|
struct aq_fw_ops {
|
|
@@ -310,6 +326,8 @@ struct aq_fw_ops {
|
|
|
|
int (*led_control)(struct aq_hw_s *self, u32 mode);
|
|
|
|
+ int (*set_phyloopback)(struct aq_hw_s *self, u32 mode, bool enable);
|
|
+
|
|
int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
|
|
u8 *mac);
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
index 8f83e91f8146..5462b7efcf2f 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
@@ -406,6 +406,8 @@ int aq_nic_start(struct aq_nic_s *self)
|
|
|
|
INIT_WORK(&self->service_task, aq_nic_service_task);
|
|
|
|
+ aq_nic_set_loopback(self);
|
|
+
|
|
timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0);
|
|
aq_nic_service_timer_cb(&self->service_timer);
|
|
|
|
@@ -625,6 +627,11 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
|
|
|
|
aq_ring_update_queue_state(ring);
|
|
|
|
+ if (self->aq_nic_cfg.priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
|
|
+ err = NETDEV_TX_BUSY;
|
|
+ goto err_exit;
|
|
+ }
|
|
+
|
|
/* Above status update may stop the queue. Check this. */
|
|
if (__netif_subqueue_stopped(self->ndev, ring->idx)) {
|
|
err = NETDEV_TX_BUSY;
|
|
@@ -973,6 +980,44 @@ u32 aq_nic_get_fw_version(struct aq_nic_s *self)
|
|
return fw_version;
|
|
}
|
|
|
|
+int aq_nic_set_loopback(struct aq_nic_s *self)
|
|
+{
|
|
+ struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
|
|
+
|
|
+ if (!self->aq_hw_ops->hw_set_loopback ||
|
|
+ !self->aq_fw_ops->set_phyloopback)
|
|
+ return -ENOTSUPP;
|
|
+
|
|
+ mutex_lock(&self->fwreq_mutex);
|
|
+ self->aq_hw_ops->hw_set_loopback(self->aq_hw,
|
|
+ AQ_HW_LOOPBACK_DMA_SYS,
|
|
+ !!(cfg->priv_flags &
|
|
+ BIT(AQ_HW_LOOPBACK_DMA_SYS)));
|
|
+
|
|
+ self->aq_hw_ops->hw_set_loopback(self->aq_hw,
|
|
+ AQ_HW_LOOPBACK_PKT_SYS,
|
|
+ !!(cfg->priv_flags &
|
|
+ BIT(AQ_HW_LOOPBACK_PKT_SYS)));
|
|
+
|
|
+ self->aq_hw_ops->hw_set_loopback(self->aq_hw,
|
|
+ AQ_HW_LOOPBACK_DMA_NET,
|
|
+ !!(cfg->priv_flags &
|
|
+ BIT(AQ_HW_LOOPBACK_DMA_NET)));
|
|
+
|
|
+ self->aq_fw_ops->set_phyloopback(self->aq_hw,
|
|
+ AQ_HW_LOOPBACK_PHYINT_SYS,
|
|
+ !!(cfg->priv_flags &
|
|
+ BIT(AQ_HW_LOOPBACK_PHYINT_SYS)));
|
|
+
|
|
+ self->aq_fw_ops->set_phyloopback(self->aq_hw,
|
|
+ AQ_HW_LOOPBACK_PHYEXT_SYS,
|
|
+ !!(cfg->priv_flags &
|
|
+ BIT(AQ_HW_LOOPBACK_PHYEXT_SYS)));
|
|
+ mutex_unlock(&self->fwreq_mutex);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int aq_nic_stop(struct aq_nic_s *self)
|
|
{
|
|
struct aq_vec_s *aq_vec = NULL;
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
index 527273502d54..bb4957a31498 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
|
|
@@ -46,6 +46,7 @@ struct aq_nic_cfg_s {
|
|
bool is_polling;
|
|
bool is_rss;
|
|
bool is_lro;
|
|
+ u32 priv_flags;
|
|
u8 tcs;
|
|
struct aq_rss_parameters aq_rss;
|
|
u32 eee_speeds;
|
|
@@ -158,6 +159,7 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
|
|
const struct ethtool_link_ksettings *cmd);
|
|
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
|
|
u32 aq_nic_get_fw_version(struct aq_nic_s *self);
|
|
+int aq_nic_set_loopback(struct aq_nic_s *self);
|
|
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
|
|
void aq_nic_shutdown(struct aq_nic_s *self);
|
|
u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
index c7297ca03624..1165689af37d 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
@@ -1427,6 +1427,30 @@ static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
|
|
return aq_hw_err_from_flags(self);
|
|
}
|
|
|
|
+static int hw_atl_b0_set_loopback(struct aq_hw_s *self, u32 mode, bool enable)
|
|
+{
|
|
+ switch (mode) {
|
|
+ case AQ_HW_LOOPBACK_DMA_SYS:
|
|
+ hw_atl_tpb_tx_dma_sys_lbk_en_set(self, enable);
|
|
+ hw_atl_rpb_dma_sys_lbk_set(self, enable);
|
|
+ break;
|
|
+ case AQ_HW_LOOPBACK_PKT_SYS:
|
|
+ hw_atl_tpo_tx_pkt_sys_lbk_en_set(self, enable);
|
|
+ hw_atl_rpf_tpo_to_rpf_sys_lbk_set(self, enable);
|
|
+ break;
|
|
+ case AQ_HW_LOOPBACK_DMA_NET:
|
|
+ hw_atl_rpf_vlan_prom_mode_en_set(self, enable);
|
|
+ hw_atl_rpfl2promiscuous_mode_en_set(self, enable);
|
|
+ hw_atl_tpb_tx_tx_clk_gate_en_set(self, !enable);
|
|
+ hw_atl_tpb_tx_dma_net_lbk_en_set(self, enable);
|
|
+ hw_atl_rpb_dma_net_lbk_set(self, enable);
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
const struct aq_hw_ops hw_atl_ops_b0 = {
|
|
.hw_set_mac_address = hw_atl_b0_hw_mac_addr_set,
|
|
.hw_init = hw_atl_b0_hw_init,
|
|
@@ -1481,5 +1505,9 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
|
|
.rx_extract_ts = hw_atl_b0_rx_extract_ts,
|
|
.extract_hwts = hw_atl_b0_extract_hwts,
|
|
.hw_set_offload = hw_atl_b0_hw_offload_set,
|
|
- .hw_set_fc = hw_atl_b0_set_fc,
|
|
+ .hw_get_hw_stats = hw_atl_utils_get_hw_stats,
|
|
+ .hw_get_fw_version = hw_atl_utils_get_fw_version,
|
|
+ .hw_set_offload = hw_atl_b0_hw_offload_set,
|
|
+ .hw_set_loopback = hw_atl_b0_set_loopback,
|
|
+ .hw_set_fc = hw_atl_b0_set_fc,
|
|
};
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
|
|
index 6cadc9054544..d1f68fc16291 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
|
|
@@ -563,6 +563,13 @@ void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk)
|
|
HW_ATL_RPB_DMA_SYS_LBK_SHIFT, dma_sys_lbk);
|
|
}
|
|
|
|
+void hw_atl_rpb_dma_net_lbk_set(struct aq_hw_s *aq_hw, u32 dma_net_lbk)
|
|
+{
|
|
+ aq_hw_write_reg_bit(aq_hw, HW_ATL_RPB_DMA_NET_LBK_ADR,
|
|
+ HW_ATL_RPB_DMA_NET_LBK_MSK,
|
|
+ HW_ATL_RPB_DMA_NET_LBK_SHIFT, dma_net_lbk);
|
|
+}
|
|
+
|
|
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
|
|
u32 rx_traf_class_mode)
|
|
{
|
|
@@ -1341,7 +1348,26 @@ void hw_atl_tpb_tx_dma_sys_lbk_en_set(struct aq_hw_s *aq_hw, u32 tx_dma_sys_lbk_
|
|
tx_dma_sys_lbk_en);
|
|
}
|
|
|
|
+void hw_atl_tpb_tx_dma_net_lbk_en_set(struct aq_hw_s *aq_hw,
|
|
+ u32 tx_dma_net_lbk_en)
|
|
+{
|
|
+ aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_DMA_NET_LBK_ADR,
|
|
+ HW_ATL_TPB_DMA_NET_LBK_MSK,
|
|
+ HW_ATL_TPB_DMA_NET_LBK_SHIFT,
|
|
+ tx_dma_net_lbk_en);
|
|
+}
|
|
+
|
|
+void hw_atl_tpb_tx_tx_clk_gate_en_set(struct aq_hw_s *aq_hw,
|
|
+ u32 tx_clk_gate_en)
|
|
+{
|
|
+ aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TX_CLK_GATE_EN_ADR,
|
|
+ HW_ATL_TPB_TX_CLK_GATE_EN_MSK,
|
|
+ HW_ATL_TPB_TX_CLK_GATE_EN_SHIFT,
|
|
+ tx_clk_gate_en);
|
|
+}
|
|
+
|
|
void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
|
|
+
|
|
u32 tx_pkt_buff_size_per_tc, u32 buffer)
|
|
{
|
|
aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBBUF_SIZE_ADR(buffer),
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
|
|
index 5750b0c9cae7..62992b23c0e8 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
|
|
@@ -288,6 +288,9 @@ void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw,
|
|
/* set dma system loopback */
|
|
void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk);
|
|
|
|
+/* set dma network loopback */
|
|
+void hw_atl_rpb_dma_net_lbk_set(struct aq_hw_s *aq_hw, u32 dma_net_lbk);
|
|
+
|
|
/* set rx traffic class mode */
|
|
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
|
|
u32 rx_traf_class_mode);
|
|
@@ -629,6 +632,14 @@ void hw_atl_tpb_tx_buff_lo_threshold_per_tc_set(struct aq_hw_s *aq_hw,
|
|
/* set tx dma system loopback enable */
|
|
void hw_atl_tpb_tx_dma_sys_lbk_en_set(struct aq_hw_s *aq_hw, u32 tx_dma_sys_lbk_en);
|
|
|
|
+/* set tx dma network loopback enable */
|
|
+void hw_atl_tpb_tx_dma_net_lbk_en_set(struct aq_hw_s *aq_hw,
|
|
+ u32 tx_dma_net_lbk_en);
|
|
+
|
|
+/* set tx clock gating enable */
|
|
+void hw_atl_tpb_tx_tx_clk_gate_en_set(struct aq_hw_s *aq_hw,
|
|
+ u32 tx_clk_gate_en);
|
|
+
|
|
/* set tx packet buffer size (per tc) */
|
|
void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw,
|
|
u32 tx_pkt_buff_size_per_tc,
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
|
|
index ec3bcdcefc4d..18de2f7b8959 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
|
|
@@ -554,6 +554,24 @@
|
|
/* default value of bitfield dma_sys_loopback */
|
|
#define HW_ATL_RPB_DMA_SYS_LBK_DEFAULT 0x0
|
|
|
|
+/* rx dma_net_loopback bitfield definitions
|
|
+ * preprocessor definitions for the bitfield "dma_net_loopback".
|
|
+ * port="pif_rpb_dma_net_lbk_i"
|
|
+ */
|
|
+
|
|
+/* register address for bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_ADR 0x00005000
|
|
+/* bitmask for bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_MSK 0x00000010
|
|
+/* inverted bitmask for bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_MSKN 0xffffffef
|
|
+/* lower bit position of bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_SHIFT 4
|
|
+/* width of bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_WIDTH 1
|
|
+/* default value of bitfield dma_net_loopback */
|
|
+#define HW_ATL_RPB_DMA_NET_LBK_DEFAULT 0x0
|
|
+
|
|
/* rx rx_tc_mode bitfield definitions
|
|
* preprocessor definitions for the bitfield "rx_tc_mode".
|
|
* port="pif_rpb_rx_tc_mode_i,pif_rpf_rx_tc_mode_i"
|
|
@@ -2107,6 +2125,24 @@
|
|
/* default value of bitfield dma_sys_loopback */
|
|
#define HW_ATL_TPB_DMA_SYS_LBK_DEFAULT 0x0
|
|
|
|
+/* tx dma_net_loopback bitfield definitions
|
|
+ * preprocessor definitions for the bitfield "dma_net_loopback".
|
|
+ * port="pif_tpb_dma_net_lbk_i"
|
|
+ */
|
|
+
|
|
+/* register address for bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_ADR 0x00007000
|
|
+/* bitmask for bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_MSK 0x00000010
|
|
+/* inverted bitmask for bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_MSKN 0xffffffef
|
|
+/* lower bit position of bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_SHIFT 4
|
|
+/* width of bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_WIDTH 1
|
|
+/* default value of bitfield dma_net_loopback */
|
|
+#define HW_ATL_TPB_DMA_NET_LBK_DEFAULT 0x0
|
|
+
|
|
/* tx tx{b}_buf_size[7:0] bitfield definitions
|
|
* preprocessor definitions for the bitfield "tx{b}_buf_size[7:0]".
|
|
* parameter: buffer {b} | stride size 0x10 | range [0, 7]
|
|
@@ -2144,6 +2180,24 @@
|
|
/* default value of bitfield tx_scp_ins_en */
|
|
#define HW_ATL_TPB_TX_SCP_INS_EN_DEFAULT 0x0
|
|
|
|
+/* tx tx_clk_gate_en bitfield definitions
|
|
+ * preprocessor definitions for the bitfield "tx_clk_gate_en".
|
|
+ * port="pif_tpb_clk_gate_en_i"
|
|
+ */
|
|
+
|
|
+/* register address for bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_ADR 0x00007900
|
|
+/* bitmask for bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_MSK 0x00000010
|
|
+/* inverted bitmask for bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_MSKN 0xffffffef
|
|
+/* lower bit position of bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_SHIFT 4
|
|
+/* width of bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_WIDTH 1
|
|
+/* default value of bitfield tx_clk_gate_en */
|
|
+#define HW_ATL_TPB_TX_CLK_GATE_EN_DEFAULT 0x1
|
|
+
|
|
/* tx ipv4_chk_en bitfield definitions
|
|
* preprocessor definitions for the bitfield "ipv4_chk_en".
|
|
* port="pif_tpo_ipv4_chk_en_i"
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
|
|
index 3dbce03c5a94..feef2b0177b2 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
|
|
@@ -42,6 +42,9 @@
|
|
#define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE)
|
|
#define HW_ATL_FW2X_CTRL_TEMPERATURE BIT(CTRL_TEMPERATURE)
|
|
#define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE)
|
|
+#define HW_ATL_FW2X_CTRL_INT_LOOPBACK BIT(CTRL_INT_LOOPBACK)
|
|
+#define HW_ATL_FW2X_CTRL_EXT_LOOPBACK BIT(CTRL_EXT_LOOPBACK)
|
|
+#define HW_ATL_FW2X_CTRL_DOWNSHIFT BIT(CTRL_DOWNSHIFT)
|
|
#define HW_ATL_FW2X_CTRL_FORCE_RECONNECT BIT(CTRL_FORCE_RECONNECT)
|
|
|
|
#define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE)
|
|
@@ -53,6 +56,7 @@
|
|
#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E
|
|
|
|
#define HW_ATL_FW_VER_LED 0x03010026U
|
|
+#define HW_ATL_FW_VER_MEDIA_CONTROL 0x0301005aU
|
|
|
|
struct __packed fw2x_msg_wol_pattern {
|
|
u8 mask[16];
|
|
@@ -539,6 +543,33 @@ static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
|
|
return 0;
|
|
}
|
|
|
|
+static int aq_fw2x_set_phyloopback(struct aq_hw_s *self, u32 mode, bool enable)
|
|
+{
|
|
+ u32 mpi_opts;
|
|
+
|
|
+ switch (mode) {
|
|
+ case AQ_HW_LOOPBACK_PHYINT_SYS:
|
|
+ mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
|
|
+ if (enable)
|
|
+ mpi_opts |= HW_ATL_FW2X_CTRL_INT_LOOPBACK;
|
|
+ else
|
|
+ mpi_opts &= ~HW_ATL_FW2X_CTRL_INT_LOOPBACK;
|
|
+ aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
|
|
+ break;
|
|
+ case AQ_HW_LOOPBACK_PHYEXT_SYS:
|
|
+ mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
|
|
+ if (enable)
|
|
+ mpi_opts |= HW_ATL_FW2X_CTRL_EXT_LOOPBACK;
|
|
+ else
|
|
+ mpi_opts &= ~HW_ATL_FW2X_CTRL_EXT_LOOPBACK;
|
|
+ aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static u32 aq_fw2x_mbox_get(struct aq_hw_s *self)
|
|
{
|
|
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR);
|
|
@@ -586,4 +617,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
|
|
.send_fw_request = aq_fw2x_send_fw_request,
|
|
.enable_ptp = aq_fw3x_enable_ptp,
|
|
.led_control = aq_fw2x_led_control,
|
|
+ .set_phyloopback = aq_fw2x_set_phyloopback,
|
|
};
|
|
--
|
|
2.13.6
|
|
|