diff options
Diffstat (limited to 'drivers/net/cris/eth_v10.c')
-rw-r--r-- | drivers/net/cris/eth_v10.c | 149 |
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) | |||
409 | static void e100_rx(struct net_device *dev); | 409 | static void e100_rx(struct net_device *dev); |
410 | static int e100_close(struct net_device *dev); | 410 | static int e100_close(struct net_device *dev); |
411 | static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); | 411 | static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); |
412 | static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr); | ||
413 | static int e100_set_config(struct net_device* dev, struct ifmap* map); | 412 | static int e100_set_config(struct net_device* dev, struct ifmap* map); |
414 | static void e100_tx_timeout(struct net_device *dev); | 413 | static void e100_tx_timeout(struct net_device *dev); |
415 | static struct net_device_stats *e100_get_stats(struct net_device *dev); | 414 | static struct net_device_stats *e100_get_stats(struct net_device *dev); |
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net); | |||
436 | static void e100_clear_network_leds(unsigned long dummy); | 435 | static void e100_clear_network_leds(unsigned long dummy); |
437 | static void e100_set_network_leds(int active); | 436 | static void e100_set_network_leds(int active); |
438 | 437 | ||
438 | static struct ethtool_ops e100_ethtool_ops; | ||
439 | |||
439 | static void broadcom_check_speed(struct net_device* dev); | 440 | static void broadcom_check_speed(struct net_device* dev); |
440 | static void broadcom_check_duplex(struct net_device* dev); | 441 | static void broadcom_check_duplex(struct net_device* dev); |
441 | static void tdk_check_speed(struct net_device* dev); | 442 | static 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 | ||
1489 | static int | 1489 | static int e100_set_settings(struct net_device *dev, |
1490 | e100_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) { | 1526 | static 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 | |||
1540 | static 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 | |||
1549 | static 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 | ||
1556 | static 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 | |||
1571 | static int | 1564 | static int |
1572 | e100_set_config(struct net_device *dev, struct ifmap *map) | 1565 | e100_set_config(struct net_device *dev, struct ifmap *map) |
1573 | { | 1566 | { |