aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r--drivers/net/skge.c152
1 files changed, 45 insertions, 107 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index bfec2e0f527..f4be5c78ebf 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -44,6 +44,7 @@
#include <linux/mii.h>
#include <linux/slab.h>
#include <linux/dmi.h>
+#include <linux/prefetch.h>
#include <asm/irq.h>
#include "skge.h"
@@ -303,7 +304,7 @@ static int skge_get_settings(struct net_device *dev,
ecmd->advertising = skge->advertising;
ecmd->autoneg = skge->autoneg;
- ecmd->speed = skge->speed;
+ ethtool_cmd_speed_set(ecmd, skge->speed);
ecmd->duplex = skge->duplex;
return 0;
}
@@ -321,8 +322,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
skge->speed = -1;
} else {
u32 setting;
+ u32 speed = ethtool_cmd_speed(ecmd);
- switch (ecmd->speed) {
+ switch (speed) {
case SPEED_1000:
if (ecmd->duplex == DUPLEX_FULL)
setting = SUPPORTED_1000baseT_Full;
@@ -355,7 +357,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
if ((setting & supported) == 0)
return -EINVAL;
- skge->speed = ecmd->speed;
+ skge->speed = speed;
skge->duplex = ecmd->duplex;
}
@@ -537,46 +539,6 @@ static int skge_nway_reset(struct net_device *dev)
return 0;
}
-static int skge_set_sg(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
- struct skge_hw *hw = skge->hw;
-
- if (hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
- return ethtool_op_set_sg(dev, data);
-}
-
-static int skge_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
- struct skge_hw *hw = skge->hw;
-
- if (hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
-
- return ethtool_op_set_tx_csum(dev, data);
-}
-
-static u32 skge_get_rx_csum(struct net_device *dev)
-{
- struct skge_port *skge = netdev_priv(dev);
-
- return skge->rx_csum;
-}
-
-/* Only Yukon supports checksum offload. */
-static int skge_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct skge_port *skge = netdev_priv(dev);
-
- if (skge->hw->chip_id == CHIP_ID_GENESIS && data)
- return -EOPNOTSUPP;
-
- skge->rx_csum = data;
- return 0;
-}
-
static void skge_get_pauseparam(struct net_device *dev,
struct ethtool_pauseparam *ecmd)
{
@@ -786,29 +748,28 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
}
/* blink LED's for finding board */
-static int skge_phys_id(struct net_device *dev, u32 data)
+static int skge_set_phys_id(struct net_device *dev,
+ enum ethtool_phys_id_state state)
{
struct skge_port *skge = netdev_priv(dev);
- unsigned long ms;
- enum led_mode mode = LED_MODE_TST;
- if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
- ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000;
- else
- ms = data * 1000;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ return 2; /* cycle on/off twice per second */
+
+ case ETHTOOL_ID_ON:
+ skge_led(skge, LED_MODE_TST);
+ break;
- while (ms > 0) {
- skge_led(skge, mode);
- mode ^= LED_MODE_TST;
+ case ETHTOOL_ID_OFF:
+ skge_led(skge, LED_MODE_OFF);
+ break;
- if (msleep_interruptible(BLINK_MS))
- break;
- ms -= BLINK_MS;
+ case ETHTOOL_ID_INACTIVE:
+ /* back to regular LED state */
+ skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
}
- /* back to regular LED state */
- skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
-
return 0;
}
@@ -925,12 +886,8 @@ static const struct ethtool_ops skge_ethtool_ops = {
.set_pauseparam = skge_set_pauseparam,
.get_coalesce = skge_get_coalesce,
.set_coalesce = skge_set_coalesce,
- .set_sg = skge_set_sg,
- .set_tx_csum = skge_set_tx_csum,
- .get_rx_csum = skge_get_rx_csum,
- .set_rx_csum = skge_set_rx_csum,
.get_strings = skge_get_strings,
- .phys_id = skge_phys_id,
+ .set_phys_id = skge_set_phys_id,
.get_sset_count = skge_get_sset_count,
.get_ethtool_stats = skge_get_ethtool_stats,
};
@@ -1191,7 +1148,7 @@ static void genesis_init(struct skge_hw *hw)
static void genesis_reset(struct skge_hw *hw, int port)
{
- const u8 zero[8] = { 0 };
+ static const u8 zero[8] = { 0 };
u32 reg;
skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
@@ -1557,7 +1514,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
int i;
u32 r;
- const u8 zero[6] = { 0 };
+ static const u8 zero[6] = { 0 };
for (i = 0; i < 10; i++) {
skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
@@ -2764,7 +2721,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
td->dma_hi = map >> 32;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- const int offset = skb_transport_offset(skb);
+ const int offset = skb_checksum_start_offset(skb);
/* This seems backwards, but it is what the sk98lin
* does. Looks like hardware is wrong?
@@ -3085,7 +3042,8 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
}
skb_put(skb, len);
- if (skge->rx_csum) {
+
+ if (dev->features & NETIF_F_RXCSUM) {
skb->csum = csum;
skb->ip_summed = CHECKSUM_COMPLETE;
}
@@ -3847,19 +3805,15 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
if (hw->chip_id != CHIP_ID_GENESIS) {
- dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
- skge->rx_csum = 1;
+ dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+ NETIF_F_RXCSUM;
+ dev->features |= dev->hw_features;
}
- dev->features |= NETIF_F_GRO;
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- /* device is off until link detection */
- netif_carrier_off(dev);
- netif_stop_queue(dev);
-
return dev;
}
@@ -4013,8 +3967,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
if (!hw)
return;
- flush_scheduled_work();
-
dev1 = hw->dev[1];
if (dev1)
unregister_netdev(dev1);
@@ -4045,53 +3997,40 @@ static void __devexit skge_remove(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+static int skge_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct skge_hw *hw = pci_get_drvdata(pdev);
- int i, err, wol = 0;
+ int i;
if (!hw)
return 0;
- err = pci_save_state(pdev);
- if (err)
- return err;
-
for (i = 0; i < hw->ports; i++) {
struct net_device *dev = hw->dev[i];
struct skge_port *skge = netdev_priv(dev);
if (netif_running(dev))
skge_down(dev);
+
if (skge->wol)
skge_wol_init(skge);
-
- wol |= skge->wol;
}
skge_write32(hw, B0_IMSK, 0);
- pci_prepare_to_sleep(pdev);
-
return 0;
}
-static int skge_resume(struct pci_dev *pdev)
+static int skge_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct skge_hw *hw = pci_get_drvdata(pdev);
int i, err;
if (!hw)
return 0;
- err = pci_back_from_sleep(pdev);
- if (err)
- goto out;
-
- err = pci_restore_state(pdev);
- if (err)
- goto out;
-
err = skge_reset(hw);
if (err)
goto out;
@@ -4112,12 +4051,19 @@ static int skge_resume(struct pci_dev *pdev)
out:
return err;
}
+
+static SIMPLE_DEV_PM_OPS(skge_pm_ops, skge_suspend, skge_resume);
+#define SKGE_PM_OPS (&skge_pm_ops)
+
+#else
+
+#define SKGE_PM_OPS NULL
#endif
static void skge_shutdown(struct pci_dev *pdev)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
- int i, wol = 0;
+ int i;
if (!hw)
return;
@@ -4128,15 +4074,10 @@ static void skge_shutdown(struct pci_dev *pdev)
if (skge->wol)
skge_wol_init(skge);
- wol |= skge->wol;
}
- if (pci_enable_wake(pdev, PCI_D3cold, wol))
- pci_enable_wake(pdev, PCI_D3hot, wol);
-
- pci_disable_device(pdev);
+ pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
pci_set_power_state(pdev, PCI_D3hot);
-
}
static struct pci_driver skge_driver = {
@@ -4144,11 +4085,8 @@ static struct pci_driver skge_driver = {
.id_table = skge_id_table,
.probe = skge_probe,
.remove = __devexit_p(skge_remove),
-#ifdef CONFIG_PM
- .suspend = skge_suspend,
- .resume = skge_resume,
-#endif
.shutdown = skge_shutdown,
+ .driver.pm = SKGE_PM_OPS,
};
static struct dmi_system_id skge_32bit_dma_boards[] = {