Thread (19 messages) flat view 19 messages, 3 authors, 2016-02-24

Re: [PATCH RFC 5/6] net/faraday: Enable NCSI interface

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2015-11-09 00:32:19

On Mon, 2015-11-09 at 11:10 +1100, Gavin Shan wrote:
-	if (likely(netif_running(netdev))) {
+	/* When running in NCSI mode, the interface should be
+	 * ready to receive or transmit NCSI packet before it's
+	 * opened.
+	 */
No, that's not right. open/close is when a driver allocates it's data
structures, DMA ring descriptors, packet buffers etc... and request
it's interrupts.

You cannot expect packets to flow on a closed interface and you
shouldn't be getting any interrupts on a closed interface either.
quoted hunk ↗ jump to hunk
+	if (likely(priv->use_ncsi || netif_running(netdev))) {
 		/* Disable interrupts for polling */
 		iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
 		napi_schedule(&priv->napi);
@@ -1162,8 +1168,18 @@ static int ftgmac100_open(struct net_device
*netdev)
 
 	/* enable all interrupts */
 	iowrite32(INT_MASK_ALL_ENABLED, priv->base +
FTGMAC100_OFFSET_IER);
+	/* Start the NCSI device */
+	if (priv->use_ncsi){
+		err = ncsi_start_dev(priv->ndev);
+		if (err)
+			goto err_ncsi;
+	}
 	return 0;
 
+err_ncsi:
+	napi_disable(&priv->napi);
+	netif_stop_queue(netdev);
+	iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
 err_hw:
 	free_irq(priv->irq, netdev);
 err_irq:
@@ -1172,7 +1188,7 @@ err_alloc:
 	return err;
 }
 
-static int ftgmac100_stop(struct net_device *netdev)
+static int ftgmac100_stop_dev(struct net_device *netdev)
 {
 	struct ftgmac100 *priv = netdev_priv(netdev);
 
@@ -1191,6 +1207,18 @@ static int ftgmac100_stop(struct net_device
*netdev)
 	return 0;
 }
 
+static int ftgmac100_stop(struct net_device *netdev)
+{
+	struct ftgmac100 *priv = netdev_priv(netdev);
+
+	/* Stop NCSI device */
+	if (priv->use_ncsi) {
+		ncsi_stop_dev(priv->ndev);
+		return 0;
+	}
+
+	return ftgmac100_stop_dev(netdev);
+}
 static int ftgmac100_hard_start_xmit(struct sk_buff *skb,
 				     struct net_device *netdev)
 {
@@ -1291,6 +1319,21 @@ static const struct net_device_ops
ftgmac100_netdev_ops = {
 	.ndo_do_ioctl		= ftgmac100_do_ioctl,
 };
 
+static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
+{
+	struct net_device *netdev = nd->nd_dev;
+
+	if (nd->nd_state != ncsi_dev_state_functional)
+		return;
+
+	if (nd->nd_link_up) {
+		pr_info("NCSI dev is up\n");
+		netif_start_queue(netdev);
+	} else {
+		pr_info("NCSI dev is down\n");
+		ftgmac100_stop_dev(netdev);
+	}
+}
 /*******************************************************************
***********
  * struct platform_driver functions
 
*********************************************************************
********/
@@ -1300,7 +1343,7 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 	int irq;
 	struct net_device *netdev;
 	struct ftgmac100 *priv;
-	int err;
+	int err = 0;
 
 	if (!pdev)
 		return -ENODEV;
@@ -1320,7 +1363,17 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 		goto err_alloc_etherdev;
 	}
 
+	/* Check for NCSI mode */
+	priv = netdev_priv(netdev);
 	SET_NETDEV_DEV(netdev, &pdev->dev);
+	if (pdev->dev.of_node &&
+	    of_get_property(pdev->dev.of_node, "use-nc-si", NULL)) {
+		dev_info(&pdev->dev, "Using NCSI interface\n");
+		priv->phydev = NULL;
+		priv->use_ncsi = true;
+	} else {
+		priv->use_ncsi = false;
+	}
 
 	netdev->ethtool_ops = &ftgmac100_ethtool_ops;
 	netdev->netdev_ops = &ftgmac100_netdev_ops;
@@ -1329,7 +1382,6 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 	platform_set_drvdata(pdev, netdev);
 
 	/* setup private data */
-	priv = netdev_priv(netdev);
 	priv->netdev = netdev;
 	priv->dev = &pdev->dev;
 
@@ -1356,24 +1408,14 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 
 	priv->irq = irq;
 
-	/* Check for NC-SI mode */
-	if (pdev->dev.of_node &&
-	    of_get_property(pdev->dev.of_node, "use-nc-si", NULL))
-		priv->use_ncsi = true;
-	else
-		priv->use_ncsi = false;
+	/* Read MAC address or setup a new one */
+	ftgmac100_setup_mac(priv);
 
-	/* If we use NC-SI, we need to set that up, which isn't
implemented yet
-	 * so we pray things were setup by the bootloader and just
mark our link
-	 * as up (otherwise we can't get packets through).
-	 *
-	 * Eventually, we'll have a proper NC-SI stack as a helper
we can
-	 * instanciate
-	 */
+	/* Register NCSI device */
 	if (priv->use_ncsi) {
-		/* XXX */
-		priv->phydev = NULL;
-		dev_info(&pdev->dev, "Using NC-SI interface\n");
+		priv->ndev = ncsi_register_dev(netdev,
ftgmac100_ncsi_handler);
+		if (!priv->ndev)
+			goto err_ncsi_dev;
 	} else {
 		err = ftgmac100_setup_mdio(priv);
 
@@ -1384,9 +1426,6 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 			dev_warn(&pdev->dev, "Error %d setting up
MDIO\n", err);
 	}
 
-	/* Read MAC address or setup a new one */
-	ftgmac100_setup_mac(priv);
-
 	/* Register network device */
 	err = register_netdev(netdev);
 	if (err) {
@@ -1399,7 +1438,11 @@ static int ftgmac100_probe(struct
platform_device *pdev)
 	return 0;
 
 err_register_netdev:
-	ftgmac100_destroy_mdio(priv);
+	if (!priv->use_ncsi)
+		ftgmac100_destroy_mdio(priv);
+	else
+		ncsi_unregister_dev(priv->ndev);
+err_ncsi_dev:
 	iounmap(priv->base);
 err_ioremap:
 	release_resource(priv->res);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help