public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Jijie Shao <shaojijie@huawei.com>
To: <yisen.zhuang@huawei.com>, <salil.mehta@huawei.com>,
	<davem@davemloft.net>, <edumazet@google.com>, <kuba@kernel.org>,
	<pabeni@redhat.com>, <horms@kernel.org>
Cc: <shenjian15@huawei.com>, <wangpeiyang1@huawei.com>,
	<liuyonglong@huawei.com>, <shaojijie@huawei.com>,
	<sudongming1@huawei.com>, <xujunsheng@huawei.com>,
	<shiyongbang@huawei.com>, <netdev@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Subject: [RFC PATCH net-next 08/10] net: hibmcge: Implement workqueue and some ethtool_ops functions
Date: Wed, 31 Jul 2024 17:42:43 +0800	[thread overview]
Message-ID: <20240731094245.1967834-9-shaojijie@huawei.com> (raw)
In-Reply-To: <20240731094245.1967834-1-shaojijie@huawei.com>

Implement a workqueue in this module, The workqueue is invoked
once every second to update link status.

Implement the .get_drvinfo .get_link .get_link_ksettings to get
the basic information and working status of the driver.
Implement the .set_link_ksettings to modify the rate, duplex,
and auto-negotiation status.

Signed-off-by: Jijie Shao <shaojijie@huawei.com>
---
 .../ethernet/hisilicon/hibmcge/hbg_common.h   |  1 +
 .../ethernet/hisilicon/hibmcge/hbg_ethtool.c  | 56 +++++++++++
 .../ethernet/hisilicon/hibmcge/hbg_ethtool.h  | 11 +++
 .../net/ethernet/hisilicon/hibmcge/hbg_main.c | 96 ++++++++++++++++++-
 4 files changed, 161 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
 create mode 100644 drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h

diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
index 25563af04897..45ec4b463e70 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h
@@ -146,6 +146,7 @@ struct hbg_priv {
 	struct hbg_vector vectors;
 	struct hbg_ring tx_ring;
 	struct hbg_ring rx_ring;
+	struct delayed_work service_task;
 };
 
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
new file mode 100644
index 000000000000..3acd6eae189e
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2024 Hisilicon Limited.
+
+#include <linux/ethtool.h>
+#include <linux/phy.h>
+#include "hbg_common.h"
+#include "hbg_ethtool.h"
+#include "hbg_hw.h"
+#include "hbg_main.h"
+#include "hbg_mdio.h"
+
+static void hbg_ethtool_get_drvinfo(struct net_device *netdev,
+				    struct ethtool_drvinfo *drvinfo)
+{
+	strscpy(drvinfo->version, HBG_MOD_VERSION, sizeof(drvinfo->version));
+	drvinfo->version[sizeof(drvinfo->version) - 1] = '\0';
+}
+
+static u32 hbg_ethtool_get_link(struct net_device *netdev)
+{
+	struct hbg_priv *priv = netdev_priv(netdev);
+
+	return priv->mac.link_status;
+}
+
+static int hbg_ethtool_get_ksettings(struct net_device *netdev,
+				     struct ethtool_link_ksettings *ksettings)
+{
+	struct hbg_priv *priv = netdev_priv(netdev);
+
+	phy_ethtool_ksettings_get(priv->mac.phydev, ksettings);
+	return 0;
+}
+
+static int hbg_ethtool_set_ksettings(struct net_device *netdev,
+				     const struct ethtool_link_ksettings *cmd)
+{
+	struct hbg_priv *priv = netdev_priv(netdev);
+
+	if (cmd->base.speed == SPEED_1000 && cmd->base.duplex == DUPLEX_HALF)
+		return -EINVAL;
+
+	return phy_ethtool_ksettings_set(priv->mac.phydev, cmd);
+}
+
+static const struct ethtool_ops hbg_ethtool_ops = {
+	.get_drvinfo		= hbg_ethtool_get_drvinfo,
+	.get_link		= hbg_ethtool_get_link,
+	.get_link_ksettings	= hbg_ethtool_get_ksettings,
+	.set_link_ksettings	= hbg_ethtool_set_ksettings,
+};
+
+void hbg_ethtool_set_ops(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &hbg_ethtool_ops;
+}
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h
new file mode 100644
index 000000000000..628707ec2686
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (c) 2024 Hisilicon Limited. */
+
+#ifndef __HBG_ETHTOOL_H
+#define __HBG_ETHTOOL_H
+
+#include <linux/netdevice.h>
+
+void hbg_ethtool_set_ops(struct net_device *netdev);
+
+#endif
diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
index bb5f8321da8a..bea596123c37 100644
--- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
+++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c
@@ -6,12 +6,15 @@
 #include <linux/netdevice.h>
 #include <linux/pci.h>
 #include "hbg_common.h"
