/* Wake on Lan only supported on Yukon chips with rev 1 or above */
static u32 wol_supported(const struct skge_hw *hw)
{
- if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0)
- return WAKE_MAGIC | WAKE_PHY;
- else
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ return 0;
+
+ if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
return 0;
+
+ return WAKE_MAGIC | WAKE_PHY;
}
static u32 pci_wake_enabled(struct pci_dev *dev)
.phys_id = skge_phys_id,
.get_stats_count = skge_get_stats_count,
.get_ethtool_stats = skge_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
/*
skge_write32(hw, B0_IMSK, hw->intr_mask);
spin_unlock_irq(&hw->hw_lock);
- netif_poll_enable(dev);
+ napi_enable(&skge->napi);
return 0;
free_rx_ring:
if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
del_timer_sync(&skge->link_timer);
- netif_poll_disable(dev);
+ napi_disable(&skge->napi);
netif_carrier_off(dev);
spin_lock_irq(&hw->hw_lock);
}
}
-static int skge_poll(struct net_device *dev, int *budget)
+static int skge_poll(struct napi_struct *napi, int to_do)
{
- struct skge_port *skge = netdev_priv(dev);
+ struct skge_port *skge = container_of(napi, struct skge_port, napi);
+ struct net_device *dev = skge->netdev;
struct skge_hw *hw = skge->hw;
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
- unsigned long flags;
- int to_do = min(dev->quota, *budget);
int work_done = 0;
skge_tx_done(dev);
wmb();
skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START);
- *budget -= work_done;
- dev->quota -= work_done;
-
- if (work_done >= to_do)
- return 1; /* not done */
-
- spin_lock_irqsave(&hw->hw_lock, flags);
- __netif_rx_complete(dev);
- hw->intr_mask |= napimask[skge->port];
- skge_write32(hw, B0_IMSK, hw->intr_mask);
- skge_read32(hw, B0_IMSK);
- spin_unlock_irqrestore(&hw->hw_lock, flags);
+ if (work_done < to_do) {
+ spin_lock_irq(&hw->hw_lock);
+ __netif_rx_complete(dev, napi);
+ hw->intr_mask |= napimask[skge->port];
+ skge_write32(hw, B0_IMSK, hw->intr_mask);
+ skge_read32(hw, B0_IMSK);
+ spin_unlock_irq(&hw->hw_lock);
+ }
- return 0;
+ return work_done;
}
/* Parity errors seem to happen when Genesis is connected to a switch
}
if (status & (IS_XA1_F|IS_R1_F)) {
+ struct skge_port *skge = netdev_priv(hw->dev[0]);
hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
- netif_rx_schedule(hw->dev[0]);
+ netif_rx_schedule(hw->dev[0], &skge->napi);
}
if (status & IS_PA_TO_TX1)
skge_mac_intr(hw, 0);
if (hw->dev[1]) {
+ struct skge_port *skge = netdev_priv(hw->dev[1]);
+
if (status & (IS_XA2_F|IS_R2_F)) {
hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
- netif_rx_schedule(hw->dev[1]);
+ netif_rx_schedule(hw->dev[1], &skge->napi);
}
if (status & IS_PA_TO_RX2) {
- struct skge_port *skge = netdev_priv(hw->dev[1]);
++skge->net_stats.rx_over_errors;
skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
}
SET_ETHTOOL_OPS(dev, &skge_ethtool_ops);
dev->tx_timeout = skge_tx_timeout;
dev->watchdog_timeo = TX_WATCHDOG;
- dev->poll = skge_poll;
- dev->weight = NAPI_WEIGHT;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = skge_netpoll;
#endif
dev->features |= NETIF_F_HIGHDMA;
skge = netdev_priv(dev);
+ netif_napi_add(dev, &skge->napi, skge_poll, NAPI_WEIGHT);
skge->netdev = dev;
skge->hw = hw;
skge->msg_enable = netif_msg_init(debug, default_msg);
skge->duplex = -1;
skge->speed = -1;
skge->advertising = skge_supported_modes(hw);
- skge->wol = pci_wake_enabled(hw->pdev) ? wol_supported(hw) : 0;
+
+ if (pci_wake_enabled(hw->pdev))
+ skge->wol = wol_supported(hw) & WAKE_MAGIC;
hw->dev[port] = dev;
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err, wol = 0;
+ if (!hw)
+ return 0;
+
err = pci_save_state(pdev);
if (err)
return err;
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err;
+ if (!hw)
+ return 0;
+
err = pci_set_power_state(pdev, PCI_D0);
if (err)
goto out;
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, wol = 0;
+ if (!hw)
+ return;
+
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
struct skge_port *skge = netdev_priv(dev);