Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH netfilter-next] xt_osf: Use continue to reduce indentation
From: Pablo Neira Ayuso @ 2014-12-23 13:22 UTC (permalink / raw)
  To: Evgeniy Polyakov
  Cc: Joe Perches, Patrick McHardy, Jozsef Kadlecsik, netfilter-devel,
	netdev, LKML
In-Reply-To: <8632531418806285@web23h.yandex.ru>

On Wed, Dec 17, 2014 at 11:51:25AM +0300, Evgeniy Polyakov wrote:
> Hi everyone
> 
> 16.12.2014, 23:17, "Joe Perches" <joe@perches.com>:
> > Invert logic in test to use continue.
> >
> > This routine already uses continue, use it a bit more to
> > minimize > 80 column long lines and unnecessary indentation.
> >
> > No change in compiled object file.
> 
> Looks good. Thank you.
> Which tree should this patch go through? Please pull it in.
> 
> Acked-by: Evgeniy Polyakov <zbr@ioremap.net>

Applied to nf-next, thanks.

^ permalink raw reply

* Re: [PATCH netfilter-next] xt_osf: Use continue to reduce indentation
From: Pablo Neira Ayuso @ 2014-12-23 13:17 UTC (permalink / raw)
  To: Evgeniy Polyakov
  Cc: Joe Perches, Patrick McHardy, Jozsef Kadlecsik, netfilter-devel,
	netdev, LKML
In-Reply-To: <8632531418806285@web23h.yandex.ru>

On Wed, Dec 17, 2014 at 11:51:25AM +0300, Evgeniy Polyakov wrote:
> Hi everyone
> 
> 16.12.2014, 23:17, "Joe Perches" <joe@perches.com>:
> > Invert logic in test to use continue.
> >
> > This routine already uses continue, use it a bit more to
> > minimize > 80 column long lines and unnecessary indentation.
> >
> > No change in compiled object file.
> 
> Looks good. Thank you.
> Which tree should this patch go through? Please pull it in.
> 
> Acked-by: Evgeniy Polyakov <zbr@ioremap.net>

Applied to nf-next, thanks.

^ permalink raw reply

* [PATCH] net: xilinx: Remove unnecessary temac_property in the driver
From: Kedareswara rao Appana @ 2014-12-23 12:37 UTC (permalink / raw)
  To: anirudh-gjFFaj9aHVfQT0dZR+AlfA, John.Linn-gjFFaj9aHVfQT0dZR+AlfA,
	michal.simek-gjFFaj9aHVfQT0dZR+AlfA,
	soren.brinkmann-gjFFaj9aHVfQT0dZR+AlfA,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Kedareswara rao Appana

This property is no longer used in the code yet the code looks for it in the device tree.
It does not cause an error if it's not in the tree.

Signed-off-by: Kedareswara rao Appana <appanad-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
---
 drivers/net/ethernet/xilinx/xilinx_axienet.h      |    2 --
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c |    4 ----
 2 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index 44b8d2b..4c9b4fa 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -388,7 +388,6 @@ struct axidma_bd {
  * @dma_err_tasklet: Tasklet structure to process Axi DMA errors
  * @tx_irq:	Axidma TX IRQ number
  * @rx_irq:	Axidma RX IRQ number
- * @temac_type:	axienet type to identify between soft and hard temac
  * @phy_type:	Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X
  * @options:	AxiEthernet option word
  * @last_link:	Phy link state in which the PHY was negotiated earlier
@@ -431,7 +430,6 @@ struct axienet_local {
 
 	int tx_irq;
 	int rx_irq;
-	u32 temac_type;
 	u32 phy_type;
 
 	u32 options;			/* Current options word */
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 4ea2d4e..c18a0c6 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1555,10 +1555,6 @@ static int axienet_of_probe(struct platform_device *op)
 		if ((be32_to_cpup(p)) >= 0x4000)
 			lp->jumbo_support = 1;
 	}
-	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type",
-				       NULL);
-	if (p)
-		lp->temac_type = be32_to_cpup(p);
 	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL);
 	if (p)
 		lp->phy_type = be32_to_cpup(p);
-- 
1.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v4] can: Convert to runtime_pm
From: Kedareswara rao Appana @ 2014-12-23 12:22 UTC (permalink / raw)
  To: wg, mkl, michal.simek, grant.likely
  Cc: netdev, Kedareswara rao Appana, Soren Brinkmann

Instead of enabling/disabling clocks at several locations in the driver,
use the runtime_pm framework. This consolidates the actions for
runtime PM in the appropriate callbacks and makes the driver more
readable and mantainable.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Chnages for v4:
 - Updated with the review comments.
Changes for v3:
  - Converted the driver to use runtime_pm.
Changes for v2:
  - Removed the struct platform_device* from suspend/resume
    as suggest by Lothar.

 drivers/net/can/xilinx_can.c |  123 +++++++++++++++++++++++++-----------------
 1 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 6c67643..c71f683 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -32,6 +32,7 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 #include <linux/can/led.h>
+#include <linux/pm_runtime.h>
 
 #define DRIVER_NAME	"xilinx_can"
 
@@ -138,7 +139,7 @@ struct xcan_priv {
 	u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
 	void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
 			u32 val);
-	struct net_device *dev;
+	struct device *dev;
 	void __iomem *reg_base;
 	unsigned long irq_flags;
 	struct clk *bus_clk;
@@ -842,6 +843,13 @@ static int xcan_open(struct net_device *ndev)
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+				__func__, ret);
+		return ret;
+	}
+
 	ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
 			ndev->name, ndev);
 	if (ret < 0) {
@@ -849,29 +857,17 @@ static int xcan_open(struct net_device *ndev)
 		goto err;
 	}
 
-	ret = clk_prepare_enable(priv->can_clk);
-	if (ret) {
-		netdev_err(ndev, "unable to enable device clock\n");
-		goto err_irq;
-	}
-
-	ret = clk_prepare_enable(priv->bus_clk);
-	if (ret) {
-		netdev_err(ndev, "unable to enable bus clock\n");
-		goto err_can_clk;
-	}
-
 	/* Set chip into reset mode */
 	ret = set_reset_mode(ndev);
 	if (ret < 0) {
 		netdev_err(ndev, "mode resetting failed!\n");
-		goto err_bus_clk;
+		goto err_irq;
 	}
 
 	/* Common open */
 	ret = open_candev(ndev);
 	if (ret)
-		goto err_bus_clk;
+		goto err_irq;
 
 	ret = xcan_chip_start(ndev);
 	if (ret < 0) {
@@ -887,13 +883,11 @@ static int xcan_open(struct net_device *ndev)
 
 err_candev:
 	close_candev(ndev);
-err_bus_clk:
-	clk_disable_unprepare(priv->bus_clk);
-err_can_clk:
-	clk_disable_unprepare(priv->can_clk);
 err_irq:
 	free_irq(ndev->irq, ndev);
 err:
+	pm_runtime_put(priv->dev);
+
 	return ret;
 }
 
