|
@@ -773,8 +773,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)) {
|
|
@@ -788,16 +787,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;
|
|
|
|
|
|
- offset = (void *)hdr - rxb_addr(rxb);
|
|
|
- p = rxb_steal_page(rxb);
|
|
|
- skb_add_rx_frag(skb, 0, p, offset, len, len);
|
|
|
+ if (fraglen) {
|
|
|
+ int offset = (void *)hdr + hdrlen - rxb_addr(rxb);
|
|
|
|
|
|
+ skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
|
|
|
+ fraglen, rxb->truesize);
|
|
|
+ }
|
|
|
iwl_update_stats(priv, false, fc, len);
|
|
|
|
|
|
/*
|