diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/mv643xx_eth.c')
-rw-r--r-- | drivers/net/ethernet/marvell/mv643xx_eth.c | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 29140502b71a..6562c736a1d8 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq) | |||
1081 | 1081 | ||
1082 | 1082 | ||
1083 | /* mii management interface *************************************************/ | 1083 | /* mii management interface *************************************************/ |
1084 | static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp) | ||
1085 | { | ||
1086 | u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL); | ||
1087 | u32 autoneg_disable = FORCE_LINK_PASS | | ||
1088 | DISABLE_AUTO_NEG_SPEED_GMII | | ||
1089 | DISABLE_AUTO_NEG_FOR_FLOW_CTRL | | ||
1090 | DISABLE_AUTO_NEG_FOR_DUPLEX; | ||
1091 | |||
1092 | if (mp->phy->autoneg == AUTONEG_ENABLE) { | ||
1093 | /* enable auto negotiation */ | ||
1094 | pscr &= ~autoneg_disable; | ||
1095 | goto out_write; | ||
1096 | } | ||
1097 | |||
1098 | pscr |= autoneg_disable; | ||
1099 | |||
1100 | if (mp->phy->speed == SPEED_1000) { | ||
1101 | /* force gigabit, half duplex not supported */ | ||
1102 | pscr |= SET_GMII_SPEED_TO_1000; | ||
1103 | pscr |= SET_FULL_DUPLEX_MODE; | ||
1104 | goto out_write; | ||
1105 | } | ||
1106 | |||
1107 | pscr &= ~SET_GMII_SPEED_TO_1000; | ||
1108 | |||
1109 | if (mp->phy->speed == SPEED_100) | ||
1110 | pscr |= SET_MII_SPEED_TO_100; | ||
1111 | else | ||
1112 | pscr &= ~SET_MII_SPEED_TO_100; | ||
1113 | |||
1114 | if (mp->phy->duplex == DUPLEX_FULL) | ||
1115 | pscr |= SET_FULL_DUPLEX_MODE; | ||
1116 | else | ||
1117 | pscr &= ~SET_FULL_DUPLEX_MODE; | ||
1118 | |||
1119 | out_write: | ||
1120 | wrlp(mp, PORT_SERIAL_CONTROL, pscr); | ||
1121 | } | ||
1122 | |||
1084 | static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) | 1123 | static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) |
1085 | { | 1124 | { |
1086 | struct mv643xx_eth_shared_private *msp = dev_id; | 1125 | struct mv643xx_eth_shared_private *msp = dev_id; |
@@ -1499,6 +1538,7 @@ static int | |||
1499 | mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1538 | mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
1500 | { | 1539 | { |
1501 | struct mv643xx_eth_private *mp = netdev_priv(dev); | 1540 | struct mv643xx_eth_private *mp = netdev_priv(dev); |
1541 | int ret; | ||
1502 | 1542 | ||
1503 | if (mp->phy == NULL) | 1543 | if (mp->phy == NULL) |
1504 | return -EINVAL; | 1544 | return -EINVAL; |
@@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1508 | */ | 1548 | */ |
1509 | cmd->advertising &= ~ADVERTISED_1000baseT_Half; | 1549 | cmd->advertising &= ~ADVERTISED_1000baseT_Half; |
1510 | 1550 | ||
1511 | return phy_ethtool_sset(mp->phy, cmd); | 1551 | ret = phy_ethtool_sset(mp->phy, cmd); |
1552 | if (!ret) | ||
1553 | mv643xx_adjust_pscr(mp); | ||
1554 | return ret; | ||
1512 | } | 1555 | } |
1513 | 1556 | ||
1514 | static void mv643xx_eth_get_drvinfo(struct net_device *dev, | 1557 | static void mv643xx_eth_get_drvinfo(struct net_device *dev, |
@@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev) | |||
2442 | static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 2485 | static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
2443 | { | 2486 | { |
2444 | struct mv643xx_eth_private *mp = netdev_priv(dev); | 2487 | struct mv643xx_eth_private *mp = netdev_priv(dev); |
2488 | int ret; | ||
2445 | 2489 | ||
2446 | if (mp->phy != NULL) | 2490 | if (mp->phy == NULL) |
2447 | return phy_mii_ioctl(mp->phy, ifr, cmd); | 2491 | return -ENOTSUPP; |
2448 | 2492 | ||
2449 | return -EOPNOTSUPP; | 2493 | ret = phy_mii_ioctl(mp->phy, ifr, cmd); |
2494 | if (!ret) | ||
2495 | mv643xx_adjust_pscr(mp); | ||
2496 | return ret; | ||
2450 | } | 2497 | } |
2451 | 2498 | ||
2452 | static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) | 2499 | static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) |