@@ -910,12 +904,11 @@ static int xcan_close(struct net_device *ndev)
 	netif_stop_queue(ndev);
 	napi_disable(&priv->napi);
 	xcan_chip_stop(ndev);
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
 	free_irq(ndev->irq, ndev);
 	close_candev(ndev);
 
 	can_led_event(ndev, CAN_LED_EVENT_STOP);
+	pm_runtime_put(priv->dev);
 
 	return 0;
 }
@@ -934,27 +927,20 @@ static int xcan_get_berr_counter(const struct net_device *ndev,
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
-	ret = clk_prepare_enable(priv->can_clk);
-	if (ret)
-		goto err;
-
-	ret = clk_prepare_enable(priv->bus_clk);
-	if (ret)
-		goto err_clk;
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+				__func__, ret);
+		return ret;
+	}
 
 	bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
 	bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
 			XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
 
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
+	pm_runtime_put(priv->dev);
 
 	return 0;
-
-err_clk:
-	clk_disable_unprepare(priv->can_clk);
-err:
-	return ret;
 }
 
 
@@ -967,15 +953,45 @@ static const struct net_device_ops xcan_netdev_ops = {
 
 /**
  * xcan_suspend - Suspend method for the driver
- * @dev:	Address of the platform_device structure
+ * @dev:	Address of the device structure
  *
  * Put the driver into low power mode.
- * Return: 0 always
+ * Return: 0 on success and failure value on error
  */
 static int __maybe_unused xcan_suspend(struct device *dev)
 {
-	struct platform_device *pdev = dev_get_drvdata(dev);
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	if (!device_may_wakeup(dev))
+		return pm_runtime_force_suspend(dev);
+
+	return 0;
+}
+
+/**
+ * xcan_resume - Resume from suspend
+ * @dev:	Address of the device structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused xcan_resume(struct device *dev)
+{
+	if (!device_may_wakeup(dev))
+		return pm_runtime_force_resume(dev);
+
+	return 0;
+
+}
+
+/**
+ * xcan_runtime_suspend - Runtime suspend method for the driver
+ * @dev:	Address of the device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 always
+ */
+static int __maybe_unused xcan_runtime_suspend(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct xcan_priv *priv = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
@@ -993,16 +1009,15 @@ static int __maybe_unused xcan_suspend(struct device *dev)
 }
 
 /**
- * xcan_resume - Resume from suspend
- * @dev:	Address of the platformdevice structure
+ * xcan_runtime_resume - Runtime resume from suspend
+ * @dev:	Address of the device structure
  *
  * Resume operation after suspend.
  * Return: 0 on success and failure value on error
  */
-static int __maybe_unused xcan_resume(struct device *dev)
+static int __maybe_unused xcan_runtime_resume(struct device *dev)
 {
-	struct platform_device *pdev = dev_get_drvdata(dev);
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
@@ -1020,9 +1035,9 @@ static int __maybe_unused xcan_resume(struct device *dev)
 
 	priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
 	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
-	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
 	if (netif_running(ndev)) {
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
 		netif_device_attach(ndev);
 		netif_start_queue(ndev);
 	}
@@ -1030,7 +1045,10 @@ static int __maybe_unused xcan_resume(struct device *dev)
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+static const struct dev_pm_ops xcan_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xcan_suspend, xcan_resume)
+	SET_PM_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL)
+};
 
 /**
  * xcan_probe - Platform registration call
@@ -1071,7 +1089,7 @@ static int xcan_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	priv = netdev_priv(ndev);
-	priv->dev = ndev;
+	priv->dev = &pdev->dev;
 	priv->can.bittiming_const = &xcan_bittiming_const;
 	priv->can.do_set_mode = xcan_do_set_mode;
 	priv->can.do_get_berr_counter = xcan_get_berr_counter;
@@ -1137,15 +1155,22 @@ static int xcan_probe(struct platform_device *pdev)
 
 	netif_napi_add(ndev, &priv->napi, xcan_rx_poll, rx_max);
 
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_irq_safe(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
 	ret = register_candev(ndev);
 	if (ret) {
 		dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
+		pm_runtime_put(priv->dev);
 		goto err_unprepare_disable_busclk;
 	}
 
 	devm_can_led_init(ndev);
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
+
+	pm_runtime_put(&pdev->dev);
+
 	netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
 			priv->reg_base, ndev->irq, priv->can.clock.freq,
 			priv->tx_max);
-- 
1.7.4

^ permalink raw reply related

* RE: [PATCH v4] can: Convert to runtime_pm
From: Appana Durga Kedareswara Rao @ 2014-12-23 12:27 UTC (permalink / raw)
  To: Appana Durga Kedareswara Rao, wg@grandegger.com,
	mkl@pengutronix.de, Michal Simek, grant.likely@linaro.org
  Cc: linux-can@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Soren Brinkmann
In-Reply-To: <1419337510-6284-1-git-send-email-appanad@xilinx.com>

Hi Marc,

I tried by splitting the xcan_berr_counter to __xcan_berr_counter but still seeing
the same crash as pointed by the Soren in the previous version of the patch.
Updated the driver with the other review comments in this patch.

Regards,
Kedar.


-----Original Message-----
From: Kedareswara rao Appana [mailto:appana.durga.rao@xilinx.com]
Sent: Tuesday, December 23, 2014 5:55 PM
To: wg@grandegger.com; mkl@pengutronix.de; Michal Simek; grant.likely@linaro.org
Cc: linux-can@vger.kernel.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Appana Durga Kedareswara Rao; Soren Brinkmann
Subject: [PATCH v4] can: Convert to runtime_pm

Instead of enabling/disabling clocks at several locations in the driver, use the runtime_pm framework. This consolidates the actions for runtime PM in the appropriate callbacks and makes the driver more readable and mantainable.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Chnages for v4:
 - Updated with the review comments.
Changes for v3:
  - Converted the driver to use runtime_pm.
Changes for v2:
  - Removed the struct platform_device* from suspend/resume
    as suggest by Lothar.

 drivers/net/can/xilinx_can.c |  123 +++++++++++++++++++++++++-----------------
 1 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 6c67643..c71f683 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -32,6 +32,7 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 #include <linux/can/led.h>
+#include <linux/pm_runtime.h>

 #define DRIVER_NAME    "xilinx_can"

@@ -138,7 +139,7 @@ struct xcan_priv {
        u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
        void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
                        u32 val);
-       struct net_device *dev;
+       struct device *dev;
        void __iomem *reg_base;
        unsigned long irq_flags;
        struct clk *bus_clk;
@@ -842,6 +843,13 @@ static int xcan_open(struct net_device *ndev)
        struct xcan_priv *priv = netdev_priv(ndev);
        int ret;

+       ret = pm_runtime_get_sync(priv->dev);
+       if (ret < 0) {
+               netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+                               __func__, ret);
+               return ret;
+       }
+
        ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
                        ndev->name, ndev);
        if (ret < 0) {
@@ -849,29 +857,17 @@ static int xcan_open(struct net_device *ndev)
                goto err;
        }

-       ret = clk_prepare_enable(priv->can_clk);
-       if (ret) {
-               netdev_err(ndev, "unable to enable device clock\n");
-               goto err_irq;
-       }
-
-       ret = clk_prepare_enable(priv->bus_clk);
-       if (ret) {
-               netdev_err(ndev, "unable to enable bus clock\n");
-               goto err_can_clk;
-       }
-
        /* Set chip into reset mode */
        ret = set_reset_mode(ndev);
        if (ret < 0) {
                netdev_err(ndev, "mode resetting failed!\n");
-               goto err_bus_clk;
+               goto err_irq;
        }

        /* Common open */
        ret = open_candev(ndev);
        if (ret)
-               goto err_bus_clk;
+               goto err_irq;

        ret = xcan_chip_start(ndev);
        if (ret < 0) {
@@ -887,13 +883,11 @@ static int xcan_open(struct net_device *ndev)

 err_candev:
        close_candev(ndev);
-err_bus_clk:
-       clk_disable_unprepare(priv->bus_clk);
-err_can_clk:
-       clk_disable_unprepare(priv->can_clk);
 err_irq:
        free_irq(ndev->irq, ndev);
 err:
+       pm_runtime_put(priv->dev);
+
        return ret;
 }

@@ -910,12 +904,11 @@ static int xcan_close(struct net_device *ndev)
        netif_stop_queue(ndev);
        napi_disable(&priv->napi);
        xcan_chip_stop(ndev);
-       clk_disable_unprepare(priv->bus_clk);
-       clk_disable_unprepare(priv->can_clk);
        free_irq(ndev->irq, ndev);
        close_candev(ndev);

        can_led_event(ndev, CAN_LED_EVENT_STOP);
+       pm_runtime_put(priv->dev);

        return 0;
 }
@@ -934,27 +927,20 @@ static int xcan_get_berr_counter(const struct net_device *ndev,
        struct xcan_priv *priv = netdev_priv(ndev);
        int ret;

-       ret = clk_prepare_enable(priv->can_clk);
-       if (ret)
-               goto err;
-
-       ret = clk_prepare_enable(priv->bus_clk);
-       if (ret)
-               goto err_clk;
+       ret = pm_runtime_get_sync(priv->dev);
+       if (ret < 0) {
+               netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+                               __func__, ret);
+               return ret;
+       }

        bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
        bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
                        XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);

-       clk_disable_unprepare(priv->bus_clk);
-       clk_disable_unprepare(priv->can_clk);
+       pm_runtime_put(priv->dev);

        return 0;
-
-err_clk:
-       clk_disable_unprepare(priv->can_clk);
-err:
-       return ret;
 }


@@ -967,15 +953,45 @@ static const struct net_device_ops xcan_netdev_ops = {

 /**
  * xcan_suspend - Suspend method for the driver
- * @dev:       Address of the platform_device structure
+ * @dev:       Address of the device structure
  *
  * Put the driver into low power mode.
- * Return: 0 always
+ * Return: 0 on success and failure value on error
  */
 static int __maybe_unused xcan_suspend(struct device *dev)  {
-       struct platform_device *pdev = dev_get_drvdata(dev);
-       struct net_device *ndev = platform_get_drvdata(pdev);
+       if (!device_may_wakeup(dev))
+               return pm_runtime_force_suspend(dev);
+
+       return 0;
+}
+
+/**
+ * xcan_resume - Resume from suspend
+ * @dev:       Address of the device structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error  */ static int
+__maybe_unused xcan_resume(struct device *dev) {
+       if (!device_may_wakeup(dev))
+               return pm_runtime_force_resume(dev);
+
+       return 0;
+
+}
+
+/**
+ * xcan_runtime_suspend - Runtime suspend method for the driver
+ * @dev:       Address of the device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 always
+ */
+static int __maybe_unused xcan_runtime_suspend(struct device *dev) {
+       struct net_device *ndev = dev_get_drvdata(dev);
        struct xcan_priv *priv = netdev_priv(ndev);

        if (netif_running(ndev)) {
@@ -993,16 +1009,15 @@ static int __maybe_unused xcan_suspend(struct device *dev)  }

 /**
- * xcan_resume - Resume from suspend
- * @dev:       Address of the platformdevice structure
+ * xcan_runtime_resume - Runtime resume from suspend
+ * @dev:       Address of the device structure
  *
  * Resume operation after suspend.
  * Return: 0 on success and failure value on error
  */
-static int __maybe_unused xcan_resume(struct device *dev)
+static int __maybe_unused xcan_runtime_resume(struct device *dev)
 {
-       struct platform_device *pdev = dev_get_drvdata(dev);
-       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct net_device *ndev = dev_get_drvdata(dev);
        struct xcan_priv *priv = netdev_priv(ndev);
        int ret;

@@ -1020,9 +1035,9 @@ static int __maybe_unused xcan_resume(struct device *dev)

        priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
        priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
-       priv->can.state = CAN_STATE_ERROR_ACTIVE;

        if (netif_running(ndev)) {
+               priv->can.state = CAN_STATE_ERROR_ACTIVE;
                netif_device_attach(ndev);
                netif_start_queue(ndev);
        }
@@ -1030,7 +1045,10 @@ static int __maybe_unused xcan_resume(struct device *dev)
        return 0;
 }

-static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+static const struct dev_pm_ops xcan_dev_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(xcan_suspend, xcan_resume)
+       SET_PM_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL)
+};

 /**
  * xcan_probe - Platform registration call @@ -1071,7 +1089,7 @@ static int xcan_probe(struct platform_device *pdev)
                return -ENOMEM;

        priv = netdev_priv(ndev);
-       priv->dev = ndev;
+       priv->dev = &pdev->dev;
        priv->can.bittiming_const = &xcan_bittiming_const;
        priv->can.do_set_mode = xcan_do_set_mode;
        priv->can.do_get_berr_counter = xcan_get_berr_counter; @@ -1137,15 +1155,22 @@ static int xcan_probe(struct platform_device *pdev)

        netif_napi_add(ndev, &priv->napi, xcan_rx_poll, rx_max);

+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_irq_safe(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
        ret = register_candev(ndev);
        if (ret) {
                dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
+               pm_runtime_put(priv->dev);
                goto err_unprepare_disable_busclk;
        }

        devm_can_led_init(ndev);
-       clk_disable_unprepare(priv->bus_clk);
-       clk_disable_unprepare(priv->can_clk);
+
+       pm_runtime_put(&pdev->dev);
+
        netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
                        priv->reg_base, ndev->irq, priv->can.clock.freq,
                        priv->tx_max);
--
1.7.4



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


^ permalink raw reply

* [PATCH v4] can: Convert to runtime_pm
From: Kedareswara rao Appana @ 2014-12-23 12:25 UTC (permalink / raw)
  To: wg, mkl, michal.simek, grant.likely
  Cc: linux-can, netdev, linux-kernel, Kedareswara rao Appana,
	Soren Brinkmann

Instead of enabling/disabling clocks at several locations in the driver,
use the runtime_pm framework. This consolidates the actions for
runtime PM in the appropriate callbacks and makes the driver more
readable and mantainable.

Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Chnages for v4:
 - Updated with the review comments.
Changes for v3:
  - Converted the driver to use runtime_pm.
Changes for v2:
  - Removed the struct platform_device* from suspend/resume
    as suggest by Lothar.

 drivers/net/can/xilinx_can.c |  123 +++++++++++++++++++++++++-----------------
 1 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 6c67643..c71f683 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -32,6 +32,7 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 #include <linux/can/led.h>
+#include <linux/pm_runtime.h>
 
 #define DRIVER_NAME	"xilinx_can"
 
@@ -138,7 +139,7 @@ struct xcan_priv {
 	u32 (*read_reg)(const struct xcan_priv *priv, enum xcan_reg reg);
 	void (*write_reg)(const struct xcan_priv *priv, enum xcan_reg reg,
 			u32 val);
-	struct net_device *dev;
+	struct device *dev;
 	void __iomem *reg_base;
 	unsigned long irq_flags;
 	struct clk *bus_clk;
@@ -842,6 +843,13 @@ static int xcan_open(struct net_device *ndev)
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+				__func__, ret);
+		return ret;
+	}
+
 	ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
 			ndev->name, ndev);
 	if (ret < 0) {
@@ -849,29 +857,17 @@ static int xcan_open(struct net_device *ndev)
 		goto err;
 	}
 
-	ret = clk_prepare_enable(priv->can_clk);
-	if (ret) {
-		netdev_err(ndev, "unable to enable device clock\n");
-		goto err_irq;
-	}
-
-	ret = clk_prepare_enable(priv->bus_clk);
-	if (ret) {
-		netdev_err(ndev, "unable to enable bus clock\n");
-		goto err_can_clk;
-	}
-
 	/* Set chip into reset mode */
 	ret = set_reset_mode(ndev);
 	if (ret < 0) {
 		netdev_err(ndev, "mode resetting failed!\n");
-		goto err_bus_clk;
+		goto err_irq;
 	}
 
 	/* Common open */
 	ret = open_candev(ndev);
 	if (ret)