+#include "hbg_ethtool.h"
 #include "hbg_hw.h"
 #include "hbg_irq.h"
 #include "hbg_main.h"
 #include "hbg_mdio.h"
 #include "hbg_txrx.h"
 
+static struct workqueue_struct *hbg_workqueue;
+
 static void hbg_enable_intr(struct hbg_priv *priv, bool enabled)
 {
 	u32 i;
@@ -136,6 +139,52 @@ static const struct net_device_ops hbg_netdev_ops = {
 	.ndo_tx_timeout		= hbg_net_tx_timeout,
 };
 
+static void hbg_update_link_status(struct hbg_priv *priv)
+{
+	u32 link;
+
+	link = hbg_get_link_status(priv);
+	if (link == priv->mac.link_status)
+		return;
+
+	priv->mac.link_status = link;
+	if (link == HBG_LINK_DOWN) {
+		netif_carrier_off(priv->netdev);
+		netif_tx_stop_all_queues(priv->netdev);
+		dev_info(&priv->pdev->dev, "link down!");
+	} else {
+		netif_tx_wake_all_queues(priv->netdev);
+		netif_carrier_on(priv->netdev);
+		dev_info(&priv->pdev->dev, "link up!");
+	}
+}
+
+static void hbg_service_task(struct work_struct *work)
+{
+	struct hbg_priv *priv =
+		container_of(work, struct hbg_priv, service_task.work);
+
+	hbg_update_link_status(priv);
+
+	mod_delayed_work(hbg_workqueue, &priv->service_task,
+			 round_jiffies_relative(HZ));
+}
+
+static void hbg_delaywork_init(struct hbg_priv *priv)
+{
+	INIT_DELAYED_WORK(&priv->service_task, hbg_service_task);
+	mod_delayed_work(hbg_workqueue, &priv->service_task,
+			 round_jiffies_relative(HZ));
+}
+
+static void hbg_delaywork_uninit(void *data)
+{
+	struct hbg_priv *priv = data;
+
+	if (priv->service_task.work.func)
+		cancel_delayed_work_sync(&priv->service_task);
+}
+
 static const u32 hbg_mode_ability[] = {
 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
 	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
@@ -177,12 +226,17 @@ static int hbg_init(struct net_device *netdev)
 	ret = hbg_irq_init(priv);
 	if (ret)
 		return ret;
-
 	ret = devm_add_action_or_reset(&priv->pdev->dev, hbg_irq_uninit, priv);
 	if (ret)
 		return ret;
 
-	return hbg_mac_init(priv);
+	ret = hbg_mac_init(priv);
+	if (ret)
+		return ret;
+
+	hbg_delaywork_init(priv);
+	return devm_add_action_or_reset(&priv->pdev->dev,
+					hbg_delaywork_uninit, priv);
 }
 
 static int hbg_pci_init(struct pci_dev *pdev)
@@ -249,6 +303,7 @@ static int hbg_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return dev_err_probe(&pdev->dev, ret,
 				     "failed to register netdev\n");
 
+	hbg_ethtool_set_ops(netdev);
 	set_bit(HBG_NIC_STATE_INITED, &priv->state);
 	return 0;
 }
