diff options
Diffstat (limited to 'drivers/net/wireless/iwlegacy/3945.c')
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index c092033945cc..f09e257759d5 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
@@ -475,6 +475,8 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header) | |||
475 | } | 475 | } |
476 | } | 476 | } |
477 | 477 | ||
478 | #define SMALL_PACKET_SIZE 256 | ||
479 | |||
478 | static void | 480 | static void |
479 | il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, | 481 | il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, |
480 | struct ieee80211_rx_status *stats) | 482 | struct ieee80211_rx_status *stats) |
@@ -483,14 +485,13 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, | |||
483 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt); | 485 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt); |
484 | struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); | 486 | struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); |
485 | struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt); | 487 | struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt); |
486 | u16 len = le16_to_cpu(rx_hdr->len); | 488 | u32 len = le16_to_cpu(rx_hdr->len); |
487 | struct sk_buff *skb; | 489 | struct sk_buff *skb; |
488 | __le16 fc = hdr->frame_control; | 490 | __le16 fc = hdr->frame_control; |
491 | u32 fraglen = PAGE_SIZE << il->hw_params.rx_page_order; | ||
489 | 492 | ||
490 | /* We received data from the HW, so stop the watchdog */ | 493 | /* We received data from the HW, so stop the watchdog */ |
491 | if (unlikely | 494 | if (unlikely(len + IL39_RX_FRAME_SIZE > fraglen)) { |
492 | (len + IL39_RX_FRAME_SIZE > | ||
493 | PAGE_SIZE << il->hw_params.rx_page_order)) { | ||
494 | D_DROP("Corruption detected!\n"); | 495 | D_DROP("Corruption detected!\n"); |
495 | return; | 496 | return; |
496 | } | 497 | } |
@@ -506,26 +507,32 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, | |||
506 | D_INFO("Woke queues - frame received on passive channel\n"); | 507 | D_INFO("Woke queues - frame received on passive channel\n"); |
507 | } | 508 | } |
508 | 509 | ||
509 | skb = dev_alloc_skb(128); | 510 | skb = dev_alloc_skb(SMALL_PACKET_SIZE); |
510 | if (!skb) { | 511 | if (!skb) { |
511 | IL_ERR("dev_alloc_skb failed\n"); | 512 | IL_ERR("dev_alloc_skb failed\n"); |
512 | return; | 513 | return; |
513 | } | 514 | } |
514 | 515 | ||
515 | if (!il3945_mod_params.sw_crypto) | 516 | if (!il3945_mod_params.sw_crypto) |
516 | il_set_decrypted_flag(il, (struct ieee80211_hdr *)rxb_addr(rxb), | 517 | il_set_decrypted_flag(il, (struct ieee80211_hdr *)pkt, |
517 | le32_to_cpu(rx_end->status), stats); | 518 | le32_to_cpu(rx_end->status), stats); |
518 | 519 | ||
519 | skb_add_rx_frag(skb, 0, rxb->page, | 520 | /* If frame is small enough to fit into skb->head, copy it |
520 | (void *)rx_hdr->payload - (void *)pkt, len, | 521 | * and do not consume a full page |
521 | len); | 522 | */ |
522 | 523 | if (len <= SMALL_PACKET_SIZE) { | |
524 | memcpy(skb_put(skb, len), rx_hdr->payload, len); | ||
525 | } else { | ||
526 | skb_add_rx_frag(skb, 0, rxb->page, | ||
527 | (void *)rx_hdr->payload - (void *)pkt, len, | ||
528 | fraglen); | ||
529 | il->alloc_rxb_page--; | ||
530 | rxb->page = NULL; | ||
531 | } | ||
523 | il_update_stats(il, false, fc, len); | 532 | il_update_stats(il, false, fc, len); |
524 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); | 533 | memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); |
525 | 534 | ||
526 | ieee80211_rx(il->hw, skb); | 535 | ieee80211_rx(il->hw, skb); |
527 | il->alloc_rxb_page--; | ||
528 | rxb->page = NULL; | ||
529 | } | 536 | } |
530 | 537 | ||
531 | #define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 538 | #define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |