aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.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/sky2.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/sky2.c')
-rw-r--r--drivers/net/sky2.c448
1 files changed, 216 insertions, 232 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 194e5cf8c763..3ee41da130c2 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -46,10 +46,6 @@
46 46
47#include <asm/irq.h> 47#include <asm/irq.h>
48 48
49#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
50#define SKY2_VLAN_TAG_USED 1
51#endif
52
53#include "sky2.h" 49#include "sky2.h"
54 50
55#define DRV_NAME "sky2" 51#define DRV_NAME "sky2"
@@ -936,7 +932,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
936 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); 932 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
937 sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 933 sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
938 934
939 /* On chips without ram buffer, pause is controled by MAC level */ 935 /* On chips without ram buffer, pause is controlled by MAC level */
940 if (!(hw->flags & SKY2_HW_RAM_BUFFER)) { 936 if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
941 /* Pause threshold is scaled by 8 in bytes */ 937 /* Pause threshold is scaled by 8 in bytes */
942 if (hw->chip_id == CHIP_ID_YUKON_FE_P && 938 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
@@ -1202,12 +1198,12 @@ static void rx_set_checksum(struct sky2_port *sky2)
1202 1198
1203 sky2_write32(sky2->hw, 1199 sky2_write32(sky2->hw,
1204 Q_ADDR(rxqaddr[sky2->port], Q_CSR), 1200 Q_ADDR(rxqaddr[sky2->port], Q_CSR),
1205 (sky2->flags & SKY2_FLAG_RX_CHECKSUM) 1201 (sky2->netdev->features & NETIF_F_RXCSUM)
1206 ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 1202 ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
1207} 1203}
1208 1204
1209/* Enable/disable receive hash calculation (RSS) */ 1205/* Enable/disable receive hash calculation (RSS) */
1210static void rx_set_rss(struct net_device *dev) 1206static void rx_set_rss(struct net_device *dev, u32 features)
1211{ 1207{
1212 struct sky2_port *sky2 = netdev_priv(dev); 1208 struct sky2_port *sky2 = netdev_priv(dev);
1213 struct sky2_hw *hw = sky2->hw; 1209 struct sky2_hw *hw = sky2->hw;
@@ -1220,7 +1216,7 @@ static void rx_set_rss(struct net_device *dev)
1220 } 1216 }
1221 1217
1222 /* Program RSS initial values */ 1218 /* Program RSS initial values */
1223 if (dev->features & NETIF_F_RXHASH) { 1219 if (features & NETIF_F_RXHASH) {
1224 u32 key[nkeys]; 1220 u32 key[nkeys];
1225 1221
1226 get_random_bytes(key, nkeys * sizeof(u32)); 1222 get_random_bytes(key, nkeys * sizeof(u32));
@@ -1326,39 +1322,34 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1326 return err; 1322 return err;
1327} 1323}
1328 1324
1329#ifdef SKY2_VLAN_TAG_USED 1325#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO)
1330static void sky2_set_vlan_mode(struct sky2_hw *hw, u16 port, bool onoff) 1326
1327static void sky2_vlan_mode(struct net_device *dev, u32 features)
1331{ 1328{
1332 if (onoff) { 1329 struct sky2_port *sky2 = netdev_priv(dev);
1330 struct sky2_hw *hw = sky2->hw;
1331 u16 port = sky2->port;
1332
1333 if (features & NETIF_F_HW_VLAN_RX)
1333 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), 1334 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
1334 RX_VLAN_STRIP_ON); 1335 RX_VLAN_STRIP_ON);
1336 else
1337 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
1338 RX_VLAN_STRIP_OFF);
1339
1340 if (features & NETIF_F_HW_VLAN_TX) {
1335 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 1341 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1336 TX_VLAN_TAG_ON); 1342 TX_VLAN_TAG_ON);
1343
1344 dev->vlan_features |= SKY2_VLAN_OFFLOADS;
1337 } else { 1345 } else {
1338 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
1339 RX_VLAN_STRIP_OFF);
1340 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 1346 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1341 TX_VLAN_TAG_OFF); 1347 TX_VLAN_TAG_OFF);
1342 }
1343}
1344
1345static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
1346{
1347 struct sky2_port *sky2 = netdev_priv(dev);
1348 struct sky2_hw *hw = sky2->hw;
1349 u16 port = sky2->port;
1350
1351 netif_tx_lock_bh(dev);
1352 napi_disable(&hw->napi);
1353 1348
1354 sky2->vlgrp = grp; 1349 /* Can't do transmit offload of vlan without hw vlan */
1355 sky2_set_vlan_mode(hw, port, grp != NULL); 1350 dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
1356 1351 }
1357 sky2_read32(hw, B0_Y2_SP_LISR);
1358 napi_enable(&hw->napi);
1359 netif_tx_unlock_bh(dev);
1360} 1352}
1361#endif
1362 1353
1363/* Amount of required worst case padding in rx buffer */ 1354/* Amount of required worst case padding in rx buffer */
1364static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) 1355static inline unsigned sky2_rx_pad(const struct sky2_hw *hw)
@@ -1472,7 +1463,7 @@ static void sky2_rx_start(struct sky2_port *sky2)
1472 rx_set_checksum(sky2); 1463 rx_set_checksum(sky2);
1473 1464
1474 if (!(hw->flags & SKY2_HW_RSS_BROKEN)) 1465 if (!(hw->flags & SKY2_HW_RSS_BROKEN))
1475 rx_set_rss(sky2->netdev); 1466 rx_set_rss(sky2->netdev, sky2->netdev->features);
1476 1467
1477 /* submit Rx ring */ 1468 /* submit Rx ring */
1478 for (i = 0; i < sky2->rx_pending; i++) { 1469 for (i = 0; i < sky2->rx_pending; i++) {
@@ -1635,9 +1626,8 @@ static void sky2_hw_up(struct sky2_port *sky2)
1635 sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, 1626 sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
1636 sky2->tx_ring_size - 1); 1627 sky2->tx_ring_size - 1);
1637 1628
1638#ifdef SKY2_VLAN_TAG_USED 1629 sky2_vlan_mode(sky2->netdev, sky2->netdev->features);
1639 sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); 1630 netdev_update_features(sky2->netdev);
1640#endif
1641 1631
1642 sky2_rx_start(sky2); 1632 sky2_rx_start(sky2);
1643} 1633}
@@ -1780,9 +1770,9 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
1780 } 1770 }
1781 1771
1782 ctrl = 0; 1772 ctrl = 0;
1783#ifdef SKY2_VLAN_TAG_USED 1773
1784 /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ 1774 /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
1785 if (sky2->vlgrp && vlan_tx_tag_present(skb)) { 1775 if (vlan_tx_tag_present(skb)) {
1786 if (!le) { 1776 if (!le) {
1787 le = get_tx_le(sky2, &slot); 1777 le = get_tx_le(sky2, &slot);
1788 le->addr = 0; 1778 le->addr = 0;
@@ -1792,7 +1782,6 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
1792 le->length = cpu_to_be16(vlan_tx_tag_get(skb)); 1782 le->length = cpu_to_be16(vlan_tx_tag_get(skb));
1793 ctrl |= INS_VLAN; 1783 ctrl |= INS_VLAN;
1794 } 1784 }
1795#endif
1796 1785
1797 /* Handle TCP checksum offload */ 1786 /* Handle TCP checksum offload */
1798 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1787 if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -1917,8 +1906,10 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1917 netif_printk(sky2, tx_done, KERN_DEBUG, dev, 1906 netif_printk(sky2, tx_done, KERN_DEBUG, dev,
1918 "tx done %u\n", idx); 1907 "tx done %u\n", idx);
1919 1908
1920 dev->stats.tx_packets++; 1909 u64_stats_update_begin(&sky2->tx_stats.syncp);
1921 dev->stats.tx_bytes += skb->len; 1910 ++sky2->tx_stats.packets;
1911 sky2->tx_stats.bytes += skb->len;
1912 u64_stats_update_end(&sky2->tx_stats.syncp);
1922 1913
1923 re->skb = NULL; 1914 re->skb = NULL;
1924 dev_kfree_skb_any(skb); 1915 dev_kfree_skb_any(skb);
@@ -2271,12 +2262,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
2271 hw->chip_id == CHIP_ID_YUKON_FE_P)) 2262 hw->chip_id == CHIP_ID_YUKON_FE_P))
2272 return -EINVAL; 2263 return -EINVAL;
2273 2264
2274 /* TSO, etc on Yukon Ultra and MTU > 1500 not supported */
2275 if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
2276 dev->features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
2277
2278 if (!netif_running(dev)) { 2265 if (!netif_running(dev)) {
2279 dev->mtu = new_mtu; 2266 dev->mtu = new_mtu;
2267 netdev_update_features(dev);
2280 return 0; 2268 return 0;
2281 } 2269 }
2282 2270
@@ -2298,6 +2286,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
2298 sky2_rx_clean(sky2); 2286 sky2_rx_clean(sky2);
2299 2287
2300 dev->mtu = new_mtu; 2288 dev->mtu = new_mtu;
2289 netdev_update_features(dev);
2301 2290
2302 mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | 2291 mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
2303 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); 2292 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
@@ -2430,11 +2419,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2430 struct sk_buff *skb = NULL; 2419 struct sk_buff *skb = NULL;
2431 u16 count = (status & GMR_FS_LEN) >> 16; 2420 u16 count = (status & GMR_FS_LEN) >> 16;
2432 2421
2433#ifdef SKY2_VLAN_TAG_USED 2422 if (status & GMR_FS_VLAN)
2434 /* Account for vlan tag */ 2423 count -= VLAN_HLEN; /* Account for vlan tag */
2435 if (sky2->vlgrp && (status & GMR_FS_VLAN))
2436 count -= VLAN_HLEN;
2437#endif
2438 2424
2439 netif_printk(sky2, rx_status, KERN_DEBUG, dev, 2425 netif_printk(sky2, rx_status, KERN_DEBUG, dev,
2440 "rx slot %u status 0x%x len %d\n", 2426 "rx slot %u status 0x%x len %d\n",
@@ -2460,7 +2446,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2460 2446
2461 /* if length reported by DMA does not match PHY, packet was truncated */ 2447 /* if length reported by DMA does not match PHY, packet was truncated */
2462 if (length != count) 2448 if (length != count)
2463 goto len_error; 2449 goto error;
2464 2450
2465okay: 2451okay:
2466 if (length < copybreak) 2452 if (length < copybreak)
@@ -2475,34 +2461,13 @@ resubmit:
2475 2461
2476 return skb; 2462 return skb;
2477 2463
2478len_error:
2479 /* Truncation of overlength packets
2480 causes PHY length to not match MAC length */
2481 ++dev->stats.rx_length_errors;
2482 if (net_ratelimit())
2483 netif_info(sky2, rx_err, dev,
2484 "rx length error: status %#x length %d\n",
2485 status, length);
2486 goto resubmit;
2487
2488error: 2464error:
2489 ++dev->stats.rx_errors; 2465 ++dev->stats.rx_errors;
2490 if (status & GMR_FS_RX_FF_OV) {
2491 dev->stats.rx_over_errors++;
2492 goto resubmit;
2493 }
2494 2466
2495 if (net_ratelimit()) 2467 if (net_ratelimit())
2496 netif_info(sky2, rx_err, dev, 2468 netif_info(sky2, rx_err, dev,
2497 "rx error, status 0x%x length %d\n", status, length); 2469 "rx error, status 0x%x length %d\n", status, length);
2498 2470
2499 if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
2500 dev->stats.rx_length_errors++;
2501 if (status & GMR_FS_FRAGMENT)
2502 dev->stats.rx_frame_errors++;
2503 if (status & GMR_FS_CRC_ERR)
2504 dev->stats.rx_crc_errors++;
2505
2506 goto resubmit; 2471 goto resubmit;
2507} 2472}
2508 2473
@@ -2523,17 +2488,9 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
2523static inline void sky2_skb_rx(const struct sky2_port *sky2, 2488static inline void sky2_skb_rx(const struct sky2_port *sky2,
2524 u32 status, struct sk_buff *skb) 2489 u32 status, struct sk_buff *skb)
2525{ 2490{
2526#ifdef SKY2_VLAN_TAG_USED 2491 if (status & GMR_FS_VLAN)
2527 u16 vlan_tag = be16_to_cpu(sky2->rx_tag); 2492 __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
2528 if (sky2->vlgrp && (status & GMR_FS_VLAN)) { 2493
2529 if (skb->ip_summed == CHECKSUM_NONE)
2530 vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag);
2531 else
2532 vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp,
2533 vlan_tag, skb);
2534 return;
2535 }
2536#endif
2537 if (skb->ip_summed == CHECKSUM_NONE) 2494 if (skb->ip_summed == CHECKSUM_NONE)
2538 netif_receive_skb(skb); 2495 netif_receive_skb(skb);
2539 else 2496 else
@@ -2543,14 +2500,19 @@ static inline void sky2_skb_rx(const struct sky2_port *sky2,
2543static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port, 2500static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port,
2544 unsigned packets, unsigned bytes) 2501 unsigned packets, unsigned bytes)
2545{ 2502{
2546 if (packets) { 2503 struct net_device *dev = hw->dev[port];
2547 struct net_device *dev = hw->dev[port]; 2504 struct sky2_port *sky2 = netdev_priv(dev);
2548 2505
2549 dev->stats.rx_packets += packets; 2506 if (packets == 0)
2550 dev->stats.rx_bytes += bytes; 2507 return;
2551 dev->last_rx = jiffies; 2508
2552 sky2_rx_update(netdev_priv(dev), rxqaddr[port]); 2509 u64_stats_update_begin(&sky2->rx_stats.syncp);
2553 } 2510 sky2->rx_stats.packets += packets;
2511 sky2->rx_stats.bytes += bytes;
2512 u64_stats_update_end(&sky2->rx_stats.syncp);
2513
2514 dev->last_rx = jiffies;
2515 sky2_rx_update(netdev_priv(dev), rxqaddr[port]);
2554} 2516}
2555 2517
2556static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) 2518static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
@@ -2572,8 +2534,11 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
2572 "%s: receive checksum problem (status = %#x)\n", 2534 "%s: receive checksum problem (status = %#x)\n",
2573 sky2->netdev->name, status); 2535 sky2->netdev->name, status);
2574 2536
2575 /* Disable checksum offload */ 2537 /* Disable checksum offload
2576 sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM; 2538 * It will be reenabled on next ndo_set_features, but if it's
2539 * really broken, will get disabled again
2540 */
2541 sky2->netdev->features &= ~NETIF_F_RXCSUM;
2577 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), 2542 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
2578 BMU_DIS_RX_CHKSUM); 2543 BMU_DIS_RX_CHKSUM);
2579 } 2544 }
@@ -2628,7 +2593,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2628 2593
2629 /* This chip reports checksum status differently */ 2594 /* This chip reports checksum status differently */
2630 if (hw->flags & SKY2_HW_NEW_LE) { 2595 if (hw->flags & SKY2_HW_NEW_LE) {
2631 if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) && 2596 if ((dev->features & NETIF_F_RXCSUM) &&
2632 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && 2597 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
2633 (le->css & CSS_TCPUDPCSOK)) 2598 (le->css & CSS_TCPUDPCSOK))
2634 skb->ip_summed = CHECKSUM_UNNECESSARY; 2599 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2645,7 +2610,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2645 goto exit_loop; 2610 goto exit_loop;
2646 break; 2611 break;
2647 2612
2648#ifdef SKY2_VLAN_TAG_USED
2649 case OP_RXVLAN: 2613 case OP_RXVLAN:
2650 sky2->rx_tag = length; 2614 sky2->rx_tag = length;
2651 break; 2615 break;
@@ -2653,9 +2617,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
2653 case OP_RXCHKSVLAN: 2617 case OP_RXCHKSVLAN:
2654 sky2->rx_tag = length; 2618 sky2->rx_tag = length;
2655 /* fall through */ 2619 /* fall through */
2656#endif
2657 case OP_RXCHKS: 2620 case OP_RXCHKS:
2658 if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM)) 2621 if (likely(dev->features & NETIF_F_RXCSUM))
2659 sky2_rx_checksum(sky2, status); 2622 sky2_rx_checksum(sky2, status);
2660 break; 2623 break;
2661 2624
@@ -3056,6 +3019,10 @@ static int __devinit sky2_init(struct sky2_hw *hw)
3056 | SKY2_HW_NEW_LE 3019 | SKY2_HW_NEW_LE
3057 | SKY2_HW_AUTO_TX_SUM 3020 | SKY2_HW_AUTO_TX_SUM
3058 | SKY2_HW_ADV_POWER_CTL; 3021 | SKY2_HW_ADV_POWER_CTL;
3022
3023 /* The workaround for status conflicts VLAN tag detection. */
3024 if (hw->chip_rev == CHIP_REV_YU_FE2_A0)
3025 hw->flags |= SKY2_HW_VLAN_BROKEN;
3059 break; 3026 break;
3060 3027
3061 case CHIP_ID_YUKON_SUPR: 3028 case CHIP_ID_YUKON_SUPR:
@@ -3290,7 +3257,7 @@ static void sky2_reset(struct sky2_hw *hw)
3290 3257
3291/* Take device down (offline). 3258/* Take device down (offline).
3292 * Equivalent to doing dev_stop() but this does not 3259 * Equivalent to doing dev_stop() but this does not
3293 * inform upper layers of the transistion. 3260 * inform upper layers of the transition.
3294 */ 3261 */
3295static void sky2_detach(struct net_device *dev) 3262static void sky2_detach(struct net_device *dev)
3296{ 3263{
@@ -3398,12 +3365,24 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3398{ 3365{
3399 struct sky2_port *sky2 = netdev_priv(dev); 3366 struct sky2_port *sky2 = netdev_priv(dev);
3400 struct sky2_hw *hw = sky2->hw; 3367 struct sky2_hw *hw = sky2->hw;
3368 bool enable_wakeup = false;
3369 int i;
3401 3370
3402 if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) || 3371 if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
3403 !device_can_wakeup(&hw->pdev->dev)) 3372 !device_can_wakeup(&hw->pdev->dev))
3404 return -EOPNOTSUPP; 3373 return -EOPNOTSUPP;
3405 3374
3406 sky2->wol = wol->wolopts; 3375 sky2->wol = wol->wolopts;
3376
3377 for (i = 0; i < hw->ports; i++) {
3378 struct net_device *dev = hw->dev[i];
3379 struct sky2_port *sky2 = netdev_priv(dev);
3380
3381 if (sky2->wol)
3382 enable_wakeup = true;
3383 }
3384 device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
3385
3407 return 0; 3386 return 0;
3408} 3387}
3409 3388
@@ -3413,18 +3392,15 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
3413 u32 modes = SUPPORTED_10baseT_Half 3392 u32 modes = SUPPORTED_10baseT_Half
3414 | SUPPORTED_10baseT_Full 3393 | SUPPORTED_10baseT_Full
3415 | SUPPORTED_100baseT_Half 3394 | SUPPORTED_100baseT_Half
3416 | SUPPORTED_100baseT_Full 3395 | SUPPORTED_100baseT_Full;
3417 | SUPPORTED_Autoneg | SUPPORTED_TP;
3418 3396
3419 if (hw->flags & SKY2_HW_GIGABIT) 3397 if (hw->flags & SKY2_HW_GIGABIT)
3420 modes |= SUPPORTED_1000baseT_Half 3398 modes |= SUPPORTED_1000baseT_Half
3421 | SUPPORTED_1000baseT_Full; 3399 | SUPPORTED_1000baseT_Full;
3422 return modes; 3400 return modes;
3423 } else 3401 } else
3424 return SUPPORTED_1000baseT_Half 3402 return SUPPORTED_1000baseT_Half
3425 | SUPPORTED_1000baseT_Full 3403 | SUPPORTED_1000baseT_Full;
3426 | SUPPORTED_Autoneg
3427 | SUPPORTED_FIBRE;
3428} 3404}
3429 3405
3430static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 3406static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -3437,10 +3413,12 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
3437 ecmd->phy_address = PHY_ADDR_MARV; 3413 ecmd->phy_address = PHY_ADDR_MARV;
3438 if (sky2_is_copper(hw)) { 3414 if (sky2_is_copper(hw)) {
3439 ecmd->port = PORT_TP; 3415 ecmd->port = PORT_TP;
3440 ecmd->speed = sky2->speed; 3416 ethtool_cmd_speed_set(ecmd, sky2->speed);
3417 ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_TP;
3441 } else { 3418 } else {
3442 ecmd->speed = SPEED_1000; 3419 ethtool_cmd_speed_set(ecmd, SPEED_1000);
3443 ecmd->port = PORT_FIBRE; 3420 ecmd->port = PORT_FIBRE;
3421 ecmd->supported |= SUPPORTED_Autoneg | SUPPORTED_FIBRE;
3444 } 3422 }
3445 3423
3446 ecmd->advertising = sky2->advertising; 3424 ecmd->advertising = sky2->advertising;
@@ -3457,14 +3435,26 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
3457 u32 supported = sky2_supported_modes(hw); 3435 u32 supported = sky2_supported_modes(hw);
3458 3436
3459 if (ecmd->autoneg == AUTONEG_ENABLE) { 3437 if (ecmd->autoneg == AUTONEG_ENABLE) {
3438 if (ecmd->advertising & ~supported)
3439 return -EINVAL;
3440
3441 if (sky2_is_copper(hw))
3442 sky2->advertising = ecmd->advertising |
3443 ADVERTISED_TP |
3444 ADVERTISED_Autoneg;
3445 else
3446 sky2->advertising = ecmd->advertising |
3447 ADVERTISED_FIBRE |
3448 ADVERTISED_Autoneg;
3449
3460 sky2->flags |= SKY2_FLAG_AUTO_SPEED; 3450 sky2->flags |= SKY2_FLAG_AUTO_SPEED;
3461 ecmd->advertising = supported;
3462 sky2->duplex = -1; 3451 sky2->duplex = -1;
3463 sky2->speed = -1; 3452 sky2->speed = -1;
3464 } else { 3453 } else {
3465 u32 setting; 3454 u32 setting;
3455 u32 speed = ethtool_cmd_speed(ecmd);
3466 3456
3467 switch (ecmd->speed) { 3457 switch (speed) {
3468 case SPEED_1000: 3458 case SPEED_1000:
3469 if (ecmd->duplex == DUPLEX_FULL) 3459 if (ecmd->duplex == DUPLEX_FULL)
3470 setting = SUPPORTED_1000baseT_Full; 3460 setting = SUPPORTED_1000baseT_Full;
@@ -3497,13 +3487,11 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
3497 if ((setting & supported) == 0) 3487 if ((setting & supported) == 0)
3498 return -EINVAL; 3488 return -EINVAL;
3499 3489
3500 sky2->speed = ecmd->speed; 3490 sky2->speed = speed;
3501 sky2->duplex = ecmd->duplex; 3491 sky2->duplex = ecmd->duplex;
3502 sky2->flags &= ~SKY2_FLAG_AUTO_SPEED; 3492 sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
3503 } 3493 }
3504 3494
3505 sky2->advertising = ecmd->advertising;
3506
3507 if (netif_running(dev)) { 3495 if (netif_running(dev)) {
3508 sky2_phy_reinit(sky2); 3496 sky2_phy_reinit(sky2);
3509 sky2_set_multicast(dev); 3497 sky2_set_multicast(dev);
@@ -3567,28 +3555,6 @@ static const struct sky2_stat {
3567 { "tx_fifo_underrun", GM_TXE_FIFO_UR }, 3555 { "tx_fifo_underrun", GM_TXE_FIFO_UR },
3568}; 3556};
3569 3557
3570static u32 sky2_get_rx_csum(struct net_device *dev)
3571{
3572 struct sky2_port *sky2 = netdev_priv(dev);
3573
3574 return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM);
3575}
3576
3577static int sky2_set_rx_csum(struct net_device *dev, u32 data)
3578{
3579 struct sky2_port *sky2 = netdev_priv(dev);
3580
3581 if (data)
3582 sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
3583 else
3584 sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
3585
3586 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
3587 data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
3588
3589 return 0;
3590}
3591
3592static u32 sky2_get_msglevel(struct net_device *netdev) 3558static u32 sky2_get_msglevel(struct net_device *netdev)
3593{ 3559{
3594 struct sky2_port *sky2 = netdev_priv(netdev); 3560 struct sky2_port *sky2 = netdev_priv(netdev);
@@ -3614,13 +3580,11 @@ static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
3614 unsigned port = sky2->port; 3580 unsigned port = sky2->port;
3615 int i; 3581 int i;
3616 3582
3617 data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32 3583 data[0] = get_stats64(hw, port, GM_TXO_OK_LO);
3618 | (u64) gma_read32(hw, port, GM_TXO_OK_LO); 3584 data[1] = get_stats64(hw, port, GM_RXO_OK_LO);
3619 data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
3620 | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
3621 3585
3622 for (i = 2; i < count; i++) 3586 for (i = 2; i < count; i++)
3623 data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset); 3587 data[i] = get_stats32(hw, port, sky2_stats[i].offset);
3624} 3588}
3625 3589
3626static void sky2_set_msglevel(struct net_device *netdev, u32 value) 3590static void sky2_set_msglevel(struct net_device *netdev, u32 value)
@@ -3738,6 +3702,51 @@ static void sky2_set_multicast(struct net_device *dev)
3738 gma_write16(hw, port, GM_RX_CTRL, reg); 3702 gma_write16(hw, port, GM_RX_CTRL, reg);
3739} 3703}
3740 3704
3705static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev,
3706 struct rtnl_link_stats64 *stats)
3707{
3708 struct sky2_port *sky2 = netdev_priv(dev);
3709 struct sky2_hw *hw = sky2->hw;
3710 unsigned port = sky2->port;
3711 unsigned int start;
3712 u64 _bytes, _packets;
3713
3714 do {
3715 start = u64_stats_fetch_begin_bh(&sky2->rx_stats.syncp);
3716 _bytes = sky2->rx_stats.bytes;
3717 _packets = sky2->rx_stats.packets;
3718 } while (u64_stats_fetch_retry_bh(&sky2->rx_stats.syncp, start));
3719
3720 stats->rx_packets = _packets;
3721 stats->rx_bytes = _bytes;
3722
3723 do {
3724 start = u64_stats_fetch_begin_bh(&sky2->tx_stats.syncp);
3725 _bytes = sky2->tx_stats.bytes;
3726 _packets = sky2->tx_stats.packets;
3727 } while (u64_stats_fetch_retry_bh(&sky2->tx_stats.syncp, start));
3728
3729 stats->tx_packets = _packets;
3730 stats->tx_bytes = _bytes;
3731
3732 stats->multicast = get_stats32(hw, port, GM_RXF_MC_OK)
3733 + get_stats32(hw, port, GM_RXF_BC_OK);
3734
3735 stats->collisions = get_stats32(hw, port, GM_TXF_COL);
3736
3737 stats->rx_length_errors = get_stats32(hw, port, GM_RXF_LNG_ERR);
3738 stats->rx_crc_errors = get_stats32(hw, port, GM_RXF_FCS_ERR);
3739 stats->rx_frame_errors = get_stats32(hw, port, GM_RXF_SHT)
3740 + get_stats32(hw, port, GM_RXE_FRAG);
3741 stats->rx_over_errors = get_stats32(hw, port, GM_RXE_FIFO_OV);
3742
3743 stats->rx_dropped = dev->stats.rx_dropped;
3744 stats->rx_fifo_errors = dev->stats.rx_fifo_errors;
3745 stats->tx_fifo_errors = dev->stats.tx_fifo_errors;
3746
3747 return stats;
3748}
3749
3741/* Can have one global because blinking is controlled by 3750/* Can have one global because blinking is controlled by
3742 * ethtool and that is always under RTNL mutex 3751 * ethtool and that is always under RTNL mutex
3743 */ 3752 */
@@ -3798,23 +3807,24 @@ static void sky2_led(struct sky2_port *sky2, enum led_mode mode)
3798} 3807}
3799 3808
3800/* blink LED's for finding board */ 3809/* blink LED's for finding board */
3801static int sky2_phys_id(struct net_device *dev, u32 data) 3810static int sky2_set_phys_id(struct net_device *dev,
3811 enum ethtool_phys_id_state state)
3802{ 3812{
3803 struct sky2_port *sky2 = netdev_priv(dev); 3813 struct sky2_port *sky2 = netdev_priv(dev);
3804 unsigned int i;
3805 3814
3806 if (data == 0) 3815 switch (state) {
3807 data = UINT_MAX; 3816 case ETHTOOL_ID_ACTIVE:
3808 3817 return 1; /* cycle on/off once per second */
3809 for (i = 0; i < data; i++) { 3818 case ETHTOOL_ID_INACTIVE:
3819 sky2_led(sky2, MO_LED_NORM);
3820 break;
3821 case ETHTOOL_ID_ON:
3810 sky2_led(sky2, MO_LED_ON); 3822 sky2_led(sky2, MO_LED_ON);
3811 if (msleep_interruptible(500)) 3823 break;
3812 break; 3824 case ETHTOOL_ID_OFF:
3813 sky2_led(sky2, MO_LED_OFF); 3825 sky2_led(sky2, MO_LED_OFF);
3814 if (msleep_interruptible(500)) 3826 break;
3815 break;
3816 } 3827 }
3817 sky2_led(sky2, MO_LED_NORM);
3818 3828
3819 return 0; 3829 return 0;
3820} 3830}
@@ -4055,34 +4065,6 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
4055 } 4065 }
4056} 4066}
4057 4067
4058/* In order to do Jumbo packets on these chips, need to turn off the
4059 * transmit store/forward. Therefore checksum offload won't work.
4060 */
4061static int no_tx_offload(struct net_device *dev)
4062{
4063 const struct sky2_port *sky2 = netdev_priv(dev);
4064 const struct sky2_hw *hw = sky2->hw;
4065
4066 return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
4067}
4068
4069static int sky2_set_tx_csum(struct net_device *dev, u32 data)
4070{
4071 if (data && no_tx_offload(dev))
4072 return -EINVAL;
4073
4074 return ethtool_op_set_tx_csum(dev, data);
4075}
4076
4077
4078static int sky2_set_tso(struct net_device *dev, u32 data)
4079{
4080 if (data && no_tx_offload(dev))
4081 return -EINVAL;
4082
4083 return ethtool_op_set_tso(dev, data);
4084}
4085
4086static int sky2_get_eeprom_len(struct net_device *dev) 4068static int sky2_get_eeprom_len(struct net_device *dev)
4087{ 4069{
4088 struct sky2_port *sky2 = netdev_priv(dev); 4070 struct sky2_port *sky2 = netdev_priv(dev);
@@ -4185,18 +4167,36 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom
4185 return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); 4167 return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
4186} 4168}
4187 4169
4188static int sky2_set_flags(struct net_device *dev, u32 data) 4170static u32 sky2_fix_features(struct net_device *dev, u32 features)
4171{
4172 const struct sky2_port *sky2 = netdev_priv(dev);
4173 const struct sky2_hw *hw = sky2->hw;
4174
4175 /* In order to do Jumbo packets on these chips, need to turn off the
4176 * transmit store/forward. Therefore checksum offload won't work.
4177 */
4178 if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
4179 features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
4180
4181 return features;
4182}
4183
4184static int sky2_set_features(struct net_device *dev, u32 features)
4189{ 4185{
4190 struct sky2_port *sky2 = netdev_priv(dev); 4186 struct sky2_port *sky2 = netdev_priv(dev);
4191 u32 supported = 4187 u32 changed = dev->features ^ features;
4192 (sky2->hw->flags & SKY2_HW_RSS_BROKEN) ? 0 : ETH_FLAG_RXHASH;
4193 int rc;
4194 4188
4195 rc = ethtool_op_set_flags(dev, data, supported); 4189 if (changed & NETIF_F_RXCSUM) {
4196 if (rc) 4190 u32 on = features & NETIF_F_RXCSUM;
4197 return rc; 4191 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
4192 on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
4193 }
4194
4195 if (changed & NETIF_F_RXHASH)
4196 rx_set_rss(dev, features);
4198 4197
4199 rx_set_rss(dev); 4198 if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
4199 sky2_vlan_mode(dev, features);
4200 4200
4201 return 0; 4201 return 0;
4202} 4202}
@@ -4216,11 +4216,6 @@ static const struct ethtool_ops sky2_ethtool_ops = {
4216 .get_eeprom_len = sky2_get_eeprom_len, 4216 .get_eeprom_len = sky2_get_eeprom_len,
4217 .get_eeprom = sky2_get_eeprom, 4217 .get_eeprom = sky2_get_eeprom,
4218 .set_eeprom = sky2_set_eeprom, 4218 .set_eeprom = sky2_set_eeprom,
4219 .set_sg = ethtool_op_set_sg,
4220 .set_tx_csum = sky2_set_tx_csum,
4221 .set_tso = sky2_set_tso,
4222 .get_rx_csum = sky2_get_rx_csum,
4223 .set_rx_csum = sky2_set_rx_csum,
4224 .get_strings = sky2_get_strings, 4219 .get_strings = sky2_get_strings,
4225 .get_coalesce = sky2_get_coalesce, 4220 .get_coalesce = sky2_get_coalesce,
4226 .set_coalesce = sky2_set_coalesce, 4221 .set_coalesce = sky2_set_coalesce,
@@ -4228,10 +4223,9 @@ static const struct ethtool_ops sky2_ethtool_ops = {
4228 .set_ringparam = sky2_set_ringparam, 4223 .set_ringparam = sky2_set_ringparam,
4229 .get_pauseparam = sky2_get_pauseparam, 4224 .get_pauseparam = sky2_get_pauseparam,
4230 .set_pauseparam = sky2_set_pauseparam, 4225 .set_pauseparam = sky2_set_pauseparam,
4231 .phys_id = sky2_phys_id, 4226 .set_phys_id = sky2_set_phys_id,
4232 .get_sset_count = sky2_get_sset_count, 4227 .get_sset_count = sky2_get_sset_count,
4233 .get_ethtool_stats = sky2_get_ethtool_stats, 4228 .get_ethtool_stats = sky2_get_ethtool_stats,
4234 .set_flags = sky2_set_flags,
4235}; 4229};
4236 4230
4237#ifdef CONFIG_SKY2_DEBUG 4231#ifdef CONFIG_SKY2_DEBUG
@@ -4511,10 +4505,10 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
4511 .ndo_set_mac_address = sky2_set_mac_address, 4505 .ndo_set_mac_address = sky2_set_mac_address,
4512 .ndo_set_multicast_list = sky2_set_multicast, 4506 .ndo_set_multicast_list = sky2_set_multicast,
4513 .ndo_change_mtu = sky2_change_mtu, 4507 .ndo_change_mtu = sky2_change_mtu,
4508 .ndo_fix_features = sky2_fix_features,
4509 .ndo_set_features = sky2_set_features,
4514 .ndo_tx_timeout = sky2_tx_timeout, 4510 .ndo_tx_timeout = sky2_tx_timeout,
4515#ifdef SKY2_VLAN_TAG_USED 4511 .ndo_get_stats64 = sky2_get_stats,
4516 .ndo_vlan_rx_register = sky2_vlan_rx_register,
4517#endif
4518#ifdef CONFIG_NET_POLL_CONTROLLER 4512#ifdef CONFIG_NET_POLL_CONTROLLER
4519 .ndo_poll_controller = sky2_netpoll, 4513 .ndo_poll_controller = sky2_netpoll,
4520#endif 4514#endif
@@ -4528,10 +4522,10 @@ static const struct net_device_ops sky2_netdev_ops[2] = {
4528 .ndo_set_mac_address = sky2_set_mac_address, 4522 .ndo_set_mac_address = sky2_set_mac_address,
4529 .ndo_set_multicast_list = sky2_set_multicast, 4523 .ndo_set_multicast_list = sky2_set_multicast,
4530 .ndo_change_mtu = sky2_change_mtu, 4524 .ndo_change_mtu = sky2_change_mtu,
4525 .ndo_fix_features = sky2_fix_features,
4526 .ndo_set_features = sky2_set_features,
4531 .ndo_tx_timeout = sky2_tx_timeout, 4527 .ndo_tx_timeout = sky2_tx_timeout,
4532#ifdef SKY2_VLAN_TAG_USED 4528 .ndo_get_stats64 = sky2_get_stats,
4533 .ndo_vlan_rx_register = sky2_vlan_rx_register,
4534#endif
4535 }, 4529 },
4536}; 4530};
4537 4531
@@ -4562,7 +4556,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
4562 /* Auto speed and flow control */ 4556 /* Auto speed and flow control */
4563 sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE; 4557 sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
4564 if (hw->chip_id != CHIP_ID_YUKON_XL) 4558 if (hw->chip_id != CHIP_ID_YUKON_XL)
4565 sky2->flags |= SKY2_FLAG_RX_CHECKSUM; 4559 dev->hw_features |= NETIF_F_RXCSUM;
4566 4560
4567 sky2->flow_mode = FC_BOTH; 4561 sky2->flow_mode = FC_BOTH;
4568 4562
@@ -4581,21 +4575,21 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
4581 4575
4582 sky2->port = port; 4576 sky2->port = port;
4583 4577
4584 dev->features |= NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_SG; 4578 dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
4579
4585 if (highmem) 4580 if (highmem)
4586 dev->features |= NETIF_F_HIGHDMA; 4581 dev->features |= NETIF_F_HIGHDMA;
4587 4582
4588 /* Enable receive hashing unless hardware is known broken */ 4583 /* Enable receive hashing unless hardware is known broken */
4589 if (!(hw->flags & SKY2_HW_RSS_BROKEN)) 4584 if (!(hw->flags & SKY2_HW_RSS_BROKEN))
4590 dev->features |= NETIF_F_RXHASH; 4585 dev->hw_features |= NETIF_F_RXHASH;
4591 4586
4592#ifdef SKY2_VLAN_TAG_USED 4587 if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) {
4593 /* The workaround for FE+ status conflicts with VLAN tag detection. */ 4588 dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
4594 if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && 4589 dev->vlan_features |= SKY2_VLAN_OFFLOADS;
4595 sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
4596 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
4597 } 4590 }
4598#endif 4591
4592 dev->features |= dev->hw_features;
4599 4593
4600 /* read the mac address */ 4594 /* read the mac address */
4601 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN); 4595 memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
@@ -4919,10 +4913,11 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
4919 pci_set_drvdata(pdev, NULL); 4913 pci_set_drvdata(pdev, NULL);
4920} 4914}
4921 4915
4922static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) 4916static int sky2_suspend(struct device *dev)
4923{ 4917{
4918 struct pci_dev *pdev = to_pci_dev(dev);
4924 struct sky2_hw *hw = pci_get_drvdata(pdev); 4919 struct sky2_hw *hw = pci_get_drvdata(pdev);
4925 int i, wol = 0; 4920 int i;
4926 4921
4927 if (!hw) 4922 if (!hw)
4928 return 0; 4923 return 0;
@@ -4939,41 +4934,24 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
4939 4934
4940 if (sky2->wol) 4935 if (sky2->wol)
4941 sky2_wol_init(sky2); 4936 sky2_wol_init(sky2);
4942
4943 wol |= sky2->wol;
4944 } 4937 }
4945 4938
4946 device_set_wakeup_enable(&pdev->dev, wol != 0);
4947
4948 sky2_power_aux(hw); 4939 sky2_power_aux(hw);
4949 rtnl_unlock(); 4940 rtnl_unlock();
4950 4941
4951 pci_save_state(pdev);
4952 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
4953 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4954
4955 return 0; 4942 return 0;
4956} 4943}
4957 4944
4958#ifdef CONFIG_PM 4945#ifdef CONFIG_PM_SLEEP
4959static int sky2_resume(struct pci_dev *pdev) 4946static int sky2_resume(struct device *dev)
4960{ 4947{
4948 struct pci_dev *pdev = to_pci_dev(dev);
4961 struct sky2_hw *hw = pci_get_drvdata(pdev); 4949 struct sky2_hw *hw = pci_get_drvdata(pdev);
4962 int err; 4950 int err;
4963 4951
4964 if (!hw) 4952 if (!hw)
4965 return 0; 4953 return 0;
4966 4954
4967 err = pci_set_power_state(pdev, PCI_D0);
4968 if (err)
4969 goto out;
4970
4971 err = pci_restore_state(pdev);
4972 if (err)
4973 goto out;
4974
4975 pci_enable_wake(pdev, PCI_D0, 0);
4976
4977 /* Re-enable all clocks */ 4955 /* Re-enable all clocks */
4978 err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0); 4956 err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
4979 if (err) { 4957 if (err) {
@@ -4993,11 +4971,20 @@ out:
4993 pci_disable_device(pdev); 4971 pci_disable_device(pdev);
4994 return err; 4972 return err;
4995} 4973}
4974
4975static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
4976#define SKY2_PM_OPS (&sky2_pm_ops)
4977
4978#else
4979
4980#define SKY2_PM_OPS NULL
4996#endif 4981#endif
4997 4982
4998static void sky2_shutdown(struct pci_dev *pdev) 4983static void sky2_shutdown(struct pci_dev *pdev)
4999{ 4984{
5000 sky2_suspend(pdev, PMSG_SUSPEND); 4985 sky2_suspend(&pdev->dev);
4986 pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
4987 pci_set_power_state(pdev, PCI_D3hot);
5001} 4988}
5002 4989
5003static struct pci_driver sky2_driver = { 4990static struct pci_driver sky2_driver = {
@@ -5005,11 +4992,8 @@ static struct pci_driver sky2_driver = {
5005 .id_table = sky2_id_table, 4992 .id_table = sky2_id_table,
5006 .probe = sky2_probe, 4993 .probe = sky2_probe,
5007 .remove = __devexit_p(sky2_remove), 4994 .remove = __devexit_p(sky2_remove),
5008#ifdef CONFIG_PM
5009 .suspend = sky2_suspend,
5010 .resume = sky2_resume,
5011#endif
5012 .shutdown = sky2_shutdown, 4995 .shutdown = sky2_shutdown,
4996 .driver.pm = SKY2_PM_OPS,
5013}; 4997};
5014 4998
5015static int __init sky2_init_module(void) 4999static int __init sky2_init_module(void)