/****************************************************************************** * mv_eth_tool_set_settings * Description: * ethtool set standard port settings * INPUT: * netdev Network device structure pointer * cmd command (settings) * OUTPUT * None * RETURN: * 0 for success * *******************************************************************************/ int mv_eth_tool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct eth_port *priv = MV_ETH_PRIV(dev); int _speed, _duplex, _autoneg, err; #ifdef CONFIG_MV_ETH_SWITCH if (isSwitch(priv)) return -EPERM; #endif /* CONFIG_MV_ETH_SWITCH */ _duplex = priv->duplex_cfg; _speed = priv->speed_cfg; _autoneg = priv->autoneg_cfg; priv->duplex_cfg = cmd->duplex; priv->speed_cfg = cmd->speed; priv->autoneg_cfg = cmd->autoneg; err = mv_eth_tool_restore_settings(dev); if (err) { priv->duplex_cfg = _duplex; priv->speed_cfg = _speed; priv->autoneg_cfg = _autoneg; } return err; }
/****************************************************************************** * mv_eth_tool_set_settings * Description: * ethtool set standard port settings * INPUT: * netdev Network device structure pointer * cmd command (settings) * OUTPUT * None * RETURN: * 0 for success * *******************************************************************************/ int mv_eth_tool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct eth_port *priv = MV_ETH_PRIV(dev); int _speed, _duplex, _autoneg, _advertise, err; if ((priv == NULL) || (isSwitch(priv)) || (MV_PON_PORT(priv->port))) { printk(KERN_ERR "%s is not supported on %s\n", __func__, dev->name); return -EOPNOTSUPP; } _duplex = priv->duplex_cfg; _speed = priv->speed_cfg; _autoneg = priv->autoneg_cfg; _advertise = priv->advertise_cfg; priv->duplex_cfg = cmd->duplex; priv->speed_cfg = cmd->speed; priv->autoneg_cfg = cmd->autoneg; priv->advertise_cfg = cmd->advertising; err = mv_eth_tool_restore_settings(dev); if (err) { priv->duplex_cfg = _duplex; priv->speed_cfg = _speed; priv->autoneg_cfg = _autoneg; priv->advertise_cfg = _advertise; } return err; }
/*********************************************************** * mv_eth_start -- * * start a network device. connect and enable interrupts * * set hw defaults. fill rx buffers. restart phy link * * auto neg. set device link flags. report status. * ***********************************************************/ int mv_eth_start(struct net_device *dev) { mv_eth_priv *priv = MV_ETH_PRIV(dev); int err; ETH_DBG( ETH_DBG_LOAD, ("%s: starting... ", dev->name ) ); /* in default link is down */ netif_carrier_off(dev); /* Stop the TX queue - it will be enabled upon PHY status change after link-up interrupt/timer */ netif_stop_queue(dev); /* enable polling on the port, must be used after netif_poll_disable */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) netif_poll_enable(dev); #else napi_enable(&priv->napi); #endif /* fill rx buffers, start rx/tx activity, set coalescing */ if (mv_eth_start_internals( priv, dev->mtu) != 0) { printk(KERN_ERR "%s: start internals failed\n", dev->name); goto error; } if (priv->flags & MV_ETH_F_FORCED_LINK) { netif_carrier_on(dev); netif_wake_queue(dev); } else { #ifdef CONFIG_MV_ETH_TOOL if ((err = mv_eth_tool_restore_settings(dev)) != 0) { printk(KERN_ERR "%s: mv_eth_tool_restore_settings failed %d\n", dev->name, err); goto error; } if (priv->autoneg_cfg == AUTONEG_DISABLE) { if (priv->flags & MV_ETH_F_LINK_UP) { netif_carrier_on(dev); netif_wake_queue(dev); } } #else mv_eth_restart_autoneg(priv->port); #endif /* CONFIG_MV_ETH_TOOL */ } if (!(priv->flags & MV_ETH_F_TIMER)) { priv->timer.expires = jiffies + ((HZ*CONFIG_MV_ETH_TIMER_PERIOD) / 1000); /* ms */ add_timer(&priv->timer); priv->flags |= MV_ETH_F_TIMER; } /* connect to port interrupt line */ if (request_irq(dev->irq, mv_eth_interrupt_handler, (IRQF_DISABLED | IRQF_SAMPLE_RANDOM), "mv_ethernet", priv)) { printk( KERN_ERR "cannot assign irq%d to %s port%d\n", dev->irq, dev->name, priv->port ); dev->irq = 0; goto error; } mv_eth_unmask_interrupts(priv); ETH_DBG( ETH_DBG_LOAD, ("%s: start ok\n", dev->name) ); printk(KERN_NOTICE "%s: started\n", dev->name); return 0; error: printk( KERN_ERR "%s: start failed\n", dev->name ); return -1; }