aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mv643xx_eth.c
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2006-01-27 03:15:30 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-27 11:11:16 -0500
commitd0412d967032b9e147bcbacc9ff0c0342636cf2d (patch)
tree1191be1a588161a4d4538536975379d0c8f61011 /drivers/net/mv643xx_eth.c
parentc28a4f8947f1b08996502967e348dc88363749a7 (diff)
[PATCH] mv643xx_eth: use MII library for ethtool functions
Use the common ethtool support functions of the MII library. Add generic MII ioctl handler. Add PHY parameter speed/duplex/negotiation initialization and modification. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r--drivers/net/mv643xx_eth.c351
1 files changed, 210 insertions, 141 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index bca7257c707a..ff2b613a7436 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -101,6 +101,7 @@ static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
101static int ethernet_phy_detect(unsigned int eth_port_num); 101static int ethernet_phy_detect(unsigned int eth_port_num);
102static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); 102static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location);
103static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); 103static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val);
104static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
104static struct ethtool_ops mv643xx_ethtool_ops; 105static struct ethtool_ops mv643xx_ethtool_ops;
105 106
106static char mv643xx_driver_name[] = "mv643xx_eth"; 107static char mv643xx_driver_name[] = "mv643xx_eth";
@@ -457,6 +458,56 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
457 return received_packets; 458 return received_packets;
458} 459}
459 460
461/* Set the mv643xx port configuration register for the speed/duplex mode. */
462static void mv643xx_eth_update_pscr(struct net_device *dev,
463 struct ethtool_cmd *ecmd)
464{
465 struct mv643xx_private *mp = netdev_priv(dev);
466 int port_num = mp->port_num;
467 u32 o_pscr, n_pscr;
468 unsigned int channels;
469
470 o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
471 n_pscr = o_pscr;
472
473 /* clear speed, duplex and rx buffer size fields */
474 n_pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100 |
475 MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
476 MV643XX_ETH_SET_FULL_DUPLEX_MODE |
477 MV643XX_ETH_MAX_RX_PACKET_MASK);
478
479 if (ecmd->duplex == DUPLEX_FULL)
480 n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE;
481
482 if (ecmd->speed == SPEED_1000)
483 n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
484 MV643XX_ETH_MAX_RX_PACKET_9700BYTE;
485 else {
486 if (ecmd->speed == SPEED_100)
487 n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100;
488 n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE;
489 }
490
491 if (n_pscr != o_pscr) {
492 if ((o_pscr & MV643XX_ETH_SERIAL_PORT_ENABLE) == 0)
493 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
494 n_pscr);
495 else {
496 channels = mv643xx_eth_port_disable_tx(port_num);
497
498 o_pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
499 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
500 o_pscr);
501 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
502 n_pscr);
503 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
504 n_pscr);
505 if (channels)
506 mv643xx_eth_port_enable_tx(port_num, channels);
507 }
508 }
509}
510
460/* 511/*
461 * mv643xx_eth_int_handler 512 * mv643xx_eth_int_handler
462 * 513 *
@@ -539,13 +590,19 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
539 } 590 }
540 /* PHY status changed */ 591 /* PHY status changed */
541 if (eth_int_cause_ext & (BIT16 | BIT20)) { 592 if (eth_int_cause_ext & (BIT16 | BIT20)) {
593 struct ethtool_cmd cmd;
594
542 if (mii_link_ok(&mp->mii)) { 595 if (mii_link_ok(&mp->mii)) {
596 mii_ethtool_gset(&mp->mii, &cmd);
597 mv643xx_eth_update_pscr(dev, &cmd);
543 if (!netif_carrier_ok(dev)) { 598 if (!netif_carrier_ok(dev)) {
544 netif_carrier_on(dev); 599 netif_carrier_on(dev);
545 netif_wake_queue(dev); 600 if (mp->tx_ring_size > mp->tx_desc_count +
546 /* Start TX queue */ 601 MAX_DESCS_PER_SKB) {
547 mv643xx_eth_port_enable_tx(port_num, 602 netif_wake_queue(dev);
548 mp->port_tx_queue_command); 603 /* Start TX queue */
604 mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command);
605 }
549 } 606 }
550 } else if (netif_carrier_ok(dev)) { 607 } else if (netif_carrier_ok(dev)) {
551 netif_stop_queue(dev); 608 netif_stop_queue(dev);
@@ -729,6 +786,34 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
729 mp->port_tx_queue_command = 1; 786 mp->port_tx_queue_command = 1;
730} 787}
731 788
789static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
790{
791 struct mv643xx_private *mp = netdev_priv(dev);
792 int err;
793
794 spin_lock_irq(&mp->lock);
795 err = mii_ethtool_sset(&mp->mii, cmd);
796 spin_unlock_irq(&mp->lock);
797
798 return err;
799}
800
801static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
802{
803 struct mv643xx_private *mp = netdev_priv(dev);
804 int err;
805
806 spin_lock_irq(&mp->lock);
807 err = mii_ethtool_gset(&mp->mii, cmd);
808 spin_unlock_irq(&mp->lock);
809
810 /* The PHY may support 1000baseT_Half, but the mv643xx does not */
811 cmd->supported &= ~SUPPORTED_1000baseT_Half;
812 cmd->advertising &= ~ADVERTISED_1000baseT_Half;
813
814 return err;
815}
816
732/* 817/*
733 * mv643xx_eth_open 818 * mv643xx_eth_open
734 * 819 *
@@ -842,6 +927,10 @@ static int mv643xx_eth_open(struct net_device *dev)
842 927
843 mv643xx_eth_rx_task(dev); /* Fill RX ring with skb's */ 928 mv643xx_eth_rx_task(dev); /* Fill RX ring with skb's */
844 929
930 /* Clear any pending ethernet port interrupts */
931 mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
932 mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
933
845 eth_port_start(dev); 934 eth_port_start(dev);
846 935
847 /* Interrupt Coalescing */ 936 /* Interrupt Coalescing */
@@ -854,16 +943,13 @@ static int mv643xx_eth_open(struct net_device *dev)
854 mp->tx_int_coal = 943 mp->tx_int_coal =
855 eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL); 944 eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
856 945
857 /* Clear any pending ethernet port interrupts */
858 mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
859 mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
860
861 /* Unmask phy and link status changes interrupts */ 946 /* Unmask phy and link status changes interrupts */
862 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 947 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
863 INT_UNMASK_ALL_EXT); 948 INT_UNMASK_ALL_EXT);
864 949
865 /* Unmask RX buffer and TX end interrupt */ 950 /* Unmask RX buffer and TX end interrupt */
866 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); 951 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL);
952
867 return 0; 953 return 0;
868 954
869out_free_tx_skb: 955out_free_tx_skb:
@@ -1318,6 +1404,35 @@ static void mv643xx_netpoll(struct net_device *netdev)
1318} 1404}
1319#endif 1405#endif
1320 1406
1407static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address,
1408 int speed, int duplex,
1409 struct ethtool_cmd *cmd)
1410{
1411 struct mv643xx_private *mp = netdev_priv(dev);
1412
1413 memset(cmd, 0, sizeof(*cmd));
1414
1415 cmd->port = PORT_MII;
1416 cmd->transceiver = XCVR_INTERNAL;
1417 cmd->phy_address = phy_address;
1418
1419 if (speed == 0) {
1420 cmd->autoneg = AUTONEG_ENABLE;
1421 /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */
1422 cmd->speed = SPEED_100;
1423 cmd->advertising = ADVERTISED_10baseT_Half |
1424 ADVERTISED_10baseT_Full |
1425 ADVERTISED_100baseT_Half |
1426 ADVERTISED_100baseT_Full;
1427 if (mp->mii.supports_gmii)
1428 cmd->advertising |= ADVERTISED_1000baseT_Full;
1429 } else {
1430 cmd->autoneg = AUTONEG_DISABLE;
1431 cmd->speed = speed;
1432 cmd->duplex = duplex;
1433 }
1434}
1435
1321/*/ 1436/*/
1322 * mv643xx_eth_probe 1437 * mv643xx_eth_probe
1323 * 1438 *
@@ -1338,6 +1453,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1338 u8 *p; 1453 u8 *p;
1339 struct resource *res; 1454 struct resource *res;
1340 int err; 1455 int err;
1456 struct ethtool_cmd cmd;
1457 u32 pscr;
1458 int duplex;
1459 int speed;
1341 1460
1342 dev = alloc_etherdev(sizeof(struct mv643xx_private)); 1461 dev = alloc_etherdev(sizeof(struct mv643xx_private));
1343 if (!dev) 1462 if (!dev)
@@ -1375,6 +1494,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1375 dev->tx_queue_len = mp->tx_ring_size; 1494 dev->tx_queue_len = mp->tx_ring_size;
1376 dev->base_addr = 0; 1495 dev->base_addr = 0;
1377 dev->change_mtu = mv643xx_eth_change_mtu; 1496 dev->change_mtu = mv643xx_eth_change_mtu;
1497 dev->do_ioctl = mv643xx_eth_do_ioctl;
1378 SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); 1498 SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops);
1379 1499
1380#ifdef MV643XX_CHECKSUM_OFFLOAD_TX 1500#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
@@ -1452,10 +1572,35 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
1452 pr_debug("MV643xx ethernet port %d: " 1572 pr_debug("MV643xx ethernet port %d: "
1453 "No PHY detected at addr %d\n", 1573 "No PHY detected at addr %d\n",
1454 port_num, ethernet_phy_get(port_num)); 1574 port_num, ethernet_phy_get(port_num));
1455 return err; 1575 goto out;
1456 } 1576 }
1457 1577
1578 pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
1579 pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
1580 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
1581 pscr = mp->port_serial_control;
1582 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
1583
1584 if (!(pscr & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX) &&
1585 !(pscr & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII))
1586 speed = 0;
1587 else if (pscr & MV643XX_ETH_PORT_STATUS_GMII_1000)
1588 speed = SPEED_1000;
1589 else if (pscr & MV643XX_ETH_PORT_STATUS_MII_100)
1590 speed = SPEED_100;
1591 else
1592 speed = SPEED_10;
1593
1594 if (pscr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
1595 duplex = DUPLEX_FULL;
1596 else
1597 duplex = DUPLEX_HALF;
1598
1599 ethernet_phy_reset(mp->port_num);
1458 mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); 1600 mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
1601 mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd);
1602 mv643xx_eth_update_pscr(dev, &cmd);
1603 mv643xx_set_settings(dev, &cmd);
1459 1604
1460 err = register_netdev(dev); 1605 err = register_netdev(dev);
1461 if (err) 1606 if (err)
@@ -1775,8 +1920,6 @@ static void eth_port_init(struct mv643xx_private *mp)
1775 eth_port_reset(mp->port_num); 1920 eth_port_reset(mp->port_num);
1776 1921
1777 eth_port_init_mac_tables(mp->port_num); 1922 eth_port_init_mac_tables(mp->port_num);
1778
1779 ethernet_phy_reset(mp->port_num);
1780} 1923}
1781 1924
1782/* 1925/*
@@ -1811,6 +1954,8 @@ static void eth_port_start(struct net_device *dev)
1811 struct mv643xx_private *mp = netdev_priv(dev); 1954 struct mv643xx_private *mp = netdev_priv(dev);
1812 unsigned int port_num = mp->port_num; 1955 unsigned int port_num = mp->port_num;
1813 int tx_curr_desc, rx_curr_desc; 1956 int tx_curr_desc, rx_curr_desc;
1957 u32 pscr;
1958 struct ethtool_cmd ethtool_cmd;
1814 1959
1815 /* Assignment of Tx CTRP of given queue */ 1960 /* Assignment of Tx CTRP of given queue */
1816 tx_curr_desc = mp->tx_curr_desc_q; 1961 tx_curr_desc = mp->tx_curr_desc_q;
@@ -1828,31 +1973,35 @@ static void eth_port_start(struct net_device *dev)
1828 /* Assign port configuration and command. */ 1973 /* Assign port configuration and command. */
1829 mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config); 1974 mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config);
1830 1975
1831 mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num), 1976 pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
1832 mp->port_config_extend); 1977 pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
1978 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
1833 1979
1980 pscr &= ~MV643XX_ETH_FORCE_LINK_PASS;
1981 pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
1982 MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII |
1983 MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX |
1984 MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL |
1985 MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED;
1834 1986
1835 /* Increase the Rx side buffer size if supporting GigE */ 1987 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
1836 if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
1837 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
1838 (mp->port_serial_control & 0xfff1ffff) | (0x5 << 17));
1839 else
1840 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
1841 mp->port_serial_control);
1842 1988
1843 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), 1989 pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE;
1844 mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) | 1990 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
1845 MV643XX_ETH_SERIAL_PORT_ENABLE);
1846 1991
1847 /* Assign port SDMA configuration */ 1992 /* Assign port SDMA configuration */
1848 mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), 1993 mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), mp->port_sdma_config);
1849 mp->port_sdma_config);
1850 1994
1851 /* Enable port Rx. */ 1995 /* Enable port Rx. */
1852 mv643xx_eth_port_enable_rx(port_num, mp->port_rx_queue_command); 1996 mv643xx_eth_port_enable_rx(port_num, mp->port_rx_queue_command);
1853 1997
1854 /* Disable port bandwidth limits by clearing MTU register */ 1998 /* Disable port bandwidth limits by clearing MTU register */
1855 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0); 1999 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
2000
2001 /* save phy settings across reset */
2002 mv643xx_get_settings(dev, &ethtool_cmd);
2003 ethernet_phy_reset(mp->port_num);
2004 mv643xx_set_settings(dev, &ethtool_cmd);
1856} 2005}
1857 2006
1858/* 2007/*
@@ -2324,6 +2473,12 @@ static void ethernet_phy_reset(unsigned int eth_port_num)
2324 eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data); 2473 eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
2325 phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ 2474 phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */
2326 eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data); 2475 eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data);
2476
2477 /* wait for PHY to come out of reset */
2478 do {
2479 udelay(1);
2480 eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
2481 } while (phy_reg_data & 0x8000);
2327} 2482}
2328 2483
2329static void mv643xx_eth_port_enable_tx(unsigned int port_num, 2484static void mv643xx_eth_port_enable_tx(unsigned int port_num,
@@ -2417,20 +2572,13 @@ static void eth_port_reset(unsigned int port_num)
2417 2572
2418 /* Reset the Enable bit in the Configuration Register */ 2573 /* Reset the Enable bit in the Configuration Register */
2419 reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); 2574 reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
2420 reg_data &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; 2575 reg_data &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE |
2576 MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL |
2577 MV643XX_ETH_FORCE_LINK_PASS);
2421 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data); 2578 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
2422} 2579}
2423 2580
2424 2581
2425static int eth_port_autoneg_supported(unsigned int eth_port_num)
2426{
2427 unsigned int phy_reg_data0;
2428
2429 eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0);
2430
2431 return phy_reg_data0 & 0x1000;
2432}
2433
2434/* 2582/*
2435 * eth_port_read_smi_reg - Read PHY registers 2583 * eth_port_read_smi_reg - Read PHY registers
2436 * 2584 *
@@ -2989,111 +3137,6 @@ static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
2989#define MV643XX_STATS_LEN \ 3137#define MV643XX_STATS_LEN \
2990 sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats) 3138 sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats)
2991 3139
2992static int
2993mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
2994{
2995 struct mv643xx_private *mp = netdev->priv;
2996 int port_num = mp->port_num;
2997 int autoneg = eth_port_autoneg_supported(port_num);
2998 int mode_10_bit;
2999 int auto_duplex;
3000 int half_duplex = 0;
3001 int full_duplex = 0;
3002 int auto_speed;
3003 int speed_10 = 0;
3004 int speed_100 = 0;
3005 int speed_1000 = 0;
3006
3007 u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
3008 u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num));
3009
3010 mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT;
3011
3012 if (mode_10_bit) {
3013 ecmd->supported = SUPPORTED_10baseT_Half;
3014 } else {
3015 ecmd->supported = (SUPPORTED_10baseT_Half |
3016 SUPPORTED_10baseT_Full |
3017 SUPPORTED_100baseT_Half |
3018 SUPPORTED_100baseT_Full |
3019 SUPPORTED_1000baseT_Full |
3020 (autoneg ? SUPPORTED_Autoneg : 0) |
3021 SUPPORTED_TP);
3022
3023 auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX);
3024 auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII);
3025
3026 ecmd->advertising = ADVERTISED_TP;
3027
3028 if (autoneg) {
3029 ecmd->advertising |= ADVERTISED_Autoneg;
3030
3031 if (auto_duplex) {
3032 half_duplex = 1;
3033 full_duplex = 1;
3034 } else {
3035 if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE)
3036 full_duplex = 1;
3037 else
3038 half_duplex = 1;
3039 }
3040
3041 if (auto_speed) {
3042 speed_10 = 1;
3043 speed_100 = 1;
3044 speed_1000 = 1;
3045 } else {
3046 if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
3047 speed_1000 = 1;
3048 else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100)
3049 speed_100 = 1;
3050 else
3051 speed_10 = 1;
3052 }
3053
3054 if (speed_10 & half_duplex)
3055 ecmd->advertising |= ADVERTISED_10baseT_Half;
3056 if (speed_10 & full_duplex)
3057 ecmd->advertising |= ADVERTISED_10baseT_Full;
3058 if (speed_100 & half_duplex)
3059 ecmd->advertising |= ADVERTISED_100baseT_Half;
3060 if (speed_100 & full_duplex)
3061 ecmd->advertising |= ADVERTISED_100baseT_Full;
3062 if (speed_1000)
3063 ecmd->advertising |= ADVERTISED_1000baseT_Full;
3064 }
3065 }
3066
3067 ecmd->port = PORT_TP;
3068 ecmd->phy_address = ethernet_phy_get(port_num);
3069
3070 ecmd->transceiver = XCVR_EXTERNAL;
3071
3072 if (netif_carrier_ok(netdev)) {
3073 if (mode_10_bit)
3074 ecmd->speed = SPEED_10;
3075 else {
3076 if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000)
3077 ecmd->speed = SPEED_1000;
3078 else if (psr & MV643XX_ETH_PORT_STATUS_MII_100)
3079 ecmd->speed = SPEED_100;
3080 else
3081 ecmd->speed = SPEED_10;
3082 }
3083
3084 if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
3085 ecmd->duplex = DUPLEX_FULL;
3086 else
3087 ecmd->duplex = DUPLEX_HALF;
3088 } else {
3089 ecmd->speed = -1;
3090 ecmd->duplex = -1;
3091 }
3092
3093 ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
3094 return 0;
3095}
3096
3097static void mv643xx_get_drvinfo(struct net_device *netdev, 3140static void mv643xx_get_drvinfo(struct net_device *netdev,
3098 struct ethtool_drvinfo *drvinfo) 3141 struct ethtool_drvinfo *drvinfo)
3099{ 3142{
@@ -3140,15 +3183,41 @@ static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset,
3140 } 3183 }
3141} 3184}
3142 3185
3186static u32 mv643xx_eth_get_link(struct net_device *dev)
3187{
3188 struct mv643xx_private *mp = netdev_priv(dev);
3189
3190 return mii_link_ok(&mp->mii);
3191}
3192
3193static int mv643xx_eth_nway_restart(struct net_device *dev)
3194{
3195 struct mv643xx_private *mp = netdev_priv(dev);
3196
3197 return mii_nway_restart(&mp->mii);
3198}
3199
3200static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
3201{
3202 struct mv643xx_private *mp = netdev_priv(dev);
3203
3204 return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
3205}
3206
3143static struct ethtool_ops mv643xx_ethtool_ops = { 3207static struct ethtool_ops mv643xx_ethtool_ops = {
3144 .get_settings = mv643xx_get_settings, 3208 .get_settings = mv643xx_get_settings,
3209 .set_settings = mv643xx_set_settings,
3145 .get_drvinfo = mv643xx_get_drvinfo, 3210 .get_drvinfo = mv643xx_get_drvinfo,
3146 .get_link = ethtool_op_get_link, 3211 .get_link = mv643xx_eth_get_link,
3147 .get_sg = ethtool_op_get_sg, 3212 .get_sg = ethtool_op_get_sg,
3148 .set_sg = ethtool_op_set_sg, 3213 .set_sg = ethtool_op_set_sg,
3149 .get_strings = mv643xx_get_strings, 3214 .get_strings = mv643xx_get_strings,
3150 .get_stats_count = mv643xx_get_stats_count, 3215 .get_stats_count = mv643xx_get_stats_count,
3151 .get_ethtool_stats = mv643xx_get_ethtool_stats, 3216 .get_ethtool_stats = mv643xx_get_ethtool_stats,
3217 .get_strings = mv643xx_get_strings,
3218 .get_stats_count = mv643xx_get_stats_count,
3219 .get_ethtool_stats = mv643xx_get_ethtool_stats,
3220 .nway_reset = mv643xx_eth_nway_restart,
3152}; 3221};
3153 3222
3154/************* End ethtool support *************************/ 3223/************* End ethtool support *************************/