diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 269b9889e39e..f5d75288bd27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -548,6 +548,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
548 | u16 len = le16_to_cpu(rx_hdr->len); | 548 | u16 len = le16_to_cpu(rx_hdr->len); |
549 | struct sk_buff *skb; | 549 | struct sk_buff *skb; |
550 | int ret; | 550 | int ret; |
551 | __le16 fc = hdr->frame_control; | ||
551 | 552 | ||
552 | /* We received data from the HW, so stop the watchdog */ | 553 | /* We received data from the HW, so stop the watchdog */ |
553 | if (unlikely(len + IWL39_RX_FRAME_SIZE > | 554 | if (unlikely(len + IWL39_RX_FRAME_SIZE > |
@@ -580,9 +581,9 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
580 | /* mac80211 currently doesn't support paged SKB. Convert it to | 581 | /* mac80211 currently doesn't support paged SKB. Convert it to |
581 | * linear SKB for management frame and data frame requires | 582 | * linear SKB for management frame and data frame requires |
582 | * software decryption or software defragementation. */ | 583 | * software decryption or software defragementation. */ |
583 | if (ieee80211_is_mgmt(hdr->frame_control) || | 584 | if (ieee80211_is_mgmt(fc) || |
584 | ieee80211_has_protected(hdr->frame_control) || | 585 | ieee80211_has_protected(fc) || |
585 | ieee80211_has_morefrags(hdr->frame_control) || | 586 | ieee80211_has_morefrags(fc) || |
586 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | 587 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) |
587 | ret = skb_linearize(skb); | 588 | ret = skb_linearize(skb); |
588 | else | 589 | else |
@@ -594,11 +595,15 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
594 | goto out; | 595 | goto out; |
595 | } | 596 | } |
596 | 597 | ||
597 | iwl_update_stats(priv, false, hdr->frame_control, len); | 598 | /* |
599 | * XXX: We cannot touch the page and its virtual memory (pkt) after | ||
600 | * here. It might have already been freed by the above skb change. | ||
601 | */ | ||
598 | 602 | ||
603 | iwl_update_stats(priv, false, fc, len); | ||
599 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 604 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
600 | ieee80211_rx(priv->hw, skb); | ||
601 | 605 | ||
606 | ieee80211_rx(priv->hw, skb); | ||
602 | out: | 607 | out: |
603 | priv->alloc_rxb_page--; | 608 | priv->alloc_rxb_page--; |
604 | rxb->page = NULL; | 609 | rxb->page = NULL; |