Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-agn-rx.c
index f94122387e25bcbc9a065f5e5bd4f96519682538..0c252c5d8bf13543f3f40121ce671812b6559c95 100644 (file)
@@ -737,8 +737,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
        struct sk_buff *skb;
        __le16 fc = hdr->frame_control;
        struct iwl_rxon_context *ctx;
-       struct page *p;
-       int offset;
+       unsigned int hdrlen, fraglen;
 
        /* We only process data packets if the interface is open */
        if (unlikely(!priv->is_open)) {
@@ -752,15 +751,24 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
            iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats))
                return;
 
-       skb = dev_alloc_skb(128);
+       /* Dont use dev_alloc_skb(), we'll have enough headroom once
+        * ieee80211_hdr pulled.
+        */
+       skb = alloc_skb(128, GFP_ATOMIC);
        if (!skb) {
-               IWL_ERR(priv, "dev_alloc_skb failed\n");
+               IWL_ERR(priv, "alloc_skb failed\n");
                return;
        }
+       hdrlen = min_t(unsigned int, len, skb_tailroom(skb));
+       memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
+       fraglen = len - hdrlen;
+
+       if (fraglen) {
+               int offset = (void *)hdr - rxb_addr(rxb) + rxb_offset(rxb);
 
-       offset = (void *)hdr - rxb_addr(rxb) + rxb_offset(rxb);
-       p = rxb_steal_page(rxb);
-       skb_add_rx_frag(skb, 0, p, offset, len, len);
+               skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
+                               fraglen, rxb->truesize);
+       }
 
        /*
        * Wake any queues that were stopped due to a passive channel tx
This page took 0.024972 seconds and 5 git commands to generate.