On Mon, Dec 07, 2020 at 10:28:59AM +0100, Tobias Heider wrote:
> 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?

Please credit Christian Ehrhardt who did all the hard work in
tracking this down :)

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;
>               }
>  
> 
> 

Reply via email to