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>
This commit is contained in:
Родитель
dc12f75afc
Коммит
ea4b4d7fc1
|
@ -325,6 +325,31 @@ Supported ethtool options
|
|||
Example:
|
||||
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
|
||||
=======================
|
||||
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] = {
|
|||
"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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче