iwmc3200wifi: Fix test of unsigned in iwm_ntf_stop_resume_tx()
[safe/jmp/linux-2.6] / drivers / net / wireless / iwlwifi / iwl-3945.c
index 7142aa5..e413bd3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
@@ -359,8 +360,6 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
                     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
        memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
-
-       iwl_leds_background(priv);
 }
 
 /******************************************************************************
@@ -550,6 +549,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
        u16 len = le16_to_cpu(rx_hdr->len);
        struct sk_buff *skb;
        int ret;
+       __le16 fc = hdr->frame_control;
 
        /* We received data from the HW, so stop the watchdog */
        if (unlikely(len + IWL39_RX_FRAME_SIZE >
@@ -565,7 +565,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
                return;
        }
 
-       skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC);
+       skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
        if (!skb) {
                IWL_ERR(priv, "alloc_skb failed\n");
                return;
@@ -576,15 +576,16 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
                                       (struct ieee80211_hdr *)rxb_addr(rxb),
                                       le32_to_cpu(rx_end->status), stats);
 
+       skb_reserve(skb, IWL_LINK_HDR_MAX);
        skb_add_rx_frag(skb, 0, rxb->page,
                        (void *)rx_hdr->payload - (void *)pkt, len);
 
        /* mac80211 currently doesn't support paged SKB. Convert it to
         * linear SKB for management frame and data frame requires
         * software decryption or software defragementation. */
-       if (ieee80211_is_mgmt(hdr->frame_control) ||
-           ieee80211_has_protected(hdr->frame_control) ||
-           ieee80211_has_morefrags(hdr->frame_control) ||
+       if (ieee80211_is_mgmt(fc) ||
+           ieee80211_has_protected(fc) ||
+           ieee80211_has_morefrags(fc) ||
            le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
                ret = skb_linearize(skb);
        else
@@ -596,11 +597,15 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
                goto out;
        }
 
-       iwl_update_stats(priv, false, hdr->frame_control, len);
+       /*
+        * XXX: We cannot touch the page and its virtual memory (pkt) after
+        * here. It might have already been freed by the above skb change.
+        */
 
+       iwl_update_stats(priv, false, fc, len);
        memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
-       ieee80211_rx(priv->hw, skb);
 
+       ieee80211_rx(priv->hw, skb);
  out:
        priv->alloc_rxb_page--;
        rxb->page = NULL;
@@ -1830,8 +1835,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
                rc = -EIO;
        }
 
-       priv->alloc_rxb_page--;
-       free_pages(cmd.reply_page, priv->hw_params.rx_page_order);
+       iwl_free_pages(priv, cmd.reply_page);
 
        return rc;
 }
@@ -1979,12 +1983,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
        return 0;
 }
 
-/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
-{
-       return 0;
-}
-
 /**
  * iwl3945_reg_txpower_periodic -  called when time to check our temperature.
  *
@@ -2837,6 +2835,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
        .led_compensation = 64,
+       .broken_powersave = true,
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2853,6 +2852,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
        .use_isr_legacy = true,
        .ht_greenfield_support = false,
        .led_compensation = 64,
+       .broken_powersave = true,
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {