Skip to content

Commit a6f187f

Browse files
saschahauerKalle Valo
authored andcommitted
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. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Tested-by: ValdikSS <iam@valdikss.org.ru> Tested-by: Alexandru gagniuc <mr.nuke.me@gmail.com> Tested-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: stable@vger.kernel.org Reviewed-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20230417140358.2240429-2-s.hauer@pengutronix.de
1 parent d16836c commit a6f187f

1 file changed

Lines changed: 47 additions & 23 deletions

File tree

  • drivers/net/wireless/realtek/rtw88

drivers/net/wireless/realtek/rtw88/usb.c

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
118118
rtw_usb_write(rtwdev, addr, val, 4);
119119
}
120120

121+
static int dma_mapping_to_ep(enum rtw_dma_mapping dma_mapping)
122+
{
123+
switch (dma_mapping) {
124+
case RTW_DMA_MAPPING_HIGH:
125+
return 0;
126+
case RTW_DMA_MAPPING_NORMAL:
127+
return 1;
128+
case RTW_DMA_MAPPING_LOW:
129+
return 2;
130+
case RTW_DMA_MAPPING_EXTRA:
131+
return 3;
132+
default:
133+
return -EINVAL;
134+
}
135+
}
136+
121137
static int rtw_usb_parse(struct rtw_dev *rtwdev,
122138
struct usb_interface *interface)
123139
{
@@ -129,6 +145,8 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
129145
int num_out_pipes = 0;
130146
int i;
131147
u8 num;
148+
const struct rtw_chip_info *chip = rtwdev->chip;
149+
const struct rtw_rqpn *rqpn;
132150

133151
for (i = 0; i < interface_desc->bNumEndpoints; i++) {
134152
endpoint = &host_interface->endpoint[i].desc;
@@ -183,31 +201,34 @@ static int rtw_usb_parse(struct rtw_dev *rtwdev,
183201

184202
rtwdev->hci.bulkout_num = num_out_pipes;
185203

186-
switch (num_out_pipes) {
187-
case 4:
188-
case 3:
189-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 2;
190-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 2;
191-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 2;
192-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 2;
193-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = 1;
194-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = 1;
195-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = 0;
196-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = 0;
197-
break;
198-
case 2:
199-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = 1;
200-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = 1;
201-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = 1;
202-
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = 1;
203-
break;
204-
case 1:
205-
break;
206-
default:
207-
rtw_err(rtwdev, "failed to get out_pipes(%d)\n", num_out_pipes);
204+
if (num_out_pipes < 1 || num_out_pipes > 4) {
205+
rtw_err(rtwdev, "invalid number of endpoints %d\n", num_out_pipes);
208206
return -EINVAL;
209207
}
210208

209+
rqpn = &chip->rqpn_table[num_out_pipes];
210+
211+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID0] = dma_mapping_to_ep(rqpn->dma_map_be);
212+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID1] = dma_mapping_to_ep(rqpn->dma_map_bk);
213+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID2] = dma_mapping_to_ep(rqpn->dma_map_bk);
214+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID3] = dma_mapping_to_ep(rqpn->dma_map_be);
215+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID4] = dma_mapping_to_ep(rqpn->dma_map_vi);
216+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID5] = dma_mapping_to_ep(rqpn->dma_map_vi);
217+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID6] = dma_mapping_to_ep(rqpn->dma_map_vo);
218+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID7] = dma_mapping_to_ep(rqpn->dma_map_vo);
219+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID8] = -EINVAL;
220+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID9] = -EINVAL;
221+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID10] = -EINVAL;
222+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID11] = -EINVAL;
223+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID12] = -EINVAL;
224+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID13] = -EINVAL;
225+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID14] = -EINVAL;
226+
rtwusb->qsel_to_ep[TX_DESC_QSEL_TID15] = -EINVAL;
227+
rtwusb->qsel_to_ep[TX_DESC_QSEL_BEACON] = dma_mapping_to_ep(rqpn->dma_map_hi);
228+
rtwusb->qsel_to_ep[TX_DESC_QSEL_HIGH] = dma_mapping_to_ep(rqpn->dma_map_hi);
229+
rtwusb->qsel_to_ep[TX_DESC_QSEL_MGMT] = dma_mapping_to_ep(rqpn->dma_map_mg);
230+
rtwusb->qsel_to_ep[TX_DESC_QSEL_H2C] = dma_mapping_to_ep(rqpn->dma_map_hi);
231+
211232
return 0;
212233
}
213234

@@ -250,7 +271,7 @@ static void rtw_usb_write_port_tx_complete(struct urb *urb)
250271
static int qsel_to_ep(struct rtw_usb *rtwusb, unsigned int qsel)
251272
{
252273
if (qsel >= ARRAY_SIZE(rtwusb->qsel_to_ep))
253-
return 0;
274+
return -EINVAL;
254275

255276
return rtwusb->qsel_to_ep[qsel];
256277
}
@@ -265,6 +286,9 @@ static int rtw_usb_write_port(struct rtw_dev *rtwdev, u8 qsel, struct sk_buff *s
265286
int ret;
266287
int ep = qsel_to_ep(rtwusb, qsel);
267288

289+
if (ep < 0)
290+
return ep;
291+
268292
pipe = usb_sndbulkpipe(usbd, rtwusb->out_ep[ep]);
269293
urb = usb_alloc_urb(0, GFP_ATOMIC);
270294
if (!urb)

0 commit comments

Comments
 (0)