Commit f552b303 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'there-are-some-bugfix-for-the-hns3-ethernet-driver'

Jijie Shao says:

====================
There are some bugfix for the HNS3 ethernet driver

There's a series of bugfix that's been accepted:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=d80a3091308491455b6501b1c4b68698c4a7cd24

However, The series is making the driver poke into IOMMU internals instead of
implementing appropriate IOMMU workarounds. After discussion, the series was reverted:
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=249cfa318fb1b77eb726c2ff4f74c9685f04e568

But only two patches are related to the IOMMU.
Other patches involve only the modification of the driver.
This series resends other patches.

v2*: https://lore.kernel.org/20241217010839.1742227-1-shaojijie@huawei.com
v2: https://lore.kernel.org/20241216132346.1197079-1-shaojijie@huawei.com
v1: https://lore.kernel.org/20241107133023.3813095-1-shaojijie@huawei.com
====================

Link: https://patch.msgid.link/20250106143642.539698-1-shaojijie@huawei.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 80fb40ba 9741e72b
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -916,9 +916,6 @@ struct hnae3_handle {

	u8 netdev_flags;
	struct dentry *hnae3_dbgfs;
	/* protects concurrent contention between debugfs commands */
	struct mutex dbgfs_lock;
	char **dbgfs_buf;

	/* Network interface message level enabled bits */
	u32 msg_enable;
+31 −65
Original line number Diff line number Diff line
@@ -1260,69 +1260,55 @@ static int hns3_dbg_read_cmd(struct hns3_dbg_data *dbg_data,
static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
			     size_t count, loff_t *ppos)
{
	struct hns3_dbg_data *dbg_data = filp->private_data;
	char *buf = filp->private_data;

	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
}

static int hns3_dbg_open(struct inode *inode, struct file *filp)
{
	struct hns3_dbg_data *dbg_data = inode->i_private;
	struct hnae3_handle *handle = dbg_data->handle;
	struct hns3_nic_priv *priv = handle->priv;
	ssize_t size = 0;
	char **save_buf;
	char *read_buf;
	u32 index;
	char *buf;
	int ret;

	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
		return -EBUSY;

	ret = hns3_dbg_get_cmd_index(dbg_data, &index);
	if (ret)
		return ret;

	mutex_lock(&handle->dbgfs_lock);
	save_buf = &handle->dbgfs_buf[index];

	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
		ret = -EBUSY;
		goto out;
	}

	if (*save_buf) {
		read_buf = *save_buf;
	} else {
		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
		if (!read_buf) {
			ret = -ENOMEM;
			goto out;
		}

		/* save the buffer addr until the last read operation */
		*save_buf = read_buf;
	buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

		/* get data ready for the first time to read */
	ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
					read_buf, hns3_dbg_cmd[index].buf_len);
		if (ret)
			goto out;
	}

	size = simple_read_from_buffer(buffer, count, ppos, read_buf,
				       strlen(read_buf));
	if (size > 0) {
		mutex_unlock(&handle->dbgfs_lock);
		return size;
				buf, hns3_dbg_cmd[index].buf_len);
	if (ret) {
		kvfree(buf);
		return ret;
	}

out:
	/* free the buffer for the last read operation */
	if (*save_buf) {
		kvfree(*save_buf);
		*save_buf = NULL;
	filp->private_data = buf;
	return 0;
}

	mutex_unlock(&handle->dbgfs_lock);
	return ret;
static int hns3_dbg_release(struct inode *inode, struct file *filp)
{
	kvfree(filp->private_data);
	filp->private_data = NULL;
	return 0;
}

static const struct file_operations hns3_dbg_fops = {
	.owner = THIS_MODULE,
	.open  = simple_open,
	.open  = hns3_dbg_open,
	.read  = hns3_dbg_read,
	.release = hns3_dbg_release,
};

static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
@@ -1379,13 +1365,6 @@ int hns3_dbg_init(struct hnae3_handle *handle)
	int ret;
	u32 i;

	handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev,
					 ARRAY_SIZE(hns3_dbg_cmd),
					 sizeof(*handle->dbgfs_buf),
					 GFP_KERNEL);
	if (!handle->dbgfs_buf)
		return -ENOMEM;

	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
				debugfs_create_dir(name, hns3_dbgfs_root);
	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
@@ -1395,8 +1374,6 @@ int hns3_dbg_init(struct hnae3_handle *handle)
			debugfs_create_dir(hns3_dbg_dentry[i].name,
					   handle->hnae3_dbgfs);

	mutex_init(&handle->dbgfs_lock);

	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
		if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
		     ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
@@ -1425,24 +1402,13 @@ int hns3_dbg_init(struct hnae3_handle *handle)
out:
	debugfs_remove_recursive(handle->hnae3_dbgfs);
	handle->hnae3_dbgfs = NULL;
	mutex_destroy(&handle->dbgfs_lock);
	return ret;
}