@@ -264,7 +319,42 @@ 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_workqueue = alloc_workqueue("%s", WQ_UNBOUND, 0, HBG_DEV_NAME);
+	if (!hbg_workqueue) {
+		pr_err("%s: failed to create workqueue\n", HBG_DEV_NAME);
+		return -ENOMEM;
+	}
+
+	ret = pci_register_driver(&hbg_driver);
+	if (ret) {
+		pr_err("%s: failed to register PCI driver, ret = %d\n",
+		       HBG_DEV_NAME, ret);
+		goto err_destroy_workqueue;
+	}
+
+	return 0;
+
+err_destroy_workqueue:
+	destroy_workqueue(hbg_workqueue);
+	hbg_workqueue = NULL;
+
+	return ret;
+}
+module_init(hbg_module_init);
+
+static void __exit hbg_module_exit(void)
+{
+	pci_unregister_driver(&hbg_driver);
+	flush_workqueue(hbg_workqueue);
+	destroy_workqueue(hbg_workqueue);
+	hbg_workqueue = NULL;
+}
+module_exit(hbg_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
-- 
2.33.0


  parent reply	other threads:[~2024-07-31  9:48 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-31  9:42 [RFC PATCH net-next 00/10] Add support of HIBMCGE Ethernet Driver Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 01/10] net: hibmcge: Add pci table supported in this module Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 02/10] net: hibmcge: Add read/write registers supported through the bar space Jijie Shao
2024-08-05 12:55   ` Simon Horman
2024-08-05 13:08     ` Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 03/10] net: hibmcge: Add mdio and hardware configuration supported in this module Jijie Shao
2024-08-01  0:42   ` Andrew Lunn
2024-08-01  9:04     ` Jijie Shao
2024-08-01 12:07       ` Andrew Lunn
2024-07-31  9:42 ` [RFC PATCH net-next 04/10] net: hibmcge: Add interrupt " Jijie Shao
2024-07-31 13:14   ` Joe Damato
2024-08-01 11:31     ` Jijie Shao
2024-08-05 12:57   ` Simon Horman
2024-08-05 13:29     ` Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 05/10] net: hibmcge: Implement some .ndo functions Jijie Shao
2024-08-01  0:51   ` Andrew Lunn
2024-08-01  9:13     ` Jijie Shao
2024-08-01 12:18       ` Andrew Lunn
2024-08-01 12:33         ` Jijie Shao
2024-08-01 12:36           ` Andrew Lunn
2024-08-01 13:08             ` Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 06/10] net: hibmcge: Implement .ndo_start_xmit function Jijie Shao
2024-07-31  9:42 ` [RFC PATCH net-next 07/10] net: hibmcge: Implement rx_poll function to receive packets Jijie Shao
2024-07-31 13:23   ` Joe Damato
2024-08-01 11:58     ` Jijie Shao
2024-07-31  9:42 ` Jijie Shao [this message]
2024-08-01  1:10   ` [RFC PATCH net-next 08/10] net: hibmcge: Implement workqueue and some ethtool_ops functions Andrew Lunn
2024-08-01 11:10     ` Jijie Shao
2024-08-01 12:26       ` Andrew Lunn
2024-08-01 13:06         ` Jijie Shao
2024-08-01 20:16           ` Andrew Lunn
2024-07-31  9:42 ` [RFC PATCH net-next 09/10] net: hibmcge: Add a Makefile and update Kconfig for hibmcge Jijie Shao
2024-08-01  1:13   ` Andrew Lunn
2024-08-01 12:15     ` Jijie Shao
2024-08-01 12:33       ` Andrew Lunn
2024-07-31  9:42 ` [RFC PATCH net-next 10/10] net: hibmcge: Add maintainer " Jijie Shao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240731094245.1967834-9-shaojijie@huawei.com \
    --to=shaojijie@huawei.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuyonglong@huawei.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=salil.mehta@huawei.com \
    --cc=shenjian15@huawei.com \
    --cc=shiyongbang@huawei.com \
    --cc=sudongming1@huawei.com \
    --cc=wangpeiyang1@huawei.com \
    --cc=xujunsheng@huawei.com \
    --cc=yisen.zhuang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox