ipw2200: convert to net_device_ops
[safe/jmp/linux-2.6] / drivers / net / wireless / ipw2x00 / ipw2200.c
index 48fa6df..b344994 100644 (file)
@@ -301,88 +301,102 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
 }
 
 /* 8-bit direct write (low 4K) */
-#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
+               u8 val)
+{
+       writeb(val, ipw->hw_base + ofs);
+}
 
 /* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
 #define ipw_write8(ipw, ofs, val) do { \
- IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write8(ipw, ofs, val); \
- } while (0)
+       IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
+                       __LINE__, (u32)(ofs), (u32)(val)); \
+       _ipw_write8(ipw, ofs, val); \
+} while (0)
 
 /* 16-bit direct write (low 4K) */
-#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
+               u16 val)
+{
+       writew(val, ipw->hw_base + ofs);
+}
 
 /* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write16(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write16(ipw, ofs, val)
+#define ipw_write16(ipw, ofs, val) do { \
+       IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
+                       __LINE__, (u32)(ofs), (u32)(val)); \
+       _ipw_write16(ipw, ofs, val); \
+} while (0)
 
 /* 32-bit direct write (low 4K) */
-#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
+               u32 val)
+{
+       writel(val, ipw->hw_base + ofs);
+}
 
 /* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write32(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write32(ipw, ofs, val)
+#define ipw_write32(ipw, ofs, val) do { \
+       IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
+                       __LINE__, (u32)(ofs), (u32)(val)); \
+       _ipw_write32(ipw, ofs, val); \
+} while (0)
 
 /* 8-bit direct read (low 4K) */
-#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
-
-/* 8-bit direct read (low 4K), with debug wrapper */
-static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
 {
-       IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
-       return _ipw_read8(ipw, ofs);
+       return readb(ipw->hw_base + ofs);
 }
 
 /* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read8(ipw, ofs) ({ \
+       IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
+                       (u32)(ofs)); \
+       _ipw_read8(ipw, ofs); \
+})
 
 /* 16-bit direct read (low 4K) */
-#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
-
-/* 16-bit direct read (low 4K), with debug wrapper */
-static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
 {
-       IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
-       return _ipw_read16(ipw, ofs);
+       return readw(ipw->hw_base + ofs);
 }
 
 /* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read16(ipw, ofs) ({ \
+       IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
+                       (u32)(ofs)); \
+       _ipw_read16(ipw, ofs); \
+})
 
 /* 32-bit direct read (low 4K) */
-#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
-
-/* 32-bit direct read (low 4K), with debug wrapper */
-static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
 {
-       IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
-       return _ipw_read32(ipw, ofs);
+       return readl(ipw->hw_base + ofs);
 }
 
 /* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read32(ipw, ofs) ({ \
+       IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
+                       (u32)(ofs)); \
+       _ipw_read32(ipw, ofs); \
+})
 
-/* multi-byte read (above 4K), with debug wrapper */
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-static inline void __ipw_read_indirect(const char *f, int l,
-                                      struct ipw_priv *a, u32 b, u8 * c, int d)
-{
-       IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
-                    d);
-       _ipw_read_indirect(a, b, c, d);
-}
-
 /* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
-#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
+#define ipw_read_indirect(a, b, c, d) ({ \
+       IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
+                       __LINE__, (u32)(b), (u32)(d)); \
+       _ipw_read_indirect(a, b, c, d); \
+})
 
 /* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
                                int num);
-#define ipw_write_indirect(a, b, c, d) \
-       IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
-       _ipw_write_indirect(a, b, c, d)
+#define ipw_write_indirect(a, b, c, d) do { \
+       IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
+                       __LINE__, (u32)(b), (u32)(d)); \
+       _ipw_write_indirect(a, b, c, d); \
+} while (0)
 
 /* 32-bit indirect write (above 4K) */
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
@@ -3895,6 +3909,7 @@ static int ipw_disassociate(void *data)
        if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
                return 0;
        ipw_send_disassociate(data, 0);
+       netif_carrier_off(priv->net_dev);
        return 1;
 }
 
@@ -4344,7 +4359,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv,
                return;
        }
 
