diff options
author | Mike McCormack <mikem@ring3k.org> | 2011-06-06 10:12:42 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-10 14:26:50 -0400 |
commit | 8db8ddf13dda0fc96937bcb6e10563e7b9a20387 (patch) | |
tree | bbdc03f8d2c828b552d74757d5c88eb9ddb818a7 /drivers/net/wireless/rtlwifi | |
parent | 2c333366a4ec1f4cdbaec285ba448d5943df8ffd (diff) |
rtlwifi: Resubmit skbs with bad CRC early
Once we realize a bad packet was received, don't
waste time unmapping it, freeing it, then allocation
a new skb and mapping it, just resubmit the existing
skb.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 81 |
1 files changed, 39 insertions, 42 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index fbb4c1309568..c89d6d740adc 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -669,6 +669,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
669 | &rx_status, | 669 | &rx_status, |
670 | (u8 *) pdesc, skb); | 670 | (u8 *) pdesc, skb); |
671 | 671 | ||
672 | if (stats.crc || stats.hwerror) | ||
673 | goto done; | ||
674 | |||
672 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | 675 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); |
673 | if (unlikely(!new_skb)) { | 676 | if (unlikely(!new_skb)) { |
674 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | 677 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), |
@@ -696,56 +699,50 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
696 | hdr = rtl_get_hdr(skb); | 699 | hdr = rtl_get_hdr(skb); |
697 | fc = rtl_get_fc(skb); | 700 | fc = rtl_get_fc(skb); |
698 | 701 | ||
699 | if (!stats.crc && !stats.hwerror) { | 702 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, |
700 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | 703 | sizeof(rx_status)); |
701 | sizeof(rx_status)); | ||
702 | 704 | ||
703 | if (is_broadcast_ether_addr(hdr->addr1)) { | 705 | if (is_broadcast_ether_addr(hdr->addr1)) { |
704 | ;/*TODO*/ | 706 | ;/*TODO*/ |
705 | } else if (is_multicast_ether_addr(hdr->addr1)) { | 707 | } else if (is_multicast_ether_addr(hdr->addr1)) { |
706 | ;/*TODO*/ | 708 | ;/*TODO*/ |
707 | } else { | 709 | } else { |
708 | unicast = true; | 710 | unicast = true; |
709 | rtlpriv->stats.rxbytesunicast += skb->len; | 711 | rtlpriv->stats.rxbytesunicast += skb->len; |
710 | } | 712 | } |
711 | 713 | ||
712 | rtl_is_special_data(hw, skb, false); | 714 | rtl_is_special_data(hw, skb, false); |
713 | 715 | ||
714 | if (ieee80211_is_data(fc)) { | 716 | if (ieee80211_is_data(fc)) { |
715 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); | 717 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); |
716 | 718 | ||
717 | if (unicast) | 719 | if (unicast) |
718 | rtlpriv->link_info.num_rx_inperiod++; | 720 | rtlpriv->link_info.num_rx_inperiod++; |
719 | } | 721 | } |
720 | 722 | ||
721 | /* for sw lps */ | 723 | /* for sw lps */ |
722 | rtl_swlps_beacon(hw, (void *)skb->data, skb->len); | 724 | rtl_swlps_beacon(hw, (void *)skb->data, skb->len); |
723 | rtl_recognize_peer(hw, (void *)skb->data, skb->len); | 725 | rtl_recognize_peer(hw, (void *)skb->data, skb->len); |
724 | if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && | 726 | if ((rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) && |
725 | (rtlpriv->rtlhal.current_bandtype == | 727 | (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) && |
726 | BAND_ON_2_4G) && | 728 | (ieee80211_is_beacon(fc) || |
727 | (ieee80211_is_beacon(fc) || | 729 | ieee80211_is_probe_resp(fc))) { |
728 | ieee80211_is_probe_resp(fc))) { | 730 | dev_kfree_skb_any(skb); |
731 | } else { | ||
732 | if (unlikely(!rtl_action_proc(hw, skb, false))) { | ||
729 | dev_kfree_skb_any(skb); | 733 | dev_kfree_skb_any(skb); |
730 | } else { | 734 | } else { |
731 | if (unlikely(!rtl_action_proc(hw, skb, | 735 | struct sk_buff *uskb = NULL; |
732 | false))) { | 736 | u8 *pdata; |
733 | dev_kfree_skb_any(skb); | 737 | uskb = dev_alloc_skb(skb->len + 128); |
734 | } else { | 738 | memcpy(IEEE80211_SKB_RXCB(uskb), |
735 | struct sk_buff *uskb = NULL; | 739 | &rx_status, sizeof(rx_status)); |
736 | u8 *pdata; | 740 | pdata = (u8 *)skb_put(uskb, skb->len); |
737 | uskb = dev_alloc_skb(skb->len + 128); | 741 | memcpy(pdata, skb->data, skb->len); |
738 | memcpy(IEEE80211_SKB_RXCB(uskb), | 742 | dev_kfree_skb_any(skb); |
739 | &rx_status, sizeof(rx_status)); | 743 | |
740 | pdata = (u8 *)skb_put(uskb, skb->len); | 744 | ieee80211_rx_irqsafe(hw, uskb); |
741 | memcpy(pdata, skb->data, skb->len); | ||
742 | dev_kfree_skb_any(skb); | ||
743 | |||
744 | ieee80211_rx_irqsafe(hw, uskb); | ||
745 | } | ||
746 | } | 745 | } |
747 | } else { | ||
748 | dev_kfree_skb_any(skb); | ||
749 | } | 746 | } |
750 | 747 | ||
751 | if (((rtlpriv->link_info.num_rx_inperiod + | 748 | if (((rtlpriv->link_info.num_rx_inperiod + |