aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy/3945.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlegacy/3945.c')
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c31
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
478static void 480static void
479il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb, 481il3945_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)