On 20/04/2023 19:12, Artem Makhutov wrote: > Hi, > > Am Do., 20. Apr. 2023 um 17:33 Uhr schrieb Bitterblue Smith > <rtl8821cerfe2@xxxxxxxxx>: >> >> On 20/04/2023 14:40, Artem Makhutov wrote: >>> Hi, >>> >>> I think that I have found the problem: It happens when rx_desc->rxht >>> == 1 - then the urb is 4 bytes shorter... >>> >> >> That's very interesting. So it has a problem with MCS rates >> >> According to Johannes Berg, the 8 bytes at the end of the working ping >> are the MIC, which mac80211 will strip. Of course mac80211 doesn't know >> that rtl8xxxu sometimes receives 4 bytes fewer. > > The strange thing is that this issue does not appear with another > Logilink WL0151 connected to my home network... Here the MCS rates > work fine and I am always getting the full 8 bytes. > >> What kind of encryption does the network have? Is it possible to try >> without any encryption? > > It uses WPA1 + WPA2 right now. Before that we had WPA2 only and it was > exactly the same. > I also did a test without encryption before. As far as I remember I > was able to send larger packets, but the issue was still there. > I will redo the test without encryption to double check it. > >> Another thing to try is software crypto, using this tested patch and >> the module parameter debug=0x8000: > > Just tried it out. There was no change at all. > > Any ideas? So it's probably not related to the encryption. The v5.2.2.4 driver uses USB RX aggregation, unless you disabled it. We can try to use it in rtl8xxxu too, with this patch and the module parameter dma_aggregation=1: diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index d9fd7f79821b..169b66333fc3 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1963,6 +1963,7 @@ struct rtl8xxxu_fileops { }; extern int rtl8xxxu_debug; +extern bool rtl8xxxu_dma_aggregation; extern const struct rtl8xxxu_reg8val rtl8xxxu_gen1_mac_init_table[]; extern const u32 rtl8xxxu_iqk_phy_iq_bb_reg[]; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c index 6d0f975f891b..ddd94d73816d 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c @@ -540,14 +540,25 @@ static void rtl8188eu_config_channel(struct ieee80211_hw *hw) static void rtl8188eu_init_aggregation(struct rtl8xxxu_priv *priv) { u8 agg_ctrl, usb_spec; + u8 rxagg_usb_size = 16; + u8 rxagg_usb_timeout = 6; usb_spec = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION); usb_spec &= ~USB_SPEC_USB_AGG_ENABLE; + if (rtl8xxxu_dma_aggregation) + usb_spec |= USB_SPEC_USB_AGG_ENABLE; rtl8xxxu_write8(priv, REG_USB_SPECIAL_OPTION, usb_spec); agg_ctrl = rtl8xxxu_read8(priv, REG_TRXDMA_CTRL); agg_ctrl &= ~TRXDMA_CTRL_RXDMA_AGG_EN; rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + + if (rtl8xxxu_dma_aggregation) { + rtl8xxxu_write8(priv, REG_USB_AGG_THRESH, rxagg_usb_size); + rtl8xxxu_write8(priv, REG_USB_AGG_TIMEOUT, rxagg_usb_timeout); + + priv->rx_buf_aggregation = 1; + } } static int rtl8188eu_parse_efuse(struct rtl8xxxu_priv *priv) @@ -1877,6 +1888,8 @@ struct rtl8xxxu_fileops rtl8188eu_fops = { .cck_rssi = rtl8188e_cck_rssi, .led_classdev_brightness_set = rtl8188eu_led_brightness_set, .writeN_block_size = 128, + .rx_agg_buf_size = 15360 - sizeof(struct rtl8xxxu_rxdesc16) + - sizeof(struct rtl8723au_phy_stats), .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), .has_tx_report = 1, diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 01285300b83b..9b7fe459cb78 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -36,7 +36,7 @@ int rtl8xxxu_debug; static bool rtl8xxxu_ht40_2g; -static bool rtl8xxxu_dma_aggregation; +bool rtl8xxxu_dma_aggregation; static int rtl8xxxu_dma_agg_timeout = -1; static int rtl8xxxu_dma_agg_pages = -1; @@ -6240,6 +6240,8 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) return RX_TYPE_ERROR; } + // pr_warn("urb_len: %d\n", urb_len); + do { rx_desc = (struct rtl8xxxu_rxdesc16 *)skb->data; _rx_desc_le = (__le32 *)skb->data; @@ -6259,8 +6261,21 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) drvinfo_sz = rx_desc->drvinfo_sz * 8; desc_shift = rx_desc->shift; + + if (rx_desc->rpt_sel == 1) { + pkt_len = 8; + drvinfo_sz = 0; + desc_shift = 0; + } else if (rx_desc->rpt_sel == 2) { + pkt_len = pkt_len & 0x3ff; + drvinfo_sz = 0; + desc_shift = 0; + } + pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift + - sizeof(struct rtl8xxxu_rxdesc16), 128); + sizeof(struct rtl8xxxu_rxdesc16), 4); + + // pr_warn(" pkt_len %d pkt_offset %d rpt_sel %d\n", pkt_len, pkt_offset, rx_desc->rpt_sel); /* * Only clone the skb if there's enough data at the end to @@ -6275,16 +6290,16 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16)); + phy_stats = (struct rtl8723au_phy_stats *)skb->data; + + skb_pull(skb, drvinfo_sz + desc_shift); + + skb_trim(skb, pkt_len); + if (rx_desc->rpt_sel) { skb_queue_tail(&priv->c2hcmd_queue, skb); schedule_work(&priv->c2hcmd_work); } else { - phy_stats = (struct rtl8723au_phy_stats *)skb->data; - - skb_pull(skb, drvinfo_sz + desc_shift); - - skb_trim(skb, pkt_len); - if (rx_desc->phy_stats) priv->fops->parse_phystats( priv, rx_status, phy_stats,