diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtl8xxxu')
7 files changed, 248 insertions, 132 deletions
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index 870c9cd5c..4341d5680 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -135,7 +135,8 @@ struct rtl8xxxu_rxdesc16 { u32 seq:12; u32 frag:4; - u32 nextpktlen:14; + u32 pkt_cnt:8; + u32 reserved:6; u32 nextind:1; u32 reserved0:1; @@ -198,7 +199,8 @@ struct rtl8xxxu_rxdesc16 { u32 reserved0:1; u32 nextind:1; - u32 nextpktlen:14; + u32 reserved:6; + u32 pkt_cnt:8; u32 frag:4; u32 seq:12; @@ -1245,6 +1247,7 @@ struct rtl8xxxu_priv { u32 ep_tx_normal_queue:1; u32 ep_tx_low_queue:1; u32 has_xtalk:1; + u32 rx_buf_aggregation:1; u8 xtalk; unsigned int pipe_interrupt; unsigned int pipe_in; @@ -1315,8 +1318,7 @@ struct rtl8xxxu_fileops { void (*phy_init_antenna_selection) (struct rtl8xxxu_priv *priv); void (*phy_iq_calibrate) (struct rtl8xxxu_priv *priv); void (*config_channel) (struct ieee80211_hw *hw); - int (*parse_rx_desc) (struct rtl8xxxu_priv *priv, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status); + int (*parse_rx_desc) (struct rtl8xxxu_priv *priv, struct sk_buff *skb); void (*init_aggregation) (struct rtl8xxxu_priv *priv); void (*init_statistics) (struct rtl8xxxu_priv *priv); void (*enable_rf) (struct rtl8xxxu_priv *priv); @@ -1329,6 +1331,7 @@ struct rtl8xxxu_fileops { void (*report_connect) (struct rtl8xxxu_priv *priv, u8 macid, bool connect); int writeN_block_size; + int rx_agg_buf_size; char tx_desc_size; char rx_desc_size; char has_s0s1; @@ -1409,13 +1412,12 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, u8 macid, bool connect); void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, u8 macid, bool connect); +void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv); void rtl8xxxu_gen1_enable_rf(struct rtl8xxxu_priv *priv); void rtl8xxxu_gen1_disable_rf(struct rtl8xxxu_priv *priv); void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv); -int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status); -int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status); +int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb); +int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb); int rtl8xxxu_gen2_channel_to_group(int channel); bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv, int result[][8], int c1, int c2); diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c index 08066dec1..1bb6ba015 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c @@ -413,13 +413,8 @@ static int rtl8192cu_parse_efuse(struct rtl8xxxu_priv *priv) dev_info(&priv->udev->dev, "%s: dumping efuse (0x%02zx bytes):\n", __func__, sizeof(struct rtl8192cu_efuse)); - for (i = 0; i < sizeof(struct rtl8192cu_efuse); i += 8) { - dev_info(&priv->udev->dev, "%02x: " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", i, - raw[i], raw[i + 1], raw[i + 2], - raw[i + 3], raw[i + 4], raw[i + 5], - raw[i + 6], raw[i + 7]); - } + for (i = 0; i < sizeof(struct rtl8192cu_efuse); i += 8) + dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]); } return 0; } @@ -565,6 +560,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = { .phy_iq_calibrate = rtl8xxxu_gen1_phy_iq_calibrate, .config_channel = rtl8xxxu_gen1_config_channel, .parse_rx_desc = rtl8xxxu_parse_rxdesc16, + .init_aggregation = rtl8xxxu_gen1_init_aggregation, .enable_rf = rtl8xxxu_gen1_enable_rf, .disable_rf = rtl8xxxu_gen1_disable_rf, .usb_quirks = rtl8xxxu_gen1_usb_quirks, @@ -572,6 +568,7 @@ struct rtl8xxxu_fileops rtl8192cu_fops = { .update_rate_mask = rtl8xxxu_update_rate_mask, .report_connect = rtl8xxxu_gen1_report_connect, .writeN_block_size = 128, + .rx_agg_buf_size = 16000, .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), .adda_1t_init = 0x0b1b25a0, diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c index 9461ecd31..70e7c42cc 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -622,13 +622,8 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) dev_info(&priv->udev->dev, "%s: dumping efuse (0x%02zx bytes):\n", __func__, sizeof(struct rtl8192eu_efuse)); - for (i = 0; i < sizeof(struct rtl8192eu_efuse); i += 8) { - dev_info(&priv->udev->dev, "%02x: " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", i, - raw[i], raw[i + 1], raw[i + 2], - raw[i + 3], raw[i + 4], raw[i + 5], - raw[i + 6], raw[i + 7]); - } + for (i = 0; i < sizeof(struct rtl8192eu_efuse); i += 8) + dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]); } return 0; } @@ -1249,11 +1244,9 @@ static void rtl8192eu_phy_iq_calibrate(struct rtl8xxxu_priv *priv) reg_e94 = result[i][0]; reg_e9c = result[i][1]; reg_ea4 = result[i][2]; - reg_eac = result[i][3]; reg_eb4 = result[i][4]; reg_ebc = result[i][5]; reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; } if (candidate >= 0) { diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c index cd6bf209d..52688d5cd 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c @@ -377,6 +377,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = { .phy_iq_calibrate = rtl8xxxu_gen1_phy_iq_calibrate, .config_channel = rtl8xxxu_gen1_config_channel, .parse_rx_desc = rtl8xxxu_parse_rxdesc16, + .init_aggregation = rtl8xxxu_gen1_init_aggregation, .enable_rf = rtl8xxxu_gen1_enable_rf, .disable_rf = rtl8xxxu_gen1_disable_rf, .usb_quirks = rtl8xxxu_gen1_usb_quirks, @@ -384,6 +385,7 @@ struct rtl8xxxu_fileops rtl8723au_fops = { .update_rate_mask = rtl8xxxu_update_rate_mask, .report_connect = rtl8xxxu_gen1_report_connect, .writeN_block_size = 1024, + .rx_agg_buf_size = 16000, .tx_desc_size = sizeof(struct rtl8xxxu_txdesc32), .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16), .adda_1t_init = 0x0b1b25a0, diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c index 6f42f0a16..1348819f6 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c @@ -466,13 +466,8 @@ static int rtl8723bu_parse_efuse(struct rtl8xxxu_priv *priv) dev_info(&priv->udev->dev, "%s: dumping efuse (0x%02zx bytes):\n", __func__, sizeof(struct rtl8723bu_efuse)); - for (i = 0; i < sizeof(struct rtl8723bu_efuse); i += 8) { - dev_info(&priv->udev->dev, "%02x: " - "%02x %02x %02x %02x %02x %02x %02x %02x\n", i, - raw[i], raw[i + 1], raw[i + 2], - raw[i + 3], raw[i + 4], raw[i + 5], - raw[i + 6], raw[i + 7]); - } + for (i = 0; i < sizeof(struct rtl8723bu_efuse); i += 8) + dev_info(&priv->udev->dev, "%02x: %8ph\n", i, &raw[i]); } return 0; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 05a1ff26f..4b56f3921 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -44,6 +44,9 @@ int rtl8xxxu_debug = RTL8XXXU_DEBUG_EFUSE; static bool rtl8xxxu_ht40_2g; +static bool rtl8xxxu_dma_aggregation; +static int rtl8xxxu_dma_agg_timeout = -1; +static int rtl8xxxu_dma_agg_pages = -1; MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>"); MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver"); @@ -54,10 +57,14 @@ module_param_named(debug, rtl8xxxu_debug, int, 0600); MODULE_PARM_DESC(debug, "Set debug mask"); module_param_named(ht40_2g, rtl8xxxu_ht40_2g, bool, 0600); MODULE_PARM_DESC(ht40_2g, "Enable HT40 support on the 2.4GHz band"); +module_param_named(dma_aggregation, rtl8xxxu_dma_aggregation, bool, 0600); +MODULE_PARM_DESC(dma_aggregation, "Enable DMA packet aggregation"); +module_param_named(dma_agg_timeout, rtl8xxxu_dma_agg_timeout, int, 0600); +MODULE_PARM_DESC(dma_agg_timeout, "Set DMA aggregation timeout (range 1-127)"); +module_param_named(dma_agg_pages, rtl8xxxu_dma_agg_pages, int, 0600); +MODULE_PARM_DESC(dma_agg_pages, "Set DMA aggregation pages (range 1-127, 0 to disable)"); #define USB_VENDOR_ID_REALTEK 0x0bda -/* Minimum IEEE80211_MAX_FRAME_LEN */ -#define RTL_RX_BUFFER_SIZE IEEE80211_MAX_FRAME_LEN #define RTL8XXXU_RX_URBS 32 #define RTL8XXXU_RX_URB_PENDING_WATER 8 #define RTL8XXXU_TX_URBS 64 @@ -4399,6 +4406,73 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt)); } +void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) +{ + u8 agg_ctrl, usb_spec, page_thresh, timeout; + + usb_spec = rtl8xxxu_read8(priv, REG_USB_SPECIAL_OPTION); + 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; + + if (!rtl8xxxu_dma_aggregation) { + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + return; + } + + agg_ctrl |= TRXDMA_CTRL_RXDMA_AGG_EN; + rtl8xxxu_write8(priv, REG_TRXDMA_CTRL, agg_ctrl); + + /* + * The number of packets we can take looks to be buffer size / 512 + * which matches the 512 byte rounding we have to do when de-muxing + * the packets. + * + * Sample numbers from the vendor driver: + * USB High-Speed mode values: + * RxAggBlockCount = 8 : 512 byte unit + * RxAggBlockTimeout = 6 + * RxAggPageCount = 48 : 128 byte unit + * RxAggPageTimeout = 4 or 6 (absolute time 34ms/(2^6)) + */ + + page_thresh = (priv->fops->rx_agg_buf_size / 512); + if (rtl8xxxu_dma_agg_pages >= 0) { + if (rtl8xxxu_dma_agg_pages <= page_thresh) + timeout = page_thresh; + else if (rtl8xxxu_dma_agg_pages <= 6) + dev_err(&priv->udev->dev, + "%s: dma_agg_pages=%i too small, minium is 6\n", + __func__, rtl8xxxu_dma_agg_pages); + else + dev_err(&priv->udev->dev, + "%s: dma_agg_pages=%i larger than limit %i\n", + __func__, rtl8xxxu_dma_agg_pages, page_thresh); + } + rtl8xxxu_write8(priv, REG_RXDMA_AGG_PG_TH, page_thresh); + /* + * REG_RXDMA_AGG_PG_TH + 1 seems to be the timeout register on + * gen2 chips and rtl8188eu. The rtl8723au seems unhappy if we + * don't set it, so better set both. + */ + timeout = 4; + + if (rtl8xxxu_dma_agg_timeout >= 0) { + if (rtl8xxxu_dma_agg_timeout <= 127) + timeout = rtl8xxxu_dma_agg_timeout; + else + dev_err(&priv->udev->dev, + "%s: Invalid dma_agg_timeout: %i\n", + __func__, rtl8xxxu_dma_agg_timeout); + } + + rtl8xxxu_write8(priv, REG_RXDMA_AGG_PG_TH + 1, timeout); + rtl8xxxu_write8(priv, REG_USB_DMA_AGG_TO, timeout); + priv->rx_buf_aggregation = 1; +} + static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg) { u32 val32; @@ -5037,55 +5111,143 @@ static void rtl8xxxu_rx_urb_work(struct work_struct *work) } } -int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status) +static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, + struct sk_buff *skb) +{ + struct rtl8723bu_c2h *c2h = (struct rtl8723bu_c2h *)skb->data; + struct device *dev = &priv->udev->dev; + int len; + + len = skb->len - 2; + + dev_dbg(dev, "C2H ID %02x seq %02x, len %02x source %02x\n", + c2h->id, c2h->seq, len, c2h->bt_info.response_source); + + switch(c2h->id) { + case C2H_8723B_BT_INFO: + if (c2h->bt_info.response_source > + BT_INFO_SRC_8723B_BT_ACTIVE_SEND) + dev_dbg(dev, "C2H_BT_INFO WiFi only firmware\n"); + else + dev_dbg(dev, "C2H_BT_INFO BT/WiFi coexist firmware\n"); + + if (c2h->bt_info.bt_has_reset) + dev_dbg(dev, "BT has been reset\n"); + if (c2h->bt_info.tx_rx_mask) + dev_dbg(dev, "BT TRx mask\n"); + + break; + case C2H_8723B_BT_MP_INFO: + dev_dbg(dev, "C2H_MP_INFO ext ID %02x, status %02x\n", + c2h->bt_mp_info.ext_id, c2h->bt_mp_info.status); + break; + case C2H_8723B_RA_REPORT: + dev_dbg(dev, + "C2H RA RPT: rate %02x, unk %i, macid %02x, noise %i\n", + c2h->ra_report.rate, c2h->ra_report.dummy0_0, + c2h->ra_report.macid, c2h->ra_report.noisy_state); + break; + default: + dev_info(dev, "Unhandled C2H event %02x seq %02x\n", + c2h->id, c2h->seq); + print_hex_dump(KERN_INFO, "C2H content: ", DUMP_PREFIX_NONE, + 16, 1, c2h->raw.payload, len, false); + break; + } +} + +int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) { - struct rtl8xxxu_rxdesc16 *rx_desc = - (struct rtl8xxxu_rxdesc16 *)skb->data; + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_rx_status *rx_status; + struct rtl8xxxu_rxdesc16 *rx_desc; struct rtl8723au_phy_stats *phy_stats; - __le32 *_rx_desc_le = (__le32 *)skb->data; - u32 *_rx_desc = (u32 *)skb->data; + struct sk_buff *next_skb = NULL; + __le32 *_rx_desc_le; + u32 *_rx_desc; int drvinfo_sz, desc_shift; - int i; + int i, pkt_cnt, pkt_len, urb_len, pkt_offset; - for (i = 0; i < (sizeof(struct rtl8xxxu_rxdesc16) / sizeof(u32)); i++) - _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); + urb_len = skb->len; + pkt_cnt = 0; - skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc16)); + do { + rx_desc = (struct rtl8xxxu_rxdesc16 *)skb->data; + _rx_desc_le = (__le32 *)skb->data; + _rx_desc = (u32 *)skb->data; - phy_stats = (struct rtl8723au_phy_stats *)skb->data; + for (i = 0; + i < (sizeof(struct rtl8xxxu_rxdesc16) / sizeof(u32)); i++) + _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); - drvinfo_sz = rx_desc->drvinfo_sz * 8; - desc_shift = rx_desc->shift; - skb_pull(skb, drvinfo_sz + desc_shift); + /* + * Only read pkt_cnt from the header if we're parsing the + * first packet + */ + if (!pkt_cnt) + pkt_cnt = rx_desc->pkt_cnt; + pkt_len = rx_desc->pktlen; - if (rx_desc->phy_stats) - rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats, - rx_desc->rxmcs); + drvinfo_sz = rx_desc->drvinfo_sz * 8; + desc_shift = rx_desc->shift; + pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift + + sizeof(struct rtl8xxxu_rxdesc16), 128); - rx_status->mactime = le32_to_cpu(rx_desc->tsfl); - rx_status->flag |= RX_FLAG_MACTIME_START; + if (pkt_cnt > 1) + next_skb = skb_clone(skb, GFP_ATOMIC); - if (!rx_desc->swdec) - rx_status->flag |= RX_FLAG_DECRYPTED; - if (rx_desc->crc32) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - if (rx_desc->bw) - rx_status->flag |= RX_FLAG_40MHZ; + rx_status = IEEE80211_SKB_RXCB(skb); + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - if (rx_desc->rxht) { - rx_status->flag |= RX_FLAG_HT; - rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0; - } else { - rx_status->rate_idx = rx_desc->rxmcs; - } + 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->phy_stats) + rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats, + rx_desc->rxmcs); + + rx_status->mactime = le32_to_cpu(rx_desc->tsfl); + rx_status->flag |= RX_FLAG_MACTIME_START; + + if (!rx_desc->swdec) + rx_status->flag |= RX_FLAG_DECRYPTED; + if (rx_desc->crc32) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + if (rx_desc->bw) + rx_status->flag |= RX_FLAG_40MHZ; + + if (rx_desc->rxht) { + rx_status->flag |= RX_FLAG_HT; + rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0; + } else { + rx_status->rate_idx = rx_desc->rxmcs; + } + + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + ieee80211_rx_irqsafe(hw, skb); + + skb = next_skb; + if (skb) + skb_pull(next_skb, pkt_offset); + + pkt_cnt--; + urb_len -= pkt_offset; + } while (skb && urb_len > 0 && pkt_cnt > 0); return RX_TYPE_DATA_PKT; } -int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status) +int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb) { + struct ieee80211_hw *hw = priv->hw; + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct rtl8xxxu_rxdesc24 *rx_desc = (struct rtl8xxxu_rxdesc24 *)skb->data; struct rtl8723au_phy_stats *phy_stats; @@ -5097,6 +5259,8 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb, for (i = 0; i < (sizeof(struct rtl8xxxu_rxdesc24) / sizeof(u32)); i++) _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); + memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + skb_pull(skb, sizeof(struct rtl8xxxu_rxdesc24)); phy_stats = (struct rtl8723au_phy_stats *)skb->data; @@ -5108,6 +5272,8 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb, if (rx_desc->rpt_sel) { struct device *dev = &priv->udev->dev; dev_dbg(dev, "%s: C2H packet\n", __func__); + rtl8723bu_handle_c2h(priv, skb); + dev_kfree_skb(skb); return RX_TYPE_C2H; } @@ -5132,52 +5298,11 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb, rx_status->rate_idx = rx_desc->rxmcs; } - return RX_TYPE_DATA_PKT; -} - -static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, - struct sk_buff *skb) -{ - struct rtl8723bu_c2h *c2h = (struct rtl8723bu_c2h *)skb->data; - struct device *dev = &priv->udev->dev; - int len; - - len = skb->len - 2; - - dev_dbg(dev, "C2H ID %02x seq %02x, len %02x source %02x\n", - c2h->id, c2h->seq, len, c2h->bt_info.response_source); - - switch(c2h->id) { - case C2H_8723B_BT_INFO: - if (c2h->bt_info.response_source > - BT_INFO_SRC_8723B_BT_ACTIVE_SEND) - dev_dbg(dev, "C2H_BT_INFO WiFi only firmware\n"); - else - dev_dbg(dev, "C2H_BT_INFO BT/WiFi coexist firmware\n"); - - if (c2h->bt_info.bt_has_reset) - dev_dbg(dev, "BT has been reset\n"); - if (c2h->bt_info.tx_rx_mask) - dev_dbg(dev, "BT TRx mask\n"); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; - break; - case C2H_8723B_BT_MP_INFO: - dev_dbg(dev, "C2H_MP_INFO ext ID %02x, status %02x\n", - c2h->bt_mp_info.ext_id, c2h->bt_mp_info.status); - break; - case C2H_8723B_RA_REPORT: - dev_dbg(dev, - "C2H RA RPT: rate %02x, unk %i, macid %02x, noise %i\n", - c2h->ra_report.rate, c2h->ra_report.dummy0_0, - c2h->ra_report.macid, c2h->ra_report.noisy_state); - break; - default: - dev_info(dev, "Unhandled C2H event %02x seq %02x\n", - c2h->id, c2h->seq); - print_hex_dump(KERN_INFO, "C2H content: ", DUMP_PREFIX_NONE, - 16, 1, c2h->raw.payload, len, false); - break; - } + ieee80211_rx_irqsafe(hw, skb); + return RX_TYPE_DATA_PKT; } static void rtl8xxxu_rx_complete(struct urb *urb) @@ -5187,26 +5312,12 @@ static void rtl8xxxu_rx_complete(struct urb *urb) struct ieee80211_hw *hw = rx_urb->hw; struct rtl8xxxu_priv *priv = hw->priv; struct sk_buff *skb = (struct sk_buff *)urb->context; - struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); struct device *dev = &priv->udev->dev; - int rx_type; skb_put(skb, urb->actual_length); if (urb->status == 0) { - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - - rx_type = priv->fops->parse_rx_desc(priv, skb, rx_status); - - rx_status->freq = hw->conf.chandef.chan->center_freq; - rx_status->band = hw->conf.chandef.chan->band; - - if (rx_type == RX_TYPE_DATA_PKT) - ieee80211_rx_irqsafe(hw, skb); - else { - rtl8723bu_handle_c2h(priv, skb); - dev_kfree_skb(skb); - } + priv->fops->parse_rx_desc(priv, skb); skb = NULL; rx_urb->urb.context = NULL; @@ -5226,12 +5337,20 @@ cleanup: static int rtl8xxxu_submit_rx_urb(struct rtl8xxxu_priv *priv, struct rtl8xxxu_rx_urb *rx_urb) { + struct rtl8xxxu_fileops *fops = priv->fops; struct sk_buff *skb; int skb_size; int ret, rx_desc_sz; - rx_desc_sz = priv->fops->rx_desc_size; - skb_size = rx_desc_sz + RTL_RX_BUFFER_SIZE; + rx_desc_sz = fops->rx_desc_size; + + if (priv->rx_buf_aggregation && fops->rx_agg_buf_size) { + skb_size = fops->rx_agg_buf_size; + skb_size += (rx_desc_sz + sizeof(struct rtl8723au_phy_stats)); + } else { + skb_size = IEEE80211_MAX_FRAME_LEN; + } + skb = __netdev_alloc_skb(NULL, skb_size, GFP_KERNEL); if (!skb) return -ENOMEM; @@ -5259,7 +5378,7 @@ static void rtl8xxxu_int_complete(struct urb *urb) if (ret) usb_unanchor_urb(urb); } else { - dev_info(dev, "%s: Error %i\n", __func__, urb->status); + dev_dbg(dev, "%s: Error %i\n", __func__, urb->status); } } diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h index b0e0c6423..921c5653f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h @@ -405,7 +405,11 @@ #define REG_DWBCN1_CTRL_8723B 0x0228 /* 0x0280 ~ 0x02FF RXDMA Configuration */ -#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXDMA_AGG_PG_TH 0x0280 /* 0-7 : USB DMA size bits + 8-14: USB DMA timeout + 15 : Aggregation enable + Only seems to be used + on 8723bu/8192eu */ #define RXDMA_USB_AGG_ENABLE BIT(31) #define REG_RXPKT_NUM 0x0284 #define RXPKT_NUM_RXDMA_IDLE BIT(17) @@ -1052,10 +1056,14 @@ #define USB_HIMR_ROK BIT(0) /* Receive DMA OK Interrupt */ #define REG_USB_SPECIAL_OPTION 0xfe55 +#define USB_SPEC_USB_AGG_ENABLE BIT(3) /* Enable USB aggregation */ +#define USB_SPEC_INT_BULK_SELECT BIT(4) /* Use interrupt endpoint to + deliver interrupt packet. + 0: Use int, 1: use bulk */ #define REG_USB_HRPWM 0xfe58 #define REG_USB_DMA_AGG_TO 0xfe5b -#define REG_USB_AGG_TO 0xfe5c -#define REG_USB_AGG_TH 0xfe5d +#define REG_USB_AGG_TIMEOUT 0xfe5c +#define REG_USB_AGG_THRESH 0xfe5d #define REG_NORMAL_SIE_VID 0xfe60 /* 0xfe60 - 0xfe61 */ #define REG_NORMAL_SIE_PID 0xfe62 /* 0xfe62 - 0xfe63 */ |