Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Couple conflicts resolved here: 1) In the MACB driver, a bug fix to properly initialize the RX tail pointer properly overlapped with some changes to support variable sized rings. 2) In XGBE we had a "CONFIG_PM" --> "CONFIG_PM_SLEEP" fix overlapping with a reorganization of the driver to support ACPI, OF, as well as PCI variants of the chip. 3) In 'net' we had several probe error path bug fixes to the stmmac driver, meanwhile a lot of this code was cleaned up and reorganized in 'net-next'. 4) The cls_flower classifier obtained a helper function in 'net-next' called __fl_delete() and this overlapped with Daniel Borkamann's bug fix to use RCU for object destruction in 'net'. It also overlapped with Jiri's change to guard the rhashtable_remove_fast() call with a check against tc_skip_sw(). 5) In mlx4, a revert bug fix in 'net' overlapped with some unrelated changes in 'net-next'. 6) In geneve, a stale header pointer after pskb_expand_head() bug fix in 'net' overlapped with a large reorganization of the same code in 'net-next'. Since the 'net-next' code no longer had the bug in question, there was nothing to do other than to simply take the 'net-next' hunks. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -422,12 +422,6 @@ static int tse_rx(struct altera_tse_private *priv, int limit)
|
||||
|
||||
skb_put(skb, pktlength);
|
||||
|
||||
/* make cache consistent with receive packet buffer */
|
||||
dma_sync_single_for_cpu(priv->device,
|
||||
priv->rx_ring[entry].dma_addr,
|
||||
priv->rx_ring[entry].len,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
dma_unmap_single(priv->device, priv->rx_ring[entry].dma_addr,
|
||||
priv->rx_ring[entry].len, DMA_FROM_DEVICE);
|
||||
|
||||
@@ -491,7 +485,6 @@ static int tse_tx_complete(struct altera_tse_private *priv)
|
||||
|
||||
if (unlikely(netif_queue_stopped(priv->dev) &&
|
||||
tse_tx_avail(priv) > TSE_TX_THRESH(priv))) {
|
||||
netif_tx_lock(priv->dev);
|
||||
if (netif_queue_stopped(priv->dev) &&
|
||||
tse_tx_avail(priv) > TSE_TX_THRESH(priv)) {
|
||||
if (netif_msg_tx_done(priv))
|
||||
@@ -499,7 +492,6 @@ static int tse_tx_complete(struct altera_tse_private *priv)
|
||||
__func__);
|
||||
netif_wake_queue(priv->dev);
|
||||
}
|
||||
netif_tx_unlock(priv->dev);
|
||||
}
|
||||
|
||||
spin_unlock(&priv->tx_lock);
|
||||
@@ -614,10 +606,6 @@ static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
buffer->dma_addr = dma_addr;
|
||||
buffer->len = nopaged_len;
|
||||
|
||||
/* Push data out of the cache hierarchy into main memory */
|
||||
dma_sync_single_for_device(priv->device, buffer->dma_addr,
|
||||
buffer->len, DMA_TO_DEVICE);
|
||||
|
||||
priv->dmaops->tx_buffer(priv, buffer);
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
@@ -841,6 +829,8 @@ static int init_phy(struct net_device *dev)
|
||||
|
||||
if (!phydev) {
|
||||
netdev_err(dev, "Could not find the PHY\n");
|
||||
if (fixed_link)
|
||||
of_phy_deregister_fixed_link(priv->device->of_node);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -1630,10 +1620,15 @@ err_free_netdev:
|
||||
static int altera_tse_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct altera_tse_private *priv = netdev_priv(ndev);
|
||||
|
||||
if (ndev->phydev)
|
||||
if (ndev->phydev) {
|
||||
phy_disconnect(ndev->phydev);
|
||||
|
||||
if (of_phy_is_fixed_link(priv->device->of_node))
|
||||
of_phy_deregister_fixed_link(priv->device->of_node);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
altera_tse_mdio_destroy(ndev);
|
||||
unregister_netdev(ndev);
|
||||
|
@@ -538,7 +538,7 @@ static int xgbe_platform_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int xgbe_platform_suspend(struct device *dev)
|
||||
{
|
||||
struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
|
||||
@@ -583,7 +583,7 @@ static int xgbe_platform_resume(struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static const struct xgbe_version_data xgbe_v1 = {
|
||||
.init_function_ptrs_phy_impl = xgbe_init_function_ptrs_phy_v1,
|
||||
|
@@ -1457,12 +1457,12 @@ static int nb8800_probe(struct platform_device *pdev)
|
||||
|
||||
ret = nb8800_hw_init(dev);
|
||||
if (ret)
|
||||
goto err_free_bus;
|
||||
goto err_deregister_fixed_link;
|
||||
|
||||
if (ops && ops->init) {
|
||||
ret = ops->init(dev);
|
||||
if (ret)
|
||||
goto err_free_bus;
|
||||
goto err_deregister_fixed_link;
|
||||
}
|
||||
|
||||
dev->netdev_ops = &nb8800_netdev_ops;
|
||||
@@ -1495,6 +1495,9 @@ static int nb8800_probe(struct platform_device *pdev)
|
||||
|
||||
err_free_dma:
|
||||
nb8800_dma_free(dev);
|
||||
err_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(pdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(pdev->dev.of_node);
|
||||
err_free_bus:
|
||||
of_node_put(priv->phy_node);
|
||||
mdiobus_unregister(bus);
|
||||
@@ -1512,6 +1515,8 @@ static int nb8800_remove(struct platform_device *pdev)
|
||||
struct nb8800_priv *priv = netdev_priv(ndev);
|
||||
|
||||
unregister_netdev(ndev);
|
||||
if (of_phy_is_fixed_link(pdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(pdev->dev.of_node);
|
||||
of_node_put(priv->phy_node);
|
||||
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
|
@@ -1755,13 +1755,13 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
if (priv->irq0 <= 0 || priv->irq1 <= 0) {
|
||||
dev_err(&pdev->dev, "invalid interrupts\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
priv->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
if (IS_ERR(priv->base)) {
|
||||
ret = PTR_ERR(priv->base);
|
||||
goto err;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
priv->netdev = dev;
|
||||
@@ -1779,7 +1779,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
ret = of_phy_register_fixed_link(dn);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register fixed PHY\n");
|
||||
goto err;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
priv->phy_dn = dn;
|
||||
@@ -1821,7 +1821,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
ret = register_netdev(dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register net_device\n");
|
||||
goto err;
|
||||
goto err_deregister_fixed_link;
|
||||
}
|
||||
|
||||
priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
|
||||
@@ -1832,7 +1832,11 @@ static int bcm_sysport_probe(struct platform_device *pdev)
|
||||
priv->base, priv->irq0, priv->irq1, txq, rxq);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
|
||||
err_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
err_free_netdev:
|
||||
free_netdev(dev);
|
||||
return ret;
|
||||
}
|
||||
@@ -1840,11 +1844,14 @@ err:
|
||||
static int bcm_sysport_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&pdev->dev);
|
||||
struct device_node *dn = pdev->dev.of_node;
|
||||
|
||||
/* Not much to do, ndo_close has been called
|
||||
* and we use managed allocations
|
||||
*/
|
||||
unregister_netdev(dev);
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
free_netdev(dev);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
|
||||
|
@@ -1165,6 +1165,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
|
||||
struct bcmgenet_tx_ring *ring)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct device *kdev = &priv->pdev->dev;
|
||||
struct enet_cb *tx_cb_ptr;
|
||||
struct netdev_queue *txq;
|
||||
unsigned int pkts_compl = 0;
|
||||
@@ -1192,13 +1193,13 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
|
||||
if (tx_cb_ptr->skb) {
|
||||
pkts_compl++;
|
||||
bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent;
|
||||
dma_unmap_single(&dev->dev,
|
||||
dma_unmap_single(kdev,
|
||||
dma_unmap_addr(tx_cb_ptr, dma_addr),
|
||||
dma_unmap_len(tx_cb_ptr, dma_len),
|
||||
DMA_TO_DEVICE);
|
||||
bcmgenet_free_cb(tx_cb_ptr);
|
||||
} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
|
||||
dma_unmap_page(&dev->dev,
|
||||
dma_unmap_page(kdev,
|
||||
dma_unmap_addr(tx_cb_ptr, dma_addr),
|
||||
dma_unmap_len(tx_cb_ptr, dma_len),
|
||||
DMA_TO_DEVICE);
|
||||
@@ -1768,6 +1769,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
|
||||
|
||||
static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
|
||||
{
|
||||
struct device *kdev = &priv->pdev->dev;
|
||||
struct enet_cb *cb;
|
||||
int i;
|
||||
|
||||
@@ -1775,7 +1777,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
|
||||
cb = &priv->rx_cbs[i];
|
||||
|
||||
if (dma_unmap_addr(cb, dma_addr)) {
|
||||
dma_unmap_single(&priv->dev->dev,
|
||||
dma_unmap_single(kdev,
|
||||
dma_unmap_addr(cb, dma_addr),
|
||||
priv->rx_buf_len, DMA_FROM_DEVICE);
|
||||
dma_unmap_addr_set(cb, dma_addr, 0);
|
||||
|
@@ -542,8 +542,10 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
|
||||
/* Make sure we initialize MoCA PHYs with a link down */
|
||||
if (phy_mode == PHY_INTERFACE_MODE_MOCA) {
|
||||
phydev = of_phy_find_device(dn);
|
||||
if (phydev)
|
||||
if (phydev) {
|
||||
phydev->link = 0;
|
||||
put_device(&phydev->mdio.dev);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -625,6 +627,7 @@ static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
|
||||
int bcmgenet_mii_init(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct device_node *dn = priv->pdev->dev.of_node;
|
||||
int ret;
|
||||
|
||||
ret = bcmgenet_mii_alloc(priv);
|
||||
@@ -638,6 +641,8 @@ int bcmgenet_mii_init(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
out:
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
of_node_put(priv->phy_dn);
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
@@ -647,7 +652,10 @@ out:
|
||||
void bcmgenet_mii_exit(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct device_node *dn = priv->pdev->dev.of_node;
|
||||
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
of_node_put(priv->phy_dn);
|
||||
mdiobus_unregister(priv->mii_bus);
|
||||
mdiobus_free(priv->mii_bus);
|
||||
|
@@ -991,6 +991,7 @@ static inline void macb_init_rx_ring(struct macb *bp)
|
||||
addr += bp->rx_buffer_size;
|
||||
}
|
||||
bp->rx_ring[bp->rx_ring_size - 1].addr |= MACB_BIT(RX_WRAP);
|
||||
bp->rx_tail = 0;
|
||||
}
|
||||
|
||||
static int macb_rx(struct macb *bp, int budget)
|
||||
@@ -1172,6 +1173,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
|
||||
if (status & MACB_BIT(RXUBR)) {
|
||||
ctrl = macb_readl(bp, NCR);
|
||||
macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
|
||||
wmb();
|
||||
macb_writel(bp, NCR, ctrl | MACB_BIT(RE));
|
||||
|
||||
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
|
||||
@@ -1736,8 +1738,6 @@ static void macb_init_rings(struct macb *bp)
|
||||
bp->queues[0].tx_head = 0;
|
||||
bp->queues[0].tx_tail = 0;
|
||||
bp->queues[0].tx_ring[bp->tx_ring_size - 1].ctrl |= MACB_BIT(TX_WRAP);
|
||||
|
||||
bp->rx_tail = 0;
|
||||
}
|
||||
|
||||
static void macb_reset_hw(struct macb *bp)
|
||||
@@ -2943,6 +2943,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
|
||||
if (intstatus & MACB_BIT(RXUBR)) {
|
||||
ctl = macb_readl(lp, NCR);
|
||||
macb_writel(lp, NCR, ctl & ~MACB_BIT(RE));
|
||||
wmb();
|
||||
macb_writel(lp, NCR, ctl | MACB_BIT(RE));
|
||||
}
|
||||
|
||||
|
@@ -168,6 +168,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509a), /* Custom T520-CR */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509b), /* Custom T540-CR LOM */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509c), /* Custom T520-CR*/
|
||||
CH_PCI_ID_TABLE_FENTRY(0x509d), /* Custom T540-CR*/
|
||||
|
||||
/* T6 adapters:
|
||||
*/
|
||||
|
@@ -574,6 +574,8 @@ struct fec_enet_private {
|
||||
unsigned int reload_period;
|
||||
int pps_enable;
|
||||
unsigned int next_counter;
|
||||
|
||||
u64 ethtool_stats[0];
|
||||
};
|
||||
|
||||
void fec_ptp_init(struct platform_device *pdev);
|
||||
|
@@ -2310,14 +2310,24 @@ static const struct fec_stat {
|
||||
{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
|
||||
};
|
||||
|
||||
static void fec_enet_get_ethtool_stats(struct net_device *dev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
static void fec_enet_update_ethtool_stats(struct net_device *dev)
|
||||
{
|
||||
struct fec_enet_private *fep = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
|
||||
data[i] = readl(fep->hwp + fec_stats[i].offset);
|
||||
fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset);
|
||||
}
|
||||
|
||||
static void fec_enet_get_ethtool_stats(struct net_device *dev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct fec_enet_private *fep = netdev_priv(dev);
|
||||
|
||||
if (netif_running(dev))
|
||||
fec_enet_update_ethtool_stats(dev);
|
||||
|
||||
memcpy(data, fep->ethtool_stats, ARRAY_SIZE(fec_stats) * sizeof(u64));
|
||||
}
|
||||
|
||||
static void fec_enet_get_strings(struct net_device *netdev,
|
||||
@@ -2861,6 +2871,8 @@ fec_enet_close(struct net_device *ndev)
|
||||
if (fep->quirks & FEC_QUIRK_ERR006687)
|
||||
imx6q_cpuidle_fec_irqs_unused();
|
||||
|
||||
fec_enet_update_ethtool_stats(ndev);
|
||||
|
||||
fec_enet_clk_enable(ndev, false);
|
||||
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
|
||||
pm_runtime_mark_last_busy(&fep->pdev->dev);
|
||||
@@ -3166,6 +3178,8 @@ static int fec_enet_init(struct net_device *ndev)
|
||||
|
||||
fec_restart(ndev);
|
||||
|
||||
fec_enet_update_ethtool_stats(ndev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3264,7 +3278,8 @@ fec_probe(struct platform_device *pdev)
|
||||
fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
|
||||
|
||||
/* Init network device */
|
||||
ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
|
||||
ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
|
||||
ARRAY_SIZE(fec_stats) * sizeof(u64),
|
||||
num_tx_qs, num_rx_qs);
|
||||
if (!ndev)
|
||||
return -ENOMEM;
|
||||
@@ -3461,6 +3476,8 @@ failed_regulator:
|
||||
failed_clk_ipg:
|
||||
fec_enet_clk_enable(ndev, false);
|
||||
failed_clk:
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
failed_phy:
|
||||
of_node_put(phy_node);
|
||||
failed_ioremap:
|
||||
@@ -3474,6 +3491,7 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
cancel_work_sync(&fep->tx_timeout_work);
|
||||
fec_ptp_stop(pdev);
|
||||
@@ -3481,6 +3499,8 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
fec_enet_mii_remove(fep);
|
||||
if (fep->reg_phy)
|
||||
regulator_disable(fep->reg_phy);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(fep->phy_node);
|
||||
free_netdev(ndev);
|
||||
|
||||
|
@@ -1107,6 +1107,9 @@ int memac_free(struct fman_mac *memac)
|
||||
{
|
||||
free_init_resources(memac);
|
||||
|
||||
if (memac->pcsphy)
|
||||
put_device(&memac->pcsphy->mdio.dev);
|
||||
|
||||
kfree(memac->memac_drv_param);
|
||||
kfree(memac);
|
||||
|
||||
|
@@ -896,6 +896,8 @@ static int mac_probe(struct platform_device *_of_dev)
|
||||
priv->fixed_link->duplex = phy->duplex;
|
||||
priv->fixed_link->pause = phy->pause;
|
||||
priv->fixed_link->asym_pause = phy->asym_pause;
|
||||
|
||||
put_device(&phy->mdio.dev);
|
||||
}
|
||||
|
||||
err = mac_dev->init(mac_dev);
|
||||
|
@@ -967,7 +967,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
|
||||
err = clk_prepare_enable(clk);
|
||||
if (err) {
|
||||
ret = err;
|
||||
goto out_free_fpi;
|
||||
goto out_deregister_fixed_link;
|
||||
}
|
||||
fpi->clk_per = clk;
|
||||
}
|
||||
@@ -1048,6 +1048,9 @@ out_put:
|
||||
of_node_put(fpi->phy_node);
|
||||
if (fpi->clk_per)
|
||||
clk_disable_unprepare(fpi->clk_per);
|
||||
out_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(ofdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(ofdev->dev.of_node);
|
||||
out_free_fpi:
|
||||
kfree(fpi);
|
||||
return ret;
|
||||
@@ -1066,6 +1069,8 @@ static int fs_enet_remove(struct platform_device *ofdev)
|
||||
of_node_put(fep->fpi->phy_node);
|
||||
if (fep->fpi->clk_per)
|
||||
clk_disable_unprepare(fep->fpi->clk_per);
|
||||
if (of_phy_is_fixed_link(ofdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(ofdev->dev.of_node);
|
||||
free_netdev(ndev);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1312,6 +1312,7 @@ static void gfar_init_addr_hash_table(struct gfar_private *priv)
|
||||
*/
|
||||
static int gfar_probe(struct platform_device *ofdev)
|
||||
{
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
struct net_device *dev = NULL;
|
||||
struct gfar_private *priv = NULL;
|
||||
int err = 0, i;
|
||||
@@ -1465,6 +1466,8 @@ static int gfar_probe(struct platform_device *ofdev)
|
||||
return 0;
|
||||
|
||||
register_fail:
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
unmap_group_regs(priv);
|
||||
gfar_free_rx_queues(priv);
|
||||
gfar_free_tx_queues(priv);
|
||||
@@ -1477,11 +1480,16 @@ register_fail:
|
||||
static int gfar_remove(struct platform_device *ofdev)
|
||||
{
|
||||
struct gfar_private *priv = platform_get_drvdata(ofdev);
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
|
||||
of_node_put(priv->phy_node);
|
||||
of_node_put(priv->tbi_node);
|
||||
|
||||
unregister_netdev(priv->ndev);
|
||||
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
|
||||
unmap_group_regs(priv);
|
||||
gfar_free_rx_queues(priv);
|
||||
gfar_free_tx_queues(priv);
|
||||
|
@@ -3867,9 +3867,8 @@ static int ucc_geth_probe(struct platform_device* ofdev)
|
||||
dev = alloc_etherdev(sizeof(*ugeth));
|
||||
|
||||
if (dev == NULL) {
|
||||
of_node_put(ug_info->tbi_node);
|
||||
of_node_put(ug_info->phy_node);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto err_deregister_fixed_link;
|
||||
}
|
||||
|
||||
ugeth = netdev_priv(dev);
|
||||
@@ -3906,10 +3905,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
|
||||
if (netif_msg_probe(ugeth))
|
||||
pr_err("%s: Cannot register net device, aborting\n",
|
||||
dev->name);
|
||||
free_netdev(dev);
|
||||
of_node_put(ug_info->tbi_node);
|
||||
of_node_put(ug_info->phy_node);
|
||||
return err;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
mac_addr = of_get_mac_address(np);
|
||||
@@ -3922,16 +3918,29 @@ static int ucc_geth_probe(struct platform_device* ofdev)
|
||||
ugeth->node = np;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_netdev:
|
||||
free_netdev(dev);
|
||||
err_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(ug_info->tbi_node);
|
||||
of_node_put(ug_info->phy_node);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ucc_geth_remove(struct platform_device* ofdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(ofdev);
|
||||
struct ucc_geth_private *ugeth = netdev_priv(dev);
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
ucc_geth_memclean(ugeth);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(ugeth->ug_info->tbi_node);
|
||||
of_node_put(ugeth->ug_info->phy_node);
|
||||
|
||||
|
@@ -4935,11 +4935,15 @@ static int igb_tso(struct igb_ring *tx_ring,
|
||||
|
||||
/* initialize outer IP header fields */
|
||||
if (ip.v4->version == 4) {
|
||||
unsigned char *csum_start = skb_checksum_start(skb);
|
||||
unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
|
||||
|
||||
/* IP header will have to cancel out any data that
|
||||
* is not a part of the outer IP header
|
||||
*/
|
||||
ip.v4->check = csum_fold(csum_add(lco_csum(skb),
|
||||
csum_unfold(l4.tcp->check)));
|
||||
ip.v4->check = csum_fold(csum_partial(trans_start,
|
||||
csum_start - trans_start,
|
||||
0));
|
||||
type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
|
||||
|
||||
ip.v4->tot_len = 0;
|
||||
|
@@ -1965,11 +1965,15 @@ static int igbvf_tso(struct igbvf_ring *tx_ring,
|
||||
|
||||
/* initialize outer IP header fields */
|
||||
if (ip.v4->version == 4) {
|
||||
unsigned char *csum_start = skb_checksum_start(skb);
|
||||
unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
|
||||
|
||||
/* IP header will have to cancel out any data that
|
||||
* is not a part of the outer IP header
|
||||
*/
|
||||
ip.v4->check = csum_fold(csum_add(lco_csum(skb),
|
||||
csum_unfold(l4.tcp->check)));
|
||||
ip.v4->check = csum_fold(csum_partial(trans_start,
|
||||
csum_start - trans_start,
|
||||
0));
|
||||
type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
|
||||
|
||||
ip.v4->tot_len = 0;
|
||||
|
@@ -7287,11 +7287,15 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
|
||||
|
||||
/* initialize outer IP header fields */
|
||||
if (ip.v4->version == 4) {
|
||||
unsigned char *csum_start = skb_checksum_start(skb);
|
||||
unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
|
||||
|
||||
/* IP header will have to cancel out any data that
|
||||
* is not a part of the outer IP header
|
||||
*/
|
||||
ip.v4->check = csum_fold(csum_add(lco_csum(skb),
|
||||
csum_unfold(l4.tcp->check)));
|
||||
ip.v4->check = csum_fold(csum_partial(trans_start,
|
||||
csum_start - trans_start,
|
||||
0));
|
||||
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
|
||||
|
||||
ip.v4->tot_len = 0;
|
||||
|
@@ -3335,11 +3335,15 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,
|
||||
|
||||
/* initialize outer IP header fields */
|
||||
if (ip.v4->version == 4) {
|
||||
unsigned char *csum_start = skb_checksum_start(skb);
|
||||
unsigned char *trans_start = ip.hdr + (ip.v4->ihl * 4);
|
||||
|
||||
/* IP header will have to cancel out any data that
|
||||
* is not a part of the outer IP header
|
||||
*/
|
||||
ip.v4->check = csum_fold(csum_add(lco_csum(skb),
|
||||
csum_unfold(l4.tcp->check)));
|
||||
ip.v4->check = csum_fold(csum_partial(trans_start,
|
||||
csum_start - trans_start,
|
||||
0));
|
||||
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
|
||||
|
||||
ip.v4->tot_len = 0;
|
||||
|
@@ -4327,6 +4327,8 @@ err_clk:
|
||||
clk_disable_unprepare(pp->clk);
|
||||
err_put_phy_node:
|
||||
of_node_put(phy_node);
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
err_free_irq:
|
||||
irq_dispose_mapping(dev->irq);
|
||||
err_free_netdev:
|
||||
@@ -4338,6 +4340,7 @@ err_free_netdev:
|
||||
static int mvneta_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct device_node *dn = pdev->dev.of_node;
|
||||
struct mvneta_port *pp = netdev_priv(dev);
|
||||
|
||||
unregister_netdev(dev);
|
||||
@@ -4345,6 +4348,8 @@ static int mvneta_remove(struct platform_device *pdev)
|
||||
clk_disable_unprepare(pp->clk);
|
||||
free_percpu(pp->ports);
|
||||
free_percpu(pp->stats);
|
||||
if (of_phy_is_fixed_link(dn))
|
||||
of_phy_deregister_fixed_link(dn);
|
||||
irq_dispose_mapping(dev->irq);
|
||||
of_node_put(pp->phy_node);
|
||||
free_netdev(dev);
|
||||
|
@@ -318,6 +318,8 @@ static int mtk_phy_connect(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
err_phy:
|
||||
if (of_phy_is_fixed_link(mac->of_node))
|
||||
of_phy_deregister_fixed_link(mac->of_node);
|
||||
of_node_put(np);
|
||||
dev_err(eth->dev, "%s: invalid phy\n", __func__);
|
||||
return -EINVAL;
|
||||
@@ -1923,6 +1925,8 @@ static void mtk_uninit(struct net_device *dev)
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
|
||||
phy_disconnect(dev->phydev);
|
||||
if (of_phy_is_fixed_link(mac->of_node))
|
||||
of_phy_deregister_fixed_link(mac->of_node);
|
||||
mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0);
|
||||
mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0);
|
||||
}
|
||||
|
@@ -2109,13 +2109,6 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void mlx4_en_shutdown(struct net_device *dev)
|
||||
{
|
||||
rtnl_lock();
|
||||
netif_device_detach(dev);
|
||||
mlx4_en_close(dev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
|
||||
struct mlx4_en_priv *src,
|
||||
@@ -2214,8 +2207,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
|
||||
{
|
||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||
struct mlx4_en_dev *mdev = priv->mdev;
|
||||
bool shutdown = mdev->dev->persist->interface_state &
|
||||
MLX4_INTERFACE_STATE_SHUTDOWN;
|
||||
int t;
|
||||
|
||||
en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
|
||||
@@ -2224,10 +2215,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
|
||||
if (priv->registered) {
|
||||
devlink_port_type_clear(mlx4_get_devlink_port(mdev->dev,
|
||||
priv->port));
|
||||
if (shutdown)
|
||||
mlx4_en_shutdown(dev);
|
||||
else
|
||||
unregister_netdev(dev);
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
|
||||
if (priv->allocated)
|
||||
@@ -2258,8 +2246,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
|
||||
kfree(priv->tx_cq[t]);
|
||||
}
|
||||
|
||||
if (!shutdown)
|
||||
free_netdev(dev);
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
||||
static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
@@ -4147,11 +4147,8 @@ static void mlx4_shutdown(struct pci_dev *pdev)
|
||||
|
||||
mlx4_info(persist->dev, "mlx4_shutdown was called\n");
|
||||
mutex_lock(&persist->interface_state_mutex);
|
||||
if (persist->interface_state & MLX4_INTERFACE_STATE_UP) {
|
||||
/* Notify mlx4 clients that the kernel is being shut down */
|
||||
persist->interface_state |= MLX4_INTERFACE_STATE_SHUTDOWN;
|
||||
if (persist->interface_state & MLX4_INTERFACE_STATE_UP)
|
||||
mlx4_unload_one(pdev);
|
||||
}
|
||||
mutex_unlock(&persist->interface_state_mutex);
|
||||
}
|
||||
|
||||
|
@@ -1457,7 +1457,12 @@ EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
|
||||
int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port,
|
||||
u32 qpn, enum mlx4_net_trans_promisc_mode mode)
|
||||
{
|
||||
struct mlx4_net_trans_rule rule;
|
||||
struct mlx4_net_trans_rule rule = {
|
||||
.queue_mode = MLX4_NET_TRANS_Q_FIFO,
|
||||
.exclusive = 0,
|
||||
.allow_loopback = 1,
|
||||
};
|
||||
|
||||
u64 *regid_p;
|
||||
|
||||
switch (mode) {
|
||||
|
@@ -212,6 +212,7 @@ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt)
|
||||
|
||||
phy_np = of_parse_phandle(np, "phy-handle", 0);
|
||||
adpt->phydev = of_phy_find_device(phy_np);
|
||||
of_node_put(phy_np);
|
||||
}
|
||||
|
||||
if (!adpt->phydev) {
|
||||
|
@@ -710,6 +710,8 @@ static int emac_probe(struct platform_device *pdev)
|
||||
err_undo_napi:
|
||||
netif_napi_del(&adpt->rx_q.napi);
|
||||
err_undo_mdiobus:
|
||||
if (!has_acpi_companion(&pdev->dev))
|
||||
put_device(&adpt->phydev->mdio.dev);
|
||||
mdiobus_unregister(adpt->mii_bus);
|
||||
err_undo_clocks:
|
||||
emac_clks_teardown(adpt);
|
||||
@@ -729,6 +731,8 @@ static int emac_remove(struct platform_device *pdev)
|
||||
|
||||
emac_clks_teardown(adpt);
|
||||
|
||||
if (!has_acpi_companion(&pdev->dev))
|
||||
put_device(&adpt->phydev->mdio.dev);
|
||||
mdiobus_unregister(adpt->mii_bus);
|
||||
free_netdev(netdev);
|
||||
|
||||
|
@@ -1008,20 +1008,18 @@ static int ravb_phy_init(struct net_device *ndev)
|
||||
of_node_put(pn);
|
||||
if (!phydev) {
|
||||
netdev_err(ndev, "failed to connect PHY\n");
|
||||
return -ENOENT;
|
||||
err = -ENOENT;
|
||||
goto err_deregister_fixed_link;
|
||||
}
|
||||
|
||||
/* This driver only support 10/100Mbit speeds on Gen3
|
||||
* at this time.
|
||||
*/
|
||||
if (priv->chip_id == RCAR_GEN3) {
|
||||
int err;
|
||||
|
||||
err = phy_set_max_speed(phydev, SPEED_100);
|
||||
if (err) {
|
||||
netdev_err(ndev, "failed to limit PHY to 100Mbit/s\n");
|
||||
phy_disconnect(phydev);
|
||||
return err;
|
||||
goto err_phy_disconnect;
|
||||
}
|
||||
|
||||
netdev_info(ndev, "limited PHY to 100Mbit/s\n");
|
||||
@@ -1033,6 +1031,14 @@ static int ravb_phy_init(struct net_device *ndev)
|
||||
phy_attached_info(phydev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_phy_disconnect:
|
||||
phy_disconnect(phydev);
|
||||
err_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* PHY control start function */
|
||||
@@ -1634,6 +1640,7 @@ static void ravb_set_rx_mode(struct net_device *ndev)
|
||||
/* Device close function for Ethernet AVB */
|
||||
static int ravb_close(struct net_device *ndev)
|
||||
{
|
||||
struct device_node *np = ndev->dev.parent->of_node;
|
||||
struct ravb_private *priv = netdev_priv(ndev);
|
||||
struct ravb_tstamp_skb *ts_skb, *ts_skb2;
|
||||
|
||||
@@ -1663,6 +1670,8 @@ static int ravb_close(struct net_device *ndev)
|
||||
if (ndev->phydev) {
|
||||
phy_stop(ndev->phydev);
|
||||
phy_disconnect(ndev->phydev);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
}
|
||||
|
||||
if (priv->chip_id != RCAR_GEN2) {
|
||||
|
@@ -518,7 +518,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
|
||||
|
||||
.ecsr_value = ECSR_ICD,
|
||||
.ecsipr_value = ECSIPR_ICDIP,
|
||||
.eesipr_value = 0xff7f009f,
|
||||
.eesipr_value = 0xe77f009f,
|
||||
|
||||
.tx_check = EESR_TC1 | EESR_FTC,
|
||||
.eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
|
||||
|
@@ -50,10 +50,23 @@ static int dwmac_generic_probe(struct platform_device *pdev)
|
||||
if (plat_dat->init) {
|
||||
ret = plat_dat->init(pdev, plat_dat->bsp_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
if (plat_dat->exit)
|
||||
plat_dat->exit(pdev, plat_dat->bsp_priv);
|
||||
err_remove_config_dt:
|
||||
if (pdev->dev.of_node)
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id dwmac_generic_match[] = {
|
||||
|
@@ -271,15 +271,17 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||
if (!gmac)
|
||||
return -ENOMEM;
|
||||
if (!gmac) {
|
||||
err = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
gmac->pdev = pdev;
|
||||
|
||||
err = ipq806x_gmac_of_parse(gmac);
|
||||
if (err) {
|
||||
dev_err(dev, "device tree parsing error\n");
|
||||
return err;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
|
||||
@@ -300,7 +302,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
phy_modes(gmac->phy_mode));
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
|
||||
|
||||
@@ -319,7 +322,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
|
||||
phy_modes(gmac->phy_mode));
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
|
||||
|
||||
@@ -346,7 +350,16 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
|
||||
plat_dat->bsp_priv = gmac;
|
||||
plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (err)
|
||||
goto err_remove_config_dt;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
|
||||
|
@@ -46,7 +46,8 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
|
||||
reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
|
||||
if (IS_ERR(reg)) {
|
||||
dev_err(&pdev->dev, "syscon lookup failed\n");
|
||||
return PTR_ERR(reg);
|
||||
ret = PTR_ERR(reg);
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
|
||||
@@ -55,13 +56,23 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev)
|
||||
ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
|
||||
} else {
|
||||
dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
regmap_update_bits(reg, LPC18XX_CREG_CREG6,
|
||||
LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_remove_config_dt;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id lpc18xx_dwmac_match[] = {
|
||||
|
@@ -64,18 +64,31 @@ static int meson6_dwmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
if (!dwmac)
|
||||
return -ENOMEM;
|
||||
if (!dwmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(dwmac->reg))
|
||||
return PTR_ERR(dwmac->reg);
|
||||
if (IS_ERR(dwmac->reg)) {
|
||||
ret = PTR_ERR(dwmac->reg);
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_remove_config_dt;
|
||||
|
||||
return 0;
|
||||
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id meson6_dwmac_match[] = {
|
||||
|
@@ -264,32 +264,48 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
if (!dwmac)
|
||||
return -ENOMEM;
|
||||
if (!dwmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(dwmac->regs))
|
||||
return PTR_ERR(dwmac->regs);
|
||||
if (IS_ERR(dwmac->regs)) {
|
||||
ret = PTR_ERR(dwmac->regs);
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
dwmac->pdev = pdev;
|
||||
dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node);
|
||||
if (dwmac->phy_mode < 0) {
|
||||
dev_err(&pdev->dev, "missing phy-mode property\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
ret = meson8b_init_clk(dwmac);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
ret = meson8b_init_prg_eth(dwmac);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_clk_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_disable:
|
||||
clk_disable_unprepare(dwmac->m25_div_clk);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int meson8b_dwmac_remove(struct platform_device *pdev)
|
||||
|
@@ -939,14 +939,27 @@ static int rk_gmac_probe(struct platform_device *pdev)
|
||||
plat_dat->fix_mac_speed = rk_fix_speed;
|
||||
|
||||
plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
|
||||
if (IS_ERR(plat_dat->bsp_priv))
|
||||
return PTR_ERR(plat_dat->bsp_priv);
|
||||
if (IS_ERR(plat_dat->bsp_priv)) {
|
||||
ret = PTR_ERR(plat_dat->bsp_priv);
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
ret = rk_gmac_powerup(plat_dat->bsp_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_gmac_powerdown;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gmac_powerdown:
|
||||
rk_gmac_powerdown(plat_dat->bsp_priv);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_gmac_remove(struct platform_device *pdev)
|
||||
|
@@ -304,6 +304,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
struct socfpga_dwmac *dwmac;
|
||||
struct net_device *ndev;
|
||||
struct stmmac_priv *stpriv;
|
||||
|
||||
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
|
||||
if (ret)
|
||||
@@ -314,32 +316,43 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
if (!dwmac)
|
||||
return -ENOMEM;
|
||||
if (!dwmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
ret = socfpga_dwmac_parse_data(dwmac, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Unable to parse OF data\n");
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
|
||||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
goto err_remove_config_dt;
|
||||
|
||||
if (!ret) {
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct stmmac_priv *stpriv = netdev_priv(ndev);
|
||||
ndev = platform_get_drvdata(pdev);
|
||||
stpriv = netdev_priv(ndev);
|
||||
|
||||
/* The socfpga driver needs to control the stmmac reset to
|
||||
* set the phy mode. Create a copy of the core reset handel
|
||||
* so it can be used by the driver later.
|
||||
*/
|
||||
dwmac->stmmac_rst = stpriv->stmmac_rst;
|
||||
/* The socfpga driver needs to control the stmmac reset to set the phy
|
||||
* mode. Create a copy of the core reset handle so it can be used by
|
||||
* the driver later.
|
||||
*/
|
||||
dwmac->stmmac_rst = stpriv->stmmac_rst;
|
||||
|
||||
ret = socfpga_dwmac_set_phy_mode(dwmac);
|
||||
}
|
||||
ret = socfpga_dwmac_set_phy_mode(dwmac);
|
||||
if (ret)
|
||||
goto err_dvr_remove;
|
||||
|
||||
return 0;
|
||||
|
||||
err_dvr_remove:
|
||||
stmmac_dvr_remove(&pdev->dev);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -329,13 +329,15 @@ static int sti_dwmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
if (!dwmac)
|
||||
return -ENOMEM;
|
||||
if (!dwmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
ret = sti_dwmac_parse_data(dwmac, pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to parse OF data\n");
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
dwmac->fix_retime_src = data->fix_retime_src;
|
||||
@@ -345,7 +347,7 @@ static int sti_dwmac_probe(struct platform_device *pdev)
|
||||
|
||||
ret = clk_prepare_enable(dwmac->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
ret = sti_dwmac_set_mode(dwmac);
|
||||
if (ret)
|
||||
@@ -359,6 +361,9 @@ static int sti_dwmac_probe(struct platform_device *pdev)
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(dwmac->clk);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -107,24 +107,33 @@ static int stm32_dwmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
|
||||
if (!dwmac)
|
||||
return -ENOMEM;
|
||||
if (!dwmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
ret = stm32_dwmac_parse_data(dwmac, &pdev->dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Unable to parse OF data\n");
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
plat_dat->bsp_priv = dwmac;
|
||||
|
||||
ret = stm32_dwmac_init(plat_dat);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
stm32_dwmac_clk_disable(dwmac);
|
||||
goto err_clk_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_disable:
|
||||
stm32_dwmac_clk_disable(dwmac);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -120,22 +120,27 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(plat_dat);
|
||||
|
||||
gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
|
||||
if (!gmac)
|
||||
return -ENOMEM;
|
||||
if (!gmac) {
|
||||
ret = -ENOMEM;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
gmac->interface = of_get_phy_mode(dev->of_node);
|
||||
|
||||
gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
|
||||
if (IS_ERR(gmac->tx_clk)) {
|
||||
dev_err(dev, "could not get tx clock\n");
|
||||
return PTR_ERR(gmac->tx_clk);
|
||||
ret = PTR_ERR(gmac->tx_clk);
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
|
||||
/* Optional regulator for PHY */
|
||||
gmac->regulator = devm_regulator_get_optional(dev, "phy");
|
||||
if (IS_ERR(gmac->regulator)) {
|
||||
if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto err_remove_config_dt;
|
||||
}
|
||||
dev_info(dev, "no regulator found\n");
|
||||
gmac->regulator = NULL;
|
||||
}
|
||||
@@ -151,11 +156,18 @@ static int sun7i_gmac_probe(struct platform_device *pdev)
|
||||
|
||||
ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_remove_config_dt;
|
||||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
|
||||
if (ret)
|
||||
sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
|
||||
goto err_gmac_exit;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gmac_exit:
|
||||
sun7i_gmac_exit(pdev, plat_dat->bsp_priv);
|
||||
err_remove_config_dt:
|
||||
stmmac_remove_config_dt(pdev, plat_dat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -3428,7 +3428,6 @@ int stmmac_dvr_remove(struct device *dev)
|
||||
stmmac_set_mac(priv->ioaddr, false);
|
||||
netif_carrier_off(ndev);
|
||||
unregister_netdev(ndev);
|
||||
of_node_put(priv->plat->phy_node);
|
||||
if (priv->stmmac_rst)
|
||||
reset_control_assert(priv->stmmac_rst);
|
||||
clk_disable_unprepare(priv->pclk);
|
||||
|
@@ -200,7 +200,6 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
|
||||
/**
|
||||
* stmmac_probe_config_dt - parse device-tree driver parameters
|
||||
* @pdev: platform_device structure
|
||||
* @plat: driver data platform structure
|
||||
* @mac: MAC address to use
|
||||
* Description:
|
||||
* this function is to read the driver parameters from device-tree and
|
||||
@@ -306,7 +305,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
of_node_put(plat->phy_node);
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
@@ -329,14 +328,37 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
|
||||
|
||||
return plat;
|
||||
}
|
||||
|
||||
/**
|
||||
* stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
|
||||
* @pdev: platform_device structure
|
||||
* @plat: driver data platform structure
|
||||
*
|
||||
* Release resources claimed by stmmac_probe_config_dt().
|
||||
*/
|
||||
void stmmac_remove_config_dt(struct platform_device *pdev,
|
||||
struct plat_stmmacenet_data *plat)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(plat->phy_node);
|
||||
}
|
||||
#else
|
||||
struct plat_stmmacenet_data *
|
||||
stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
void stmmac_remove_config_dt(struct platform_device *pdev,
|
||||
struct plat_stmmacenet_data *plat)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_OF */
|
||||
EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
|
||||
EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
|
||||
|
||||
int stmmac_get_platform_resources(struct platform_device *pdev,
|
||||
struct stmmac_resources *stmmac_res)
|
||||
@@ -392,10 +414,13 @@ int stmmac_pltfr_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
struct plat_stmmacenet_data *plat = priv->plat;
|
||||
int ret = stmmac_dvr_remove(&pdev->dev);
|
||||
|
||||
if (priv->plat->exit)
|
||||
priv->plat->exit(pdev, priv->plat->bsp_priv);
|
||||
if (plat->exit)
|
||||
plat->exit(pdev, plat->bsp_priv);
|
||||
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@
|
||||
|
||||
struct plat_stmmacenet_data *
|
||||
stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
|
||||
void stmmac_remove_config_dt(struct platform_device *pdev,
|
||||
struct plat_stmmacenet_data *plat);
|
||||
|
||||
int stmmac_get_platform_resources(struct platform_device *pdev,
|
||||
struct stmmac_resources *stmmac_res);
|
||||
|
@@ -2881,7 +2881,7 @@ static int dwceqos_probe(struct platform_device *pdev)
|
||||
ret = of_get_phy_mode(lp->pdev->dev.of_node);
|
||||
if (ret < 0) {
|
||||
dev_err(&lp->pdev->dev, "error in getting phy i/f\n");
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
|
||||
lp->phy_interface = ret;
|
||||
@@ -2889,14 +2889,14 @@ static int dwceqos_probe(struct platform_device *pdev)
|
||||
ret = dwceqos_mii_init(lp);
|
||||
if (ret) {
|
||||
dev_err(&lp->pdev->dev, "error in dwceqos_mii_init\n");
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
|
||||
ret = dwceqos_mii_probe(ndev);
|
||||
if (ret != 0) {
|
||||
netdev_err(ndev, "mii_probe fail.\n");
|
||||
ret = -ENXIO;
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
|
||||
dwceqos_set_umac_addr(lp, lp->ndev->dev_addr, 0);
|
||||
@@ -2914,7 +2914,7 @@ static int dwceqos_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(&lp->pdev->dev, "Unable to retrieve DT, error %d\n",
|
||||
ret);
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
dev_info(&lp->pdev->dev, "pdev->id %d, baseaddr 0x%08lx, irq %d\n",
|
||||
pdev->id, ndev->base_addr, ndev->irq);
|
||||
@@ -2924,7 +2924,7 @@ static int dwceqos_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(&lp->pdev->dev, "Unable to request IRQ %d, error %d\n",
|
||||
ndev->irq, ret);
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
|
||||
if (netif_msg_probe(lp))
|
||||
@@ -2935,11 +2935,14 @@ static int dwceqos_probe(struct platform_device *pdev)
|
||||
ret = register_netdev(ndev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
|
||||
goto err_out_clk_dis_phy;
|
||||
goto err_out_deregister_fixed_link;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(pdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(pdev->dev.of_node);
|
||||
err_out_clk_dis_phy:
|
||||
clk_disable_unprepare(lp->phy_ref_clk);
|
||||
err_out_clk_dis_aper:
|
||||
@@ -2959,8 +2962,11 @@ static int dwceqos_remove(struct platform_device *pdev)
|
||||
if (ndev) {
|
||||
lp = netdev_priv(ndev);
|
||||
|
||||
if (ndev->phydev)
|
||||
if (ndev->phydev) {
|
||||
phy_disconnect(ndev->phydev);
|
||||
if (of_phy_is_fixed_link(pdev->dev.of_node))
|
||||
of_phy_deregister_fixed_link(pdev->dev.of_node);
|
||||
}
|
||||
mdiobus_unregister(lp->mii_bus);
|
||||
mdiobus_free(lp->mii_bus);
|
||||
|
||||
|
@@ -2671,20 +2671,8 @@ static void cpsw_remove_dt(struct platform_device *pdev)
|
||||
if (strcmp(slave_node->name, "slave"))
|
||||
continue;
|
||||
|
||||
if (of_phy_is_fixed_link(slave_node)) {
|
||||
struct phy_device *phydev;
|
||||
|
||||
phydev = of_phy_find_device(slave_node);
|
||||
if (phydev) {
|
||||
fixed_phy_unregister(phydev);
|
||||
/* Put references taken by
|
||||
* of_phy_find_device() and
|
||||
* of_phy_register_fixed_link().
|
||||
*/
|
||||
phy_device_free(phydev);
|
||||
phy_device_free(phydev);
|
||||
}
|
||||
}
|
||||
if (of_phy_is_fixed_link(slave_node))
|
||||
of_phy_deregister_fixed_link(slave_node);
|
||||
|
||||
of_node_put(slave_data->phy_node);
|
||||
|
||||
@@ -3155,6 +3143,8 @@ static int cpsw_resume(struct device *dev)
|
||||
/* Select default pin state */
|
||||
pinctrl_pm_select_default_state(dev);
|
||||
|
||||
/* shut up ASSERT_RTNL() warning in netif_set_real_num_tx/rx_queues */
|
||||
rtnl_lock();
|
||||
if (cpsw->data.dual_emac) {
|
||||
int i;
|
||||
|
||||
@@ -3166,6 +3156,8 @@ static int cpsw_resume(struct device *dev)
|
||||
if (netif_running(ndev))
|
||||
cpsw_ndo_open(ndev);
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@@ -1767,6 +1767,7 @@ static int davinci_emac_try_get_mac(struct platform_device *pdev,
|
||||
*/
|
||||
static int davinci_emac_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
int rc = 0;
|
||||
struct resource *res, *res_ctrl;
|
||||
struct net_device *ndev;
|
||||
@@ -1805,7 +1806,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
rc = -ENODEV;
|
||||
goto no_pdata;
|
||||
goto err_free_netdev;
|
||||
}
|
||||
|
||||
/* MAC addr and PHY mask , RMII enable info from platform_data */
|
||||
@@ -1941,6 +1942,10 @@ no_cpdma_chan:
|
||||
cpdma_chan_destroy(priv->rxchan);
|
||||
cpdma_ctlr_destroy(priv->dma);
|
||||
no_pdata:
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(priv->phy_node);
|
||||
err_free_netdev:
|
||||
free_netdev(ndev);
|
||||
return rc;
|
||||
}
|
||||
@@ -1956,6 +1961,7 @@ static int davinci_emac_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct emac_priv *priv = netdev_priv(ndev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
|
||||
|
||||
@@ -1968,6 +1974,8 @@ static int davinci_emac_remove(struct platform_device *pdev)
|
||||
unregister_netdev(ndev);
|
||||
of_node_put(priv->phy_node);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
free_netdev(ndev);
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user