Hi,
In iwm_rx_pkt() the calculation of "remain" seems to be wrong if
there are three or more MPDUs in one packet.
"remain" is initialized with the output buffer size.
Each time an MPDU is found in the packet remain is reduced
by the offset of the MPDU in the receive buffer, which is only
correct for the first MPDU in the packet.
This causes spurious input errors.
We can fix this by removing the "remain" variable.
The variable "offset" always points to the current position in the
receive buffer and the maximum size of the receive buffer is fixed.
Thus offset can be used for the caculation of maxlen.
ok?
Index: if_iwm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.315
diff -u -p -r1.315 if_iwm.c
--- if_iwm.c 11 Oct 2020 07:05:28 -0000 1.315
+++ if_iwm.c 7 Dec 2020 09:02:44 -0000
@@ -8494,7 +8494,6 @@ iwm_rx_pkt(struct iwm_softc *sc, struct
uint32_t offset = 0, nextoff = 0, nmpdu = 0, len;
struct mbuf *m0, *m;
const size_t minsz = sizeof(pkt->len_n_flags) + sizeof(pkt->hdr);
- size_t remain = IWM_RBUF_SIZE;
int qid, idx, code, handled = 1;
bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
@@ -8531,7 +8530,7 @@ iwm_rx_pkt(struct iwm_softc *sc, struct
break;
case IWM_REPLY_RX_MPDU_CMD: {
- size_t maxlen = remain - minsz;
+ size_t maxlen = IWM_RBUF_SIZE - offset - minsz;
nextoff = offset +
roundup(len, IWM_FH_RSCSR_FRAME_ALIGN);
nextpkt = (struct iwm_rx_packet *)
@@ -8569,11 +8568,6 @@ iwm_rx_pkt(struct iwm_softc *sc, struct
iwm_rx_mpdu(sc, m, pkt->data,
maxlen, ml);
}
-
- if (offset + minsz < remain)
- remain -= offset;
- else
- remain = minsz;
break;
}