Merge branch 'there-are-some-bugfix-for-hibmcge-driver'

Jijie Shao says:

====================
There are some bugfix for hibmcge driver

v2: https://lore.kernel.org/20250403135311.545633-7-shaojijie@huawei.com/
v1: https://lore.kernel.org/20250402133905.895421-1-shaojijie@huawei.com/
====================

Link: https://patch.msgid.link/20250410021327.590362-1-shaojijie@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-04-11 20:17:38 -07:00
commit 8c941f14a6
9 changed files with 55 additions and 22 deletions

View File

@ -108,14 +108,16 @@ struct hbg_irq_info {
bool re_enable;
bool need_print;
bool need_reset;
u64 count;
void (*irq_handle)(struct hbg_priv *priv, struct hbg_irq_info *info);
void (*irq_handle)(struct hbg_priv *priv,
const struct hbg_irq_info *info);
};
struct hbg_vector {
char name[HBG_VECTOR_NUM][32];
struct hbg_irq_info *info_array;
u64 *stats_array;
const struct hbg_irq_info *info_array;
u32 info_array_len;
};

View File

@ -61,7 +61,7 @@ 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;
const struct hbg_irq_info *info;
u32 i;
for (i = 0; i < priv->vectors.info_array_len; i++) {
@ -73,7 +73,7 @@ static int hbg_dbg_irq_info(struct seq_file *s, void *unused)
info->mask)),
str_true_false(info->need_reset),
str_true_false(info->need_print),
info->count);
priv->vectors.stats_array[i]);
}
return 0;
@ -106,6 +106,7 @@ 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);
bool np_link_fail;
seq_printf(s, "event handling state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_EVENT_HANDLING));
@ -117,8 +118,10 @@ static int hbg_dbg_nic_state(struct seq_file *s, void *unused)
reset_type_str[priv->reset_type]);
seq_printf(s, "need reset state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_NEED_RESET));
seq_printf(s, "np_link fail state: %s\n",
state_str_true_false(priv, HBG_NIC_STATE_NP_LINK_FAIL));
np_link_fail = !hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR,
HBG_REG_AN_NEG_STATE_NP_LINK_OK_B);
seq_printf(s, "np_link fail state: %s\n", str_true_false(np_link_fail));
return 0;
}

View File

@ -234,7 +234,7 @@ static u64 hbg_get_irq_stats(struct hbg_vector *vectors, u32 mask)
for (i = 0; i < vectors->info_array_len; i++)
if (vectors->info_array[i].mask == mask)
return vectors->info_array[i].count;
return vectors->stats_array[i];
return 0;
}

View File

@ -26,12 +26,15 @@ static void hbg_restore_mac_table(struct hbg_priv *priv)
static void hbg_restore_user_def_settings(struct hbg_priv *priv)
{
/* The index of host mac is always 0. */
u64 rx_pause_addr = ether_addr_to_u64(priv->filter.mac_table[0].addr);
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);
hbg_hw_set_rx_pause_mac_addr(priv, rx_pause_addr);
}
int hbg_rebuild(struct hbg_priv *priv)

View File

@ -234,6 +234,10 @@ 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);
/* only uc filter is supported, so set all bits of mc mask reg to 1 */
hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_MSK_0, U64_MAX);
hbg_reg_write64(priv, HBG_REG_STATION_ADDR_LOW_MSK_1, U64_MAX);
}
void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en)
@ -242,6 +246,9 @@ void hbg_hw_set_pause_enable(struct hbg_priv *priv, u32 tx_en, u32 rx_en)
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);
hbg_reg_write_field(priv, HBG_REG_REC_FILT_CTRL_ADDR,
HBG_REG_REC_FILT_CTRL_PAUSE_FRM_PASS_B, rx_en);
}
void hbg_hw_get_pause_enable(struct hbg_priv *priv, u32 *tx_en, u32 *rx_en)

View File

