From e5d1ab1a73ad275c0205cbc09a0a9f9f42bbb87f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 3 Jan 2023 13:41:15 +0100 Subject: wifi: brcmfmac: avoid handling disabled channels for survey dump An issue was reported in which periodically error messages are printed in the kernel log: [ 26.303445] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43455-sdio for chip BCM4345/6 [ 26.303554] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.bin failed with error -2 [ 26.516752] brcmfmac_wcc: brcmf_wcc_attach: executing [ 26.528264] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4345/6 wl0: Jan 4 2021 19:56:29 version 7.45.229 (617f1f5 CY) FWID 01-2dbd9d2e [ 27.076829] Bluetooth: hci0: BCM: features 0x2f [ 27.078592] Bluetooth: hci0: BCM43455 37.4MHz Raspberry Pi 3+ [ 27.078601] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0342 [ 30.142104] Adding 102396k swap on /var/swap. Priority:-2 extents:1 across:102396k SS [ 30.590017] Bluetooth: MGMT ver 1.22 [ 104.897615] brcmfmac: cfg80211_set_channel: set chanspec 0x100e fail, reason -52 [ 104.897992] brcmfmac: cfg80211_set_channel: set chanspec 0xd022 fail, reason -52 [ 105.007672] brcmfmac: cfg80211_set_channel: set chanspec 0xd026 fail, reason -52 [ 105.117654] brcmfmac: cfg80211_set_channel: set chanspec 0xd02a fail, reason -52 [ 105.227636] brcmfmac: cfg80211_set_channel: set chanspec 0xd02e fail, reason -52 [ 106.987552] brcmfmac: cfg80211_set_channel: set chanspec 0xd090 fail, reason -52 [ 106.987911] brcmfmac: cfg80211_set_channel: set chanspec 0xd095 fail, reason -52 [ 106.988233] brcmfmac: cfg80211_set_channel: set chanspec 0xd099 fail, reason -52 [ 106.988565] brcmfmac: cfg80211_set_channel: set chanspec 0xd09d fail, reason -52 [ 106.988909] brcmfmac: cfg80211_set_channel: set chanspec 0xd0a1 fail, reason -52 This happens in brcmf_cfg80211_dump_survey() because we try a disabled channel. When channel is marked as disabled we do not need to fill any other info so bail out. Fixes: 6c04deae1438 ("brcmfmac: Add dump_survey cfg80211 ops for HostApd AutoChannelSelection") Reported-by: Stefan Wahren Signed-off-by: Arend van Spriel Tested-by: Stefan Wahren Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230103124117.271988-2-arend.vanspriel@broadcom.com --- .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index bff3128c2f26..478ca3848c64 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -7937,6 +7937,9 @@ cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + if (chan->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; + /* set_channel */ chspec = channel_to_chanspec(&cfg->d11inf, chan); if (chspec != INVCHANSPEC) { @@ -7961,7 +7964,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct brcmf_dump_survey survey = {}; struct ieee80211_supported_band *band; - struct ieee80211_channel *chan; struct cca_msrmnt_query req; u32 noise; int err; @@ -7987,13 +7989,10 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, } /* Setting current channel to the requested channel */ - chan = &band->channels[idx]; - err = cfg80211_set_channel(wiphy, ndev, chan, NL80211_CHAN_HT20); - if (err) { - info->channel = chan; - info->filled = 0; + info->filled = 0; + info->channel = &band->channels[idx]; + if (cfg80211_set_channel(wiphy, ndev, info->channel, NL80211_CHAN_HT20)) return 0; - } /* Disable mpc */ brcmf_set_mpc(ifp, 0); @@ -8028,7 +8027,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, if (err) goto exit; - info->channel = chan; info->noise = noise; info->time = ACS_MSRMNT_DELAY; info->time_busy = ACS_MSRMNT_DELAY - survey.idle; @@ -8040,7 +8038,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, SURVEY_INFO_TIME_TX; brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n", - ieee80211_frequency_to_channel(chan->center_freq), + ieee80211_frequency_to_channel(info->channel->center_freq), ACS_MSRMNT_DELAY); brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n", info->noise, info->time_busy, info->time_rx, info->time_tx); -- cgit v1.2.3 From aadb50d1571211c73248605bcc1f4b9f8e3d1364 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 3 Jan 2023 13:41:16 +0100 Subject: wifi: brcmfmac: avoid NULL-deref in survey dump for 2G only device When dealing with a device for 2GHz band only the wiphy->bands for 5GHz will be NULL. This would result in a NULL-deref in the brcmf_cfg80211_dump_survey() function. Rework the code with a for-loop to make it easier to add another band. Fixes: 6c04deae1438 ("brcmfmac: Add dump_survey cfg80211 ops for HostApd AutoChannelSelection") Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230103124117.271988-3-arend.vanspriel@broadcom.com --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 478ca3848c64..b115902eb475 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -7964,6 +7964,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct brcmf_dump_survey survey = {}; struct ieee80211_supported_band *band; + enum nl80211_band band_id; struct cca_msrmnt_query req; u32 noise; int err; @@ -7976,21 +7977,23 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, return -EBUSY; } - band = wiphy->bands[NL80211_BAND_2GHZ]; - if (band && idx >= band->n_channels) { - idx -= band->n_channels; - band = NULL; - } + for (band_id = 0; band_id < NUM_NL80211_BANDS; band_id++) { + band = wiphy->bands[band_id]; + if (!band) + continue; + if (idx >= band->n_channels) { + idx -= band->n_channels; + continue; + } - if (!band || idx >= band->n_channels) { - band = wiphy->bands[NL80211_BAND_5GHZ]; - if (idx >= band->n_channels) - return -ENOENT; + info->channel = &band->channels[idx]; + break; } + if (band_id == NUM_NL80211_BANDS) + return -ENOENT; /* Setting current channel to the requested channel */ info->filled = 0; - info->channel = &band->channels[idx]; if (cfg80211_set_channel(wiphy, ndev, info->channel, NL80211_CHAN_HT20)) return 0; -- cgit v1.2.3 From ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 11 Jan 2023 12:24:19 +0100 Subject: wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices A sanity check was introduced considering maximum flowrings above 256 as insane and effectively aborting the device probe. This resulted in regression for number of users as the value turns out to be sane after all. Fixes: 2aca4f3734bd ("brcmfmac: return error when getting invalid max_flowrings from dongle") Reported-by: chainofflowers Link: https://lore.kernel.org/all/4781984.GXAFRqVoOG@luna/ Reported-by: Christian Marillat Link: https://bugzilla.kernel.org/show_bug.cgi?id=216894 Cc: stable@vger.kernel.org Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230111112419.24185-1-arend.vanspriel@broadcom.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index ae57a9a3ab05..b67f6d0810b6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1228,7 +1228,7 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) BRCMF_NROF_H2D_COMMON_MSGRINGS; max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; } - if (max_flowrings > 256) { + if (max_flowrings > 512) { brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings); return -EIO; } -- cgit v1.2.3 From b870e73a56c4cccbec33224233eaf295839f228c Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Wed, 11 Jan 2023 18:50:31 +0100 Subject: wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid Since resplen and respoffs are signed integers sufficiently large values of unsigned int len and offset members of RNDIS response will result in negative values of prior variables. This may be utilized to bypass implemented security checks to either extract memory contents by manipulating offset or overflow the data buffer via memcpy by manipulating both offset and len. Additionally assure that sum of resplen and respoffs does not overflow so buffer boundaries are kept. Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond") Signed-off-by: Szymon Heidrich Reviewed-by: Alexander Duyck Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230111175031.7049-1-szymon.heidrich@gmail.com --- drivers/net/wireless/rndis_wlan.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 82a7458e01ae..bf72e5fd39cf 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -696,8 +696,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) struct rndis_query *get; struct rndis_query_c *get_c; } u; - int ret, buflen; - int resplen, respoffs, copylen; + int ret; + size_t buflen, resplen, respoffs, copylen; buflen = *len + sizeof(*u.get); if (buflen < CONTROL_BUFFER_SIZE) @@ -732,22 +732,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) if (respoffs > buflen) { /* Device returned data offset outside buffer, error. */ - netdev_dbg(dev->net, "%s(%s): received invalid " - "data offset: %d > %d\n", __func__, - oid_to_string(oid), respoffs, buflen); + netdev_dbg(dev->net, + "%s(%s): received invalid data offset: %zu > %zu\n", + __func__, oid_to_string(oid), respoffs, buflen); ret = -EINVAL; goto exit_unlock; } - if ((resplen + respoffs) > buflen) { - /* Device would have returned more data if buffer would - * have been big enough. Copy just the bits that we got. - */ - copylen = buflen - respoffs; - } else { - copylen = resplen; - } + copylen = min(resplen, buflen - respoffs); if (copylen > *len) copylen = *len; -- cgit v1.2.3 From 1132d1c834d6185c89aef07c860fc143a6f2db93 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 13 Jan 2023 11:58:46 +0100 Subject: wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails Do not increment queue head if mt76_dma_add_buf fails for Wireless Ethernet Dispatcher rx queues. Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau (cherry picked from commit fe13dad8992be0b26c1be390bcd111acf9892c17) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-1-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index f795548562f5..c058a02e9ba5 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -212,14 +212,14 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, { struct mt76_queue_entry *entry; struct mt76_desc *desc; - u32 ctrl; int i, idx = -1; + u32 ctrl, next; for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; idx = q->head; - q->head = (q->head + 1) % q->ndesc; + next = (q->head + 1) % q->ndesc; desc = &q->desc[idx]; entry = &q->entry[idx]; @@ -239,8 +239,8 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, MT_DMA_CTL_TO_HOST; } else { if (txwi) { - q->entry[q->head].txwi = DMA_DUMMY_DATA; - q->entry[q->head].skip_buf0 = true; + q->entry[next].txwi = DMA_DUMMY_DATA; + q->entry[next].skip_buf0 = true; } if (buf[0].skip_unmap) @@ -271,6 +271,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, WRITE_ONCE(desc->info, cpu_to_le32(info)); WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + q->head = next; q->queued++; } -- cgit v1.2.3 From e5c3ac895750b39ef53b84ff4814617ecd69d556 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 13 Jan 2023 11:58:47 +0100 Subject: wifi: mt76: handle possible mt76_rx_token_consume failures Take into account possible error conditions of mt76_rx_token_consume routine in mt7915_mmio_wed_init_rx_buf() and mt76_dma_add_buf() Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau (cherry picked from commit 96f134dc19645be4994e89a2f68fa89309becbee) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-2-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 10 +++++++++- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 7 +++++++ drivers/net/wireless/mediatek/mt76/tx.c | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index c058a02e9ba5..61a8ab9e1db5 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -234,6 +234,9 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, rx_token = mt76_rx_token_consume(dev, (void *)skb, t, buf[0].addr); + if (rx_token < 0) + return -ENOMEM; + buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) | MT_DMA_CTL_TO_HOST; @@ -602,7 +605,12 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) qbuf.addr = addr + offset; qbuf.len = len - offset; qbuf.skip_unmap = false; - mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t); + if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) { + dma_unmap_single(dev->dma_dev, addr, len, + DMA_FROM_DEVICE); + skb_free_frag(buf); + break; + } frames++; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 0a95c3da241b..8388e2a65853 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -653,6 +653,13 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) desc->buf0 = cpu_to_le32(phy_addr); token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr); + if (token < 0) { + dma_unmap_single(dev->mt76.dma_dev, phy_addr, + wed->wlan.rx_size, DMA_TO_DEVICE); + skb_free_frag(ptr); + goto unmap; + } + desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN, token)); desc++; diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 24568b98ed9d..1f309d05380a 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -764,11 +764,12 @@ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, spin_lock_bh(&dev->rx_token_lock); token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size, GFP_ATOMIC); + if (token >= 0) { + t->ptr = ptr; + t->dma_addr = phys; + } spin_unlock_bh(&dev->rx_token_lock); - t->ptr = ptr; - t->dma_addr = phys; - return token; } EXPORT_SYMBOL_GPL(mt76_rx_token_consume); -- cgit v1.2.3 From 953519b35227d5dbbb5c5724f1f539735fbf7781 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Jan 2023 11:58:48 +0100 Subject: wifi: mt76: dma: fix a regression in adding rx buffers When adding WED support, mt76_dma_add_buf was accidentally changed to set the skip_buf0 flag for tx buffers on the wrong queue descriptor entry. Additionally, there is a rxwi leak when rx buffer allocation fails. Fix this and make the code more readable by adding a separate function for adding rx buffers. Reported-by: Mikhail Gavrilov Tested-by: Mikhail Gavrilov Link: https://lore.kernel.org/r/CABXGCsMEnQd=gYKTd1knRsWuxCb=Etv5nAre%2BXJS_s5FgVteYA@mail.gmail.com/ Reported-by: Mike Lothian Link: https://bugzilla.kernel.org/show_bug.cgi?id=216829 Reported-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/lkml/20230112171706.294550-1-angelogioacchino.delregno@collabora.com/ Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-3-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 124 ++++++++++++++++++------------- 1 file changed, 72 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 61a8ab9e1db5..06161815c180 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -205,6 +205,52 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q) mt76_dma_sync_idx(dev, q); } +static int +mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, + struct mt76_queue_buf *buf, void *data) +{ + struct mt76_desc *desc = &q->desc[q->head]; + struct mt76_queue_entry *entry = &q->entry[q->head]; + struct mt76_txwi_cache *txwi = NULL; + u32 buf1 = 0, ctrl; + int idx = q->head; + int rx_token; + + ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); + + if ((q->flags & MT_QFLAG_WED) && + FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { + txwi = mt76_get_rxwi(dev); + if (!txwi) + return -ENOMEM; + + rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr); + if (rx_token < 0) { + mt76_put_rxwi(dev, txwi); + return -ENOMEM; + } + + buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); + ctrl |= MT_DMA_CTL_TO_HOST; + } + + WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr)); + WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); + WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + WRITE_ONCE(desc->info, 0); + + entry->dma_addr[0] = buf->addr; + entry->dma_len[0] = buf->len; + entry->txwi = txwi; + entry->buf = data; + entry->wcid = 0xffff; + entry->skip_buf1 = true; + q->head = (q->head + 1) % q->ndesc; + q->queued++; + + return idx; +} + static int mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_buf *buf, int nbufs, u32 info, @@ -215,6 +261,11 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, int i, idx = -1; u32 ctrl, next; + if (txwi) { + q->entry[q->head].txwi = DMA_DUMMY_DATA; + q->entry[q->head].skip_buf0 = true; + } + for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; @@ -224,51 +275,28 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, desc = &q->desc[idx]; entry = &q->entry[idx]; - if ((q->flags & MT_QFLAG_WED) && - FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { - struct mt76_txwi_cache *t = txwi; - int rx_token; - - if (!t) - return -ENOMEM; - - rx_token = mt76_rx_token_consume(dev, (void *)skb, t, - buf[0].addr); - if (rx_token < 0) - return -ENOMEM; - - buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); - ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) | - MT_DMA_CTL_TO_HOST; - } else { - if (txwi) { - q->entry[next].txwi = DMA_DUMMY_DATA; - q->entry[next].skip_buf0 = true; - } - - if (buf[0].skip_unmap) - entry->skip_buf0 = true; - entry->skip_buf1 = i == nbufs - 1; - - entry->dma_addr[0] = buf[0].addr; - entry->dma_len[0] = buf[0].len; - - ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); - if (i < nbufs - 1) { - entry->dma_addr[1] = buf[1].addr; - entry->dma_len[1] = buf[1].len; - buf1 = buf[1].addr; - ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len); - if (buf[1].skip_unmap) - entry->skip_buf1 = true; - } - - if (i == nbufs - 1) - ctrl |= MT_DMA_CTL_LAST_SEC0; - else if (i == nbufs - 2) - ctrl |= MT_DMA_CTL_LAST_SEC1; + if (buf[0].skip_unmap) + entry->skip_buf0 = true; + entry->skip_buf1 = i == nbufs - 1; + + entry->dma_addr[0] = buf[0].addr; + entry->dma_len[0] = buf[0].len; + + ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); + if (i < nbufs - 1) { + entry->dma_addr[1] = buf[1].addr; + entry->dma_len[1] = buf[1].len; + buf1 = buf[1].addr; + ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len); + if (buf[1].skip_unmap) + entry->skip_buf1 = true; } + if (i == nbufs - 1) + ctrl |= MT_DMA_CTL_LAST_SEC0; + else if (i == nbufs - 2) + ctrl |= MT_DMA_CTL_LAST_SEC1; + WRITE_ONCE(desc->buf0, cpu_to_le32(buf0)); WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); WRITE_ONCE(desc->info, cpu_to_le32(info)); @@ -581,17 +609,9 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) spin_lock_bh(&q->lock); while (q->queued < q->ndesc - 1) { - struct mt76_txwi_cache *t = NULL; struct mt76_queue_buf qbuf; void *buf = NULL; - if ((q->flags & MT_QFLAG_WED) && - FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { - t = mt76_get_rxwi(dev); - if (!t) - break; - } - buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC); if (!buf) break; @@ -605,7 +625,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) qbuf.addr = addr + offset; qbuf.len = len - offset; qbuf.skip_unmap = false; - if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) { + if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) { dma_unmap_single(dev->dma_dev, addr, len, DMA_FROM_DEVICE); skb_free_frag(buf); -- cgit v1.2.3