-		goto err_bus_clk;
+		goto err_irq;
 
 	ret = xcan_chip_start(ndev);
 	if (ret < 0) {
@@ -887,13 +883,11 @@ static int xcan_open(struct net_device *ndev)
 
 err_candev:
 	close_candev(ndev);
-err_bus_clk:
-	clk_disable_unprepare(priv->bus_clk);
-err_can_clk:
-	clk_disable_unprepare(priv->can_clk);
 err_irq:
 	free_irq(ndev->irq, ndev);
 err:
+	pm_runtime_put(priv->dev);
+
 	return ret;
 }
 
@@ -910,12 +904,11 @@ static int xcan_close(struct net_device *ndev)
 	netif_stop_queue(ndev);
 	napi_disable(&priv->napi);
 	xcan_chip_stop(ndev);
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
 	free_irq(ndev->irq, ndev);
 	close_candev(ndev);
 
 	can_led_event(ndev, CAN_LED_EVENT_STOP);
+	pm_runtime_put(priv->dev);
 
 	return 0;
 }
@@ -934,27 +927,20 @@ static int xcan_get_berr_counter(const struct net_device *ndev,
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
-	ret = clk_prepare_enable(priv->can_clk);
-	if (ret)
-		goto err;
-
-	ret = clk_prepare_enable(priv->bus_clk);
-	if (ret)
-		goto err_clk;
+	ret = pm_runtime_get_sync(priv->dev);
+	if (ret < 0) {
+		netdev_err(ndev, "%s: pm_runtime_get failed\r(%d)\n\r",
+				__func__, ret);
+		return ret;
+	}
 
 	bec->txerr = priv->read_reg(priv, XCAN_ECR_OFFSET) & XCAN_ECR_TEC_MASK;
 	bec->rxerr = ((priv->read_reg(priv, XCAN_ECR_OFFSET) &
 			XCAN_ECR_REC_MASK) >> XCAN_ESR_REC_SHIFT);
 
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
+	pm_runtime_put(priv->dev);
 
 	return 0;
-
-err_clk:
-	clk_disable_unprepare(priv->can_clk);
-err:
-	return ret;
 }
 
 
@@ -967,15 +953,45 @@ static const struct net_device_ops xcan_netdev_ops = {
 
 /**
  * xcan_suspend - Suspend method for the driver
- * @dev:	Address of the platform_device structure
+ * @dev:	Address of the device structure
  *
  * Put the driver into low power mode.
- * Return: 0 always
+ * Return: 0 on success and failure value on error
  */
 static int __maybe_unused xcan_suspend(struct device *dev)
 {
-	struct platform_device *pdev = dev_get_drvdata(dev);
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	if (!device_may_wakeup(dev))
+		return pm_runtime_force_suspend(dev);
+
+	return 0;
+}
+
+/**
+ * xcan_resume - Resume from suspend
+ * @dev:	Address of the device structure
+ *
+ * Resume operation after suspend.
+ * Return: 0 on success and failure value on error
+ */
+static int __maybe_unused xcan_resume(struct device *dev)
+{
+	if (!device_may_wakeup(dev))
+		return pm_runtime_force_resume(dev);
+
+	return 0;
+
+}
+
+/**
+ * xcan_runtime_suspend - Runtime suspend method for the driver
+ * @dev:	Address of the device structure
+ *
+ * Put the driver into low power mode.
+ * Return: 0 always
+ */
+static int __maybe_unused xcan_runtime_suspend(struct device *dev)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct xcan_priv *priv = netdev_priv(ndev);
 
 	if (netif_running(ndev)) {
@@ -993,16 +1009,15 @@ static int __maybe_unused xcan_suspend(struct device *dev)
 }
 
 /**
- * xcan_resume - Resume from suspend
- * @dev:	Address of the platformdevice structure
+ * xcan_runtime_resume - Runtime resume from suspend
+ * @dev:	Address of the device structure
  *
  * Resume operation after suspend.
  * Return: 0 on success and failure value on error
  */
-static int __maybe_unused xcan_resume(struct device *dev)
+static int __maybe_unused xcan_runtime_resume(struct device *dev)
 {
-	struct platform_device *pdev = dev_get_drvdata(dev);
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct xcan_priv *priv = netdev_priv(ndev);
 	int ret;
 
@@ -1020,9 +1035,9 @@ static int __maybe_unused xcan_resume(struct device *dev)
 
 	priv->write_reg(priv, XCAN_MSR_OFFSET, 0);
 	priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_CEN_MASK);
-	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
 	if (netif_running(ndev)) {
+		priv->can.state = CAN_STATE_ERROR_ACTIVE;
 		netif_device_attach(ndev);
 		netif_start_queue(ndev);
 	}
@@ -1030,7 +1045,10 @@ static int __maybe_unused xcan_resume(struct device *dev)
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+static const struct dev_pm_ops xcan_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xcan_suspend, xcan_resume)
+	SET_PM_RUNTIME_PM_OPS(xcan_runtime_suspend, xcan_runtime_resume, NULL)
+};
 
 /**
  * xcan_probe - Platform registration call
@@ -1071,7 +1089,7 @@ static int xcan_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	priv = netdev_priv(ndev);
-	priv->dev = ndev;
+	priv->dev = &pdev->dev;
 	priv->can.bittiming_const = &xcan_bittiming_const;
 	priv->can.do_set_mode = xcan_do_set_mode;
 	priv->can.do_get_berr_counter = xcan_get_berr_counter;
@@ -1137,15 +1155,22 @@ static int xcan_probe(struct platform_device *pdev)
 
 	netif_napi_add(ndev, &priv->napi, xcan_rx_poll, rx_max);
 
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_irq_safe(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
 	ret = register_candev(ndev);
 	if (ret) {
 		dev_err(&pdev->dev, "fail to register failed (err=%d)\n", ret);
+		pm_runtime_put(priv->dev);
 		goto err_unprepare_disable_busclk;
 	}
 
 	devm_can_led_init(ndev);
-	clk_disable_unprepare(priv->bus_clk);
-	clk_disable_unprepare(priv->can_clk);
+
+	pm_runtime_put(&pdev->dev);
+
 	netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
 			priv->reg_base, ndev->irq, priv->can.clock.freq,
 			priv->tx_max);
-- 
1.7.4

^ permalink raw reply related

* [PATCH] net: phy: micrel: use generic config_init for KSZ8021/KSZ8031
From: Johan Hovold @ 2014-12-23 11:59 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev, linux-kernel, Bruno Thomsen, Johan Hovold

Use generic config_init callback also for KSZ8021 and KSZ8031.

This has been avoided this far due to commit b838b4aced99 ("phy/micrel:
KSZ8031RNL RMII clock reconfiguration bug"), which claims that the PHY
becomes unresponsive if the broadcast-disable flag is set before
configuring the clock mode.

Turns out that the problem seemingly worked-around by the above
mentioned commit was really due to a hardware-configuration issue, where
the PHY was in fact strapped to address 3 rather than 0.

Tested-by: Bruno Thomsen <bth@kamstrup.dk>
Signed-off-by: Johan Hovold <johan@kernel.org>
---
 drivers/net/phy/micrel.c | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index c530de1e63f5..3ad8ca76196d 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -88,6 +88,7 @@ struct kszphy_priv {
 
 static const struct kszphy_type ksz8021_type = {
 	.led_mode_reg		= MII_KSZPHY_CTRL_2,
+	.has_broadcast_disable	= true,
 	.has_rmii_ref_clk_sel	= true,
 };
 
@@ -258,19 +259,6 @@ static int kszphy_config_init(struct phy_device *phydev)
 	return 0;
 }
 
-static int ksz8021_config_init(struct phy_device *phydev)
-{
-	int rc;
-
-	rc = kszphy_config_init(phydev);
-	if (rc)
-		return rc;
-
-	rc = kszphy_broadcast_disable(phydev);
-
-	return rc < 0 ? rc : 0;
-}
-
 static int ksz9021_load_values_from_of(struct phy_device *phydev,
 				       struct device_node *of_node, u16 reg,
 				       char *field1, char *field2,
@@ -584,7 +572,7 @@ static struct phy_driver ksphy_driver[] = {
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8021_type,
 	.probe		= kszphy_probe,
-	.config_init	= ksz8021_config_init,
+	.config_init	= kszphy_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= kszphy_ack_interrupt,
@@ -601,7 +589,7 @@ static struct phy_driver ksphy_driver[] = {
 	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 	.driver_data	= &ksz8021_type,
 	.probe		= kszphy_probe,
-	.config_init	= ksz8021_config_init,
+	.config_init	= kszphy_config_init,
 	.config_aneg	= genphy_config_aneg,
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= kszphy_ack_interrupt,
-- 
2.0.5

^ permalink raw reply related

* [PATCH 3/3] net/fsl: remove hardcoded clock setting from xgmac_mdio
From: shh.xie @ 2014-12-23  9:47 UTC (permalink / raw)
  To: netdev, davem; +Cc: Shaohui Xie

From: Shaohui Xie <Shaohui.Xie@freescale.com>

There is no need to set the clock speed in read/write which will be performed
unnecessarily for each mdio access. Init it during probe is enough.

Also, the hardcoded clock value is not a proper way for all SoCs.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/net/ethernet/freescale/xgmac_mdio.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index 72e0b85..f8c3bc0 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -94,13 +94,6 @@ static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 val
 	uint16_t dev_addr = regnum >> 16;
 	int ret;
 
-	/* Setup the MII Mgmt clock speed */
-	out_be32(&regs->mdio_stat, MDIO_STAT_CLKDIV(100));
-
-	ret = xgmac_wait_until_free(&bus->dev, regs);
-	if (ret)
-		return ret;
-
 	/* Set the port and dev addr */
 	out_be32(&regs->mdio_ctl,
 		 MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr));
@@ -135,13 +128,6 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 	uint16_t value;
 	int ret;
 
-	/* Setup the MII Mgmt clock speed */
-	out_be32(&regs->mdio_stat, MDIO_STAT_CLKDIV(100));
-
-	ret = xgmac_wait_until_free(&bus->dev, regs);
-	if (ret)
-		return ret;
-
 	/* Set the Port and Device Addrs */
 	mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
 	out_be32(&regs->mdio_ctl, mdio_ctl);
-- 
1.8.4.1

^ permalink raw reply related

* [PATCH 2/3] net/fsl: remove irq assignment from xgmac_mdio
From: shh.xie @ 2014-12-23  9:46 UTC (permalink / raw)
  To: netdev, davem; +Cc: Shaohui Xie

From: Shaohui Xie <Shaohui.Xie@freescale.com>

Which is wrong and not used, so no extra space needed by
mdio_alloc_size(), change the parameter accordingly.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/net/ethernet/freescale/xgmac_mdio.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index 90adba1..72e0b85 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -187,14 +187,13 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int));
+	bus = mdiobus_alloc_size(0);
 	if (!bus)
 		return -ENOMEM;
 
 	bus->name = "Freescale XGMAC MDIO Bus";
 	bus->read = xgmac_mdio_read;
 	bus->write = xgmac_mdio_write;
-	bus->irq = bus->priv;
 	bus->parent = &pdev->dev;
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start);
 
-- 
1.8.4.1

^ permalink raw reply related

* Re: [PATCH v3 1/3] igb: Add igb_disable_sriov in error handling
From: Sergei Shtylyov @ 2014-12-23 11:23 UTC (permalink / raw)
  To: Jia-Ju Bai, davem, jeffrey.t.kirsher, bruce.w.allan,
	jesse.brandeburg
  Cc: linux.nics, e1000-devel, netdev
In-Reply-To: <1419319024-30455-1-git-send-email-baijiaju1990@163.com>

Hello.

On 12/23/2014 10:17 AM, Jia-Ju Bai wrote:

> For linux-3.18.0

    For the future: such words should be placed under --- tear line...