@ -6,7 +6,7 @@
#include "hbg_hw.h"
static void hbg_irq_handle_err(struct hbg_priv *priv,
struct hbg_irq_info *irq_info)
const struct hbg_irq_info *irq_info)
{
if (irq_info->need_print)
dev_err(&priv->pdev->dev,
@ -17,30 +17,30 @@ static void hbg_irq_handle_err(struct hbg_priv *priv,
}
static void hbg_irq_handle_tx(struct hbg_priv *priv,
struct hbg_irq_info *irq_info)
const struct hbg_irq_info *irq_info)
{
napi_schedule(&priv->tx_ring.napi);
}
static void hbg_irq_handle_rx(struct hbg_priv *priv,
struct hbg_irq_info *irq_info)
const struct hbg_irq_info *irq_info)
{
napi_schedule(&priv->rx_ring.napi);
}
static void hbg_irq_handle_rx_buf_val(struct hbg_priv *priv,
struct hbg_irq_info *irq_info)
const struct hbg_irq_info *irq_info)
{
priv->stats.rx_fifo_less_empty_thrsld_cnt++;
}
#define HBG_IRQ_I(name, handle) \
{#name, HBG_INT_MSK_##name##_B, false, false, false, 0, handle}
{#name, HBG_INT_MSK_##name##_B, false, false, false, handle}
#define HBG_ERR_IRQ_I(name, need_print, ndde_reset) \
{#name, HBG_INT_MSK_##name##_B, true, need_print, \
ndde_reset, 0, hbg_irq_handle_err}
ndde_reset, hbg_irq_handle_err}
static struct hbg_irq_info hbg_irqs[] = {
static const struct hbg_irq_info hbg_irqs[] = {
HBG_IRQ_I(RX, hbg_irq_handle_rx),
HBG_IRQ_I(TX, hbg_irq_handle_tx),
HBG_ERR_IRQ_I(TX_PKT_CPL, true, true),
@ -64,7 +64,7 @@ static struct hbg_irq_info hbg_irqs[] = {
static irqreturn_t hbg_irq_handle(int irq_num, void *p)
{
struct hbg_irq_info *info;
const struct hbg_irq_info *info;
struct hbg_priv *priv = p;
u32 status;
u32 i;
@ -79,7 +79,7 @@ static irqreturn_t hbg_irq_handle(int irq_num, void *p)
hbg_hw_irq_enable(priv, info->mask, false);
hbg_hw_irq_clear(priv, info->mask);
info->count++;
priv->vectors.stats_array[i]++;
if (info->irq_handle)
info->irq_handle(priv, info);
@ -132,6 +132,12 @@ int hbg_irq_init(struct hbg_priv *priv)
irq_names_map[i]);
}
vectors->stats_array = devm_kcalloc(&priv->pdev->dev,
ARRAY_SIZE(hbg_irqs),
sizeof(u64), GFP_KERNEL);
if (!vectors->stats_array)
return -ENOMEM;
vectors->info_array = hbg_irqs;
vectors->info_array_len = ARRAY_SIZE(hbg_irqs);
return 0;

View File

@ -21,7 +21,7 @@
static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled)
{
struct hbg_irq_info *info;
const struct hbg_irq_info *info;
u32 i;
for (i = 0; i < priv->vectors.info_array_len; i++) {
@ -203,12 +203,12 @@ static int hbg_net_change_mtu(struct net_device *netdev, int new_mtu)
if (netif_running(netdev))
return -EBUSY;
hbg_hw_set_mtu(priv, new_mtu);
WRITE_ONCE(netdev->mtu, new_mtu);
dev_dbg(&priv->pdev->dev,
"change mtu from %u to %u\n", netdev->mtu, new_mtu);
hbg_hw_set_mtu(priv, new_mtu);
WRITE_ONCE(netdev->mtu, new_mtu);
return 0;
}

View File

@ -2,6 +2,7 @@
// Copyright (c) 2024 Hisilicon Limited.
#include <linux/phy.h>
#include <linux/rtnetlink.h>
#include "hbg_common.h"
#include "hbg_hw.h"
#include "hbg_mdio.h"
@ -133,12 +134,17 @@ void hbg_fix_np_link_fail(struct hbg_priv *priv)
{
struct device *dev = &priv->pdev->dev;
rtnl_lock();
if (priv->stats.np_link_fail_cnt >= HBG_NP_LINK_FAIL_RETRY_TIMES) {
dev_err(dev, "failed to fix the MAC link status\n");
priv->stats.np_link_fail_cnt = 0;
return;
goto unlock;
}
if (!priv->mac.phydev->link)
goto unlock;
priv->stats.np_link_fail_cnt++;
dev_err(dev, "failed to link between MAC and PHY, try to fix...\n");
@ -147,6 +153,9 @@ void hbg_fix_np_link_fail(struct hbg_priv *priv)
*/
hbg_phy_stop(priv);
hbg_phy_start(priv);
unlock:
rtnl_unlock();
}
static void hbg_phy_adjust_link(struct net_device *netdev)

View File

@ -68,6 +68,7 @@
#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_REC_FILT_CTRL_PAUSE_FRM_PASS_B BIT(4)
#define HBG_REG_RX_OCTETS_TOTAL_OK_ADDR (HBG_REG_SGMII_BASE + 0x0080)
#define HBG_REG_RX_OCTETS_BAD_ADDR (HBG_REG_SGMII_BASE + 0x0084)
#define HBG_REG_RX_UC_PKTS_ADDR (HBG_REG_SGMII_BASE + 0x0088)
@ -134,6 +135,8 @@
#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)
#define HBG_REG_STATION_ADDR_LOW_MSK_0 (HBG_REG_SGMII_BASE + 0x0230)
#define HBG_REG_STATION_ADDR_LOW_MSK_1 (HBG_REG_SGMII_BASE + 0x0238)
/* PCU */
#define HBG_REG_TX_FIFO_THRSLD_ADDR (HBG_REG_SGMII_BASE + 0x0420)