void hns3_dbg_uninit(struct hnae3_handle *handle)
{
	u32 i;

	debugfs_remove_recursive(handle->hnae3_dbgfs);
	handle->hnae3_dbgfs = NULL;

	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
		if (handle->dbgfs_buf[i]) {
			kvfree(handle->dbgfs_buf[i]);
			handle->dbgfs_buf[i] = NULL;
		}

	mutex_destroy(&handle->dbgfs_lock);
}

void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
+0 −1
Original line number Diff line number Diff line
@@ -2452,7 +2452,6 @@ static int hns3_nic_set_features(struct net_device *netdev,
			return ret;
	}

	netdev->features = features;
	return 0;
}

+36 −9
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@@ -3574,6 +3575,17 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
	return ret;
}

static void hclge_set_reset_pending(struct hclge_dev *hdev,
				    enum hnae3_reset_type reset_type)
{
	/* When an incorrect reset type is executed, the get_reset_level
	 * function generates the HNAE3_NONE_RESET flag. As a result, this
	 * type do not need to pending.
	 */
	if (reset_type != HNAE3_NONE_RESET)
		set_bit(reset_type, &hdev->reset_pending);
}

static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
{
	u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg;
@@ -3594,7 +3606,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
	 */
	if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) {
		dev_info(&hdev->pdev->dev, "IMP reset interrupt\n");
		set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
		hclge_set_reset_pending(hdev, HNAE3_IMP_RESET);
		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
		*clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
		hdev->rst_stats.imp_rst_cnt++;
@@ -3604,7 +3616,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
	if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) {
		dev_info(&hdev->pdev->dev, "global reset interrupt\n");
		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
		set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
		hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET);
		*clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
		hdev->rst_stats.global_rst_cnt++;
		return HCLGE_VECTOR0_EVENT_RST;
@@ -3759,7 +3771,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
	snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s",
		 HCLGE_NAME, pci_name(hdev->pdev));
	ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
			  0, hdev->misc_vector.name, hdev);
			  IRQF_NO_AUTOEN, hdev->misc_vector.name, hdev);
	if (ret) {
		hclge_free_vector(hdev, 0);
		dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
@@ -4052,7 +4064,7 @@ static void hclge_do_reset(struct hclge_dev *hdev)
	case HNAE3_FUNC_RESET:
		dev_info(&pdev->dev, "PF reset requested\n");
		/* schedule again to check later */
		set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
		hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET);
		hclge_reset_task_schedule(hdev);
		break;
	default:
@@ -4086,6 +4098,8 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev,
		clear_bit(HNAE3_FLR_RESET, addr);
	}

	clear_bit(HNAE3_NONE_RESET, addr);

	if (hdev->reset_type != HNAE3_NONE_RESET &&
	    rst_level < hdev->reset_type)
		return HNAE3_NONE_RESET;
@@ -4227,7 +4241,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
		return false;
	} else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) {
		hdev->rst_stats.reset_fail_cnt++;
		set_bit(hdev->reset_type, &hdev->reset_pending);
		hclge_set_reset_pending(hdev, hdev->reset_type);
		dev_info(&hdev->pdev->dev,
			 "re-schedule reset task(%u)\n",
			 hdev->rst_stats.reset_fail_cnt);
@@ -4470,8 +4484,20 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
					enum hnae3_reset_type rst_type)
{
#define HCLGE_SUPPORT_RESET_TYPE \
	(BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \
	BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET))

	struct hclge_dev *hdev = ae_dev->priv;

	if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) {
		/* To prevent reset triggered by hclge_reset_event */
		set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
		dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n",
			 rst_type);
		return;
	}

	set_bit(rst_type, &hdev->default_reset_request);
}

@@ -11881,9 +11907,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)

	hclge_init_rxd_adv_layout(hdev);

	/* Enable MISC vector(vector0) */
	hclge_enable_vector(&hdev->misc_vector, true);

	ret = hclge_init_wol(hdev);
	if (ret)
		dev_warn(&pdev->dev,
@@ -11896,6 +11919,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
	hclge_state_init(hdev);
	hdev->last_reset_time = jiffies;

	/* Enable MISC vector(vector0) */
	enable_irq(hdev->misc_vector.vector_irq);
	hclge_enable_vector(&hdev->misc_vector, true);

	dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
		 HCLGE_DRIVER_NAME);

@@ -12301,7 +12328,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)

	/* Disable MISC vector(vector0) */
	hclge_enable_vector(&hdev->misc_vector, false);
	synchronize_irq(hdev->misc_vector.vector_irq);
	disable_irq(hdev->misc_vector.vector_irq);

	/* Disable all hw interrupts */
	hclge_config_mac_tnl_int(hdev, false);
+3 −0
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
	struct hclge_dev *hdev = vport->back;
	struct hclge_ptp *ptp = hdev->ptp;

	if (!ptp)
		return false;

	if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
	    test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
		ptp->tx_skipped++;
Loading