> The driver lacks igb_disable_sriov in error handling,
> which should match igb_enable_sriov in igb_probe.
> This patch fixes this problem, and it has been tested in runtime.

> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
> ---

    .... here.

>   drivers/net/ethernet/intel/igb/igb_main.c |    4 ++++
>   1 file changed, 4 insertions(+)

WBR, Sergei

^ permalink raw reply

* [PATCH 1/3] net/fsl: remove reset from xgmac_mdio
From: shh.xie @ 2014-12-23  9:45 UTC (permalink / raw)
  To: netdev, davem; +Cc: Shaohui Xie

From: Shaohui Xie <Shaohui.Xie@freescale.com>

Since the reset is just clock setting, individual mdio reset is
not available.

Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
---
 drivers/net/ethernet/freescale/xgmac_mdio.c | 19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
index 6e7db66..90adba1 100644
--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
+++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
@@ -174,24 +174,6 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 	return value;
 }
 
-/* Reset the MIIM registers, and wait for the bus to free */
-static int xgmac_mdio_reset(struct mii_bus *bus)
-{
-	struct tgec_mdio_controller __iomem *regs = bus->priv;
-	int ret;
-
-	mutex_lock(&bus->mdio_lock);
-
-	/* Setup the MII Mgmt clock speed */
-	out_be32(&regs->mdio_stat, MDIO_STAT_CLKDIV(100));
-
-	ret = xgmac_wait_until_free(&bus->dev, regs);
-
-	mutex_unlock(&bus->mdio_lock);
-
-	return ret;
-}
-
 static int xgmac_mdio_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -212,7 +194,6 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
 	bus->name = "Freescale XGMAC MDIO Bus";
 	bus->read = xgmac_mdio_read;
 	bus->write = xgmac_mdio_write;
-	bus->reset = xgmac_mdio_reset;
 	bus->irq = bus->priv;
 	bus->parent = &pdev->dev;
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start);
-- 
1.8.4.1

^ permalink raw reply related

* Re: [PATCH RFC] ipw2200: select CFG80211_WEXT
From: Kalle Valo @ 2014-12-23 10:55 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Paul Bolle, Stanislav Yakovlev, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <1419330521.6091.1.camel@sipsolutions.net>

Johannes Berg <johannes@sipsolutions.net> writes:

> On Mon, 2014-12-22 at 19:10 +0100, Paul Bolle wrote:
>> Commit 24a0aa212ee2 ("cfg80211: make WEXT compatibility unselectable")
>> made it impossible to depend on CFG80211_WEXT. It does still allow to
>> select that symbol. (Yes, the commit summary is confusing.)
>> 
>> So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
>> built again.
>> 
>> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
>> ---
>> Johannes,
>> 
>> Building v3.19-rc1 for an outdated ThinkPad X41 left me without the
>> ipw2200 driver. It turns out this trivial patch is all that's needed to
>> make ipw2200 buildable again.
>> 
>> (A similar patch would be needed for the drivers behind Kconfig symbol
>> HERMES. Ie, orinico and friends.) 
>
> Yeah, config HERMES needs the same change.
>
> Kalle, do you want to take those through your tree, or should I fix it
> seeing that I introduced the bug in a sense?

To keep things simple I would prefer to take this through
wireless-drivers.git, if it's ok for you.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH RFC] ipw2200: select CFG80211_WEXT
From: Kalle Valo @ 2014-12-23 10:50 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Johannes Berg, Stanislav Yakovlev, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <1419330055.30945.76.camel@x220>

Paul Bolle <pebolle@tiscali.nl> writes:

> On Tue, 2014-12-23 at 08:52 +0200, Kalle Valo wrote:
>> Paul Bolle <pebolle@tiscali.nl> writes:
>> 
>> > Commit 24a0aa212ee2 ("cfg80211: make WEXT compatibility unselectable")
>> > made it impossible to depend on CFG80211_WEXT. It does still allow to
>> > select that symbol. (Yes, the commit summary is confusing.)
>> >
>> > So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
>> > built again.
>> 
>> I think the last sentence is a bit misleading (this isn't a compilation
>> error, right?)
>
> No, it's not a compilation error.
>
> The reasoning here is that all code hidden behind a Kconfig symbol that
> cannot be set will, in practice, never be built. Sure, there are hoops
> one can jump through to try to bypass the generated .config, but no one
> should have to do that.
>
>>  and I would like to clarify it like this:
>> 
>> "So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
>> enabled in config again."
>> 
>> Does that look ok?
>
> I understand the confusion my text might cause, so I'm fine with your
> amendment.

Thanks for checking. I'll modify the commit log and apply it to
wireless-drivers.git.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH net-next v2] packet: make packet_snd fail on len smaller than l2 header
From: Jouni Malinen @ 2014-12-23 10:37 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: netdev, davem, eric.dumazet, dborkman
In-Reply-To: <1416420616-5029-1-git-send-email-willemb@google.com>

On Wed, Nov 19, 2014 at 8:10 PM, Willem de Bruijn <willemb@google.com> wrote:
> When sending packets out with PF_PACKET, SOCK_RAW, ensure that the
> packet is at least as long as the device's expected link layer header.
> This check already exists in tpacket_snd, but not in packet_snd.

Was this supposed to be refusing zero-length payload following the
header like the implementation does or accept zero-length payload like
this commit message seems to imply? Based on the commit message, I'd
assume 14 byte buffer on Ethernet netdev should have been accepted.

I just noticed that once pulling this commit in into my automated test
setup, one of the test cases started failing because of the change
here. That test case was trying to transmit a minimum length Ethernet
header using raw packet socket. Not that I care too much since I can
easily change the test case to use one octet longer data to send and
this was not really a real protocol case, but I wanted to confirm what
was the expected behavior here since this commit seems to have number
of inconsistent statements between the commit message, actual
validation step, debug print, and code comment..

> diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
> @@ -2095,6 +2095,18 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
> +static bool ll_header_truncated(const struct net_device *dev, int len)
> +{
> +       /* net device doesn't like empty head */

I'm not sure how to interpret "empty head". Is that saying that the
data following the header should not be empty? Or that header should
be at least hard_header_len?

> +       if (unlikely(len <= dev->hard_header_len)) {

That would be rejecting exactly hard_header_len, i.e,., I would have
expected < instead of <= here based on the commit message.

> +               net_warn_ratelimited("%s: packet size is too short (%d < %d)\n",
> +                                    current->comm, len, dev->hard_header_len);

But that debug print uses < instead of <= which is not consistent with
the actual condition (and yes, I realize this was there even before
this commit).

- Jouni

^ permalink raw reply

* Re: [PATCH RFC] ipw2200: select CFG80211_WEXT
From: Johannes Berg @ 2014-12-23 10:28 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Stanislav Yakovlev, Kalle Valo, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <1419271817.2317.12.camel@tiscali.nl>

On Mon, 2014-12-22 at 19:10 +0100, Paul Bolle wrote:
> Commit 24a0aa212ee2 ("cfg80211: make WEXT compatibility unselectable")
> made it impossible to depend on CFG80211_WEXT. It does still allow to
> select that symbol. (Yes, the commit summary is confusing.)
> 
> So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
> built again.
> 
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
> ---
> Johannes,
> 
> Building v3.19-rc1 for an outdated ThinkPad X41 left me without the
> ipw2200 driver. It turns out this trivial patch is all that's needed to
> make ipw2200 buildable again.
> 
> (A similar patch would be needed for the drivers behind Kconfig symbol
> HERMES. Ie, orinico and friends.) 

Yeah, config HERMES needs the same change.

Kalle, do you want to take those through your tree, or should I fix it
seeing that I introduced the bug in a sense?

johannes

^ permalink raw reply

* Re: [PATCH RFC] ipw2200: select CFG80211_WEXT
From: Paul Bolle @ 2014-12-23 10:20 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Johannes Berg, Stanislav Yakovlev, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <871tnqhn7j.fsf@kamboji.qca.qualcomm.com>

On Tue, 2014-12-23 at 08:52 +0200, Kalle Valo wrote:
> Paul Bolle <pebolle@tiscali.nl> writes:
> 
> > Commit 24a0aa212ee2 ("cfg80211: make WEXT compatibility unselectable")
> > made it impossible to depend on CFG80211_WEXT. It does still allow to
> > select that symbol. (Yes, the commit summary is confusing.)
> >
> > So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
> > built again.
> 
> I think the last sentence is a bit misleading (this isn't a compilation
> error, right?)

No, it's not a compilation error.

The reasoning here is that all code hidden behind a Kconfig symbol that
cannot be set will, in practice, never be built. Sure, there are hoops
one can jump through to try to bypass the generated .config, but no one
should have to do that.

>  and I would like to clarify it like this:
> 
> "So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
> enabled in config again."
> 
> Does that look ok?

I understand the confusion my text might cause, so I'm fine with your
amendment.

Thanks,


Paul Bolle

^ permalink raw reply

* Re: caif: Fix napi poll list corruption
From: Jason Wang @ 2014-12-22 10:02 UTC (permalink / raw)
  To: Herbert Xu
  Cc: David Vrabel, netdev, xen-devel, konrad.wilk, boris.ostrovsky,
	edumazet, David S. Miller
In-Reply-To: <20141222093525.GA18616@gondor.apana.org.au>



On Mon, Dec 22, 2014 at 5:35 PM, Herbert Xu 
<herbert@gondor.apana.org.au> wrote:
> On Mon, Dec 22, 2014 at 04:18:33PM +0800, Jason Wang wrote:
>> 
>>  btw, looks like at least caif_virtio has the same issue.
> 
> Good catch.
> 
> -- >8 --
> The commit d75b1ade567ffab085e8adbbdacf0092d10cd09c (net: less
> interrupt masking in NAPI) breaks caif.
> 
> It is now required that if the entire budget is consumed when poll
> returns, the napi poll_list must remain empty.  However, like some
> other drivers caif tries to do a last-ditch check and if there is
> more work it will call napi_schedule and then immediately process
> some of this new work.  Should the entire budget be consumed while
> processing such new work then we will violate the new caller
> contract.
> 
> This patch fixes this by not touching any work when we reschedule
> in caif.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Acked-by: Jason Wang <jasowang@redhat.com>

Thanks.
> 
> 
> diff --git a/drivers/net/caif/caif_virtio.c 
> b/drivers/net/caif/caif_virtio.c
> index a5fefb9..b306210 100644
> --- a/drivers/net/caif/caif_virtio.c
> +++ b/drivers/net/caif/caif_virtio.c
> @@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, 
> int quota)
>  	struct vringh_kiov *riov = &cfv->ctx.riov;
>  	unsigned int skb_len;
>  
> -again:
>  	do {
>  		skb = NULL;
>  
> @@ -322,7 +321,6 @@ exit:
>  		    napi_schedule_prep(napi)) {
>  			vringh_notify_disable_kern(cfv->vr_rx);
>  			__napi_schedule(napi);
> -			goto again;
>  		}
>  		break;
> 
> Thanks,
> -- 
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
> 

^ permalink raw reply

* Re: [PATCH v3 3/3] igb: Fix a memory leak in igb_probe
From: Varka Bhadram @ 2014-12-23  7:29 UTC (permalink / raw)
  To: Jia-Ju Bai
  Cc: davem@davemloft.net, Sergei Shtylyov, Kirsher, Jeffrey T,
	Allan, Bruce W, Brandeburg, Jesse, <linux.nics@intel.com>,
	e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org
In-Reply-To: <1419319024-30455-3-git-send-email-baijiaju1990@163.com>

On Tue, Dec 23, 2014 at 12:47 PM, Jia-Ju Bai <baijiaju1990@163.com> wrote:
> For linux-3.18.0
> The driver calls kcalloc to allocate memory for adapter->shadow_vfta
> in igb_sw_init, but kfree is not called in error handling of igb_probe.
> So when register_netdev or igb_init_i2c is failed, a memory leak occurs.
> This patch fixes this problem, and it has been tested in runtime.
>
> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
> ---
>  drivers/net/ethernet/intel/igb/igb_main.c |    1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index 487cd9c..a0be1e5 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2659,6 +2659,7 @@ err_eeprom:
>         if (hw->flash_address)
>                 iounmap(hw->flash_address);
>  err_sw_init:
> +       kfree(adapter->shadow_vfta);
Why dont you use devm_kcalloc()..? So no need to worry about freeing it.
>         igb_clear_interrupt_scheme(adapter);
>         pci_iounmap(pdev, hw->hw_addr);
>  err_ioremap:
> --
> 1.7.9.5
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks and Regards,
Varka Bhadram.

^ permalink raw reply

* Re: [PATCH iproute2 v2] tc: Show classes in tree view
From: Vadim Kochan @ 2014-12-23  7:10 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Vadim Kochan, netdev
In-Reply-To: <20141222173554.349bb18c@urahara>

On Mon, Dec 22, 2014 at 05:35:54PM -0800, Stephen Hemminger wrote:
> On Mon, 22 Dec 2014 17:51:58 +0200
> Vadim Kochan <vadim4j@gmail.com> wrote:
> 
> > +	while (cls && cls->cls_parent) {
> > +		cls->cls_parent->cls_right = cls;
> > +		cls = cls->cls_parent;
> > +	}
> > +	while (cls && cls->cls_right)
> > +	{
> 
> Why the sudden shift of bracketing style?
Oh no, it happened, in company where I work they uses different style, sorry ...

Thanks,

^ permalink raw reply

* [PATCH v3 3/3] igb: Fix a memory leak in igb_probe
From: Jia-Ju Bai @ 2014-12-23  7:17 UTC (permalink / raw)
  To: davem, sergei.shtylyov, jeffrey.t.kirsher, bruce.w.allan,
	jesse.brandeburg
  Cc: e1000-devel, netdev, Jia-Ju Bai, linux.nics
In-Reply-To: <1419319024-30455-1-git-send-email-baijiaju1990@163.com>

For linux-3.18.0
The driver calls kcalloc to allocate memory for adapter->shadow_vfta
in igb_sw_init, but kfree is not called in error handling of igb_probe.
So when register_netdev or igb_init_i2c is failed, a memory leak occurs.
This patch fixes this problem, and it has been tested in runtime.

Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 487cd9c..a0be1e5 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2659,6 +2659,7 @@ err_eeprom:
 	if (hw->flash_address)
 		iounmap(hw->flash_address);
 err_sw_init:
+	kfree(adapter->shadow_vfta);
 	igb_clear_interrupt_scheme(adapter);
 	pci_iounmap(pdev, hw->hw_addr);
 err_ioremap:
-- 
1.7.9.5



------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply related

* [PATCH v3 2/3] igb: Add pci_disable_pcie_error_reporting in error handling
From: Jia-Ju Bai @ 2014-12-23  7:17 UTC (permalink / raw)
  To: davem, sergei.shtylyov, jeffrey.t.kirsher, bruce.w.allan,
	jesse.brandeburg
  Cc: e1000-devel, netdev, Jia-Ju Bai, linux.nics
In-Reply-To: <1419319024-30455-1-git-send-email-baijiaju1990@163.com>

For linux-3.18.0
The driver lacks pci_disable_pcie_error_reporting in error handling,
which should match pci_enable_pcie_error_reporting in igb_probe.
This patch fixes this problem, and it has been tested in runtime.

Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 487cd9c..59e0ba4 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -2664,6 +2664,7 @@ err_sw_init:
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
+	pci_disable_pcie_error_reporting(pdev);
 	pci_release_selected_regions(pdev,
 				     pci_select_bars(pdev, IORESOURCE_MEM));
 err_pci_reg:
-- 
1.7.9.5



------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply related

* [PATCH v3 1/3] igb: Add igb_disable_sriov in error handling
From: Jia-Ju Bai @ 2014-12-23  7:17 UTC (permalink / raw)
  To: davem, sergei.shtylyov, jeffrey.t.kirsher, bruce.w.allan,
	jesse.brandeburg
  Cc: e1000-devel, netdev, Jia-Ju Bai, linux.nics

For linux-3.18.0
The driver lacks igb_disable_sriov in error handling,
which should match igb_enable_sriov in igb_probe.
This patch fixes this problem, and it has been tested in runtime.

Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 487cd9c..91914e4 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -179,6 +179,7 @@ static void igb_check_vf_rate_limit(struct igb_adapter *);
 #ifdef CONFIG_PCI_IOV
 static int igb_vf_configure(struct igb_adapter *adapter, int vf);
 static int igb_pci_enable_sriov(struct pci_dev *dev, int num_vfs);
+static int igb_disable_sriov(struct pci_dev *pdev);
 #endif
 
 #ifdef CONFIG_PM
@@ -2653,6 +2654,9 @@ err_register:
 	igb_release_hw_control(adapter);
 	memset(&adapter->i2c_adap, 0, sizeof(adapter->i2c_adap));
 err_eeprom:
+#ifdef CONFIG_PCI_IOV
+	igb_disable_sriov(pdev);
+#endif
 	if (!igb_check_reset_block(hw))
 		igb_reset_phy(hw);
 
-- 
1.7.9.5



------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply related

* Re: [PATCH RFC] ipw2200: select CFG80211_WEXT
From: Kalle Valo @ 2014-12-23  6:52 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Johannes Berg, Stanislav Yakovlev, linux-wireless, netdev,
	linux-kernel
In-Reply-To: <1419271817.2317.12.camel@tiscali.nl>

Paul Bolle <pebolle@tiscali.nl> writes:

> Commit 24a0aa212ee2 ("cfg80211: make WEXT compatibility unselectable")
> made it impossible to depend on CFG80211_WEXT. It does still allow to
> select that symbol. (Yes, the commit summary is confusing.)
>
> So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
> built again.

I think the last sentence is a bit misleading (this isn't a compilation
error, right?) and I would like to clarify it like this:

"So make IPW2200 select CFG80211_WEXT, so that the ipw2200 driver can be
enabled in config again."

Does that look ok?

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH for 3.19] rtlwifi: Fix error when accessing unmapped memory in skb
From: Kalle Valo @ 2014-12-23  6:37 UTC (permalink / raw)
  To: Larry Finger; +Cc: Eric Biggers, linux-wireless, netdev, Stable
In-Reply-To: <54989E12.6050808@lwfinger.net>

Larry Finger <Larry.Finger@lwfinger.net> writes:

> You are correct. In trying to get a small patch for stable, I missed
> some important points.
>
> Please look at the attached patch. I think it handles the skb
> allocations correctly. The critical point is that
> _rtl_pci_init_one_rxdesc() cannot be allowed to fail to allocate an
> skb while in the interrupt path. Now, I have already allocated the skb
> before the call and bypassed this routine if the allocation fails.
> After a couple of crashes, this one now works for the case when the
> allocation wouldn't fail anyway. I will likely pull the allocation out
> of _rtl_pci_init_one_rxdesc() in all cases for the final patch.
>
> @Kalle: Please drop the patch I submitted this morning with this
> subject. It would not help the problem. I will resubmit after I am
> sure of the proper fix.

Ack. I'll wait for v2.

-- 
Kalle Valo

^ permalink raw reply

* RE: [PATCH net] net: Generalize ndo_gso_check to ndo_features_check
From: Sathya Perla @ 2014-12-23  6:24 UTC (permalink / raw)
  To: Tom Herbert, Jesse Gross
  Cc: David Miller, Linux Netdev List, Joe Stringer, Eric Dumazet
In-Reply-To: <CA+mtBx9vYV5i9_u=XMmEgSV3Uj9SEJAZHrKhTgyGgBG9Ojs-dA@mail.gmail.com>

> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Tom Herbert
> 
> On Mon, Dec 22, 2014 at 8:03 AM, Jesse Gross <jesse@nicira.com> wrote:
> > GSO isn't the only offload feature with restrictions that
> > potentially can't be expressed with the current features mechanism.
> > Checksum is another although it's a general issue that could in
> > theory apply to anything. Even if it may be possible to
> > implement these restrictions in other ways, it can result in
> > duplicate code or inefficient per-packet behavior.
> >
> > This generalizes ndo_gso_check so that drivers can remove any
> > features that don't make sense for a given packet, similar to
> > netif_skb_features(). It also converts existing driver
> > restrictions to the new format, completing the work that was
> > done to support tunnel protocols since the issues apply to
> > checksums as well.
> >
> It's a nice feature, but I really hope that this is not used for
> checksums. We already have a sufficiently general interface for that
> and checksum is already computed in drivers to work around HW bugs.
> 
The ndo_featureas_check() interface that includes a means to report
inability to compute inner checksums on some tunnel types, seems like
a useful feature. The Skyhawk-R NIC can support inner csum offload for
either vxlan or nv-gre, but not both simultaneously. So, this ndo_
is useful in reporting this situation.
This would also obviate the need to have extra code in the drivers to
compute csums in the above scenario.

thanks,
-Sathya

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox