[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231204084854.31543-1-quic_snehshah@quicinc.com>
Date: Mon, 4 Dec 2023 14:18:54 +0530
From: Sneh Shah <quic_snehshah@...cinc.com>
To: Vinod Koul <vkoul@...nel.org>,
Bhupesh Sharma <bhupesh.sharma@...aro.org>,
Alexandre Torgue <alexandre.torgue@...s.st.com>,
Jose Abreu <joabreu@...opsys.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Maxime Coquelin <mcoquelin.stm32@...il.com>,
netdev@...r.kernel.org, linux-arm-msm@...r.kernel.org,
linux-stm32@...md-mailman.stormreply.com,
linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org
Cc: Sneh Shah <quic_snehshah@...cinc.com>, kernel@...cinc.com,
Andrew Halaney <ahalaney@...hat.com>
Subject: [PATCH net-next] net: stmmac: qcom-ethqos: Add sysfs nodes for qcom ethqos
Add sysfs nodes to conifigure routing of specific vlan id to GVM queue.
GVM queue is not exposed to PVM stmmac, so TC ops can't configure routing.
Signed-off-by: Sneh Shah <quic_snehshah@...cinc.com>
---
.../stmicro/stmmac/dwmac-qcom-ethqos.c | 216 +++++++++++++++++-
1 file changed, 215 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index d3bf42d0fceb..ea89045a90a1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -109,6 +109,8 @@ struct qcom_ethqos {
unsigned int num_por;
bool rgmii_config_loopback_en;
bool has_emac_ge_3;
+ int gvm_vlan_prio;
+ int gvm_queue;
};
static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
@@ -710,6 +712,214 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
netdev_dbg(priv->dev, "PTP rate %d\n", plat_dat->clk_ptp_rate);
}
+static ssize_t gvm_vlan_routing_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *user_buf, size_t size)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct stmmac_priv *priv;
+ struct qcom_ethqos *ethqos;
+ u32 prio;
+ s8 input = 0;
+
+ if (!netdev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ priv = netdev_priv(netdev);
+ if (!priv) {
+ pr_err("priv is NULL\n");
+ return -EINVAL;
+ }
+
+ ethqos = priv->plat->bsp_priv;
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ if (kstrtos8(user_buf, 0, &input)) {
+ pr_err("Error in reading option from user\n");
+ return -EINVAL;
+ }
+
+ if (input < 1 || input > 7) {
+ pr_err("Invalid option set by user\n");
+ return -EINVAL;
+ }
+
+ if (input == ethqos->gvm_vlan_prio)
+ pr_err("No effect as duplicate input\n");
+
+ ethqos->gvm_vlan_prio = input;
+ prio = 1 << input;
+
+ stmmac_rx_queue_prio(priv, priv->hw, prio, ethqos->gvm_queue);
+
+ return size;
+}
+
+static ssize_t gvm_queue_mapping_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *user_buf, size_t size)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct stmmac_priv *priv;
+ struct qcom_ethqos *ethqos;
+ u32 prio;
+ s8 input = 0;
+
+ if (!netdev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ priv = netdev_priv(netdev);
+ if (!priv) {
+ pr_err("priv is NULL\n");
+ return -EINVAL;
+ }
+
+ ethqos = priv->plat->bsp_priv;
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ if (kstrtos8(user_buf, 0, &input)) {
+ pr_err("Error in reading option from user\n");
+ return -EINVAL;
+ }
+
+ if (input == ethqos->gvm_queue)
+ pr_err("No effect as duplicate input\n");
+
+ ethqos->gvm_queue = input;
+ prio = 1 << input;
+
+ return size;
+}
+
+static ssize_t gvm_queue_mapping_show(struct device *dev,
+ struct device_attribute *attr, char *user_buf)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct stmmac_priv *priv;
+ struct qcom_ethqos *ethqos;
+
+ if (!netdev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ priv = netdev_priv(netdev);
+ if (!priv) {
+ pr_err("priv is NULL\n");
+ return -EINVAL;
+ }
+
+ ethqos = priv->plat->bsp_priv;
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ return scnprintf(user_buf, 256, "%d\n", ethqos->gvm_queue);
+}
+
+static ssize_t gvm_vlan_routing_show(struct device *dev,
+ struct device_attribute *attr, char *user_buf)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct stmmac_priv *priv;
+ struct qcom_ethqos *ethqos;
+
+ if (!netdev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ priv = netdev_priv(netdev);
+ if (!priv) {
+ pr_err("priv is NULL\n");
+ return -EINVAL;
+ }
+
+ ethqos = priv->plat->bsp_priv;
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ return scnprintf(user_buf, 256, "%d\n", ethqos->gvm_vlan_prio);
+}
+
+static DEVICE_ATTR_RW(gvm_queue_mapping);
+
+static DEVICE_ATTR_RW(gvm_vlan_routing);
+
+static int ethqos_remove_sysfs(struct qcom_ethqos *ethqos)
+{
+ struct net_device *net_dev;
+
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ net_dev = platform_get_drvdata(ethqos->pdev);
+ if (!net_dev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ sysfs_remove_file(&net_dev->dev.kobj,
+ &dev_attr_gvm_queue_mapping.attr);
+ sysfs_remove_file(&net_dev->dev.kobj,
+ &dev_attr_gvm_vlan_routing.attr);
+
+ return 0;
+}
+
+static int ethqos_create_sysfs(struct qcom_ethqos *ethqos)
+{
+ int ret;
+ struct net_device *net_dev;
+
+ if (!ethqos) {
+ pr_err("ethqos is NULL\n");
+ return -EINVAL;
+ }
+
+ net_dev = platform_get_drvdata(ethqos->pdev);
+ if (!net_dev) {
+ pr_err("netdev is NULL\n");
+ return -EINVAL;
+ }
+
+ ret = sysfs_create_file(&net_dev->dev.kobj,
+ &dev_attr_gvm_queue_mapping.attr);
+ if (ret) {
+ pr_err("unable to create passthrough_en sysfs node\n");
+ goto fail;
+ }
+
+ ret = sysfs_create_file(&net_dev->dev.kobj,
+ &dev_attr_gvm_vlan_routing.attr);
+ if (ret) {
+ pr_err("unable to create cv2x_priority sysfs node\n");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ ethqos_remove_sysfs(ethqos);
+
+ return ret;
+}
+
static int qcom_ethqos_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -812,7 +1022,11 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
plat_dat->serdes_powerdown = qcom_ethqos_serdes_powerdown;
}
- return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
+ ret = devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
+ if (ret)
+ return ret;
+
+ return ethqos_create_sysfs(ethqos);
}
static const struct of_device_id qcom_ethqos_match[] = {
--
2.17.1
Powered by blists - more mailing lists