On Mon, Dec 04, 2023 at 02:18:54PM +0530, Sneh Shah wrote: > 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. > Perhaps I'm just not familiar enough with the details of stmmac, but can you please describe what PVM and GVM is? Regards, Bjorn > Signed-off-by: Sneh Shah <quic_snehshah@xxxxxxxxxxx> > --- > .../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 > >