-       if (priv->status & STATUS_SCANNING) {
+       if (priv->status & STATUS_SCANNING &&
+           missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
                /* Stop scan to keep fw from getting
                 * stuck (only if we aren't roaming --
                 * otherwise we'll never scan more than 2 or 3
@@ -6270,6 +6286,20 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
        }
 }
 
+static int ipw_passive_dwell_time(struct ipw_priv *priv)
+{
+       /* staying on passive channels longer than the DTIM interval during a
+        * scan, while associated, causes the firmware to cancel the scan
+        * without notification. Hence, don't stay on passive channels longer
+        * than the beacon interval.
+        */
+       if (priv->status & STATUS_ASSOCIATED
+           && priv->assoc_network->beacon_interval > 10)
+               return priv->assoc_network->beacon_interval - 10;
+       else
+               return 120;
+}
+
 static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
 {
        struct ipw_scan_request_ext scan;
@@ -6313,16 +6343,16 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
        scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
 
        if (type == IW_SCAN_TYPE_PASSIVE) {
-               IPW_DEBUG_WX("use passive scanning\n");
-               scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
+               IPW_DEBUG_WX("use passive scanning\n");
+               scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
                scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
-                       cpu_to_le16(120);
+                       cpu_to_le16(ipw_passive_dwell_time(priv));
                ipw_add_scan_channels(priv, &scan, scan_type);
                goto send_request;
        }
 
        /* Use active scan by default. */
-       if (priv->config & CFG_SPEED_SCAN)
+       if (priv->config & CFG_SPEED_SCAN)
                scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
                        cpu_to_le16(30);
        else
@@ -6332,7 +6362,8 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
        scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
                cpu_to_le16(20);
 
-       scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
+       scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
+               cpu_to_le16(ipw_passive_dwell_time(priv));
        scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
 
 #ifdef CONFIG_IPW2200_MONITOR
@@ -7700,22 +7731,23 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
                                   struct ipw_rx_mem_buffer *rxb,
                                   struct ieee80211_rx_stats *stats)
 {
+       struct net_device *dev = priv->net_dev;
        struct ieee80211_hdr_4addr *hdr;
        struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 
        /* We received data from the HW, so stop the watchdog */
-       priv->net_dev->trans_start = jiffies;
+       dev->trans_start = jiffies;
 
        /* We only process data packets if the
         * interface is open */
        if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
                     skb_tailroom(rxb->skb))) {
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
                return;
        } else if (unlikely(!netif_running(priv->net_dev))) {
-               priv->ieee->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
@@ -7737,7 +7769,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
                ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
        if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
        else {                  /* ieee80211_rx succeeded, so it now owns the SKB */
                rxb->skb = NULL;
                __ipw_led_activity_on(priv);
@@ -7749,6 +7781,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
                                           struct ipw_rx_mem_buffer *rxb,
                                           struct ieee80211_rx_stats *stats)
 {
+       struct net_device *dev = priv->net_dev;
        struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
        struct ipw_rx_frame *frame = &pkt->u.frame;
 
@@ -7766,18 +7799,18 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
        short len = le16_to_cpu(pkt->u.frame.length);
 
        /* We received data from the HW, so stop the watchdog */
-       priv->net_dev->trans_start = jiffies;
+       dev->trans_start = jiffies;
 
        /* We only process data packets if the
         * interface is open */
        if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
                     skb_tailroom(rxb->skb))) {
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
                return;
        } else if (unlikely(!netif_running(priv->net_dev))) {
-               priv->ieee->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
@@ -7787,7 +7820,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
         * that now */
        if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
                /* FIXME: Should alloc bigger skb instead */
-               priv->ieee->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                priv->wstats.discard.misc++;
                IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
                return;
@@ -7893,7 +7926,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
        IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
        if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
-               priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
        else {                  /* ieee80211_rx succeeded, so it now owns the SKB */
                rxb->skb = NULL;
                /* no LED during capture */
@@ -7925,6 +7958,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
                                      struct ipw_rx_mem_buffer *rxb,
                                      struct ieee80211_rx_stats *stats)
 {
+       struct net_device *dev = priv->prom_net_dev;
        struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
        struct ipw_rx_frame *frame = &pkt->u.frame;
        struct ipw_rt_hdr *ipw_rt;
@@ -7947,17 +7981,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
                return;
 
        /* We received data from the HW, so stop the watchdog */
-       priv->prom_net_dev->trans_start = jiffies;
+       dev->trans_start = jiffies;
 
        if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
-               priv->prom_priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
                return;
        }
 
        /* We only process data packets if the interface is open */
-       if (unlikely(!netif_running(priv->prom_net_dev))) {
-               priv->prom_priv->ieee->stats.rx_dropped++;
+       if (unlikely(!netif_running(dev))) {
+               dev->stats.rx_dropped++;
                IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
                return;
        }
@@ -7966,7 +8000,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
         * that now */
        if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
                /* FIXME: Should alloc bigger skb instead */
-               priv->prom_priv->ieee->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
                return;
        }
@@ -8098,7 +8132,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
        IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
 
        if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
-               priv->prom_priv->ieee->stats.rx_errors++;
+               dev->stats.rx_errors++;
                dev_kfree_skb_any(skb);
        }
 }
