From: James Chapman <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> Signed-off-by: Dale Farnsworth <[EMAIL PROTECTED]> arch/ppc/platforms/hdpu.c | 5 drivers/net/mv643xx_eth.c | 429 ++++++++++++++++++++++++---------------------- drivers/net/mv643xx_eth.h | 4 include/linux/mv643xx.h | 40 +--- 4 files changed, 246 insertions(+), 232 deletions(-) --- I heavily modified James' original patch. All bugs are mine. -Dale Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c =================================================================== --- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c +++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c @@ -82,6 +82,8 @@ static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *MacAddr); static void eth_port_set_multicast_list(struct net_device *); +static void mv643xx_eth_port_disable_tx(unsigned int port_num); +static void mv643xx_eth_port_disable_rx(unsigned int port_num); static int mv643xx_eth_open(struct net_device *); static int mv643xx_eth_stop(struct net_device *); static int mv643xx_eth_change_mtu(struct net_device *, int); @@ -95,6 +97,7 @@ static void ethernet_phy_set(unsigned in static int ethernet_phy_detect(unsigned int eth_port_num); static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); +static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static struct ethtool_ops mv643xx_ethtool_ops; static char mv643xx_driver_name[] = "mv643xx_eth"; @@ -259,13 +262,14 @@ static void mv643xx_eth_update_mac_addre static void mv643xx_eth_set_rx_mode(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); + u32 config_reg; + config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num)); if (dev->flags & IFF_PROMISC) - mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; else - mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; - - mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config); + config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), config_reg); eth_port_set_multicast_list(dev); } @@ -450,6 +454,56 @@ static int mv643xx_eth_receive_queue(str return received_packets; } +/* Set the mv643xx port configuration register for the speed/duplex mode. */ +static void mv643xx_eth_update_pscr(struct net_device *dev, + struct ethtool_cmd *ecmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + int port_num = mp->port_num; + u32 pscr; + + mv643xx_eth_port_disable_tx(port_num); + + pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); + + /* disable port */ + pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + + /* clear speed and duplex bits and default to 1518 byte rx buffer */ + pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100 | + MV643XX_ETH_SET_GMII_SPEED_TO_1000 | + MV643XX_ETH_SET_FULL_DUPLEX_MODE | + (7 << 17)); + + /* disable the chip's autonegotiation, we use the mii library */ + pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | + MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII | + MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX; + + if (ecmd->duplex == DUPLEX_FULL) + pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE; + + switch (ecmd->speed) { + case SPEED_1000: + pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000; + pscr |= (5 << 17); /* 9700 byte rx buffer */ + break; + case SPEED_100: + pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100; + /* NOBREAK */ + case SPEED_10: + pscr |= (1 << 17); /* 1522 byte rx buffer */ + break; + } + + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + + /* re-enable port */ + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + pscr | MV643XX_ETH_SERIAL_PORT_ENABLE); +} + /* * mv643xx_eth_int_handler * @@ -537,13 +591,14 @@ static irqreturn_t mv643xx_eth_int_handl /* mii library handles link maintenance tasks */ mii_ethtool_gset(&mp->mii, &cmd); - - if(mii_link_ok(&mp->mii) && !netif_carrier_ok(dev)) { - netif_wake_queue(dev); - /* Start TX queue */ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 1); - - } else if(!mii_link_ok(&mp->mii) && netif_carrier_ok(dev)) + if (mii_link_ok(&mp->mii)) { + mv643xx_eth_update_pscr(dev, &cmd); + if (!netif_carrier_ok(dev)) { + netif_wake_queue(dev); + /* Start TX queue */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 1); + } + } else if (netif_carrier_ok(dev)) netif_stop_queue(dev); mii_check_link(&mp->mii); @@ -725,6 +780,27 @@ static void ether_init_tx_desc_ring(stru mp->port_tx_queue_command |= 1; } +static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + + return mii_ethtool_sset(&mp->mii, cmd); +} + +static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + int err; + + err = mii_ethtool_gset(&mp->mii, cmd); + + /* The PHY may support 1000baseT_Half, but the mv643xx does not */ + cmd->supported &= ~SUPPORTED_1000baseT_Half; + cmd->advertising &= ~ADVERTISED_1000baseT_Half; + + return err; +} + /* * mv643xx_eth_open * @@ -753,9 +829,6 @@ static int mv643xx_eth_open(struct net_d return -EAGAIN; } - /* Stop RX Queues */ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); - eth_port_init(mp); INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev); @@ -863,6 +936,7 @@ static int mv643xx_eth_open(struct net_d /* Unmask RX buffer and TX end interrupt */ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); + return 0; out_free_tx_skb: @@ -1316,6 +1390,35 @@ static void mv643xx_netpoll(struct net_d } #endif +static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, + int speed, int duplex, + struct ethtool_cmd *cmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + + memset(cmd, 0, sizeof(*cmd)); + + cmd->port = PORT_MII; + cmd->transceiver = XCVR_INTERNAL; + cmd->phy_address = phy_address; + + if (speed == 0) { + cmd->autoneg = AUTONEG_ENABLE; + /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */ + cmd->speed = SPEED_100; + cmd->advertising = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full; + if (mp->mii.supports_gmii) + cmd->advertising |= ADVERTISED_1000baseT_Full; + } else { + cmd->autoneg = AUTONEG_DISABLE; + cmd->speed = speed; + cmd->duplex = duplex; + } +} + /*/ * mv643xx_eth_probe * @@ -1336,6 +1439,7 @@ static int mv643xx_eth_probe(struct plat u8 *p; struct resource *res; int err; + struct ethtool_cmd cmd; dev = alloc_etherdev(sizeof(struct mv643xx_private)); if (!dev) @@ -1373,6 +1477,7 @@ static int mv643xx_eth_probe(struct plat dev->tx_queue_len = mp->tx_ring_size; dev->base_addr = 0; dev->change_mtu = mv643xx_eth_change_mtu; + dev->do_ioctl = mv643xx_eth_do_ioctl; SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); #ifdef MV643XX_CHECKSUM_OFFLOAD_TX @@ -1385,15 +1490,6 @@ static int mv643xx_eth_probe(struct plat #endif #endif - /* Hook up MII support for ethtool */ - mp->mii.dev = dev; - mp->mii.mdio_read = mv643xx_mdio_read; - mp->mii.mdio_write = mv643xx_mdio_write; - mp->mii.phy_id = ethernet_phy_get(mp->port_num); - mp->mii.phy_id_mask = 0x3f; - mp->mii.reg_num_mask = 0x1f; - mp->mii.supports_gmii = 1; - /* Configure the timeout task */ INIT_WORK(&mp->tx_timeout_task, (void (*)(void *))mv643xx_eth_tx_timeout_task, dev); @@ -1402,32 +1498,16 @@ static int mv643xx_eth_probe(struct plat /* set default config values */ eth_port_uc_addr_get(dev, dev->dev_addr); - mp->port_config = MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE; - mp->port_config_extend = MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE; - mp->port_sdma_config = MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE; - mp->port_serial_control = MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE; mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE; mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; pd = pdev->dev.platform_data; if (pd) { - if (pd->mac_addr != NULL) + if (pd->mac_addr) memcpy(dev->dev_addr, pd->mac_addr, 6); if (pd->phy_addr || pd->force_phy_addr) - ethernet_phy_set(port_num, pd->phy_addr); - - if (pd->port_config || pd->force_port_config) - mp->port_config = pd->port_config; - - if (pd->port_config_extend || pd->force_port_config_extend) - mp->port_config_extend = pd->port_config_extend; - - if (pd->port_sdma_config || pd->force_port_sdma_config) - mp->port_sdma_config = pd->port_sdma_config; - - if (pd->port_serial_control || pd->force_port_serial_control) - mp->port_serial_control = pd->port_serial_control; + ethernet_phy_set(mp->port_num, pd->phy_addr); if (pd->rx_queue_size) mp->rx_ring_size = pd->rx_queue_size; @@ -1446,14 +1526,30 @@ static int mv643xx_eth_probe(struct plat } } + /* Hook up MII support for ethtool */ + mp->mii.dev = dev; + mp->mii.mdio_read = mv643xx_mdio_read; + mp->mii.mdio_write = mv643xx_mdio_write; + mp->mii.phy_id = ethernet_phy_get(port_num); + mp->mii.phy_id_mask = 0x3f; + mp->mii.reg_num_mask = 0x1f; + err = ethernet_phy_detect(port_num); if (err) { - pr_debug("MV643xx ethernet port %d: " + printk(KERN_ERR "MV643xx ethernet port %d: " "No PHY detected at addr %d\n", port_num, ethernet_phy_get(port_num)); - return err; + goto out; } + mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); + + ethernet_phy_reset(mp->port_num); + mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, pd->speed, pd->duplex, + &cmd); + mv643xx_eth_update_pscr(dev, &cmd); + mv643xx_set_settings(dev, &cmd); + err = register_netdev(dev); if (err) goto out; @@ -1782,8 +1878,6 @@ static void eth_port_init(struct mv643xx eth_port_reset(mp->port_num); eth_port_init_mac_tables(mp->port_num); - - ethernet_phy_reset(mp->port_num); } /* @@ -1818,6 +1912,7 @@ static void eth_port_start(struct net_de struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; int tx_curr_desc, rx_curr_desc; + u32 pscr; /* Assignment of Tx CTRP of given queue */ tx_curr_desc = mp->tx_curr_desc_q; @@ -1833,27 +1928,28 @@ static void eth_port_start(struct net_de eth_port_uc_addr_set(port_num, dev->dev_addr); /* Assign port configuration and command. */ - mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config); + mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), + MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE); mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num), - mp->port_config_extend); + MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE); + pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - /* Increase the Rx side buffer size if supporting GigE */ - if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000) - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - (mp->port_serial_control & 0xfff1ffff) | (0x5 << 17)); - else - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - mp->port_serial_control); + pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) | - MV643XX_ETH_SERIAL_PORT_ENABLE); + pscr |= MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED | + MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL; + + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + + pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE; + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); /* Assign port SDMA configuration */ mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), - mp->port_sdma_config); + MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE); /* Enable port Rx. */ mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), @@ -2334,6 +2430,51 @@ static void ethernet_phy_reset(unsigned eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data); } +static void mv643xx_eth_port_disable_tx(unsigned int port_num) +{ + u32 channels; + + /* Stop Tx port activity. Check port Tx activity. */ + channels = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) + & 0xFF; + if (channels) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), + (channels << 8)); + + /* Wait for all Tx activity to terminate. */ + /* Check port cause register that all Tx queues are stopped */ + while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + + /* Wait for Tx FIFO to empty */ + while (mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)) & + ETH_PORT_TX_FIFO_EMPTY) + udelay(10); + } +} + +static void mv643xx_eth_port_disable_rx(unsigned int port_num) +{ + u32 channels; + + /* Stop Rx port activity. Check port Rx activity. */ + channels = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num) + & 0xFF); + if (channels) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), + (channels << 8)); + + /* Wait for all Rx activity to terminate. */ + /* Check port cause register that all Rx queues are stopped */ + while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + } +} + /* * eth_port_reset - Reset Ethernet port * @@ -2356,35 +2497,8 @@ static void eth_port_reset(unsigned int { unsigned int reg_data; - /* Stop Tx port activity. Check port Tx activity. */ - reg_data = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)); - - if (reg_data & 0xFF) { - /* Issue stop command for active channels only */ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), - (reg_data << 8)); - - /* Wait for all Tx activity to terminate. */ - /* Check port cause register that all Tx queues are stopped */ - while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(10); - } - - /* Stop Rx port activity. Check port Rx activity. */ - reg_data = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)); - - if (reg_data & 0xFF) { - /* Issue stop command for active channels only */ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), - (reg_data << 8)); - - /* Wait for all Rx activity to terminate. */ - /* Check port cause register that all Rx queues are stopped */ - while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(10); - } + mv643xx_eth_port_disable_tx(port_num); + mv643xx_eth_port_disable_rx(port_num); /* Clear all MIB counters */ eth_clear_mib_counters(port_num); @@ -2396,15 +2510,6 @@ static void eth_port_reset(unsigned int } -static int eth_port_autoneg_supported(unsigned int eth_port_num) -{ - unsigned int phy_reg_data0; - - eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0); - - return phy_reg_data0 & 0x1000; -} - /* * eth_port_read_smi_reg - Read PHY registers * @@ -2963,111 +3068,6 @@ static const struct mv643xx_stats mv643x #define MV643XX_STATS_LEN \ sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats) -static int -mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) -{ - struct mv643xx_private *mp = netdev->priv; - int port_num = mp->port_num; - int autoneg = eth_port_autoneg_supported(port_num); - int mode_10_bit; - int auto_duplex; - int half_duplex = 0; - int full_duplex = 0; - int auto_speed; - int speed_10 = 0; - int speed_100 = 0; - int speed_1000 = 0; - - u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)); - - mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT; - - if (mode_10_bit) { - ecmd->supported = SUPPORTED_10baseT_Half; - } else { - ecmd->supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - (autoneg ? SUPPORTED_Autoneg : 0) | - SUPPORTED_TP); - - auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX); - auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII); - - ecmd->advertising = ADVERTISED_TP; - - if (autoneg) { - ecmd->advertising |= ADVERTISED_Autoneg; - - if (auto_duplex) { - half_duplex = 1; - full_duplex = 1; - } else { - if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE) - full_duplex = 1; - else - half_duplex = 1; - } - - if (auto_speed) { - speed_10 = 1; - speed_100 = 1; - speed_1000 = 1; - } else { - if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000) - speed_1000 = 1; - else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100) - speed_100 = 1; - else - speed_10 = 1; - } - - if (speed_10 & half_duplex) - ecmd->advertising |= ADVERTISED_10baseT_Half; - if (speed_10 & full_duplex) - ecmd->advertising |= ADVERTISED_10baseT_Full; - if (speed_100 & half_duplex) - ecmd->advertising |= ADVERTISED_100baseT_Half; - if (speed_100 & full_duplex) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (speed_1000) - ecmd->advertising |= ADVERTISED_1000baseT_Full; - } - } - - ecmd->port = PORT_TP; - ecmd->phy_address = ethernet_phy_get(port_num); - - ecmd->transceiver = XCVR_EXTERNAL; - - if (netif_carrier_ok(netdev)) { - if (mode_10_bit) - ecmd->speed = SPEED_10; - else { - if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000) - ecmd->speed = SPEED_1000; - else if (psr & MV643XX_ETH_PORT_STATUS_MII_100) - ecmd->speed = SPEED_100; - else - ecmd->speed = SPEED_10; - } - - if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX) - ecmd->duplex = DUPLEX_FULL; - else - ecmd->duplex = DUPLEX_HALF; - } else { - ecmd->speed = -1; - ecmd->duplex = -1; - } - - ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; - return 0; -} - static void mv643xx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) { @@ -3114,15 +3114,40 @@ static void mv643xx_get_strings(struct n } } +static u32 mv643xx_eth_get_link(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + return mii_link_ok(&mp->mii); +} + +static int mv643xx_eth_nway_restart(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + + return mii_nway_restart(&mp->mii); +} + +static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + + return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); +} + static struct ethtool_ops mv643xx_ethtool_ops = { .get_settings = mv643xx_get_settings, + .set_settings = mv643xx_set_settings, .get_drvinfo = mv643xx_get_drvinfo, - .get_link = ethtool_op_get_link, + .get_link = mv643xx_eth_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_strings = mv643xx_get_strings, .get_stats_count = mv643xx_get_stats_count, .get_ethtool_stats = mv643xx_get_ethtool_stats, + .get_strings = mv643xx_get_strings, + .get_stats_count = mv643xx_get_stats_count, + .get_ethtool_stats = mv643xx_get_ethtool_stats, + .nway_reset = mv643xx_eth_nway_restart, }; /************* End ethtool support *************************/ Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h =================================================================== --- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.h +++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.h @@ -321,10 +321,6 @@ struct mv643xx_mib_counters { struct mv643xx_private { int port_num; /* User Ethernet port number */ - u32 port_config; /* User port configuration value*/ - u32 port_config_extend; /* User port config extend value*/ - u32 port_sdma_config; /* User port SDMA config value */ - u32 port_serial_control; /* User port serial control value */ u32 port_tx_queue_command; /* Port active Tx queues summary*/ u32 port_rx_queue_command; /* Port active Rx queues summary*/ Index: linux-2.6-mv643xx_enet/include/linux/mv643xx.h =================================================================== --- linux-2.6-mv643xx_enet.orig/include/linux/mv643xx.h +++ linux-2.6-mv643xx_enet/include/linux/mv643xx.h @@ -1214,6 +1214,7 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_FORCE_BP_MODE_NO_JAM 0 #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX (1<<7) #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1<<8) +#define MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED (1<<9) #define MV643XX_ETH_FORCE_LINK_FAIL 0 #define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL (1<<10) #define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS 0 @@ -1285,29 +1286,22 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_NAME "mv643xx_eth" struct mv643xx_eth_platform_data { - /* - * Non-values for mac_addr, phy_addr, port_config, etc. - * override the default value. Setting the corresponding - * force_* field, causes the default value to be overridden - * even when zero. - */ - unsigned int force_phy_addr:1; - unsigned int force_port_config:1; - unsigned int force_port_config_extend:1; - unsigned int force_port_sdma_config:1; - unsigned int force_port_serial_control:1; - int phy_addr; - char *mac_addr; /* pointer to mac address */ - u32 port_config; - u32 port_config_extend; - u32 port_sdma_config; - u32 port_serial_control; - u32 tx_queue_size; - u32 rx_queue_size; - u32 tx_sram_addr; - u32 tx_sram_size; - u32 rx_sram_addr; - u32 rx_sram_size; + char *mac_addr; + + /* If speed is 0, then speed and duplex are auto-negotiated. */ + int speed; /* 0, SPEED_10, SPEED_100 or SPEED_1000 */ + int duplex; /* either DUPLEX_HALF or DUPLEX_FULL */ + + /* non-zero values of the following fields override defaults */ + u16 phy_addr; + u16 force_phy_addr; /* force override if phy_addr == 0 */ + + u32 tx_queue_size; + u32 rx_queue_size; + u32 tx_sram_addr; + u32 tx_sram_size; + u32 rx_sram_addr; + u32 rx_sram_size; }; #endif /* __ASM_MV643XX_H */ Index: linux-2.6-mv643xx_enet/arch/ppc/platforms/hdpu.c =================================================================== --- linux-2.6-mv643xx_enet.orig/arch/ppc/platforms/hdpu.c +++ linux-2.6-mv643xx_enet/arch/ppc/platforms/hdpu.c @@ -319,11 +319,10 @@ static void __init hdpu_fixup_eth_pdata( struct mv643xx_eth_platform_data *eth_pd; eth_pd = pd->dev.platform_data; - eth_pd->port_serial_control = - mv64x60_read(&bh, MV643XX_ETH_PORT_SERIAL_CONTROL_REG(pd->id) & ~1); - eth_pd->force_phy_addr = 1; eth_pd->phy_addr = pd->id; + eth_pd->speed = SPEED_100; + eth_pd->duplex = DUPLEX_FULL; eth_pd->tx_queue_size = 400; eth_pd->rx_queue_size = 800; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html