Search Linux Wireless

RE: [PATCH v2 1/2] wifi: rtw88: usb: fix priority queue to endpoint mapping

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
> Sent: Tuesday, April 4, 2023 3:25 PM
> To: linux-wireless <linux-wireless@xxxxxxxxxxxxxxx>
> Cc: Hans Ulli Kroll <linux@xxxxxxxxxxxxx>; Larry Finger <Larry.Finger@xxxxxxxxxxxx>; Ping-Ke Shih
> <pkshih@xxxxxxxxxxx>; Tim K <tpkuester@xxxxxxxxx>; Alex G . <mr.nuke.me@xxxxxxxxx>; Nick Morrow
> <morrownr@xxxxxxxxx>; Viktor Petrenko <g0000ga@xxxxxxxxx>; Andreas Henriksson <andreas@xxxxxxxx>;
> ValdikSS <iam@xxxxxxxxxxxxxxx>; kernel@xxxxxxxxxxxxxx; Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>;
> stable@xxxxxxxxxxxxxxx
> Subject: [PATCH v2 1/2] wifi: rtw88: usb: fix priority queue to endpoint mapping
> 
> The RTW88 chipsets have four different priority queues in hardware. For
> the USB type chipsets the packets destined for a specific priority queue
> must be sent through the endpoint corresponding to the queue. This was
> not fully understood when porting from the RTW88 USB out of tree driver
> and thus violated.
> 
> This patch implements the qsel to endpoint mapping as in
> get_usb_bulkout_id_88xx() in the downstream driver.
> 
> Without this the driver often issues "timed out to flush queue 3"
> warnings and often TX stalls completely.
> 

Add a Fixes tag?

Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support")

As well as second patch.

> Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
> Tested-by: ValdikSS <iam@xxxxxxxxxxxxxxx>
> Tested-by: Alexandru gagniuc <mr.nuke.me@xxxxxxxxx>
> Tested-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx

Reviewed-by: Ping-Ke Shih <pkshih@xxxxxxxxxxx>

> ---
>  drivers/net/wireless/realtek/rtw88/usb.c | 70 ++++++++++++++++--------
>  1 file changed, 47 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
> index 2a8336b1847a5..a10d6fef4ffaf 100644
> --- a/drivers/net/wireless/realtek/rtw88/usb.c
> +++ b/drivers/net/wireless/realtek/rtw88/usb.c
> @@ -118,6 +118,22 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
>         rtw_usb_write(rtwdev, addr, val, 4);
>  }
> 
> +static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping)
> +{
> +       switch (dma_mapping) {
> +       case RTW_DMA_MAPPING_HIGH:
> +               return 0;
> +       case RTW_DMA_MAPPING_NORMAL:
> +               return 1;
> +       case RTW_DMA_MAPPING_LOW:
> +               return 2;
> +       case RTW_DMA_MAPPING_EXTRA:
> +               return 3;
> +       default:
> +               return -EINVAL;
> +       }
> +}
> +
>  static int rtw_usb_parse(struct rtw_dev *rtwdev,
>                          struct usb_interface *interface)
>  {
> @@ -129,6 +145,8 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
>         int num_out_pipes = 0;
>         int i;
>         u8 num;
> +       const struct rtw_chip_info *chip = rtwdev->chip;
> +       const struct rtw_rqpn *rqpn;
> 
>         for (i = 0; i < interface_desc->bNumEndpoints; i++) {
>                 endpoint = &host_interface->endpoint[i].desc;
> @@ -183,31 +201,34 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
> 
>         rtwdev->hci.bulkout_num = num_out_pipes;
> 
> -       switch (num_out_pipes) {
> -       case 4:
> -       case 3:
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
> -               break;
> -       case 2:
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
> -               rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
> -               break;
> -       case 1:
> -               break;
> -       default:
> -               rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
> +       if (num_out_pipes < 1 || num_out_pipes > 4) {
> +               rtw_err(rtwdev, "invalid number of endpoints %d\n", num_out_pipes);
>                 return -EINVAL;
>         }
> 
> +       rqpn = &chip->rqpn_table[num_out_pipes];
> +
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = dma_mapping_to_ep(rqpn->dma_map_be);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = dma_mapping_to_ep(rqpn->dma_map_bk);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = dma_mapping_to_ep(rqpn->dma_map_bk);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = dma_mapping_to_ep(rqpn->dma_map_be);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = dma_mapping_to_ep(rqpn->dma_map_vi);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = dma_mapping_to_ep(rqpn->dma_map_vi);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = dma_mapping_to_ep(rqpn->dma_map_vo);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = dma_mapping_to_ep(rqpn->dma_map_vo);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID8] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID9] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID10] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID11] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID12] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID13] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID14] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_TID15] = -EINVAL;
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_BEACON] = dma_mapping_to_ep(rqpn->dma_map_hi);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_HIGH] = dma_mapping_to_ep(rqpn->dma_map_hi);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_MGMT] = dma_mapping_to_ep(rqpn->dma_map_mg);
> +       rtwusb->qsel_to_ep[TX_DESC_QSEL_H2C] = dma_mapping_to_ep(rqpn->dma_map_hi);
> +
>         return 0;
>  }
> 
> @@ -250,7 +271,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb)
>  static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
>  {
>         if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
> -               return 0;
> +               return -EINVAL;
> 
>         return rtwusb->qsel_to_ep[qsel];
>  }
> @@ -265,6 +286,9 @@ static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *s
>         int ret;
>         int ep = qsel_to_ep(rtwusb, qsel);
> 
> +       if (ep < 0)
> +               return ep;
> +
>         pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
>         urb = usb_alloc_urb(0, GFP_ATOMIC);
>         if (!urb)
> --
> 2.39.2




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux