Merge branch 'support-some-features-for-the-hibmcge-driver'

Jijie Shao says:

====================
Support some features for the HIBMCGE driver

In this patch series, The HIBMCGE driver implements some functions
such as dump register, unicast MAC address filtering, debugfs and reset.
====================

Link: https://patch.msgid.link/20241216040532.1566229-1-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-12-17 20:01:41 -08:00
commit 2b9da35f48
12 changed files with 811 additions and 28 deletions

View File

@ -5,4 +5,5 @@
obj-$(CONFIG_HIBMCGE) += hibmcge.o
hibmcge-objs = hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_ethtool.o
hibmcge-objs = hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_ethtool.o \
hbg_debugfs.o hbg_err.o

View File

@ -4,6 +4,7 @@
#ifndef __HBG_COMMON_H
#define __HBG_COMMON_H
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include "hbg_reg.h"
@ -33,6 +34,14 @@ enum hbg_tx_state {
enum hbg_nic_state {
HBG_NIC_STATE_EVENT_HANDLING = 0,
HBG_NIC_STATE_RESETTING,
HBG_NIC_STATE_RESET_FAIL,
};
enum hbg_reset_type {
HBG_RESET_TYPE_NONE = 0,
HBG_RESET_TYPE_FLR,
HBG_RESET_TYPE_FUNCTION,
};
struct hbg_buffer {
@ -84,6 +93,7 @@ struct hbg_dev_specs {
u32 vlan_layers;
u32 max_mtu;
u32 min_mtu;
u32 uc_mac_num;
u32 max_frame_len;
u32 rx_buf_size;
@ -114,6 +124,22 @@ struct hbg_mac {
u32 duplex;
u32 autoneg;
u32 link_status;
u32 pause_autoneg;
};
struct hbg_mac_table_entry {
u8 addr[ETH_ALEN];
};
struct hbg_mac_filter {
struct hbg_mac_table_entry *mac_table;
u32 table_max_len;
bool enabled;
};
/* saved for restore after rest */
struct hbg_user_def {
struct ethtool_pauseparam pause_param;
};
struct hbg_priv {
@ -126,6 +152,9 @@ struct hbg_priv {
struct hbg_vector vectors;
struct hbg_ring tx_ring;
struct hbg_ring rx_ring;
struct hbg_mac_filter filter;
enum hbg_reset_type reset_type;
struct hbg_user_def user_def;
};
#endif

View File

@ -0,0 +1,160 @@
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2024 Hisilicon Limited.
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/seq_file.h>
#include <linux/string_choices.h>
#include "hbg_common.h"
#include "hbg_debugfs.h"
#include "hbg_hw.h"
#include "hbg_irq.h"
#include "hbg_txrx.h"
static struct dentry *hbg_dbgfs_root;
struct hbg_dbg_info {
const char *name;
int (*read)(struct seq_file *seq, void *data);
};
#define state_str_true_false(p, s) str_true_false(test_bit(s, &(p)->state))
static void hbg_dbg_ring(struct hbg_priv *priv, struct hbg_ring *ring,
struct seq_file *s)
{
u32 irq_mask = ring->dir == HBG_DIR_TX ? HBG_INT_MSK_TX_B :
HBG_INT_MSK_RX_B;
seq_printf(s, "ring used num: %u\n",
hbg_get_queue_used_num(ring));
seq_printf(s, "ring max num: %u\n", ring->len);
seq_printf(s, "ring head: %u, tail: %u\n", ring->head, ring->tail);
seq_printf(s, "fifo used num: %u\n",
hbg_hw_get_fifo_used_num(priv, ring->dir));
seq_printf(s, "fifo max num: %u\n",
hbg_get_spec_fifo_max_num(priv, ring->dir));
seq_printf(s, "irq enabled: %s\n",
str_true_false(hbg_hw_irq_is_enabled(priv, irq_mask)));
}
static int hbg_dbg_tx_ring(struct seq_file *s, void *unused)
{
struct net_device *netdev = dev_get_drvdata(s->private);
struct hbg_priv *priv = netdev_priv(netdev);
hbg_dbg_ring(priv, &priv->tx_ring, s);
return 0;
}
static int hbg_dbg_rx_ring(struct seq_file *s, void *unused)
{
struct net_device *netdev = dev_get_drvdata(s->private);
struct hbg_priv *priv = netdev_priv(netdev);
hbg_dbg_ring(priv, &priv->rx_ring, s);
return 0;
}
static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
{
struct net_device *netdev = dev_get_drvdata(s->private);
struct hbg_priv *priv = netdev_priv(netdev);
struct hbg_irq_info *info;
u32 i;
for (i = 0; i < priv->vectors.info_array_len; i++) {
info = &priv->vectors.info_array[i];
seq_printf(s,
"%-20s: enabled: %-5s, logged: %-5s, count: %llu\n",
info->name,
str_true_false(hbg_hw_irq_is_enabled(priv,
info->mask)),
str_true_false(info->need_print),
info->count);
}
return 0;
}
static int hbg_dbg_mac_table(struct seq_file *s, void *unused)
{
struct net_device *netdev = dev_get_drvdata(s->private);
struct hbg_priv *priv = netdev_priv(netdev);
struct hbg_mac_filter *filter;
u32 i;
filter = &priv->filter;
seq_printf(s, "mac addr max count: %u\n", filter->table_max_len);
seq_printf(s, "filter enabled: %s\n", str_true_false(filter->enabled));
for (i = 0; i < filter->table_max_len; i++) {
if (is_zero_ether_addr(filter->mac_table[i].addr))
continue;
seq_printf(s, "[%u] %pM\n", i, filter->mac_table[i].addr);
}
return 0;
}
static const char * const reset_type_str[] = {"None", "FLR", "Function"};
static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
{
struct net_device *netdev = dev_get_drvdata(s->private);
struct hbg_priv *priv = netdev_priv(netdev);
seq_printf(s, "event handling state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
seq_printf(s, "resetting state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_RESETTING));
seq_printf(s, "reset fail state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_RESET_FAIL));
seq_printf(s, "last reset type: %s\n",
reset_type_str[priv->reset_type]);
return 0;
}
static const struct hbg_dbg_info hbg_dbg_infos[] = {
{ "tx_ring", hbg_dbg_tx_ring },
{ "rx_ring", hbg_dbg_rx_ring },
{ "irq_info", hbg_dbg_irq_info },
{ "mac_table", hbg_dbg_mac_table },
{ "nic_state", hbg_dbg_nic_state },
};
static void hbg_debugfs_uninit(void *data)
{
debugfs_remove_recursive((struct dentry *)data);
}
void hbg_debugfs_init(struct hbg_priv *priv)
{
const char *name = pci_name(priv->pdev);
struct device *dev = &priv->pdev->dev;
struct dentry *root;
u32 i;
root = debugfs_create_dir(name, hbg_dbgfs_root);
for (i = 0; i < ARRAY_SIZE(hbg_dbg_infos); i++)
debugfs_create_devm_seqfile(dev, hbg_dbg_infos[i].name,
root, hbg_dbg_infos[i].read);
/* Ignore the failure because debugfs is not a key feature. */
devm_add_action_or_reset(dev, hbg_debugfs_uninit, root);
}
void hbg_debugfs_register(void)
{
hbg_dbgfs_root = debugfs_create_dir("hibmcge", NULL);
}
void hbg_debugfs_unregister(void)
{
debugfs_remove_recursive(hbg_dbgfs_root);
hbg_dbgfs_root = NULL;
}

View File

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2024 Hisilicon Limited. */
#ifndef __HBG_DEBUGFS_H
#define __HBG_DEBUGFS_H
void hbg_debugfs_register(void);
void hbg_debugfs_unregister(void);
void hbg_debugfs_init(struct hbg_priv *priv);
#endif

View File

@ -0,0 +1,134 @@
// SPDX-License-Identifier: GPL-2.0+
// Copyright (c) 2024 Hisilicon Limited.
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/rtnetlink.h>
#include "hbg_common.h"
#include "hbg_err.h"
#include "hbg_hw.h"
static void hbg_restore_mac_table(struct hbg_priv *priv)
{
struct hbg_mac_filter *filter = &priv->filter;
u64 addr;
u32 i;
for (i = 0; i < filter->table_max_len; i++)
if (!is_zero_ether_addr(filter->mac_table[i].addr)) {
addr = ether_addr_to_u64(filter->mac_table[i].addr);
hbg_hw_set_uc_addr(priv, addr, i);
}
hbg_hw_set_mac_filter_enable(priv, priv->filter.enabled);
}
static void hbg_restore_user_def_settings(struct hbg_priv *priv)
{
struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;
hbg_restore_mac_table(priv);
hbg_hw_set_mtu(priv, priv->netdev->mtu);
hbg_hw_set_pause_enable(priv, pause_param->tx_pause,
pause_param->rx_pause);
}
int hbg_rebuild(struct hbg_priv *priv)
{
int ret;
ret = hbg_hw_init(priv);
if (ret)
return ret;
hbg_restore_user_def_settings(priv);
return 0;
}
static int hbg_reset_prepare(struct hbg_priv *priv, enum hbg_reset_type type)
{
int ret;
ASSERT_RTNL();
if (netif_running(priv->netdev)) {
dev_warn(&priv->pdev->dev,
"failed to reset because port is up\n");
return -EBUSY;
}
priv->reset_type = type;
set_bit(HBG_NIC_STATE_RESETTING, &priv->state);
clear_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
ret = hbg_hw_event_notify(priv, HBG_HW_EVENT_RESET);
if (ret) {
set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
}
return ret;
}
static int hbg_reset_done(struct hbg_priv *priv, enum hbg_reset_type type)
{
int ret;
if (!test_bit(HBG_NIC_STATE_RESETTING, &priv->state) ||
type != priv->reset_type)
return 0;
ASSERT_RTNL();
clear_bit(HBG_NIC_STATE_RESETTING, &priv->state);
ret = hbg_rebuild(priv);
if (ret) {
set_bit(HBG_NIC_STATE_RESET_FAIL, &priv->state);
dev_err(&priv->pdev->dev, "failed to rebuild after reset\n");
return ret;
}
dev_info(&priv->pdev->dev, "reset done\n");
return ret;
}
/* must be protected by rtnl lock */
int hbg_reset(struct hbg_priv *priv)
{
int ret;
ASSERT_RTNL();
ret = hbg_reset_prepare(priv, HBG_RESET_TYPE_FUNCTION);
if (ret)
return ret;
return hbg_reset_done(priv, HBG_RESET_TYPE_FUNCTION);
}
static void hbg_pci_err_reset_prepare(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct hbg_priv *priv = netdev_priv(netdev);
rtnl_lock();
hbg_reset_prepare(priv, HBG_RESET_TYPE_FLR);
}
static void hbg_pci_err_reset_done(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct hbg_priv *priv = netdev_priv(netdev);
hbg_reset_done(priv, HBG_RESET_TYPE_FLR);
rtnl_unlock();
}
static const struct pci_error_handlers hbg_pci_err_handler = {
.reset_prepare = hbg_pci_err_reset_prepare,
.reset_done = hbg_pci_err_reset_done,
};
void hbg_set_pci_err_handler(struct pci_driver *pdrv)
{
pdrv->err_handler = &hbg_pci_err_handler;
}

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) 2024 Hisilicon Limited. */
#ifndef __HBG_ERR_H
#define __HBG_ERR_H
#include <linux/pci.h>
void hbg_set_pci_err_handler(struct pci_driver *pdrv);
int hbg_reset(struct hbg_priv *priv);
int hbg_rebuild(struct hbg_priv *priv);
#endif

View File

@ -3,12 +3,193 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/rtnetlink.h>
#include "hbg_common.h"
#include "hbg_err.h"
#include "hbg_ethtool.h"
#include "hbg_hw.h"
enum hbg_reg_dump_type {
HBG_DUMP_REG_TYPE_SPEC = 0,
HBG_DUMP_REG_TYPE_MDIO,
HBG_DUMP_REG_TYPE_GMAC,
HBG_DUMP_REG_TYPE_PCU,
};
struct hbg_reg_info {
u32 type;
u32 offset;
u32 val;
};
#define HBG_DUMP_SPEC_I(offset) {HBG_DUMP_REG_TYPE_SPEC, offset, 0}
#define HBG_DUMP_MDIO_I(offset) {HBG_DUMP_REG_TYPE_MDIO, offset, 0}
#define HBG_DUMP_GMAC_I(offset) {HBG_DUMP_REG_TYPE_GMAC, offset, 0}
#define HBG_DUMP_PCU_I(offset) {HBG_DUMP_REG_TYPE_PCU, offset, 0}
static const struct hbg_reg_info hbg_dump_reg_infos[] = {
/* dev specs */
HBG_DUMP_SPEC_I(HBG_REG_SPEC_VALID_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_EVENT_REQ_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MAC_ID_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_PHY_ID_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_HIGH_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_UC_MAC_NUM_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MDIO_FREQ_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MAX_MTU_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_MIN_MTU_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_TX_FIFO_NUM_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_RX_FIFO_NUM_ADDR),
HBG_DUMP_SPEC_I(HBG_REG_VLAN_LAYERS_ADDR),
/* mdio */
HBG_DUMP_MDIO_I(HBG_REG_MDIO_COMMAND_ADDR),
HBG_DUMP_MDIO_I(HBG_REG_MDIO_ADDR_ADDR),
HBG_DUMP_MDIO_I(HBG_REG_MDIO_WDATA_ADDR),
HBG_DUMP_MDIO_I(HBG_REG_MDIO_RDATA_ADDR),
HBG_DUMP_MDIO_I(HBG_REG_MDIO_STA_ADDR),
/* gmac */
HBG_DUMP_GMAC_I(HBG_REG_DUPLEX_TYPE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_FD_FC_TYPE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_FC_TX_TIMER_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_LOW_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_HIGH_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_MAX_FRAME_SIZE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_PORT_MODE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_PORT_ENABLE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_PAUSE_ENABLE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_AN_NEG_STATE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_TRANSMIT_CTRL_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_REC_FILT_CTRL_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_LINE_LOOP_BACK_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_CF_CRC_STRIP_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_MODE_CHANGE_EN_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_LOOP_REG_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_RECV_CTRL_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_VLAN_CODE_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_0_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_0_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_1_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_1_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_2_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_2_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_3_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_3_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_4_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_4_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_5_ADDR),
HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_5_ADDR),
/* pcu */
HBG_DUMP_PCU_I(HBG_REG_TX_FIFO_THRSLD_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_FIFO_THRSLD_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CFG_FIFO_THRSLD_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_MSK_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_STAT_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_CLR_ADDR),
HBG_DUMP_PCU_I(HBG_REG_TX_BUS_ERR_ADDR_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_BUS_ERR_ADDR_ADDR),
HBG_DUMP_PCU_I(HBG_REG_MAX_FRAME_LEN_ADDR),
HBG_DUMP_PCU_I(HBG_REG_DEBUG_ST_MCH_ADDR),
HBG_DUMP_PCU_I(HBG_REG_FIFO_CURR_STATUS_ADDR),
HBG_DUMP_PCU_I(HBG_REG_FIFO_HIST_STATUS_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_CFF_DATA_NUM_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_TX_PAUSE_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_CFF_ADDR_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_BUF_SIZE_ADDR),
HBG_DUMP_PCU_I(HBG_REG_BUS_CTRL_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_CTRL_ADDR),
HBG_DUMP_PCU_I(HBG_REG_RX_PKT_MODE_ADDR),
HBG_DUMP_PCU_I(HBG_REG_DBG_ST0_ADDR),
HBG_DUMP_PCU_I(HBG_REG_DBG_ST1_ADDR),
HBG_DUMP_PCU_I(HBG_REG_DBG_ST2_ADDR),
HBG_DUMP_PCU_I(HBG_REG_BUS_RST_EN_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_MSK_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_STAT_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_CLR_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_MSK_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_STAT_ADDR),
HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_CLR_ADDR),
};
static const u32 hbg_dump_type_base_array[] = {
[HBG_DUMP_REG_TYPE_SPEC] = 0,
[HBG_DUMP_REG_TYPE_MDIO] = HBG_REG_MDIO_BASE,
[HBG_DUMP_REG_TYPE_GMAC] = HBG_REG_SGMII_BASE,
[HBG_DUMP_REG_TYPE_PCU] = HBG_REG_SGMII_BASE,
};
static int hbg_ethtool_get_regs_len(struct net_device *netdev)
{
return ARRAY_SIZE(hbg_dump_reg_infos) * sizeof(struct hbg_reg_info);
}
static void hbg_ethtool_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *data)
{
struct hbg_priv *priv = netdev_priv(netdev);
struct hbg_reg_info *info;
u32 i, offset = 0;
regs->version = 0;
for (i = 0; i < ARRAY_SIZE(hbg_dump_reg_infos); i++) {
info = data + offset;
*info = hbg_dump_reg_infos[i];
info->val = hbg_reg_read(priv, info->offset);
info->offset -= hbg_dump_type_base_array[info->type];
offset += sizeof(*info);
}
}
static void hbg_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *param)
{
struct hbg_priv *priv = netdev_priv(net_dev);
param->autoneg = priv->mac.pause_autoneg;
hbg_hw_get_pause_enable(priv, &param->tx_pause, &param->rx_pause);
}
static int hbg_ethtool_set_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *param)
{
struct hbg_priv *priv = netdev_priv(net_dev);
priv->mac.pause_autoneg = param->autoneg;
phy_set_asym_pause(priv->mac.phydev, param->rx_pause, param->tx_pause);
if (!param->autoneg)
hbg_hw_set_pause_enable(priv, param->tx_pause, param->rx_pause);
priv->user_def.pause_param = *param;
return 0;
}
static int hbg_ethtool_reset(struct net_device *netdev, u32 *flags)
{
struct hbg_priv *priv = netdev_priv(netdev);
if (*flags != ETH_RESET_DEDICATED)
return -EOPNOTSUPP;
*flags = 0;
return hbg_reset(priv);
}
static const struct ethtool_ops hbg_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
.get_regs_len = hbg_ethtool_get_regs_len,
.get_regs = hbg_ethtool_get_regs,
.get_pauseparam = hbg_ethtool_get_pauseparam,
.set_pauseparam = hbg_ethtool_set_pauseparam,
.reset = hbg_ethtool_reset,
.nway_reset = phy_ethtool_nway_reset,
};
void hbg_ethtool_set_ops(struct net_device *netdev)

