net: sh_eth: Add r8a7794 support
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / net / ethernet / renesas / sh_eth.c
index 185f185..177d263 100644 (file)
@@ -887,7 +887,7 @@ static int sh_eth_reset(struct net_device *ndev)
 
                ret = sh_eth_check_reset(ndev);
                if (ret)
-                       goto out;
+                       return ret;
 
                /* Table Init */
                sh_eth_write(ndev, 0x0, TDLAR);
@@ -914,7 +914,6 @@ static int sh_eth_reset(struct net_device *ndev)
                             EDMR);
        }
 
-out:
        return ret;
 }
 
@@ -1095,20 +1094,16 @@ static void sh_eth_ring_free(struct net_device *ndev)
 
        /* Free Rx skb ringbuffer */
        if (mdp->rx_skbuff) {
-               for (i = 0; i < mdp->num_rx_ring; i++) {
-                       if (mdp->rx_skbuff[i])
-                               dev_kfree_skb(mdp->rx_skbuff[i]);
-               }
+               for (i = 0; i < mdp->num_rx_ring; i++)
+                       dev_kfree_skb(mdp->rx_skbuff[i]);
        }
        kfree(mdp->rx_skbuff);
        mdp->rx_skbuff = NULL;
 
        /* Free Tx skb ringbuffer */
        if (mdp->tx_skbuff) {
-               for (i = 0; i < mdp->num_tx_ring; i++) {
-                       if (mdp->tx_skbuff[i])
-                               dev_kfree_skb(mdp->tx_skbuff[i]);
-               }
+               for (i = 0; i < mdp->num_tx_ring; i++)
+                       dev_kfree_skb(mdp->tx_skbuff[i]);
        }
        kfree(mdp->tx_skbuff);
        mdp->tx_skbuff = NULL;
@@ -1278,7 +1273,7 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
        /* Soft Reset */
        ret = sh_eth_reset(ndev);
        if (ret)
-               goto out;
+               return ret;
 
        if (mdp->cd->rmiimode)
                sh_eth_write(ndev, 0x1, RMIIMODE);
@@ -1357,7 +1352,6 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start)
                netif_start_queue(ndev);
        }
 
-out:
        return ret;
 }
 
@@ -1401,7 +1395,6 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
        int entry = mdp->cur_rx % mdp->num_rx_ring;
        int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
        struct sk_buff *skb;
-       int exceeded = 0;
        u16 pkt_len = 0;
        u32 desc_status;
 
@@ -1413,10 +1406,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                if (--boguscnt < 0)
                        break;
 
-               if (*quota <= 0) {
-                       exceeded = 1;
+               if (*quota <= 0)
                        break;
-               }
+
                (*quota)--;
 
                if (!(desc_status & RDFEND))
@@ -1464,7 +1456,6 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                        ndev->stats.rx_packets++;
                        ndev->stats.rx_bytes += pkt_len;
                }
-               rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
                entry = (++mdp->cur_rx) % mdp->num_rx_ring;
                rxdesc = &mdp->rx_ring[entry];
        }
@@ -1510,7 +1501,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
                sh_eth_write(ndev, EDRRR_R, EDRRR);
        }
 
-       return exceeded;
+       return *quota <= 0;
 }
 
 static void sh_eth_rcv_snd_disable(struct net_device *ndev)
@@ -1571,8 +1562,7 @@ ignore_link:
                /* Unused write back interrupt */
                if (intr_status & EESR_TABT) {  /* Transmit Abort int */
                        ndev->stats.tx_aborted_errors++;
-                       if (netif_msg_tx_err(mdp))
-                               netdev_err(ndev, "Transmit Abort\n");
+                       netif_err(mdp, tx_err, ndev, "Transmit Abort\n");
                }
        }
 
@@ -1581,45 +1571,38 @@ ignore_link:
                if (intr_status & EESR_RFRMER) {
                        /* Receive Frame Overflow int */
                        ndev->stats.rx_frame_errors++;
-                       if (netif_msg_rx_err(mdp))
-                               netdev_err(ndev, "Receive Abort\n");
+                       netif_err(mdp, rx_err, ndev, "Receive Abort\n");
                }
        }
 
        if (intr_status & EESR_TDE) {
                /* Transmit Descriptor Empty int */
                ndev->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       netdev_err(ndev, "Transmit Descriptor Empty\n");
+               netif_err(mdp, tx_err, ndev, "Transmit Descriptor Empty\n");
        }
 
        if (intr_status & EESR_TFE) {
                /* FIFO under flow */
                ndev->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       netdev_err(ndev, "Transmit FIFO Under flow\n");
+               netif_err(mdp, tx_err, ndev, "Transmit FIFO Under flow\n");
        }
 
        if (intr_status & EESR_RDE) {
                /* Receive Descriptor Empty int */
                ndev->stats.rx_over_errors++;
-
-               if (netif_msg_rx_err(mdp))
-                       netdev_err(ndev, "Receive Descriptor Empty\n");
+               netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n");
        }
 
        if (intr_status & EESR_RFE) {
                /* Receive FIFO Overflow int */
                ndev->stats.rx_fifo_errors++;
-               if (netif_msg_rx_err(mdp))
-                       netdev_err(ndev, "Receive FIFO Overflow\n");
+               netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n");
        }
 
        if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
                /* Address Error */
                ndev->stats.tx_fifo_errors++;
