aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cris/eth_v10.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cris/eth_v10.c')
-rw-r--r--drivers/net/cris/eth_v10.c149
1 files changed, 71 insertions, 78 deletions
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409static void e100_rx(struct net_device *dev); 409static void e100_rx(struct net_device *dev);
410static int e100_close(struct net_device *dev); 410static int e100_close(struct net_device *dev);
411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
412static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
413static int e100_set_config(struct net_device* dev, struct ifmap* map); 412static int e100_set_config(struct net_device* dev, struct ifmap* map);
414static void e100_tx_timeout(struct net_device *dev); 413static void e100_tx_timeout(struct net_device *dev);
415static struct net_device_stats *e100_get_stats(struct net_device *dev); 414static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
436static void e100_clear_network_leds(unsigned long dummy); 435static void e100_clear_network_leds(unsigned long dummy);
437static void e100_set_network_leds(int active); 436static void e100_set_network_leds(int active);
438 437
438static struct ethtool_ops e100_ethtool_ops;
439
439static void broadcom_check_speed(struct net_device* dev); 440static void broadcom_check_speed(struct net_device* dev);
440static void broadcom_check_duplex(struct net_device* dev); 441static void broadcom_check_duplex(struct net_device* dev);
441static void tdk_check_speed(struct net_device* dev); 442static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
495 dev->get_stats = e100_get_stats; 496 dev->get_stats = e100_get_stats;
496 dev->set_multicast_list = set_multicast_list; 497 dev->set_multicast_list = set_multicast_list;
497 dev->set_mac_address = e100_set_mac_address; 498 dev->set_mac_address = e100_set_mac_address;
499 dev->ethtool_ops = &e100_ethtool_ops;
498 dev->do_ioctl = e100_ioctl; 500 dev->do_ioctl = e100_ioctl;
499 dev->set_config = e100_set_config; 501 dev->set_config = e100_set_config;
500 dev->tx_timeout = e100_tx_timeout; 502 dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448 1450
1449 spin_lock(&np->lock); /* Preempt protection */ 1451 spin_lock(&np->lock); /* Preempt protection */
1450 switch (cmd) { 1452 switch (cmd) {
1451 case SIOCETHTOOL:
1452 return e100_ethtool_ioctl(dev,ifr);
1453 case SIOCGMIIPHY: /* Get PHY address */ 1453 case SIOCGMIIPHY: /* Get PHY address */
1454 data->phy_id = mdio_phy_addr; 1454 data->phy_id = mdio_phy_addr;
1455 break; 1455 break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1486 return 0; 1486 return 0;
1487} 1487}
1488 1488
1489static int 1489static int e100_set_settings(struct net_device *dev,
1490e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) 1490 struct ethtool_cmd *ecmd)
1491{ 1491{
1492 struct ethtool_cmd ecmd; 1492 ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1493
1494 if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
1495 return -EFAULT;
1496
1497 switch (ecmd.cmd) {
1498 case ETHTOOL_GSET:
1499 {
1500 memset((void *) &ecmd, 0, sizeof (ecmd));
1501 ecmd.supported =
1502 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1503 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | 1493 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1504 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; 1494 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
1505 ecmd.port = PORT_TP; 1495 ecmd->port = PORT_TP;
1506 ecmd.transceiver = XCVR_EXTERNAL; 1496 ecmd->transceiver = XCVR_EXTERNAL;
1507 ecmd.phy_address = mdio_phy_addr; 1497 ecmd->phy_address = mdio_phy_addr;
1508 ecmd.speed = current_speed; 1498 ecmd->speed = current_speed;
1509 ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1499 ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1510 ecmd.advertising = ADVERTISED_TP; 1500 ecmd->advertising = ADVERTISED_TP;
1511 if (current_duplex == autoneg && current_speed_selection == 0) 1501
1512 ecmd.advertising |= ADVERTISED_Autoneg; 1502 if (current_duplex == autoneg && current_speed_selection == 0)
1513 else { 1503 ecmd->advertising |= ADVERTISED_Autoneg;
1514 ecmd.advertising |= 1504 else {
1515 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | 1505 ecmd->advertising |=
1516 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; 1506 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
1517 if (current_speed_selection == 10) 1507 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
1518 ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); 1508 if (current_speed_selection == 10)
1519 else if (current_speed_selection == 100) 1509 ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
1520 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); 1510 ADVERTISED_100baseT_Full);
1521 if (current_duplex == half) 1511 else if (current_speed_selection == 100)
1522 ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); 1512 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1523 else if (current_duplex == full) 1513 ADVERTISED_10baseT_Full);
1524 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); 1514 if (current_duplex == half)
1525 } 1515 ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
1526 ecmd.autoneg = AUTONEG_ENABLE; 1516 ADVERTISED_100baseT_Full);
1527 if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) 1517 else if (current_duplex == full)
1528 return -EFAULT; 1518 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1529 } 1519 ADVERTISED_100baseT_Half);
1530 break; 1520 }
1531 case ETHTOOL_SSET: 1521
1532 { 1522 ecmd->autoneg = AUTONEG_ENABLE;
1533 if (!capable(CAP_NET_ADMIN)) { 1523 return 0;
1534 return -EPERM; 1524}
1535 } 1525
1536 if (ecmd.autoneg == AUTONEG_ENABLE) { 1526static int e100_set_settings(struct net_device *dev,
1537 e100_set_duplex(dev, autoneg); 1527 struct ethtool_cmd *ecmd)
1538 e100_set_speed(dev, 0); 1528{
1539 } else { 1529 if (ecmd->autoneg == AUTONEG_ENABLE) {
1540 e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); 1530 e100_set_duplex(dev, autoneg);
1541 e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); 1531 e100_set_speed(dev, 0);
1542 } 1532 } else {
1543 } 1533 e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
1544 break; 1534 e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
1545 case ETHTOOL_GDRVINFO:
1546 {
1547 struct ethtool_drvinfo info;
1548 memset((void *) &info, 0, sizeof (info));
1549 strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
1550 strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
1551 strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
1552 strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
1553 info.regdump_len = 0;
1554 info.eedump_len = 0;
1555 info.testinfo_len = 0;
1556 if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
1557 return -EFAULT;
1558 }
1559 break;
1560 case ETHTOOL_NWAY_RST:
1561 if (current_duplex == autoneg && current_speed_selection == 0)
1562 e100_negotiate(dev);
1563 break;
1564 default:
1565 return -EOPNOTSUPP;
1566 break;
1567 } 1535 }
1536
1537 return 0;
1538}
1539
1540static void e100_get_drvinfo(struct net_device *dev,
1541 struct ethtool_drvinfo *info)
1542{
1543 strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
1544 strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
1545 strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
1546 strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
1547}
1548
1549static int e100_nway_reset(struct net_device *dev)
1550{
1551 if (current_duplex == autoneg && current_speed_selection == 0)
1552 e100_negotiate(dev);
1568 return 0; 1553 return 0;
1569} 1554}
1570 1555
1556static struct ethtool_ops e100_ethtool_ops = {
1557 .get_settings = e100_get_settings,
1558 .set_settings = e100_set_settings,
1559 .get_drvinfo = e100_get_drvinfo,
1560 .nway_reset = e100_nway_reset,
1561 .get_link = ethtool_op_get_link,
1562};
1563
1571static int 1564static int
1572e100_set_config(struct net_device *dev, struct ifmap *map) 1565e100_set_config(struct net_device *dev, struct ifmap *map)
1573{ 1566{