aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-11-04 11:20:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-11 17:09:07 -0500
commit5ca42627f3ddc0e4fc3e62d879cc35ab5beaaa8b (patch)
tree097aec55f4b63beb7d2d37d81161e51d93d09be7
parentdbfc22df1afbeb91d528e2f84d6603ac9ce98bc2 (diff)
ath9k: avoid the copy skb->cb on every RX'd skb
The skb->cb (control buffer, 48 bytes) is available to the skb upon skb allocation. You can fill it up imediately after skb allocation. ath9k was copying onto the skb->cb the data from the processed skb for mac80211 from a stack struct ieee80211_rx_status structure. This is unnecessary, instead use the skb->cb for the rx status immediately after the skb becomes available and DMA synched. Additionally, avoid the copy of the skb->cb also for virtual wiphys as skb_copy() will copy over the skb->cb for us as well. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c38
1 files changed, 16 insertions, 22 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 4c4c22f54e99..079361423efc 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -283,8 +283,6 @@ static int ath_rx_prepare(struct ath_common *common,
283{ 283{
284 struct ath_hw *ah = common->ah; 284 struct ath_hw *ah = common->ah;
285 285
286 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
287
288 if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) 286 if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error))
289 goto rx_next; 287 goto rx_next;
290 288
@@ -654,7 +652,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
654 652
655static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, 653static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
656 struct ath_softc *sc, struct sk_buff *skb, 654 struct ath_softc *sc, struct sk_buff *skb,
657 struct ieee80211_rx_status *rx_status) 655 struct ieee80211_rx_status *rxs)
658{ 656{
659 struct ieee80211_hdr *hdr; 657 struct ieee80211_hdr *hdr;
660 658
@@ -674,19 +672,14 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw,
674 if (aphy == NULL) 672 if (aphy == NULL)
675 continue; 673 continue;
676 nskb = skb_copy(skb, GFP_ATOMIC); 674 nskb = skb_copy(skb, GFP_ATOMIC);
677 if (nskb) { 675 if (!nskb)
678 memcpy(IEEE80211_SKB_RXCB(nskb), rx_status, 676 continue;
679 sizeof(*rx_status)); 677 ieee80211_rx(aphy->hw, nskb);
680 ieee80211_rx(aphy->hw, nskb);
681 }
682 } 678 }
683 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
684 ieee80211_rx(sc->hw, skb); 679 ieee80211_rx(sc->hw, skb);
685 } else { 680 } else
686 /* Deliver unicast frames based on receiver address */ 681 /* Deliver unicast frames based on receiver address */
687 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
688 ieee80211_rx(hw, skb); 682 ieee80211_rx(hw, skb);
689 }
690} 683}
691 684
692int ath_rx_tasklet(struct ath_softc *sc, int flush) 685int ath_rx_tasklet(struct ath_softc *sc, int flush)
@@ -699,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
699 struct ath_desc *ds; 692 struct ath_desc *ds;
700 struct ath_rx_status *rx_stats; 693 struct ath_rx_status *rx_stats;
701 struct sk_buff *skb = NULL, *requeue_skb; 694 struct sk_buff *skb = NULL, *requeue_skb;
702 struct ieee80211_rx_status rx_status; 695 struct ieee80211_rx_status *rxs;
703 struct ath_hw *ah = sc->sc_ah; 696 struct ath_hw *ah = sc->sc_ah;
704 struct ath_common *common = ath9k_hw_common(ah); 697 struct ath_common *common = ath9k_hw_common(ah);
705 /* 698 /*
@@ -788,6 +781,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
788 DMA_FROM_DEVICE); 781 DMA_FROM_DEVICE);
789 782
790 hdr = (struct ieee80211_hdr *) skb->data; 783 hdr = (struct ieee80211_hdr *) skb->data;
784 rxs = IEEE80211_SKB_RXCB(skb);
785
791 hw = ath_get_virt_hw(sc, hdr); 786 hw = ath_get_virt_hw(sc, hdr);
792 rx_stats = &ds->ds_rxstat; 787 rx_stats = &ds->ds_rxstat;
793 788
@@ -806,7 +801,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
806 goto requeue; 801 goto requeue;
807 802
808 if (!ath_rx_prepare(common, hw, skb, rx_stats, 803 if (!ath_rx_prepare(common, hw, skb, rx_stats,
809 &rx_status, &decrypt_error)) 804 rxs, &decrypt_error))
810 goto requeue; 805 goto requeue;
811 806
812 /* Ensure we always have an skb to requeue once we are done 807 /* Ensure we always have an skb to requeue once we are done
@@ -848,20 +843,19 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
848 keyix = rx_stats->rs_keyix; 843 keyix = rx_stats->rs_keyix;
849 844
850 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { 845 if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
851 rx_status.flag |= RX_FLAG_DECRYPTED; 846 rxs->flag |= RX_FLAG_DECRYPTED;
852 } else if (ieee80211_has_protected(fc) 847 } else if (ieee80211_has_protected(fc)
853 && !decrypt_error && skb->len >= hdrlen + 4) { 848 && !decrypt_error && skb->len >= hdrlen + 4) {
854 keyix = skb->data[hdrlen + 3] >> 6; 849 keyix = skb->data[hdrlen + 3] >> 6;
855 850
856 if (test_bit(keyix, sc->keymap)) 851 if (test_bit(keyix, sc->keymap))
857 rx_status.flag |= RX_FLAG_DECRYPTED; 852 rxs->flag |= RX_FLAG_DECRYPTED;
858 } 853 }
859 if (ah->sw_mgmt_crypto && 854 if (ah->sw_mgmt_crypto &&
860 (rx_status.flag & RX_FLAG_DECRYPTED) && 855 (rxs->flag & RX_FLAG_DECRYPTED) &&
861 ieee80211_is_mgmt(fc)) { 856 ieee80211_is_mgmt(fc))
862 /* Use software decrypt for management frames. */ 857 /* Use software decrypt for management frames. */
863 rx_status.flag &= ~RX_FLAG_DECRYPTED; 858 rxs->flag &= ~RX_FLAG_DECRYPTED;
864 }
865 859
866 /* We will now give hardware our shiny new allocated skb */ 860 /* We will now give hardware our shiny new allocated skb */
867 bf->bf_mpdu = requeue_skb; 861 bf->bf_mpdu = requeue_skb;
@@ -874,7 +868,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
874 bf->bf_mpdu = NULL; 868 bf->bf_mpdu = NULL;
875 ath_print(common, ATH_DBG_FATAL, 869 ath_print(common, ATH_DBG_FATAL,
876 "dma_mapping_error() on RX\n"); 870 "dma_mapping_error() on RX\n");
877 ath_rx_send_to_mac80211(hw, sc, skb, &rx_status); 871 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
878 break; 872 break;
879 } 873 }
880 bf->bf_dmacontext = bf->bf_buf_addr; 874 bf->bf_dmacontext = bf->bf_buf_addr;
@@ -895,7 +889,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
895 SC_OP_WAIT_FOR_PSPOLL_DATA))) 889 SC_OP_WAIT_FOR_PSPOLL_DATA)))
896 ath_rx_ps(sc, skb); 890 ath_rx_ps(sc, skb);
897 891
898 ath_rx_send_to_mac80211(hw, sc, skb, &rx_status); 892 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
899 893
900requeue: 894requeue:
901 list_move_tail(&bf->list, &sc->rx.rxbuf); 895 list_move_tail(&bf->list, &sc->rx.rxbuf);