-               if (netif_msg_tx_err(mdp))
-                       netdev_err(ndev, "Address Error\n");
+               netif_err(mdp, tx_err, ndev, "Address Error\n");
        }
 
        mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
@@ -2078,11 +2061,9 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
 
        netif_stop_queue(ndev);
 
-       if (netif_msg_timer(mdp)) {
-               netdev_err(ndev,
-                          "transmit timed out, status %8.8x, resetting...\n",
-                          (int)sh_eth_read(ndev, EESR));
-       }
+       netif_err(mdp, timer, ndev,
+                 "transmit timed out, status %8.8x, resetting...\n",
+                 (int)sh_eth_read(ndev, EESR));
 
        /* tx_errors count up */
        ndev->stats.tx_errors++;
@@ -2092,13 +2073,11 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
                rxdesc = &mdp->rx_ring[i];
                rxdesc->status = 0;
                rxdesc->addr = 0xBADF00D0;
-               if (mdp->rx_skbuff[i])
-                       dev_kfree_skb(mdp->rx_skbuff[i]);
+               dev_kfree_skb(mdp->rx_skbuff[i]);
                mdp->rx_skbuff[i] = NULL;
        }
        for (i = 0; i < mdp->num_tx_ring; i++) {
-               if (mdp->tx_skbuff[i])
-                       dev_kfree_skb(mdp->tx_skbuff[i]);
+               dev_kfree_skb(mdp->tx_skbuff[i]);
                mdp->tx_skbuff[i] = NULL;
        }
 
@@ -2117,8 +2096,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        spin_lock_irqsave(&mdp->lock, flags);
        if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
                if (!sh_eth_txfree(ndev)) {
-                       if (netif_msg_tx_queued(mdp))
-                               netdev_warn(ndev, "TxFD exhausted.\n");
+                       netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n");
                        netif_stop_queue(ndev);
                        spin_unlock_irqrestore(&mdp->lock, flags);
                        return NETDEV_TX_BUSY;
@@ -2608,37 +2586,30 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 }
 
 /* MDIO bus release function */
-static int sh_mdio_release(struct net_device *ndev)
+static int sh_mdio_release(struct sh_eth_private *mdp)
 {
-       struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
-
        /* unregister mdio bus */
-       mdiobus_unregister(bus);
-
-       /* remove mdio bus info from net_device */
-       dev_set_drvdata(&ndev->dev, NULL);
+       mdiobus_unregister(mdp->mii_bus);
 
        /* free bitbang info */
-       free_mdio_bitbang(bus);
+       free_mdio_bitbang(mdp->mii_bus);
 
        return 0;
 }
 
 /* MDIO bus init function */
-static int sh_mdio_init(struct net_device *ndev, int id,
+static int sh_mdio_init(struct sh_eth_private *mdp,
                        struct sh_eth_plat_data *pd)
 {
        int ret, i;
        struct bb_info *bitbang;
-       struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct platform_device *pdev = mdp->pdev;
+       struct device *dev = &mdp->pdev->dev;
 
        /* create bit control struct for PHY */
-       bitbang = devm_kzalloc(&ndev->dev, sizeof(struct bb_info),
-                              GFP_KERNEL);
-       if (!bitbang) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       bitbang = devm_kzalloc(dev, sizeof(struct bb_info), GFP_KERNEL);
+       if (!bitbang)
+               return -ENOMEM;
 
        /* bitbang init */
        bitbang->addr = mdp->addr + mdp->reg_offset[PIR];
@@ -2651,30 +2622,26 @@ static int sh_mdio_init(struct net_device *ndev, int id,
 
        /* MII controller setting */
        mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
-       if (!mdp->mii_bus) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!mdp->mii_bus)
+               return -ENOMEM;
 
        /* Hook up MII support for ethtool */
        mdp->mii_bus->name = "sh_mii";
-       mdp->mii_bus->parent = &ndev->dev;
+       mdp->mii_bus->parent = dev;
        snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
-                mdp->pdev->name, id);
+                pdev->name, pdev->id);
 
        /* PHY IRQ */
-       mdp->mii_bus->irq = devm_kzalloc(&ndev->dev,
-                                        sizeof(int) * PHY_MAX_ADDR,
-                                        GFP_KERNEL);
+       mdp->mii_bus->irq = devm_kmalloc_array(dev, PHY_MAX_ADDR, sizeof(int),
+                                              GFP_KERNEL);
        if (!mdp->mii_bus->irq) {
                ret = -ENOMEM;
                goto out_free_bus;
        }
 
-       /* register mdio bus */
-       if (ndev->dev.parent->of_node) {
-               ret = of_mdiobus_register(mdp->mii_bus,
-                                         ndev->dev.parent->of_node);
+       /* register MDIO bus */
+       if (dev->of_node) {
+               ret = of_mdiobus_register(mdp->mii_bus, dev->of_node);
        } else {
                for (i = 0; i < PHY_MAX_ADDR; i++)
                        mdp->mii_bus->irq[i] = PHY_POLL;
@@ -2687,14 +2654,10 @@ static int sh_mdio_init(struct net_device *ndev, int id,
        if (ret)
                goto out_free_bus;
 
-       dev_set_drvdata(&ndev->dev, mdp->mii_bus);
-
        return 0;
 
 out_free_bus:
        free_mdio_bitbang(mdp->mii_bus);
-
-out:
        return ret;
 }
 
@@ -2783,6 +2746,7 @@ static const struct of_device_id sh_eth_match_table[] = {
        { .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data },
        { .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data },
        { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data },
+       { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data },
        { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data },
        { }
 };
@@ -2807,15 +2771,15 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (unlikely(res == NULL)) {
                dev_err(&pdev->dev, "invalid resource\n");
-               ret = -EINVAL;
-               goto out;
+               return -EINVAL;
        }
 
        ndev = alloc_etherdev(sizeof(struct sh_eth_private));
-       if (!ndev) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       if (!ndev)
+               return -ENOMEM;
+
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
 
        /* The sh Ether-specific entries in the device structure. */
        ndev->base_addr = res->start;
@@ -2844,8 +2808,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 
        spin_lock_init(&mdp->lock);
        mdp->pdev = pdev;
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_resume(&pdev->dev);
 
        if (pdev->dev.of_node)
                pd = sh_eth_parse_dt(&pdev->dev);
@@ -2925,6 +2887,13 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
                }
        }
 
+       /* MDIO bus init */
+       ret = sh_mdio_init(mdp, pd);
+       if (ret) {
+               dev_err(&ndev->dev, "failed to initialise MDIO\n");
+               goto out_release;
+       }
+
        netif_napi_add(ndev, &mdp->napi, sh_eth_poll, 64);
 
        /* network device register */
@@ -2932,33 +2901,26 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        if (ret)
                goto out_napi_del;
 
-       /* mdio bus init */
-       ret = sh_mdio_init(ndev, pdev->id, pd);
-       if (ret) {
-               dev_err(&ndev->dev, "failed to initialise MDIO\n");
-               goto out_unregister;
-       }
-
        /* print device information */
        netdev_info(ndev, "Base address at 0x%x, %pM, IRQ %d.\n",
                    (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
 
+       pm_runtime_put(&pdev->dev);
        platform_set_drvdata(pdev, ndev);
 
        return ret;
 
-out_unregister:
-       unregister_netdev(ndev);
-
 out_napi_del:
        netif_napi_del(&mdp->napi);
+       sh_mdio_release(mdp);
 
 out_release:
        /* net_dev free */
        if (ndev)
                free_netdev(ndev);
 
-out:
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
        return ret;
 }
 
@@ -2967,9 +2929,9 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct sh_eth_private *mdp = netdev_priv(ndev);
 
-       sh_mdio_release(ndev);
        unregister_netdev(ndev);
        netif_napi_del(&mdp->napi);
+       sh_mdio_release(mdp);
        pm_runtime_disable(&pdev->dev);
        free_netdev(ndev);
 
@@ -3011,6 +2973,7 @@ static struct platform_device_id sh_eth_id_table[] = {
        { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
        { "r8a7790-ether", (kernel_ulong_t)&r8a779x_data },
        { "r8a7791-ether", (kernel_ulong_t)&r8a779x_data },
+       { "r8a7794-ether", (kernel_ulong_t)&r8a779x_data },
        { }
 };
 MODULE_DEVICE_TABLE(platform, sh_eth_id_table);