Commit ea4b4d7f authored by Igor Russkikh's avatar Igor Russkikh Committed by David S. Miller

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: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dc12f75a
...@@ -325,6 +325,31 @@ Supported ethtool options ...@@ -325,6 +325,31 @@ Supported ethtool options
Example: Example:
ethtool -N eth0 flow-type udp4 action 0 loc 32 ethtool -N eth0 flow-type udp4 action 0 loc 32
Private flags (testing)
---------------------------------
Atlantic driver supports private flags for hardware custom features:
$ ethtool --show-priv-flags ethX
Private flags for ethX:
DMASystemLoopback : off
PKTSystemLoopback : off
DMANetworkLoopback : off
PHYInternalLoopback: off
PHYExternalLoopback: off
Example:
$ ethtool --set-priv-flags ethX DMASystemLoopback on
DMASystemLoopback: DMA Host loopback.
PKTSystemLoopback: Packet buffer host loopback.
DMANetworkLoopback: Network side loopback on DMA block.
PHYInternalLoopback: Internal loopback on Phy.
PHYExternalLoopback: External loopback on Phy (with loopback ethernet cable).
Command Line Parameters Command Line Parameters
======================= =======================
The following command line parameters are available on atlantic driver: The following command line parameters are available on atlantic driver:
......
...@@ -92,6 +92,14 @@ static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = { ...@@ -92,6 +92,14 @@ static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
"Queue[%d] InErrors", "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, static void aq_ethtool_stats(struct net_device *ndev,
struct ethtool_stats *stats, u64 *data) struct ethtool_stats *stats, u64 *data)
{ {
...@@ -137,7 +145,8 @@ static void aq_ethtool_get_strings(struct net_device *ndev, ...@@ -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); struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
u8 *p = data; u8 *p = data;
if (stringset == ETH_SS_STATS) { switch (stringset) {
case ETH_SS_STATS:
memcpy(p, aq_ethtool_stat_names, memcpy(p, aq_ethtool_stat_names,
sizeof(aq_ethtool_stat_names)); sizeof(aq_ethtool_stat_names));
p = p + 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, ...@@ -150,6 +159,11 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
p += ETH_GSTRING_LEN; 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) ...@@ -193,6 +207,9 @@ static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
ret = ARRAY_SIZE(aq_ethtool_stat_names) + ret = ARRAY_SIZE(aq_ethtool_stat_names) +
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
break; break;
case ETH_SS_PRIV_FLAGS:
ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
break;
default: default:
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
} }
...@@ -650,6 +667,40 @@ static void aq_set_msg_level(struct net_device *ndev, u32 data) ...@@ -650,6 +667,40 @@ static void aq_set_msg_level(struct net_device *ndev, u32 data)
aq_nic->msg_enable = 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 = { const struct ethtool_ops aq_ethtool_ops = {
.get_link = aq_ethtool_get_link, .get_link = aq_ethtool_get_link,
.get_regs_len = aq_ethtool_get_regs_len, .get_regs_len = aq_ethtool_get_regs_len,
...@@ -676,6 +727,8 @@ const struct ethtool_ops aq_ethtool_ops = { ...@@ -676,6 +727,8 @@ const struct ethtool_ops aq_ethtool_ops = {
.set_msglevel = aq_set_msg_level, .set_msglevel = aq_set_msg_level,
.get_sset_count = aq_ethtool_get_sset_count, .get_sset_count = aq_ethtool_get_sset_count,
.get_ethtool_stats = aq_ethtool_stats, .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, .get_link_ksettings = aq_ethtool_get_link_ksettings,
.set_link_ksettings = aq_ethtool_set_link_ksettings, .set_link_ksettings = aq_ethtool_set_link_ksettings,
.get_coalesce = aq_ethtool_get_coalesce, .get_coalesce = aq_ethtool_get_coalesce,
......
...@@ -12,5 +12,6 @@ ...@@ -12,5 +12,6 @@
#include "aq_common.h" #include "aq_common.h"
extern const struct ethtool_ops aq_ethtool_ops; extern const struct ethtool_ops aq_ethtool_ops;
#define AQ_PRIV_FLAGS_MASK (AQ_HW_LOOPBACK_MASK)
#endif /* AQ_ETHTOOL_H */ #endif /* AQ_ETHTOOL_H */
...@@ -122,6 +122,20 @@ struct aq_stats_s { ...@@ -122,6 +122,20 @@ struct aq_stats_s {
#define AQ_HW_LED_BLINK 0x2U #define AQ_HW_LED_BLINK 0x2U
#define AQ_HW_LED_DEFAULT 0x0U #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 { struct aq_hw_s {
atomic_t flags; atomic_t flags;
u8 rbl_enabled:1; u8 rbl_enabled:1;
...@@ -280,6 +294,8 @@ struct aq_hw_ops { ...@@ -280,6 +294,8 @@ struct aq_hw_ops {
u64 *timestamp); u64 *timestamp);
int (*hw_set_fc)(struct aq_hw_s *self, u32 fc, u32 tc); 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 { struct aq_fw_ops {
...@@ -310,6 +326,8 @@ struct aq_fw_ops { ...@@ -310,6 +326,8 @@ struct aq_fw_ops {
int (*led_control)(struct aq_hw_s *self, u32 mode); 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, int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
u8 *mac); u8 *mac);
......
...@@ -406,6 +406,8 @@ int aq_nic_start(struct aq_nic_s *self) ...@@ -406,6 +406,8 @@ int aq_nic_start(struct aq_nic_s *self)
INIT_WORK(&self->service_task, aq_nic_service_task); 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); timer_setup(&self->service_timer, aq_nic_service_timer_cb, 0);
aq_nic_service_timer_cb(&self->service_timer); 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) ...@@ -625,6 +627,11 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb)
aq_ring_update_queue_state(ring); 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. */ /* Above status update may stop the queue. Check this. */
if (__netif_subqueue_stopped(self->ndev, ring->idx)) { if (__netif_subqueue_stopped(self->ndev, ring->idx)) {
err = NETDEV_TX_BUSY; err = NETDEV_TX_BUSY;
...@@ -973,6 +980,44 @@ u32 aq_nic_get_fw_version(struct aq_nic_s *self) ...@@ -973,6 +980,44 @@ u32 aq_nic_get_fw_version(struct aq_nic_s *self)
return fw_version; 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) int aq_nic_stop(struct aq_nic_s *self)
{ {
struct aq_vec_s *aq_vec = NULL; struct aq_vec_s *aq_vec = NULL;
......
...@@ -46,6 +46,7 @@ struct aq_nic_cfg_s { ...@@ -46,6 +46,7 @@ struct aq_nic_cfg_s {
bool is_polling; bool is_polling;
bool is_rss; bool is_rss;
bool is_lro; bool is_lro;
u32 priv_flags;
u8 tcs; u8 tcs;
struct aq_rss_parameters aq_rss; struct aq_rss_parameters aq_rss;
u32 eee_speeds; u32 eee_speeds;
...@@ -158,6 +159,7 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self, ...@@ -158,6 +159,7 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
const struct ethtool_link_ksettings *cmd); const struct ethtool_link_ksettings *cmd);
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self); 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); 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); int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
void aq_nic_shutdown(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); u8 aq_nic_reserve_filter(struct aq_nic_s *self, enum aq_rx_filter_type type);
......
...@@ -1427,6 +1427,30 @@ static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable) ...@@ -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); 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 = { const struct aq_hw_ops hw_atl_ops_b0 = {
.hw_set_mac_address = hw_atl_b0_hw_mac_addr_set, .hw_set_mac_address = hw_atl_b0_hw_mac_addr_set,
.hw_init = hw_atl_b0_hw_init, .hw_init = hw_atl_b0_hw_init,
...@@ -1481,5 +1505,9 @@ const struct aq_hw_ops hw_atl_ops_b0 = { ...@@ -1481,5 +1505,9 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
.rx_extract_ts = hw_atl_b0_rx_extract_ts, .rx_extract_ts = hw_atl_b0_rx_extract_ts,
.extract_hwts = hw_atl_b0_extract_hwts, .extract_hwts = hw_atl_b0_extract_hwts,
.hw_set_offload = hw_atl_b0_hw_offload_set, .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,
}; };
...@@ -563,6 +563,13 @@ void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk) ...@@ -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); 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, void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
u32 rx_traf_class_mode) 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_ ...@@ -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); 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, 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) u32 tx_pkt_buff_size_per_tc, u32 buffer)
{ {
aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBBUF_SIZE_ADR(buffer), aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TXBBUF_SIZE_ADR(buffer),
......
...@@ -288,6 +288,9 @@ void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw, ...@@ -288,6 +288,9 @@ void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw,
/* set dma system loopback */ /* set dma system loopback */
void hw_atl_rpb_dma_sys_lbk_set(struct aq_hw_s *aq_hw, u32 dma_sys_lbk); 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 */ /* set rx traffic class mode */
void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw, void hw_atl_rpb_rpf_rx_traf_class_mode_set(struct aq_hw_s *aq_hw,
u32 rx_traf_class_mode); 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, ...@@ -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 */ /* 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); 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) */ /* set tx packet buffer size (per tc) */
void hw_atl_tpb_tx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, 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 tx_pkt_buff_size_per_tc,
......
...@@ -554,6 +554,24 @@ ...@@ -554,6 +554,24 @@
/* default value of bitfield dma_sys_loopback */ /* default value of bitfield dma_sys_loopback */
#define HW_ATL_RPB_DMA_SYS_LBK_DEFAULT 0x0 #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 /* rx rx_tc_mode bitfield definitions
* preprocessor definitions for the bitfield "rx_tc_mode". * preprocessor definitions for the bitfield "rx_tc_mode".
* port="pif_rpb_rx_tc_mode_i,pif_rpf_rx_tc_mode_i" * port="pif_rpb_rx_tc_mode_i,pif_rpf_rx_tc_mode_i"
...@@ -2107,6 +2125,24 @@ ...@@ -2107,6 +2125,24 @@
/* default value of bitfield dma_sys_loopback */ /* default value of bitfield dma_sys_loopback */
#define HW_ATL_TPB_DMA_SYS_LBK_DEFAULT 0x0 #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 /* tx tx{b}_buf_size[7:0] bitfield definitions
* preprocessor definitions for the bitfield "tx{b}_buf_size[7:0]". * preprocessor definitions for the bitfield "tx{b}_buf_size[7:0]".
* parameter: buffer {b} | stride size 0x10 | range [0, 7] * parameter: buffer {b} | stride size 0x10 | range [0, 7]
...@@ -2144,6 +2180,24 @@ ...@@ -2144,6 +2180,24 @@
/* default value of bitfield tx_scp_ins_en */ /* default value of bitfield tx_scp_ins_en */
#define HW_ATL_TPB_TX_SCP_INS_EN_DEFAULT 0x0 #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 /* tx ipv4_chk_en bitfield definitions
* preprocessor definitions for the bitfield "ipv4_chk_en". * preprocessor definitions for the bitfield "ipv4_chk_en".
* port="pif_tpo_ipv4_chk_en_i" * port="pif_tpo_ipv4_chk_en_i"
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
#define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE) #define HW_ATL_FW2X_CTRL_PAUSE BIT(CTRL_PAUSE)
#define HW_ATL_FW2X_CTRL_TEMPERATURE BIT(CTRL_TEMPERATURE) #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_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_CTRL_FORCE_RECONNECT BIT(CTRL_FORCE_RECONNECT)
#define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE) #define HW_ATL_FW2X_CAP_EEE_1G_MASK BIT(CAPS_HI_1000BASET_FD_EEE)
...@@ -53,6 +56,7 @@ ...@@ -53,6 +56,7 @@
#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E #define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL 0x0E
#define HW_ATL_FW_VER_LED 0x03010026U #define HW_ATL_FW_VER_LED 0x03010026U
#define HW_ATL_FW_VER_MEDIA_CONTROL 0x0301005aU
struct __packed fw2x_msg_wol_pattern { struct __packed fw2x_msg_wol_pattern {
u8 mask[16]; u8 mask[16];
...@@ -539,6 +543,33 @@ static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode) ...@@ -539,6 +543,33 @@ static u32 aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fcmode)
return 0; 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) static u32 aq_fw2x_mbox_get(struct aq_hw_s *self)
{ {
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR); 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 = { ...@@ -586,4 +617,5 @@ const struct aq_fw_ops aq_fw_2x_ops = {
.send_fw_request = aq_fw2x_send_fw_request, .send_fw_request = aq_fw2x_send_fw_request,
.enable_ptp = aq_fw3x_enable_ptp, .enable_ptp = aq_fw3x_enable_ptp,
.led_control = aq_fw2x_led_control, .led_control = aq_fw2x_led_control,
.set_phyloopback = aq_fw2x_set_phyloopback,
}; };
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