@@ -8255,7 +8289,7 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
                skb_reset_mac_header(skb);
 
                skb->pkt_type = PACKET_OTHERHOST;
-               skb->protocol = __constant_htons(ETH_P_80211_STATS);
+               skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
                memset(skb->cb, 0, sizeof(rxb->skb->cb));
                netif_rx(skb);
                rxb->skb = NULL;
@@ -8382,7 +8416,7 @@ static void ipw_rx(struct ipw_priv *priv)
                                        IPW_DEBUG_DROP
                                            ("Received packet is too small. "
                                             "Dropping.\n");
-                                       priv->ieee->stats.rx_errors++;
+                                       priv->net_dev->stats.rx_errors++;
                                        priv->wstats.discard.misc++;
                                        break;
                                }
@@ -10155,6 +10189,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
        u16 remaining_bytes;
        int fc;
 
+       if (!(priv->status & STATUS_ASSOCIATED))
+               goto drop;
+
        hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
        switch (priv->ieee->iw_mode) {
        case IW_MODE_ADHOC:
@@ -10450,15 +10487,6 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
        return ret;
 }
 
-static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
-{
-       struct ipw_priv *priv = ieee80211_priv(dev);
-
-       priv->ieee->stats.tx_packets = priv->tx_packets;
-       priv->ieee->stats.rx_packets = priv->rx_packets;
-       return &priv->ieee->stats;
-}
-
 static void ipw_net_set_multicast_list(struct net_device *dev)
 {
 
@@ -11204,6 +11232,12 @@ static int ipw_up(struct ipw_priv *priv)
 {
        int rc, i, j;
 
+       /* Age scan list entries found before suspend */
+       if (priv->suspend_time) {
+               ieee80211_networks_age(priv->ieee, priv->suspend_time);
+               priv->suspend_time = 0;
+       }
+
        if (priv->status & STATUS_EXIT_PENDING)
                return -EIO;
 
@@ -11495,11 +11529,14 @@ static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return -EOPNOTSUPP;
 }
 
-static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
-{
-       struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
-       return &prom_priv->ieee->stats;
-}
+static const struct net_device_ops ipw_prom_netdev_ops = {
+       .ndo_open               = ipw_prom_open,
+       .ndo_stop               = ipw_prom_stop,
+       .ndo_start_xmit         = ipw_prom_hard_start_xmit,
+       .ndo_change_mtu         = ieee80211_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
 
 static int ipw_prom_alloc(struct ipw_priv *priv)
 {
@@ -11520,10 +11557,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
        memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
        priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-       priv->prom_net_dev->open = ipw_prom_open;
-       priv->prom_net_dev->stop = ipw_prom_stop;
-       priv->prom_net_dev->get_stats = ipw_prom_get_stats;
-       priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
+       priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
 
        priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
        SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
@@ -11551,6 +11585,17 @@ static void ipw_prom_free(struct ipw_priv *priv)
 
 #endif
 
+static const struct net_device_ops ipw_netdev_ops = {
+       .ndo_init               = ipw_net_init,
+       .ndo_open               = ipw_net_open,
+       .ndo_stop               = ipw_net_stop,
+       .ndo_set_multicast_list = ipw_net_set_multicast_list,
+       .ndo_set_mac_address    = ipw_net_set_mac_address,
+       .ndo_start_xmit         = ieee80211_xmit,
+       .ndo_change_mtu         = ieee80211_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
 
 static int __devinit ipw_pci_probe(struct pci_dev *pdev,
                                   const struct pci_device_id *ent)
@@ -11652,12 +11697,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
        priv->ieee->perfect_rssi = -20;
        priv->ieee->worst_rssi = -85;
 
-       net_dev->open = ipw_net_open;
-       net_dev->stop = ipw_net_stop;
-       net_dev->init = ipw_net_init;
-       net_dev->get_stats = ipw_net_get_stats;
-       net_dev->set_multicast_list = ipw_net_set_multicast_list;
-       net_dev->set_mac_address = ipw_net_set_mac_address;
+       net_dev->netdev_ops = &ipw_netdev_ops;
        priv->wireless_data.spy_data = &priv->ieee->spy_data;
        net_dev->wireless_data = &priv->wireless_data;
        net_dev->wireless_handlers = &ipw_wx_handler_def;
@@ -11804,6 +11844,8 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        pci_disable_device(pdev);
        pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
+       priv->suspend_at = get_seconds();
+
        return 0;
 }
 
@@ -11839,6 +11881,8 @@ static int ipw_pci_resume(struct pci_dev *pdev)
         * the queue of needed */
        netif_device_attach(dev);
 
+       priv->suspend_time = get_seconds() - priv->suspend_at;
+
        /* Bring the device back up */
        queue_work(priv->workqueue, &priv->up);