View File

@ -3,6 +3,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/iopoll.h>
#include <linux/minmax.h>
#include "hbg_common.h"
@ -67,6 +68,8 @@ static int hbg_hw_dev_specs_init(struct hbg_priv *priv)
specs->vlan_layers = hbg_reg_read(priv, HBG_REG_VLAN_LAYERS_ADDR);
specs->rx_fifo_num = hbg_reg_read(priv, HBG_REG_RX_FIFO_NUM_ADDR);
specs->tx_fifo_num = hbg_reg_read(priv, HBG_REG_TX_FIFO_NUM_ADDR);
specs->uc_mac_num = hbg_reg_read(priv, HBG_REG_UC_MAC_NUM_ADDR);
mac_addr = hbg_reg_read64(priv, HBG_REG_MAC_ADDR_ADDR);
u64_to_ether_addr(mac_addr, (u8 *)specs->mac_addr.sa_data);
@ -135,9 +138,13 @@ void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable)
hbg_reg_write(priv, HBG_REG_CF_INTRPT_MSK_ADDR, value);
}
void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr)
void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr, u32 index)
{
hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_2_ADDR, mac_addr);
u32 addr;
/* mac addr is u64, so the addr offset is 0x8 */
addr = HBG_REG_STATION_ADDR_LOW_2_ADDR + (index * 0x8);
hbg_reg_write64(priv, addr, mac_addr);
}
static void hbg_hw_set_pcu_max_frame_len(struct hbg_priv *priv,
@ -161,8 +168,13 @@ static void hbg_hw_set_mac_max_frame_len(struct hbg_priv *priv,
void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu)
{
hbg_hw_set_pcu_max_frame_len(priv, mtu);
hbg_hw_set_mac_max_frame_len(priv, mtu);
u32 frame_len;
frame_len = mtu + VLAN_HLEN * priv->dev_specs.vlan_layers +
ETH_HLEN + ETH_FCS_LEN;
hbg_hw_set_pcu_max_frame_len(priv, frame_len);
hbg_hw_set_mac_max_frame_len(priv, frame_len);
}
void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable)
@ -207,6 +219,34 @@ void hbg_hw_adjust_link(struct hbg_priv *priv, u32 speed, u32 duplex)
HBG_REG_DUPLEX_B, duplex);
}
/* only support uc filter */
void hbg_hw_set_mac_filter_enable(struct hbg_priv *priv, u32 enable)
{
hbg_reg_write_field(priv, HBG_REG_REC_FILT_CTRL_ADDR,
HBG_REG_REC_FILT_CTRL_UC_MATCH_EN_B, enable);
}
void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en)
{
hbg_reg_write_field(priv, HBG_REG_PAUSE_ENABLE_ADDR,
HBG_REG_PAUSE_ENABLE_TX_B, tx_en);
hbg_reg_write_field(priv, HBG_REG_PAUSE_ENABLE_ADDR,
HBG_REG_PAUSE_ENABLE_RX_B, rx_en);
}
void hbg_hw_get_pause_enable(struct hbg_priv *priv, u32 *tx_en, u32 *rx_en)
{
*tx_en = hbg_reg_read_field(priv, HBG_REG_PAUSE_ENABLE_ADDR,
HBG_REG_PAUSE_ENABLE_TX_B);
*rx_en = hbg_reg_read_field(priv, HBG_REG_PAUSE_ENABLE_ADDR,
HBG_REG_PAUSE_ENABLE_RX_B);
}
void hbg_hw_set_rx_pause_mac_addr(struct hbg_priv *priv, u64 mac_addr)
{
hbg_reg_write64(priv, HBG_REG_FD_FC_ADDR_LOW_ADDR, mac_addr);
}
static void hbg_hw_init_transmit_ctrl(struct hbg_priv *priv)
{
u32 ctrl = 0;

View File

@ -51,9 +51,13 @@ bool hbg_hw_irq_is_enabled(struct hbg_priv *priv, u32 mask);
void hbg_hw_irq_enable(struct hbg_priv *priv, u32 mask, bool enable);
void hbg_hw_set_mtu(struct hbg_priv *priv, u16 mtu);
void hbg_hw_mac_enable(struct hbg_priv *priv, u32 enable);
void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr);
void hbg_hw_set_uc_addr(struct hbg_priv *priv, u64 mac_addr, u32 index);
u32 hbg_hw_get_fifo_used_num(struct hbg_priv *priv, enum hbg_dir dir);
void hbg_hw_set_tx_desc(struct hbg_priv *priv, struct hbg_tx_desc *tx_desc);
void hbg_hw_fill_buffer(struct hbg_priv *priv, u32 buffer_dma_addr);
void hbg_hw_set_mac_filter_enable(struct hbg_priv *priv, u32 enable);
void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en);
void hbg_hw_get_pause_enable(struct hbg_priv *priv, u32 *tx_en, u32 *rx_en);
void hbg_hw_set_rx_pause_mac_addr(struct hbg_priv *priv, u64 mac_addr);
#endif

