Message ID | 1447027806-4744-6-git-send-email-gwshan@linux.vnet.ibm.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
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. > + 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); -- 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
On Mon, Nov 09, 2015 at 11:32:07AM +1100, Benjamin Herrenschmidt wrote: >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. > Yeah, It's something that I hilighed in the cover letter. I was thinking we might need a better way to enable Tx/Rx before the interrupt is up, but couldn't figure out one way. So I need some advice here. Thanks, Gavin >> + 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); > -- 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
On Mon, 2015-11-09 at 18:30 +1100, Gavin Shan wrote: > > Yeah, It's something that I hilighed in the cover letter. I was > thinking we might need a better way to enable Tx/Rx before the > interrupt is up, but couldn't figure out one way. So I need some > advice here. No, that's not right. For Tx/Rx to work the interface must be opened, there is simply no way around that and that's perfectly fine. The situation with an MDIO PHY is the same, most drivers can't talk to their PHY until the interface has been opened because the chip is basically powered down otherwise. So we require the interface to be opened to talk, so far so good, the NC-SI stack doesn't even need to open it itself, it's acceptable to require userspace to do it. IE. Userspace will chose what interface to use, open it (for DHCP etc... or whatever other reason) and *that* will then trigger the NC-SI negociation. Cheers, Ben. -- 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
On Tue, Nov 10, 2015 at 07:28:24AM +1100, Benjamin Herrenschmidt wrote: >On Mon, 2015-11-09 at 18:30 +1100, Gavin Shan wrote: >> >> Yeah, It's something that I hilighed in the cover letter. I was >> thinking we might need a better way to enable Tx/Rx before the >> interrupt is up, but couldn't figure out one way. So I need some >> advice here. > >No, that's not right. For Tx/Rx to work the interface must be opened, >there is simply no way around that and that's perfectly fine. The >situation with an MDIO PHY is the same, most drivers can't talk to >their PHY until the interface has been opened because the chip is >basically powered down otherwise. > >So we require the interface to be opened to talk, so far so good, >the NC-SI stack doesn't even need to open it itself, it's acceptable >to require userspace to do it. IE. Userspace will chose what interface >to use, open it (for DHCP etc... or whatever other reason) and *that* >will then trigger the NC-SI negociation. > Yes, NCSI is smiliar to PHY to some extent. However, PHY's negotiation is purly electrical procedure, no packets received from MAC for it. We have the same situation when the NCSI/PHY is going to be brought down. At the beginning, the NCSI packets can be received and transmitted after the interface is opened. Before NCSI negotiation is done, no other packets can be received and transmitted. For the Rx path (for other packets), the NCSI link isn't enabled when NCSI negotiation isn't finished. There might have lots of egress packets whose IP addresses can't be resolved to MAC address as ARP resolution doesn't work before NCSI negotiation is done. So there is a weird window: interface is up, but no packets (except NCSI packets) can be received or transmitted. When the interface is brought down, for example by "ifconfig eth0 down", The NCSI interface needs to be teared down by transmitting and receiving NCSI commands and responses. Similiarly, it introduces another weird window: interface is down, but NCSI packets still can be transmitted and received. >Cheers, >Ben. > Thanks, Gavin -- 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
On Tue, 2015-11-10 at 17:12 +1100, Gavin Shan wrote: > > > So we require the interface to be opened to talk, so far so good, > > the NC-SI stack doesn't even need to open it itself, it's acceptable > > to require userspace to do it. IE. Userspace will chose what interface > > to use, open it (for DHCP etc... or whatever other reason) and *that* > > will then trigger the NC-SI negociation. > > > > Yes, NCSI is smiliar to PHY to some extent. However, PHY's negotiation > is purly electrical procedure, no packets received from MAC for it. We > have the same situation when the NCSI/PHY is going to be brought down. Right but we similarily only support PHY nego once the driver is open, at least on most drivers. The only difference really is that we only set the netif_carrier_on() when the PHY detects a link, while for NC-SI we currently need to keep it on always or we lose the queues, but that can be looked at separately. > At the beginning, the NCSI packets can be received and transmitted after > the interface is opened. Right. > Before NCSI negotiation is done, no other packets > can be received and transmitted. The interface doesn't care. We can transmit them, they just may not go anywhere, its not our problem. Similarily, the companion NIC may or may not forward incoming packets before the nego is complete, we don't actually have to care or enforce anything here. > For the Rx path (for other packets), the > NCSI link isn't enabled when NCSI negotiation isn't finished. There might > have lots of egress packets whose IP addresses can't be resolved to MAC > address as ARP resolution doesn't work before NCSI negotiation is done. Correct, but is that a problem ? it's the same thing when we don't have a link, though I suppose we have a faster path to drop them when the carrier is down. > So there is a weird window: interface is up, but no packets (except NCSI > packets) can be received or transmitted. Right but that's similar to what we used to do before we had "intelligent" PHY control... our drivers didn't always know when the link was up or even if there was a cable plugged. I agree, it would be nicer to have the "Carrier" follow the establishment of the NC-SI link, and we should look into fixing that separately, possibly by establishing a special queue discipline rather than noop when in that "limbo" mode, but that shouldn't be a blocker for the patches and certainly doesn't require your driver change that deals with interrupts while the interface is closed. > When the interface is brought down, for example by "ifconfig eth0 down", > The NCSI interface needs to be teared down by transmitting and receiving > NCSI commands and responses. That can be done synchronously from the close callback (With timeouts), can't it ? If the core messes around with our state before close is called, then we need to do something in the netdev core. However, it's probably fine to just not do anything, worst case the companion NIC will forward packets to a closed interface. Not a big deal and definitely not a show stopper. > Similiarly, it introduces another weird window: > interface is down, but NCSI packets still can be transmitted and received. No, when interface is down, it's down. Nothing comes in and out, we free the rings, rx skb's, interrupt, it's all gone. We even power down the NIC in most cases. Ben. > > Cheers, > > Ben. > > > > Thanks, > Gavin > > -- > 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 -- 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
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 778bee8..1b13fd4 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -31,6 +31,7 @@ #include <linux/phy.h> #include <linux/platform_device.h> #include <net/ip.h> +#include <net/ncsi.h> #include "ftgmac100.h" @@ -68,6 +69,7 @@ struct ftgmac100 { struct net_device *netdev; struct device *dev; + struct ncsi_dev *ndev; struct napi_struct napi; struct mii_bus *mii_bus; @@ -1038,7 +1040,11 @@ static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id) struct net_device *netdev = dev_id; struct ftgmac100 *priv = netdev_priv(netdev); - 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. + */ + 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);
The NIC has the possibility to connect to NCSI package and channel. This supports NCSI enabled interface. When the network device is registered, the accompanying NCSI device is registered. When the interface is to be brought up, the NCSI device is started to probe NCSI topology and choose one active channel automatically. On the other handle, when the interface is to be brought down, the interface will be shuted down when the NCSI device is teared down. Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> --- drivers/net/ethernet/faraday/ftgmac100.c | 91 +++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 24 deletions(-)