diff options
Diffstat (limited to 'drivers/net/ethernet/renesas')
-rw-r--r-- | drivers/net/ethernet/renesas/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 71 | ||||
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.h | 10 |
3 files changed, 71 insertions, 12 deletions
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 19a8a045e077..a30c4395b232 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig @@ -13,4 +13,4 @@ config SH_ETH Renesas SuperH Ethernet device driver. This driver supporting CPUs are: - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, - R8A7740 and R8A7779. + R8A7740, R8A777x and R8A7790. diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index a753928bab9c..5cd831ebfa83 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -189,6 +189,7 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { [RMCR] = 0x0258, [TFUCR] = 0x0264, [RFOCR] = 0x0268, + [RMIIMODE] = 0x026c, [FCFTR] = 0x0270, [TRIMD] = 0x027c, }; @@ -377,6 +378,8 @@ static struct sh_eth_cpu_data r8a777x_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_r8a777x, + .register_type = SH_ETH_REG_FAST_RCAR, + .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, .eesipr_value = 0x01ff009f, @@ -392,6 +395,30 @@ static struct sh_eth_cpu_data r8a777x_data = { .hw_swap = 1, }; +/* R8A7790 */ +static struct sh_eth_cpu_data r8a7790_data = { + .set_duplex = sh_eth_set_duplex, + .set_rate = sh_eth_set_rate_r8a777x, + + .register_type = SH_ETH_REG_FAST_RCAR, + + .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, + .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, + .eesipr_value = 0x01ff009f, + + .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, + .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | + EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | + EESR_ECI, + + .apr = 1, + .mpr = 1, + .tpauser = 1, + .hw_swap = 1, + .rmiimode = 1, + .shift_rd0 = 1, +}; + static void sh_eth_set_rate_sh7724(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -413,6 +440,8 @@ static struct sh_eth_cpu_data sh7724_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_sh7724, + .register_type = SH_ETH_REG_FAST_SH4, + .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, .eesipr_value = 0x01ff009f, @@ -451,6 +480,8 @@ static struct sh_eth_cpu_data sh7757_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_sh7757, + .register_type = SH_ETH_REG_FAST_SH4, + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, .rmcr_value = 0x00000001, @@ -519,6 +550,8 @@ static struct sh_eth_cpu_data sh7757_data_giga = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_giga, + .register_type = SH_ETH_REG_GIGABIT, + .ecsr_value = ECSR_ICD | ECSR_MPD, .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, @@ -577,6 +610,8 @@ static struct sh_eth_cpu_data sh7734_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_gether, + .register_type = SH_ETH_REG_GIGABIT, + .ecsr_value = ECSR_ICD | ECSR_MPD, .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, @@ -604,6 +639,8 @@ static struct sh_eth_cpu_data sh7763_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_gether, + .register_type = SH_ETH_REG_GIGABIT, + .ecsr_value = ECSR_ICD | ECSR_MPD, .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, @@ -641,6 +678,8 @@ static struct sh_eth_cpu_data r8a7740_data = { .set_duplex = sh_eth_set_duplex, .set_rate = sh_eth_set_rate_gether, + .register_type = SH_ETH_REG_GIGABIT, + .ecsr_value = ECSR_ICD | ECSR_MPD, .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, @@ -663,6 +702,8 @@ static struct sh_eth_cpu_data r8a7740_data = { }; static struct sh_eth_cpu_data sh7619_data = { + .register_type = SH_ETH_REG_FAST_SH3_SH2, + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, .apr = 1, @@ -672,6 +713,8 @@ static struct sh_eth_cpu_data sh7619_data = { }; static struct sh_eth_cpu_data sh771x_data = { + .register_type = SH_ETH_REG_FAST_SH3_SH2, + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, .tsu = 1, }; @@ -1124,6 +1167,9 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) if (ret) goto out; + if (mdp->cd->rmiimode) + sh_eth_write(ndev, 0x1, RMIIMODE); + /* Descriptor format */ sh_eth_ring_format(ndev); if (mdp->cd->rpadir) @@ -1297,9 +1343,12 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) mdp->rx_skbuff[entry] = NULL; if (mdp->cd->rpadir) skb_reserve(skb, NET_IP_ALIGN); + dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, + mdp->rx_buf_sz, + DMA_FROM_DEVICE); skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, ndev); - netif_rx(skb); + netif_receive_skb(skb); ndev->stats.rx_packets++; ndev->stats.rx_bytes += pkt_len; } @@ -1857,11 +1906,13 @@ static int sh_eth_open(struct net_device *ndev) pm_runtime_get_sync(&mdp->pdev->dev); + napi_enable(&mdp->napi); + ret = request_irq(ndev->irq, sh_eth_interrupt, mdp->cd->irq_flags, ndev->name, ndev); if (ret) { dev_err(&ndev->dev, "Can not assign IRQ number\n"); - return ret; + goto out_napi_off; } /* Descriptor set */ @@ -1879,12 +1930,12 @@ static int sh_eth_open(struct net_device *ndev) if (ret) goto out_free_irq; - napi_enable(&mdp->napi); - return ret; out_free_irq: free_irq(ndev->irq, ndev); +out_napi_off: + napi_disable(&mdp->napi); pm_runtime_put_sync(&mdp->pdev->dev); return ret; } @@ -1976,8 +2027,6 @@ static int sh_eth_close(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); - napi_disable(&mdp->napi); - netif_stop_queue(ndev); /* Disable interrupts by clearing the interrupt mask. */ @@ -1995,6 +2044,8 @@ static int sh_eth_close(struct net_device *ndev) free_irq(ndev->irq, ndev); + napi_disable(&mdp->napi); + /* Free all the skbuffs in the Rx queue. */ sh_eth_ring_free(ndev); @@ -2561,7 +2612,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) struct resource *res; struct net_device *ndev = NULL; struct sh_eth_private *mdp = NULL; - struct sh_eth_plat_data *pd = pdev->dev.platform_data; + struct sh_eth_plat_data *pd = dev_get_platdata(&pdev->dev); const struct platform_device_id *id = platform_get_device_id(pdev); /* get base addr */ @@ -2594,9 +2645,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) SET_NETDEV_DEV(ndev, &pdev->dev); - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(ndev); - mdp = netdev_priv(ndev); mdp->num_tx_ring = TX_RING_SIZE; mdp->num_rx_ring = RX_RING_SIZE; @@ -2618,10 +2666,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev) mdp->edmac_endian = pd->edmac_endian; mdp->no_ether_link = pd->no_ether_link; mdp->ether_link_active_low = pd->ether_link_active_low; - mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); /* set cpu data */ mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; + mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type); sh_eth_set_default_cpu_data(mdp->cd); /* set function */ @@ -2749,6 +2797,7 @@ static struct platform_device_id sh_eth_id_table[] = { { "sh7763-gether", (kernel_ulong_t)&sh7763_data }, { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data }, { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data }, + { "r8a7790-ether", (kernel_ulong_t)&r8a7790_data }, { } }; MODULE_DEVICE_TABLE(platform, sh_eth_id_table); diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 99995bf38c40..a0db02c63b11 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -60,6 +60,7 @@ enum { EDOCR, TFUCR, RFOCR, + RMIIMODE, FCFTR, RPADIR, TRIMD, @@ -156,6 +157,13 @@ enum { SH_ETH_MAX_REGISTER_OFFSET, }; +enum { + SH_ETH_REG_GIGABIT, + SH_ETH_REG_FAST_RCAR, + SH_ETH_REG_FAST_SH4, + SH_ETH_REG_FAST_SH3_SH2 +}; + /* Driver's parameters */ #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) #define SH4_SKB_RX_ALIGN 32 @@ -453,6 +461,7 @@ struct sh_eth_cpu_data { void (*set_rate)(struct net_device *ndev); /* mandatory initialize value */ + int register_type; unsigned long eesipr_value; /* optional initialize value */ @@ -482,6 +491,7 @@ struct sh_eth_cpu_data { unsigned hw_crc:1; /* E-DMAC have CSMR */ unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ unsigned shift_rd0:1; /* shift Rx descriptor word 0 right by 16 */ + unsigned rmiimode:1; /* EtherC has RMIIMODE register */ }; struct sh_eth_private { |