View File

@ -6,13 +6,13 @@
#include <linux/netdevice.h>
#include <linux/pci.h>
#include "hbg_common.h"
#include "hbg_err.h"
#include "hbg_ethtool.h"
#include "hbg_hw.h"
#include "hbg_irq.h"
#include "hbg_mdio.h"
#include "hbg_txrx.h"
static void hbg_change_mtu(struct hbg_priv *priv, int new_mtu);
#include "hbg_debugfs.h"
static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled)
{
@ -55,11 +55,7 @@ static int hbg_hw_txrx_clear(struct hbg_priv *priv)
return ret;
/* After reset, regs need to be reconfigured */
hbg_hw_init(priv);
hbg_hw_set_uc_addr(priv, ether_addr_to_u64(priv->netdev->dev_addr));
hbg_change_mtu(priv, priv->netdev->mtu);
return 0;
return hbg_rebuild(priv);
}
static int hbg_net_stop(struct net_device *netdev)
@ -74,31 +70,127 @@ static int hbg_net_stop(struct net_device *netdev)
return hbg_hw_txrx_clear(priv);
}
static void hbg_update_promisc_mode(struct net_device *netdev, bool overflow)
{
struct hbg_priv *priv = netdev_priv(netdev);
/* Only when not table_overflow, and netdev->flags not set IFF_PROMISC,
* The MAC filter will be enabled.
* Otherwise the filter will be disabled.
*/
priv->filter.enabled = !(overflow || (netdev->flags & IFF_PROMISC));
hbg_hw_set_mac_filter_enable(priv, priv->filter.enabled);
}
static void hbg_set_mac_to_mac_table(struct hbg_priv *priv,
u32 index, const u8 *addr)
{
if (addr) {
ether_addr_copy(priv->filter.mac_table[index].addr, addr);
hbg_hw_set_uc_addr(priv, ether_addr_to_u64(addr), index);
} else {
eth_zero_addr(priv->filter.mac_table[index].addr);
hbg_hw_set_uc_addr(priv, 0, index);
}
}
static int hbg_get_index_from_mac_table(struct hbg_priv *priv,
const u8 *addr, u32 *index)
{
u32 i;
for (i = 0; i < priv->filter.table_max_len; i++)
if (ether_addr_equal(priv->filter.mac_table[i].addr, addr)) {
*index = i;
return 0;
}
return -EINVAL;
}
static int hbg_add_mac_to_filter(struct hbg_priv *priv, const u8 *addr)
{
u32 index;
/* already exists */
if (!hbg_get_index_from_mac_table(priv, addr, &index))
return 0;
for (index = 0; index < priv->filter.table_max_len; index++)
if (is_zero_ether_addr(priv->filter.mac_table[index].addr)) {
hbg_set_mac_to_mac_table(priv, index, addr);
return 0;
}
return -ENOSPC;
}
static void hbg_del_mac_from_filter(struct hbg_priv *priv, const u8 *addr)
{
u32 index;
/* not exists */
if (hbg_get_index_from_mac_table(priv, addr, &index))
return;
hbg_set_mac_to_mac_table(priv, index, NULL);
}
static int hbg_uc_sync(struct net_device *netdev, const unsigned char *addr)
{
struct hbg_priv *priv = netdev_priv(netdev);
return hbg_add_mac_to_filter(priv, addr);
}
static int hbg_uc_unsync(struct net_device *netdev, const unsigned char *addr)
{
struct hbg_priv *priv = netdev_priv(netdev);
if (ether_addr_equal(netdev->dev_addr, (u8 *)addr))
return 0;
hbg_del_mac_from_filter(priv, addr);
return 0;
}
static void hbg_net_set_rx_mode(struct net_device *netdev)
{
int ret;
ret = __dev_uc_sync(netdev, hbg_uc_sync, hbg_uc_unsync);
/* If ret != 0, overflow has occurred */
hbg_update_promisc_mode(netdev, !!ret);
}
static int hbg_net_set_mac_address(struct net_device *netdev, void *addr)
{
struct hbg_priv *priv = netdev_priv(netdev);
u8 *mac_addr;
bool exists;
u32 index;
mac_addr = ((struct sockaddr *)addr)->sa_data;
if (!is_valid_ether_addr(mac_addr))
return -EADDRNOTAVAIL;
hbg_hw_set_uc_addr(priv, ether_addr_to_u64(mac_addr));
/* The index of host mac is always 0.
* If new mac address already exists,
* delete the existing mac address and
* add it to the position with index 0.
*/
exists = !hbg_get_index_from_mac_table(priv, mac_addr, &index);
hbg_set_mac_to_mac_table(priv, 0, mac_addr);
if (exists)
hbg_set_mac_to_mac_table(priv, index, NULL);
hbg_hw_set_rx_pause_mac_addr(priv, ether_addr_to_u64(mac_addr));
dev_addr_set(netdev, mac_addr);
return 0;
}
static void hbg_change_mtu(struct hbg_priv *priv, int new_mtu)
{
u32 frame_len;
frame_len = new_mtu + VLAN_HLEN * priv->dev_specs.vlan_layers +
ETH_HLEN + ETH_FCS_LEN;
hbg_hw_set_mtu(priv, frame_len);
}
static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu)
{
struct hbg_priv *priv = netdev_priv(netdev);
@ -106,7 +198,7 @@ static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu)
if (netif_running(netdev))
return -EBUSY;
hbg_change_mtu(priv, new_mtu);
hbg_hw_set_mtu(priv, new_mtu);
WRITE_ONCE(netdev->mtu, new_mtu);
dev_dbg(&priv->pdev->dev,
@ -142,8 +234,39 @@ static const struct net_device_ops hbg_netdev_ops = {
.ndo_set_mac_address = hbg_net_set_mac_address,
.ndo_change_mtu = hbg_net_change_mtu,
.ndo_tx_timeout = hbg_net_tx_timeout,
.ndo_set_rx_mode = hbg_net_set_rx_mode,
};
static int hbg_mac_filter_init(struct hbg_priv *priv)
{
struct hbg_dev_specs *dev_specs = &priv->dev_specs;
struct hbg_mac_filter *filter = &priv->filter;
struct hbg_mac_table_entry *tmp_table;
tmp_table = devm_kcalloc(&priv->pdev->dev, dev_specs->uc_mac_num,
sizeof(*tmp_table), GFP_KERNEL);
if (!tmp_table)
return -ENOMEM;
filter->mac_table = tmp_table;
filter->table_max_len = dev_specs->uc_mac_num;
filter->enabled = true;
hbg_hw_set_mac_filter_enable(priv, filter->enabled);
return 0;
}
static void hbg_init_user_def(struct hbg_priv *priv)
{
struct ethtool_pauseparam *pause_param = &priv->user_def.pause_param;
priv->mac.pause_autoneg = HBG_STATUS_ENABLE;
pause_param->autoneg = priv->mac.pause_autoneg;
hbg_hw_get_pause_enable(priv, &pause_param->tx_pause,
&pause_param->rx_pause);
}
static int hbg_init(struct hbg_priv *priv)
{
int ret;
@ -160,7 +283,17 @@ static int hbg_init(struct hbg_priv *priv)
if (ret)
return ret;
return hbg_mdio_init(priv);
ret = hbg_mdio_init(priv);
if (ret)
return ret;
ret = hbg_mac_filter_init(priv);
if (ret)
return ret;
hbg_debugfs_init(priv);
hbg_init_user_def(priv);
return 0;
}
static int hbg_pci_init(struct pci_dev *pdev)
@ -216,13 +349,15 @@ static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
return ret;
netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
netdev->max_mtu = priv->dev_specs.max_mtu;
netdev->min_mtu = priv->dev_specs.min_mtu;
netdev->netdev_ops = &hbg_netdev_ops;
netdev->watchdog_timeo = 5 * HZ;
hbg_change_mtu(priv, ETH_DATA_LEN);
hbg_hw_set_mtu(priv, ETH_DATA_LEN);
hbg_net_set_mac_address(priv->netdev, &priv->dev_specs.mac_addr);
hbg_ethtool_set_ops(netdev);
@ -245,7 +380,27 @@ static struct pci_driver hbg_driver = {
.id_table = hbg_pci_tbl,
.probe = hbg_probe,
};
module_pci_driver(hbg_driver);
static int __init hbg_module_init(void)
{
int ret;
hbg_debugfs_register();
hbg_set_pci_err_handler(&hbg_driver);
ret = pci_register_driver(&hbg_driver);
if (ret)
hbg_debugfs_unregister();
return ret;
}
module_init(hbg_module_init);
static void __exit hbg_module_exit(void)
{
pci_unregister_driver(&hbg_driver);
hbg_debugfs_unregister();
}
module_exit(hbg_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Huawei Tech. Co., Ltd.");

View File

@ -114,6 +114,19 @@ static void hbg_mdio_init_hw(struct hbg_priv *priv)
hbg_mdio_set_command(mac, cmd);
}
static void hbg_flowctrl_cfg(struct hbg_priv *priv)
{
struct phy_device *phydev = priv->mac.phydev;
bool rx_pause;
bool tx_pause;
if (!priv->mac.pause_autoneg)
return;
phy_get_pause(phydev, &tx_pause, &rx_pause);
hbg_hw_set_pause_enable(priv, tx_pause, rx_pause);
}
static void hbg_phy_adjust_link(struct net_device *netdev)
{
struct hbg_priv *priv = netdev_priv(netdev);
@ -140,6 +153,7 @@ static void hbg_phy_adjust_link(struct net_device *netdev)
priv->mac.duplex = phydev->duplex;
priv->mac.autoneg = phydev->autoneg;
hbg_hw_adjust_link(priv, speed, phydev->duplex);
hbg_flowctrl_cfg(priv);
}
priv->mac.link_status = phydev->link;
@ -168,6 +182,7 @@ static int hbg_phy_connect(struct hbg_priv *priv)
return ret;
phy_remove_link_mode(phydev, ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
phy_support_asym_pause(phydev);
phy_attached_info(phydev);
return 0;

View File

@ -10,6 +10,8 @@
#define HBG_REG_MAC_ID_ADDR 0x0008
#define HBG_REG_PHY_ID_ADDR 0x000C
#define HBG_REG_MAC_ADDR_ADDR 0x0010
#define HBG_REG_MAC_ADDR_HIGH_ADDR 0x0014
#define HBG_REG_UC_MAC_NUM_ADDR 0x0018
#define HBG_REG_MDIO_FREQ_ADDR 0x0024
#define HBG_REG_MAX_MTU_ADDR 0x0028
#define HBG_REG_MIN_MTU_ADDR 0x002C
@ -28,6 +30,7 @@
#define HBG_REG_MDIO_COMMAND_OP_M GENMASK(11, 10)
#define HBG_REG_MDIO_COMMAND_PRTAD_M GENMASK(9, 5)
#define HBG_REG_MDIO_COMMAND_DEVAD_M GENMASK(4, 0)
#define HBG_REG_MDIO_ADDR_ADDR (HBG_REG_MDIO_BASE + 0x0004)
#define HBG_REG_MDIO_WDATA_ADDR (HBG_REG_MDIO_BASE + 0x0008)
#define HBG_REG_MDIO_WDATA_M GENMASK(15, 0)
#define HBG_REG_MDIO_RDATA_ADDR (HBG_REG_MDIO_BASE + 0x000C)
@ -36,6 +39,10 @@
/* GMAC */
#define HBG_REG_SGMII_BASE 0x10000
#define HBG_REG_DUPLEX_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x0008)
#define HBG_REG_FD_FC_TYPE_ADDR (HBG_REG_SGMII_BASE + 0x000C)
#define HBG_REG_FC_TX_TIMER_ADDR (HBG_REG_SGMII_BASE + 0x001C)
#define HBG_REG_FD_FC_ADDR_LOW_ADDR (HBG_REG_SGMII_BASE + 0x0020)
#define HBG_REG_FD_FC_ADDR_HIGH_ADDR (HBG_REG_SGMII_BASE + 0x0024)
#define HBG_REG_DUPLEX_B BIT(0)
#define HBG_REG_MAX_FRAME_SIZE_ADDR (HBG_REG_SGMII_BASE + 0x003C)
#define HBG_REG_PORT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x0040)
@ -43,20 +50,42 @@
#define HBG_REG_PORT_ENABLE_ADDR (HBG_REG_SGMII_BASE + 0x0044)
#define HBG_REG_PORT_ENABLE_RX_B BIT(1)
#define HBG_REG_PORT_ENABLE_TX_B BIT(2)
#define HBG_REG_PAUSE_ENABLE_ADDR (HBG_REG_SGMII_BASE + 0x0048)
#define HBG_REG_PAUSE_ENABLE_RX_B BIT(0)
#define HBG_REG_PAUSE_ENABLE_TX_B BIT(1)
#define HBG_REG_AN_NEG_STATE_ADDR (HBG_REG_SGMII_BASE + 0x0058)
#define HBG_REG_TRANSMIT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0060)
#define HBG_REG_TRANSMIT_CTRL_PAD_EN_B BIT(7)
#define HBG_REG_TRANSMIT_CTRL_CRC_ADD_B BIT(6)
#define HBG_REG_TRANSMIT_CTRL_AN_EN_B BIT(5)
#define HBG_REG_REC_FILT_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x0064)
#define HBG_REG_REC_FILT_CTRL_UC_MATCH_EN_B BIT(0)
#define HBG_REG_LINE_LOOP_BACK_ADDR (HBG_REG_SGMII_BASE + 0x01A8)
#define HBG_REG_CF_CRC_STRIP_ADDR (HBG_REG_SGMII_BASE + 0x01B0)
#define HBG_REG_CF_CRC_STRIP_B BIT(0)
#define HBG_REG_MODE_CHANGE_EN_ADDR (HBG_REG_SGMII_BASE + 0x01B4)
#define HBG_REG_MODE_CHANGE_EN_B BIT(0)
#define HBG_REG_LOOP_REG_ADDR (HBG_REG_SGMII_BASE + 0x01DC)
#define HBG_REG_RECV_CTRL_ADDR (HBG_REG_SGMII_BASE + 0x01E0)
#define HBG_REG_RECV_CTRL_STRIP_PAD_EN_B BIT(3)
#define HBG_REG_VLAN_CODE_ADDR (HBG_REG_SGMII_BASE + 0x01E8)
#define HBG_REG_STATION_ADDR_LOW_0_ADDR (HBG_REG_SGMII_BASE + 0x0200)
#define HBG_REG_STATION_ADDR_HIGH_0_ADDR (HBG_REG_SGMII_BASE + 0x0204)
#define HBG_REG_STATION_ADDR_LOW_1_ADDR (HBG_REG_SGMII_BASE + 0x0208)
#define HBG_REG_STATION_ADDR_HIGH_1_ADDR (HBG_REG_SGMII_BASE + 0x020C)
#define HBG_REG_STATION_ADDR_LOW_2_ADDR (HBG_REG_SGMII_BASE + 0x0210)
#define HBG_REG_STATION_ADDR_HIGH_2_ADDR (HBG_REG_SGMII_BASE + 0x0214)
#define HBG_REG_STATION_ADDR_LOW_3_ADDR (HBG_REG_SGMII_BASE + 0x0218)
#define HBG_REG_STATION_ADDR_HIGH_3_ADDR (HBG_REG_SGMII_BASE + 0x021C)
#define HBG_REG_STATION_ADDR_LOW_4_ADDR (HBG_REG_SGMII_BASE + 0x0220)
#define HBG_REG_STATION_ADDR_HIGH_4_ADDR (HBG_REG_SGMII_BASE + 0x0224)
#define HBG_REG_STATION_ADDR_LOW_5_ADDR (HBG_REG_SGMII_BASE + 0x0228)
#define HBG_REG_STATION_ADDR_HIGH_5_ADDR (HBG_REG_SGMII_BASE + 0x022C)
/* PCU */
#define HBG_REG_TX_FIFO_THRSLD_ADDR (HBG_REG_SGMII_BASE + 0x0420)
#define HBG_REG_RX_FIFO_THRSLD_ADDR (HBG_REG_SGMII_BASE + 0x0424)
#define HBG_REG_CFG_FIFO_THRSLD_ADDR (HBG_REG_SGMII_BASE + 0x0428)
#define HBG_REG_CF_INTRPT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x042C)
#define HBG_INT_MSK_WE_ERR_B BIT(31)
#define HBG_INT_MSK_RBREQ_ERR_B BIT(30)
@ -78,11 +107,17 @@
#define HBG_INT_MSK_RX_B BIT(0) /* just used in driver */
#define HBG_REG_CF_INTRPT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0434)
#define HBG_REG_CF_INTRPT_CLR_ADDR (HBG_REG_SGMII_BASE + 0x0438)
#define HBG_REG_TX_BUS_ERR_ADDR_ADDR (HBG_REG_SGMII_BASE + 0x043C)
#define HBG_REG_RX_BUS_ERR_ADDR_ADDR (HBG_REG_SGMII_BASE + 0x0440)
#define HBG_REG_MAX_FRAME_LEN_ADDR (HBG_REG_SGMII_BASE + 0x0444)
#define HBG_REG_MAX_FRAME_LEN_M GENMASK(15, 0)
#define HBG_REG_DEBUG_ST_MCH_ADDR (HBG_REG_SGMII_BASE + 0x0450)
#define HBG_REG_FIFO_CURR_STATUS_ADDR (HBG_REG_SGMII_BASE + 0x0454)
#define HBG_REG_FIFO_HIST_STATUS_ADDR (HBG_REG_SGMII_BASE + 0x0458)
#define HBG_REG_CF_CFF_DATA_NUM_ADDR (HBG_REG_SGMII_BASE + 0x045C)
#define HBG_REG_CF_CFF_DATA_NUM_ADDR_TX_M GENMASK(8, 0)
#define HBG_REG_CF_CFF_DATA_NUM_ADDR_RX_M GENMASK(24, 16)
#define HBG_REG_CF_TX_PAUSE_ADDR (HBG_REG_SGMII_BASE + 0x0470)
#define HBG_REG_TX_CFF_ADDR_0_ADDR (HBG_REG_SGMII_BASE + 0x0488)
#define HBG_REG_TX_CFF_ADDR_1_ADDR (HBG_REG_SGMII_BASE + 0x048C)
#define HBG_REG_TX_CFF_ADDR_2_ADDR (HBG_REG_SGMII_BASE + 0x0490)
@ -101,6 +136,10 @@
#define HBG_REG_RX_CTRL_RXBUF_1ST_SKIP_SIZE2_M GENMASK(3, 0)
#define HBG_REG_RX_PKT_MODE_ADDR (HBG_REG_SGMII_BASE + 0x04F4)
#define HBG_REG_RX_PKT_MODE_PARSE_MODE_M GENMASK(22, 21)
#define HBG_REG_DBG_ST0_ADDR (HBG_REG_SGMII_BASE + 0x05E4)
#define HBG_REG_DBG_ST1_ADDR (HBG_REG_SGMII_BASE + 0x05E8)
#define HBG_REG_DBG_ST2_ADDR (HBG_REG_SGMII_BASE + 0x05EC)
#define HBG_REG_BUS_RST_EN_ADDR (HBG_REG_SGMII_BASE + 0x0688)
#define HBG_REG_CF_IND_TXINT_MSK_ADDR (HBG_REG_SGMII_BASE + 0x0694)
#define HBG_REG_IND_INTR_MASK_B BIT(0)
#define HBG_REG_CF_IND_TXINT_STAT_ADDR (HBG_REG_SGMII_BASE + 0x0698)