diff options
author | Ben Hutchings <ben.hutchings@codethink.co.uk> | 2015-01-16 12:51:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-19 15:37:40 -0500 |
commit | b37feed7c2803cce71a746623594f19bbb5a21aa (patch) | |
tree | 555eac27573c32dc946084ab483be1f015a16d52 | |
parent | 9d289715eb5c252ae15bd547cb252ca547a3c4f2 (diff) |
sh_eth: Fix promiscuous mode on chips without TSU
Currently net_device_ops::set_rx_mode is only implemented for
chips with a TSU (multiple address table). However we do need
to turn the PRM (promiscuous) flag on and off for other chips.
- Remove the unlikely() from the TSU functions that we may safely
call for chips without a TSU
- Make setting of the MCT flag conditional on the tsu capability flag
- Rename sh_eth_set_multicast_list() to sh_eth_set_rx_mode() and plumb
it into both net_device_ops structures
- Remove the previously-unreachable branch in sh_eth_rx_mode() that
would otherwise reset the flags to defaults for non-TSU chips
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 8d227d919e19..01dfae4fece0 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -2417,7 +2417,7 @@ static int sh_eth_tsu_purge_all(struct net_device *ndev) | |||
2417 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2417 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2418 | int i, ret; | 2418 | int i, ret; |
2419 | 2419 | ||
2420 | if (unlikely(!mdp->cd->tsu)) | 2420 | if (!mdp->cd->tsu) |
2421 | return 0; | 2421 | return 0; |
2422 | 2422 | ||
2423 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { | 2423 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { |
@@ -2440,7 +2440,7 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2440 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); | 2440 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); |
2441 | int i; | 2441 | int i; |
2442 | 2442 | ||
2443 | if (unlikely(!mdp->cd->tsu)) | 2443 | if (!mdp->cd->tsu) |
2444 | return; | 2444 | return; |
2445 | 2445 | ||
2446 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { | 2446 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { |
@@ -2450,8 +2450,8 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2450 | } | 2450 | } |
2451 | } | 2451 | } |
2452 | 2452 | ||
2453 | /* Multicast reception directions set */ | 2453 | /* Update promiscuous flag and multicast filter */ |
2454 | static void sh_eth_set_multicast_list(struct net_device *ndev) | 2454 | static void sh_eth_set_rx_mode(struct net_device *ndev) |
2455 | { | 2455 | { |
2456 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2456 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2457 | u32 ecmr_bits; | 2457 | u32 ecmr_bits; |
@@ -2462,7 +2462,9 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2462 | /* Initial condition is MCT = 1, PRM = 0. | 2462 | /* Initial condition is MCT = 1, PRM = 0. |
2463 | * Depending on ndev->flags, set PRM or clear MCT | 2463 | * Depending on ndev->flags, set PRM or clear MCT |
2464 | */ | 2464 | */ |
2465 | ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; | 2465 | ecmr_bits = sh_eth_read(ndev, ECMR) & ~ECMR_PRM; |
2466 | if (mdp->cd->tsu) | ||
2467 | ecmr_bits |= ECMR_MCT; | ||
2466 | 2468 | ||
2467 | if (!(ndev->flags & IFF_MULTICAST)) { | 2469 | if (!(ndev->flags & IFF_MULTICAST)) { |
2468 | sh_eth_tsu_purge_mcast(ndev); | 2470 | sh_eth_tsu_purge_mcast(ndev); |
@@ -2491,9 +2493,6 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2491 | } | 2493 | } |
2492 | } | 2494 | } |
2493 | } | 2495 | } |
2494 | } else { | ||
2495 | /* Normal, unicast/broadcast-only mode. */ | ||
2496 | ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; | ||
2497 | } | 2496 | } |
2498 | 2497 | ||
2499 | /* update the ethernet mode */ | 2498 | /* update the ethernet mode */ |
@@ -2701,6 +2700,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { | |||
2701 | .ndo_stop = sh_eth_close, | 2700 | .ndo_stop = sh_eth_close, |
2702 | .ndo_start_xmit = sh_eth_start_xmit, | 2701 | .ndo_start_xmit = sh_eth_start_xmit, |
2703 | .ndo_get_stats = sh_eth_get_stats, | 2702 | .ndo_get_stats = sh_eth_get_stats, |
2703 | .ndo_set_rx_mode = sh_eth_set_rx_mode, | ||
2704 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2704 | .ndo_tx_timeout = sh_eth_tx_timeout, |
2705 | .ndo_do_ioctl = sh_eth_do_ioctl, | 2705 | .ndo_do_ioctl = sh_eth_do_ioctl, |
2706 | .ndo_validate_addr = eth_validate_addr, | 2706 | .ndo_validate_addr = eth_validate_addr, |
@@ -2713,7 +2713,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { | |||
2713 | .ndo_stop = sh_eth_close, | 2713 | .ndo_stop = sh_eth_close, |
2714 | .ndo_start_xmit = sh_eth_start_xmit, | 2714 | .ndo_start_xmit = sh_eth_start_xmit, |
2715 | .ndo_get_stats = sh_eth_get_stats, | 2715 | .ndo_get_stats = sh_eth_get_stats, |
2716 | .ndo_set_rx_mode = sh_eth_set_multicast_list, | 2716 | .ndo_set_rx_mode = sh_eth_set_rx_mode, |
2717 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, | 2717 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, |
2718 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, | 2718 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, |
2719 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2719 | .ndo_tx_timeout = sh_eth_tx_timeout, |