aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/skge.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r--drivers/net/skge.c155
1 files changed, 47 insertions, 108 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 465ae7e84507..f4be5c78ebfd 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -44,6 +44,7 @@
44#include <linux/mii.h> 44#include <linux/mii.h>
45#include <linux/slab.h> 45#include <linux/slab.h>
46#include <linux/dmi.h> 46#include <linux/dmi.h>
47#include <linux/prefetch.h>
47#include <asm/irq.h> 48#include <asm/irq.h>
48 49
49#include "skge.h" 50#include "skge.h"
@@ -303,7 +304,7 @@ static int skge_get_settings(struct net_device *dev,
303 304
304 ecmd->advertising = skge->advertising; 305 ecmd->advertising = skge->advertising;
305 ecmd->autoneg = skge->autoneg; 306 ecmd->autoneg = skge->autoneg;
306 ecmd->speed = skge->speed; 307 ethtool_cmd_speed_set(ecmd, skge->speed);
307 ecmd->duplex = skge->duplex; 308 ecmd->duplex = skge->duplex;
308 return 0; 309 return 0;
309} 310}
@@ -321,8 +322,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
321 skge->speed = -1; 322 skge->speed = -1;
322 } else { 323 } else {
323 u32 setting; 324 u32 setting;
325 u32 speed = ethtool_cmd_speed(ecmd);
324 326
325 switch (ecmd->speed) { 327 switch (speed) {
326 case SPEED_1000: 328 case SPEED_1000:
327 if (ecmd->duplex == DUPLEX_FULL) 329 if (ecmd->duplex == DUPLEX_FULL)
328 setting = SUPPORTED_1000baseT_Full; 330 setting = SUPPORTED_1000baseT_Full;
@@ -355,7 +357,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
355 if ((setting & supported) == 0) 357 if ((setting & supported) == 0)
356 return -EINVAL; 358 return -EINVAL;
357 359
358 skge->speed = ecmd->speed; 360 skge->speed = speed;
359 skge->duplex = ecmd->duplex; 361 skge->duplex = ecmd->duplex;
360 } 362 }
361 363
@@ -537,46 +539,6 @@ static int skge_nway_reset(struct net_device *dev)
537 return 0; 539 return 0;
538} 540}
539 541
540static int skge_set_sg(struct net_device *dev, u32 data)
541{
542 struct skge_port *skge = netdev_priv(dev);
543 struct skge_hw *hw = skge->hw;
544
545 if (hw->chip_id == CHIP_ID_GENESIS && data)
546 return -EOPNOTSUPP;
547 return ethtool_op_set_sg(dev, data);
548}
549
550static int skge_set_tx_csum(struct net_device *dev, u32 data)
551{
552 struct skge_port *skge = netdev_priv(dev);
553 struct skge_hw *hw = skge->hw;
554
555 if (hw->chip_id == CHIP_ID_GENESIS && data)
556 return -EOPNOTSUPP;
557
558 return ethtool_op_set_tx_csum(dev, data);
559}
560
561static u32 skge_get_rx_csum(struct net_device *dev)
562{
563 struct skge_port *skge = netdev_priv(dev);
564
565 return skge->rx_csum;
566}
567
568/* Only Yukon supports checksum offload. */
569static int skge_set_rx_csum(struct net_device *dev, u32 data)
570{
571 struct skge_port *skge = netdev_priv(dev);
572
573 if (skge->hw->chip_id == CHIP_ID_GENESIS && data)
574 return -EOPNOTSUPP;
575
576 skge->rx_csum = data;
577 return 0;
578}
579
580static void skge_get_pauseparam(struct net_device *dev, 542static void skge_get_pauseparam(struct net_device *dev,
581 struct ethtool_pauseparam *ecmd) 543 struct ethtool_pauseparam *ecmd)
582{ 544{
@@ -786,28 +748,27 @@ static void skge_led(struct skge_port *skge, enum led_mode mode)
786} 748}
787 749
788/* blink LED's for finding board */ 750/* blink LED's for finding board */
789static int skge_phys_id(struct net_device *dev, u32 data) 751static int skge_set_phys_id(struct net_device *dev,
752 enum ethtool_phys_id_state state)
790{ 753{
791 struct skge_port *skge = netdev_priv(dev); 754 struct skge_port *skge = netdev_priv(dev);
792 unsigned long ms;
793 enum led_mode mode = LED_MODE_TST;
794 755
795 if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) 756 switch (state) {
796 ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000; 757 case ETHTOOL_ID_ACTIVE:
797 else 758 return 2; /* cycle on/off twice per second */
798 ms = data * 1000;
799 759
800 while (ms > 0) { 760 case ETHTOOL_ID_ON:
801 skge_led(skge, mode); 761 skge_led(skge, LED_MODE_TST);
802 mode ^= LED_MODE_TST; 762 break;
803 763
804 if (msleep_interruptible(BLINK_MS)) 764 case ETHTOOL_ID_OFF:
805 break; 765 skge_led(skge, LED_MODE_OFF);
806 ms -= BLINK_MS; 766 break;
807 }
808 767
809 /* back to regular LED state */ 768 case ETHTOOL_ID_INACTIVE:
810 skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF); 769 /* back to regular LED state */
770 skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
771 }
811 772
812 return 0; 773 return 0;
813} 774}
@@ -925,12 +886,8 @@ static const struct ethtool_ops skge_ethtool_ops = {
925 .set_pauseparam = skge_set_pauseparam, 886 .set_pauseparam = skge_set_pauseparam,
926 .get_coalesce = skge_get_coalesce, 887 .get_coalesce = skge_get_coalesce,
927 .set_coalesce = skge_set_coalesce, 888 .set_coalesce = skge_set_coalesce,
928 .set_sg = skge_set_sg,
929 .set_tx_csum = skge_set_tx_csum,
930 .get_rx_csum = skge_get_rx_csum,
931 .set_rx_csum = skge_set_rx_csum,
932 .get_strings = skge_get_strings, 889 .get_strings = skge_get_strings,
933 .phys_id = skge_phys_id, 890 .set_phys_id = skge_set_phys_id,
934 .get_sset_count = skge_get_sset_count, 891 .get_sset_count = skge_get_sset_count,
935 .get_ethtool_stats = skge_get_ethtool_stats, 892 .get_ethtool_stats = skge_get_ethtool_stats,
936}; 893};
@@ -1191,7 +1148,7 @@ static void genesis_init(struct skge_hw *hw)
1191 1148
1192static void genesis_reset(struct skge_hw *hw, int port) 1149static void genesis_reset(struct skge_hw *hw, int port)
1193{ 1150{
1194 const u8 zero[8] = { 0 }; 1151 static const u8 zero[8] = { 0 };
1195 u32 reg; 1152 u32 reg;
1196 1153
1197 skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); 1154 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)
1557 int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN; 1514 int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
1558 int i; 1515 int i;
1559 u32 r; 1516 u32 r;
1560 const u8 zero[6] = { 0 }; 1517 static const u8 zero[6] = { 0 };
1561 1518
1562 for (i = 0; i < 10; i++) { 1519 for (i = 0; i < 10; i++) {
1563 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), 1520 skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
@@ -2764,7 +2721,7 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
2764 td->dma_hi = map >> 32; 2721 td->dma_hi = map >> 32;
2765 2722
2766 if (skb->ip_summed == CHECKSUM_PARTIAL) { 2723 if (skb->ip_summed == CHECKSUM_PARTIAL) {
2767 const int offset = skb_transport_offset(skb); 2724 const int offset = skb_checksum_start_offset(skb);
2768 2725
2769 /* This seems backwards, but it is what the sk98lin 2726 /* This seems backwards, but it is what the sk98lin
2770 * does. Looks like hardware is wrong? 2727 * does. Looks like hardware is wrong?
@@ -3085,7 +3042,8 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
3085 } 3042 }
3086 3043
3087 skb_put(skb, len); 3044 skb_put(skb, len);
3088 if (skge->rx_csum) { 3045
3046 if (dev->features & NETIF_F_RXCSUM) {
3089 skb->csum = csum; 3047 skb->csum = csum;
3090 skb->ip_summed = CHECKSUM_COMPLETE; 3048 skb->ip_summed = CHECKSUM_COMPLETE;
3091 } 3049 }
@@ -3179,8 +3137,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
3179 3137
3180 skb = skge_rx_get(dev, e, control, rd->status, rd->csum2); 3138 skb = skge_rx_get(dev, e, control, rd->status, rd->csum2);
3181 if (likely(skb)) { 3139 if (likely(skb)) {
3182 netif_receive_skb(skb); 3140 napi_gro_receive(napi, skb);
3183
3184 ++work_done; 3141 ++work_done;
3185 } 3142 }
3186 } 3143 }
@@ -3193,6 +3150,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
3193 if (work_done < to_do) { 3150 if (work_done < to_do) {
3194 unsigned long flags; 3151 unsigned long flags;
3195 3152
3153 napi_gro_flush(napi);
3196 spin_lock_irqsave(&hw->hw_lock, flags); 3154 spin_lock_irqsave(&hw->hw_lock, flags);
3197 __napi_complete(napi); 3155 __napi_complete(napi);
3198 hw->intr_mask |= napimask[skge->port]; 3156 hw->intr_mask |= napimask[skge->port];
@@ -3847,18 +3805,15 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3847 setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge); 3805 setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
3848 3806
3849 if (hw->chip_id != CHIP_ID_GENESIS) { 3807 if (hw->chip_id != CHIP_ID_GENESIS) {
3850 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; 3808 dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
3851 skge->rx_csum = 1; 3809 NETIF_F_RXCSUM;
3810 dev->features |= dev->hw_features;
3852 } 3811 }
3853 3812
3854 /* read the mac address */ 3813 /* read the mac address */
3855 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); 3814 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
3856 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); 3815 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
3857 3816
3858 /* device is off until link detection */
3859 netif_carrier_off(dev);
3860 netif_stop_queue(dev);
3861
3862 return dev; 3817 return dev;
3863} 3818}
3864 3819
@@ -4012,8 +3967,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
4012 if (!hw) 3967 if (!hw)
4013 return; 3968 return;
4014 3969
4015 flush_scheduled_work();
4016
4017 dev1 = hw->dev[1]; 3970 dev1 = hw->dev[1];
4018 if (dev1) 3971 if (dev1)
4019 unregister_netdev(dev1); 3972 unregister_netdev(dev1);
@@ -4044,53 +3997,40 @@ static void __devexit skge_remove(struct pci_dev *pdev)
4044} 3997}
4045 3998
4046#ifdef CONFIG_PM 3999#ifdef CONFIG_PM
4047static int skge_suspend(struct pci_dev *pdev, pm_message_t state) 4000static int skge_suspend(struct device *dev)
4048{ 4001{
4002 struct pci_dev *pdev = to_pci_dev(dev);
4049 struct skge_hw *hw = pci_get_drvdata(pdev); 4003 struct skge_hw *hw = pci_get_drvdata(pdev);
4050 int i, err, wol = 0; 4004 int i;
4051 4005
4052 if (!hw) 4006 if (!hw)
4053 return 0; 4007 return 0;
4054 4008
4055 err = pci_save_state(pdev);
4056 if (err)
4057 return err;
4058
4059 for (i = 0; i < hw->ports; i++) { 4009 for (i = 0; i < hw->ports; i++) {
4060 struct net_device *dev = hw->dev[i]; 4010 struct net_device *dev = hw->dev[i];
4061 struct skge_port *skge = netdev_priv(dev); 4011 struct skge_port *skge = netdev_priv(dev);
4062 4012
4063 if (netif_running(dev)) 4013 if (netif_running(dev))
4064 skge_down(dev); 4014 skge_down(dev);
4015
4065 if (skge->wol) 4016 if (skge->wol)
4066 skge_wol_init(skge); 4017 skge_wol_init(skge);
4067
4068 wol |= skge->wol;
4069 } 4018 }
4070 4019
4071 skge_write32(hw, B0_IMSK, 0); 4020 skge_write32(hw, B0_IMSK, 0);
4072 4021
4073 pci_prepare_to_sleep(pdev);
4074
4075 return 0; 4022 return 0;
4076} 4023}
4077 4024
4078static int skge_resume(struct pci_dev *pdev) 4025static int skge_resume(struct device *dev)
4079{ 4026{
4027 struct pci_dev *pdev = to_pci_dev(dev);
4080 struct skge_hw *hw = pci_get_drvdata(pdev); 4028 struct skge_hw *hw = pci_get_drvdata(pdev);
4081 int i, err; 4029 int i, err;
4082 4030
4083 if (!hw) 4031 if (!hw)
4084 return 0; 4032 return 0;
4085 4033
4086 err = pci_back_from_sleep(pdev);
4087 if (err)
4088 goto out;
4089
4090 err = pci_restore_state(pdev);
4091 if (err)
4092 goto out;
4093
4094 err = skge_reset(hw); 4034 err = skge_reset(hw);
4095 if (err) 4035 if (err)
4096 goto out; 4036 goto out;
@@ -4111,12 +4051,19 @@ static int skge_resume(struct pci_dev *pdev)
4111out: 4051out:
4112 return err; 4052 return err;
4113} 4053}
4054
4055static SIMPLE_DEV_PM_OPS(skge_pm_ops, skge_suspend, skge_resume);
4056#define SKGE_PM_OPS (&skge_pm_ops)
4057
4058#else
4059
4060#define SKGE_PM_OPS NULL
4114#endif 4061#endif
4115 4062
4116static void skge_shutdown(struct pci_dev *pdev) 4063static void skge_shutdown(struct pci_dev *pdev)
4117{ 4064{
4118 struct skge_hw *hw = pci_get_drvdata(pdev); 4065 struct skge_hw *hw = pci_get_drvdata(pdev);
4119 int i, wol = 0; 4066 int i;
4120 4067
4121 if (!hw) 4068 if (!hw)
4122 return; 4069 return;
@@ -4127,15 +4074,10 @@ static void skge_shutdown(struct pci_dev *pdev)
4127 4074
4128 if (skge->wol) 4075 if (skge->wol)
4129 skge_wol_init(skge); 4076 skge_wol_init(skge);
4130 wol |= skge->wol;
4131 } 4077 }
4132 4078
4133 if (pci_enable_wake(pdev, PCI_D3cold, wol)) 4079 pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
4134 pci_enable_wake(pdev, PCI_D3hot, wol);
4135
4136 pci_disable_device(pdev);
4137 pci_set_power_state(pdev, PCI_D3hot); 4080 pci_set_power_state(pdev, PCI_D3hot);
4138
4139} 4081}
4140 4082
4141static struct pci_driver skge_driver = { 4083static struct pci_driver skge_driver = {
@@ -4143,11 +4085,8 @@ static struct pci_driver skge_driver = {
4143 .id_table = skge_id_table, 4085 .id_table = skge_id_table,
4144 .probe = skge_probe, 4086 .probe = skge_probe,
4145 .remove = __devexit_p(skge_remove), 4087 .remove = __devexit_p(skge_remove),
4146#ifdef CONFIG_PM
4147 .suspend = skge_suspend,
4148 .resume = skge_resume,
4149#endif
4150 .shutdown = skge_shutdown, 4088 .shutdown = skge_shutdown,
4089 .driver.pm = SKGE_PM_OPS,
4151}; 4090};
4152 4091
4153static struct dmi_system_id skge_32bit_dma_boards[] = { 4092static struct dmi_system_id skge_32bit_dma_boards[] = {