tp->duplex = cmd->duplex;
}
- return 0;
+ out:
+ return err;
}
- static inline int
- typhoon_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+ static void
+ typhoon_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
- struct typhoon *tp = (struct typhoon *) dev->priv;
- u32 ethcmd;
-
- if(copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
- return -EFAULT;
-
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: {
- struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-
- typhoon_ethtool_gdrvinfo(tp, &info);
- if(copy_to_user(useraddr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- case ETHTOOL_GSET: {
- struct ethtool_cmd cmd = { ETHTOOL_GSET };
+ struct typhoon *tp = netdev_priv(dev);
+
+ wol->supported = WAKE_PHY | WAKE_MAGIC;
+ wol->wolopts = 0;
+ if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT)
+ wol->wolopts |= WAKE_PHY;
+ if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
+ wol->wolopts |= WAKE_MAGIC;
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+ }
- typhoon_ethtool_gset(tp, &cmd);
- if(copy_to_user(useraddr, &cmd, sizeof(cmd)))
- return -EFAULT;
- return 0;
- }
- case ETHTOOL_SSET: {
- struct ethtool_cmd cmd;
- if(copy_from_user(&cmd, useraddr, sizeof(cmd)))
- return -EFAULT;
+ static int
+ typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+ struct typhoon *tp = netdev_priv(dev);
- return typhoon_ethtool_sset(tp, &cmd);
- }
- case ETHTOOL_GLINK:{
- struct ethtool_value edata = { ETHTOOL_GLINK };
+ if(wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
+ return -EINVAL;
- edata.data = netif_carrier_ok(dev) ? 1 : 0;
- if(copy_to_user(useraddr, &edata, sizeof(edata)))
- return -EFAULT;
- return 0;
- }
- case ETHTOOL_GWOL: {
- struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
-
- if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT)
- wol.wolopts |= WAKE_PHY;
- if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
- wol.wolopts |= WAKE_MAGIC;
- if(copy_to_user(useraddr, &wol, sizeof(wol)))
- return -EFAULT;
- return 0;
- }
- case ETHTOOL_SWOL: {
- struct ethtool_wolinfo wol;
-
- if(copy_from_user(&wol, useraddr, sizeof(wol)))
- return -EFAULT;
- tp->wol_events = 0;
- if(wol.wolopts & WAKE_PHY)
- tp->wol_events |= TYPHOON_WAKE_LINK_EVENT;
- if(wol.wolopts & WAKE_MAGIC)
- tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT;
- return 0;
- }
- default:
- break;
- }
+ tp->wol_events = 0;
+ if(wol->wolopts & WAKE_PHY)
+ tp->wol_events |= TYPHOON_WAKE_LINK_EVENT;
+ if(wol->wolopts & WAKE_MAGIC)
+ tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT;
- return -EOPNOTSUPP;
+ return 0;
}
- static int
- typhoon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ static u32
+ typhoon_get_rx_csum(struct net_device *dev)
{
- switch (cmd) {
- case SIOCETHTOOL:
- return typhoon_ethtool_ioctl(dev, ifr->ifr_data);
- default:
- break;
- }
+ /* For now, we don't allow turning off RX checksums.
+ */
+ return 1;
+ }
- return -EOPNOTSUPP;
+ static void
+ typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+ {
+ ering->rx_max_pending = RXENT_ENTRIES;
+ ering->rx_mini_max_pending = 0;
+ ering->rx_jumbo_max_pending = 0;
+ ering->tx_max_pending = TXLO_ENTRIES - 1;
+
+ ering->rx_pending = RXENT_ENTRIES;
+ ering->rx_mini_pending = 0;
+ ering->rx_jumbo_pending = 0;
+ ering->tx_pending = TXLO_ENTRIES - 1;
}
+ static struct ethtool_ops typhoon_ethtool_ops = {
+ .get_settings = typhoon_get_settings,
+ .set_settings = typhoon_set_settings,
+ .get_drvinfo = typhoon_get_drvinfo,
+ .get_wol = typhoon_get_wol,
+ .set_wol = typhoon_set_wol,
+ .get_link = ethtool_op_get_link,
+ .get_rx_csum = typhoon_get_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = ethtool_op_set_tso,
+ .get_ringparam = typhoon_get_ringparam,
+ };
+
static int
-typhoon_wait_interrupt(unsigned long ioaddr)
+typhoon_wait_interrupt(void __iomem *ioaddr)
{
int i, err = 0;
static void
typhoon_tx_timeout(struct net_device *dev)
{
- struct typhoon *tp = (struct typhoon *) dev->priv;
+ struct typhoon *tp = netdev_priv(dev);
- if(typhoon_reset(dev->base_addr, WaitNoSleep) < 0) {
+ if(typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) {
printk(KERN_WARNING "%s: could not reset in tx timeout\n",
dev->name);
goto truely_dead;
pci_free_consistent(pdev, sizeof(struct typhoon_shared),
shared, shared_dma);
error_out_remap:
- iounmap((void *) ioaddr);
+ iounmap(ioaddr_mapped);
error_out_regions:
pci_release_regions(pdev);
+ error_out_mwi:
+ pci_clear_mwi(pdev);
+ error_out_disable:
+ pci_disable_device(pdev);
error_out_dev:
free_netdev(dev);
error_out: