1 --- a/drivers/net/wireless/ath/ath9k/main.c
2 +++ b/drivers/net/wireless/ath/ath9k/main.c
3 @@ -1291,6 +1291,11 @@ static void ath9k_stop(struct ieee80211_
8 + dev_kfree_skb_any(sc->rx.frag);
12 /* disable HAL and put h/w to sleep */
14 ath9k_hw_configpcipowersave(ah, 1, 1);
15 --- a/drivers/net/wireless/ath/ath9k/recv.c
16 +++ b/drivers/net/wireless/ath/ath9k/recv.c
17 @@ -209,11 +209,6 @@ static int ath_rx_edma_init(struct ath_s
22 - common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN +
23 - ah->caps.rx_status_len,
24 - min(common->cachelsz, (u16)64));
26 ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize -
27 ah->caps.rx_status_len);
29 @@ -300,12 +295,12 @@ int ath_rx_init(struct ath_softc *sc, in
30 sc->sc_flags &= ~SC_OP_RXFLUSH;
31 spin_lock_init(&sc->rx.rxbuflock);
33 + common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
34 + sc->sc_ah->caps.rx_status_len;
36 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
37 return ath_rx_edma_init(sc, nbufs);
39 - common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
40 - min(common->cachelsz, (u16)64));
42 ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
43 common->cachelsz, common->rx_bufsize);
45 @@ -815,15 +810,9 @@ static bool ath9k_rx_accept(struct ath_c
46 if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
50 - * rs_more indicates chained descriptors which can be used
51 - * to link buffers together for a sort of scatter-gather
53 - * reject the frame, we don't support scatter-gather yet and
54 - * the frame is probably corrupt anyway
56 + /* Only use error bits from the last fragment */
57 if (rx_stats->rs_more)
62 * The rx_stats->rs_status will not be set until the end of the
63 @@ -981,6 +970,10 @@ static int ath9k_rx_skb_preprocess(struc
64 if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error))
67 + /* Only use status info from the last fragment */
68 + if (rx_stats->rs_more)
71 ath9k_process_rssi(common, hw, hdr, rx_stats);
73 if (ath9k_process_rate(common, hw, rx_stats, rx_status))
74 @@ -1582,7 +1575,7 @@ div_comb_done:
75 int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
78 - struct sk_buff *skb = NULL, *requeue_skb;
79 + struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb;
80 struct ieee80211_rx_status *rxs;
81 struct ath_hw *ah = sc->sc_ah;
82 struct ath_common *common = ath9k_hw_common(ah);
83 @@ -1633,8 +1626,17 @@ int ath_rx_tasklet(struct ath_softc *sc,
87 - hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len);
88 - rxs = IEEE80211_SKB_RXCB(skb);
90 + * Take frame header from the first fragment and RX status from
94 + hdr_skb = sc->rx.frag;
98 + hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
99 + rxs = IEEE80211_SKB_RXCB(hdr_skb);
101 ath_debug_stat_rx(sc, &rs);
103 @@ -1643,12 +1645,12 @@ int ath_rx_tasklet(struct ath_softc *sc,
104 * chain it back at the queue without processing it.
108 + goto requeue_drop_frag;
110 retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
111 rxs, &decrypt_error);
114 + goto requeue_drop_frag;
116 rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
117 if (rs.rs_tstamp > tsf_lower &&
118 @@ -1668,7 +1670,7 @@ int ath_rx_tasklet(struct ath_softc *sc,
119 * skb and put it at the tail of the sc->rx.rxbuf list for
123 + goto requeue_drop_frag;
125 /* Unmap the frame */
126 dma_unmap_single(sc->dev, bf->bf_buf_addr,
127 @@ -1679,8 +1681,9 @@ int ath_rx_tasklet(struct ath_softc *sc,
128 if (ah->caps.rx_status_len)
129 skb_pull(skb, ah->caps.rx_status_len);
131 - ath9k_rx_skb_postprocess(common, skb, &rs,
132 - rxs, decrypt_error);
134 + ath9k_rx_skb_postprocess(common, hdr_skb, &rs,
135 + rxs, decrypt_error);
137 /* We will now give hardware our shiny new allocated skb */
138 bf->bf_mpdu = requeue_skb;
139 @@ -1697,6 +1700,38 @@ int ath_rx_tasklet(struct ath_softc *sc,
145 + * rs_more indicates chained descriptors which can be
146 + * used to link buffers together for a sort of
147 + * scatter-gather operation.
150 + /* too many fragments - cannot handle frame */
151 + dev_kfree_skb_any(sc->rx.frag);
152 + dev_kfree_skb_any(skb);
160 + int space = skb->len - skb_tailroom(hdr_skb);
162 + sc->rx.frag = NULL;
164 + if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) {
165 + dev_kfree_skb(skb);
166 + goto requeue_drop_frag;
169 + skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len),
171 + dev_kfree_skb_any(skb);
176 * change the default rx antenna if rx diversity chooses the
177 * other antenna 3 times in a row.
178 @@ -1722,6 +1757,11 @@ int ath_rx_tasklet(struct ath_softc *sc,
180 ieee80211_rx(hw, skb);
184 + dev_kfree_skb_any(sc->rx.frag);
185 + sc->rx.frag = NULL;
189 list_add_tail(&bf->list, &sc->rx.rxbuf);
190 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
191 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
192 @@ -311,6 +311,8 @@ struct ath_rx {
193 struct ath_descdma rxdma;
194 struct ath_buf *rx_bufptr;
195 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
197 + struct sk_buff *frag;
200 int ath_startrecv(struct ath_softc *sc);