diff options
author | David S. Miller <davem@davemloft.net> | 2015-01-19 15:37:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-19 15:37:44 -0500 |
commit | 852c5d9c98a0017d413ec99d6dccb206ccb2b96b (patch) | |
tree | 685c3ae92315b1627d99a9b72e6906031f3baba8 | |
parent | 9d289715eb5c252ae15bd547cb252ca547a3c4f2 (diff) | |
parent | 4f9dce230b32eec45cec8c28cae61efdfa2f7d57 (diff) |
Merge branch 'sh_eth'
Ben Hutchings says:
====================
sh_eth fixes
I'm currently looking at Ethernet support on the R-Car H2 chip,
reviewing and testing the sh_eth driver. Here are fixes for two fairly
obvious bugs in the driver; I will probably have some more later.
These are not tested on any of the other supported chips.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 8d227d919e19..6576243222af 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -1827,6 +1827,9 @@ static int sh_eth_get_settings(struct net_device *ndev, | |||
1827 | unsigned long flags; | 1827 | unsigned long flags; |
1828 | int ret; | 1828 | int ret; |
1829 | 1829 | ||
1830 | if (!mdp->phydev) | ||
1831 | return -ENODEV; | ||
1832 | |||
1830 | spin_lock_irqsave(&mdp->lock, flags); | 1833 | spin_lock_irqsave(&mdp->lock, flags); |
1831 | ret = phy_ethtool_gset(mdp->phydev, ecmd); | 1834 | ret = phy_ethtool_gset(mdp->phydev, ecmd); |
1832 | spin_unlock_irqrestore(&mdp->lock, flags); | 1835 | spin_unlock_irqrestore(&mdp->lock, flags); |
@@ -1841,6 +1844,9 @@ static int sh_eth_set_settings(struct net_device *ndev, | |||
1841 | unsigned long flags; | 1844 | unsigned long flags; |
1842 | int ret; | 1845 | int ret; |
1843 | 1846 | ||
1847 | if (!mdp->phydev) | ||
1848 | return -ENODEV; | ||
1849 | |||
1844 | spin_lock_irqsave(&mdp->lock, flags); | 1850 | spin_lock_irqsave(&mdp->lock, flags); |
1845 | 1851 | ||
1846 | /* disable tx and rx */ | 1852 | /* disable tx and rx */ |
@@ -1875,6 +1881,9 @@ static int sh_eth_nway_reset(struct net_device *ndev) | |||
1875 | unsigned long flags; | 1881 | unsigned long flags; |
1876 | int ret; | 1882 | int ret; |
1877 | 1883 | ||
1884 | if (!mdp->phydev) | ||
1885 | return -ENODEV; | ||
1886 | |||
1878 | spin_lock_irqsave(&mdp->lock, flags); | 1887 | spin_lock_irqsave(&mdp->lock, flags); |
1879 | ret = phy_start_aneg(mdp->phydev); | 1888 | ret = phy_start_aneg(mdp->phydev); |
1880 | spin_unlock_irqrestore(&mdp->lock, flags); | 1889 | spin_unlock_irqrestore(&mdp->lock, flags); |
@@ -2184,6 +2193,7 @@ static int sh_eth_close(struct net_device *ndev) | |||
2184 | if (mdp->phydev) { | 2193 | if (mdp->phydev) { |
2185 | phy_stop(mdp->phydev); | 2194 | phy_stop(mdp->phydev); |
2186 | phy_disconnect(mdp->phydev); | 2195 | phy_disconnect(mdp->phydev); |
2196 | mdp->phydev = NULL; | ||
2187 | } | 2197 | } |
2188 | 2198 | ||
2189 | free_irq(ndev->irq, ndev); | 2199 | free_irq(ndev->irq, ndev); |
@@ -2417,7 +2427,7 @@ static int sh_eth_tsu_purge_all(struct net_device *ndev) | |||
2417 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2427 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2418 | int i, ret; | 2428 | int i, ret; |
2419 | 2429 | ||
2420 | if (unlikely(!mdp->cd->tsu)) | 2430 | if (!mdp->cd->tsu) |
2421 | return 0; | 2431 | return 0; |
2422 | 2432 | ||
2423 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { | 2433 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { |
@@ -2440,7 +2450,7 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2440 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); | 2450 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); |
2441 | int i; | 2451 | int i; |
2442 | 2452 | ||
2443 | if (unlikely(!mdp->cd->tsu)) | 2453 | if (!mdp->cd->tsu) |
2444 | return; | 2454 | return; |
2445 | 2455 | ||
2446 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { | 2456 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { |
@@ -2450,8 +2460,8 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2450 | } | 2460 | } |
2451 | } | 2461 | } |
2452 | 2462 | ||
2453 | /* Multicast reception directions set */ | 2463 | /* Update promiscuous flag and multicast filter */ |
2454 | static void sh_eth_set_multicast_list(struct net_device *ndev) | 2464 | static void sh_eth_set_rx_mode(struct net_device *ndev) |
2455 | { | 2465 | { |
2456 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2466 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2457 | u32 ecmr_bits; | 2467 | u32 ecmr_bits; |
@@ -2462,7 +2472,9 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2462 | /* Initial condition is MCT = 1, PRM = 0. | 2472 | /* Initial condition is MCT = 1, PRM = 0. |
2463 | * Depending on ndev->flags, set PRM or clear MCT | 2473 | * Depending on ndev->flags, set PRM or clear MCT |
2464 | */ | 2474 | */ |
2465 | ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; | 2475 | ecmr_bits = sh_eth_read(ndev, ECMR) & ~ECMR_PRM; |
2476 | if (mdp->cd->tsu) | ||
2477 | ecmr_bits |= ECMR_MCT; | ||
2466 | 2478 | ||
2467 | if (!(ndev->flags & IFF_MULTICAST)) { | 2479 | if (!(ndev->flags & IFF_MULTICAST)) { |
2468 | sh_eth_tsu_purge_mcast(ndev); | 2480 | sh_eth_tsu_purge_mcast(ndev); |
@@ -2491,9 +2503,6 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2491 | } | 2503 | } |
2492 | } | 2504 | } |
2493 | } | 2505 | } |
2494 | } else { | ||
2495 | /* Normal, unicast/broadcast-only mode. */ | ||
2496 | ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; | ||
2497 | } | 2506 | } |
2498 | 2507 | ||
2499 | /* update the ethernet mode */ | 2508 | /* update the ethernet mode */ |
@@ -2701,6 +2710,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { | |||
2701 | .ndo_stop = sh_eth_close, | 2710 | .ndo_stop = sh_eth_close, |
2702 | .ndo_start_xmit = sh_eth_start_xmit, | 2711 | .ndo_start_xmit = sh_eth_start_xmit, |
2703 | .ndo_get_stats = sh_eth_get_stats, | 2712 | .ndo_get_stats = sh_eth_get_stats, |
2713 | .ndo_set_rx_mode = sh_eth_set_rx_mode, | ||
2704 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2714 | .ndo_tx_timeout = sh_eth_tx_timeout, |
2705 | .ndo_do_ioctl = sh_eth_do_ioctl, | 2715 | .ndo_do_ioctl = sh_eth_do_ioctl, |
2706 | .ndo_validate_addr = eth_validate_addr, | 2716 | .ndo_validate_addr = eth_validate_addr, |
@@ -2713,7 +2723,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { | |||
2713 | .ndo_stop = sh_eth_close, | 2723 | .ndo_stop = sh_eth_close, |
2714 | .ndo_start_xmit = sh_eth_start_xmit, | 2724 | .ndo_start_xmit = sh_eth_start_xmit, |
2715 | .ndo_get_stats = sh_eth_get_stats, | 2725 | .ndo_get_stats = sh_eth_get_stats, |
2716 | .ndo_set_rx_mode = sh_eth_set_multicast_list, | 2726 | .ndo_set_rx_mode = sh_eth_set_rx_mode, |
2717 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, | 2727 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, |
2718 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, | 2728 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, |
2719 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2729 | .ndo_tx_timeout = sh_eth_tx_timeout, |