Skip to content

Commit edb5b63

Browse files
committed
Merge tag 'wireless-2023-01-18' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless
Kalle Valo says: ==================== wireless fixes for v6.2 Third set of fixes for v6.2. This time most of them are for drivers, only one revert for mac80211. For an important mt76 fix we had to cherry pick two commits from wireless-next. * tag 'wireless-2023-01-18' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: Revert "wifi: mac80211: fix memory leak in ieee80211_if_add()" wifi: mt76: dma: fix a regression in adding rx buffers wifi: mt76: handle possible mt76_rx_token_consume failures wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices wifi: brcmfmac: avoid NULL-deref in survey dump for 2G only device wifi: brcmfmac: avoid handling disabled channels for survey dump ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents b9fb10d + 80f8a66 commit edb5b63

File tree

7 files changed

+117
-87
lines changed

7 files changed

+117
-87
lines changed

drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7937,6 +7937,9 @@ cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
79377937
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
79387938
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
79397939

7940+
if (chan->flags & IEEE80211_CHAN_DISABLED)
7941+
return -EINVAL;
7942+
79407943
/* set_channel */
79417944
chspec = channel_to_chanspec(&cfg->d11inf, chan);
79427945
if (chspec != INVCHANSPEC) {
@@ -7961,7 +7964,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
79617964
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
79627965
struct brcmf_dump_survey survey = {};
79637966
struct ieee80211_supported_band *band;
7964-
struct ieee80211_channel *chan;
7967+
enum nl80211_band band_id;
79657968
struct cca_msrmnt_query req;
79667969
u32 noise;
79677970
int err;
@@ -7974,26 +7977,25 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
79747977
return -EBUSY;
79757978
}
79767979

7977-
band = wiphy->bands[NL80211_BAND_2GHZ];
7978-
if (band && idx >= band->n_channels) {
7979-
idx -= band->n_channels;
7980-
band = NULL;
7981-
}
7980+
for (band_id = 0; band_id < NUM_NL80211_BANDS; band_id++) {
7981+
band = wiphy->bands[band_id];
7982+
if (!band)
7983+
continue;
7984+
if (idx >= band->n_channels) {
7985+
idx -= band->n_channels;
7986+
continue;
7987+
}
79827988

7983-
if (!band || idx >= band->n_channels) {
7984-
band = wiphy->bands[NL80211_BAND_5GHZ];
7985-
if (idx >= band->n_channels)
7986-
return -ENOENT;
7989+
info->channel = &band->channels[idx];
7990+
break;
79877991
}
7992+
if (band_id == NUM_NL80211_BANDS)
7993+
return -ENOENT;
79887994

79897995
/* Setting current channel to the requested channel */
7990-
chan = &band->channels[idx];
7991-
err = cfg80211_set_channel(wiphy, ndev, chan, NL80211_CHAN_HT20);
7992-
if (err) {
7993-
info->channel = chan;
7994-
info->filled = 0;
7996+
info->filled = 0;
7997+
if (cfg80211_set_channel(wiphy, ndev, info->channel, NL80211_CHAN_HT20))
79957998
return 0;
7996-
}
79977999

79988000
/* Disable mpc */
79998001
brcmf_set_mpc(ifp, 0);
@@ -8028,7 +8030,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
80288030
if (err)
80298031
goto exit;
80308032

8031-
info->channel = chan;
80328033
info->noise = noise;
80338034
info->time = ACS_MSRMNT_DELAY;
80348035
info->time_busy = ACS_MSRMNT_DELAY - survey.idle;
@@ -8040,7 +8041,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
80408041
SURVEY_INFO_TIME_TX;
80418042

80428043
brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n",
8043-
ieee80211_frequency_to_channel(chan->center_freq),
8044+
ieee80211_frequency_to_channel(info->channel->center_freq),
80448045
ACS_MSRMNT_DELAY);
80458046
brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
80468047
info->noise, info->time_busy, info->time_rx, info->time_tx);

drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
12281228
BRCMF_NROF_H2D_COMMON_MSGRINGS;
12291229
max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
12301230
}
1231-
if (max_flowrings > 256) {
1231+
if (max_flowrings > 512) {
12321232
brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
12331233
return -EIO;
12341234
}

drivers/net/wireless/mediatek/mt76/dma.c

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -205,72 +205,104 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
205205
mt76_dma_sync_idx(dev, q);
206206
}
207207

208+
static int
209+
mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
210+
struct mt76_queue_buf *buf, void *data)
211+
{
212+
struct mt76_desc *desc = &q->desc[q->head];
213+
struct mt76_queue_entry *entry = &q->entry[q->head];
214+
struct mt76_txwi_cache *txwi = NULL;
215+
u32 buf1 = 0, ctrl;
216+
int idx = q->head;
217+
int rx_token;
218+
219+
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
220+
221+
if ((q->flags & MT_QFLAG_WED) &&
222+
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
223+
txwi = mt76_get_rxwi(dev);
224+
if (!txwi)
225+
return -ENOMEM;
226+
227+
rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
228+
if (rx_token < 0) {
229+
mt76_put_rxwi(dev, txwi);
230+
return -ENOMEM;
231+
}
232+
233+
buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
234+
ctrl |= MT_DMA_CTL_TO_HOST;
235+
}
236+
237+
WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr));
238+
WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
239+
WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
240+
WRITE_ONCE(desc->info, 0);
241+
242+
entry->dma_addr[0] = buf->addr;
243+
entry->dma_len[0] = buf->len;
244+
entry->txwi = txwi;
245+
entry->buf = data;
246+
entry->wcid = 0xffff;
247+
entry->skip_buf1 = true;
248+
q->head = (q->head + 1) % q->ndesc;
249+
q->queued++;
250+
251+
return idx;
252+
}
253+
208254
static int
209255
mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
210256
struct mt76_queue_buf *buf, int nbufs, u32 info,
211257
struct sk_buff *skb, void *txwi)
212258
{
213259
struct mt76_queue_entry *entry;
214260
struct mt76_desc *desc;
215-
u32 ctrl;
216261
int i, idx = -1;
262+
u32 ctrl, next;
263+
264+
if (txwi) {
265+
q->entry[q->head].txwi = DMA_DUMMY_DATA;
266+
q->entry[q->head].skip_buf0 = true;
267+
}
217268

218269
for (i = 0; i < nbufs; i += 2, buf += 2) {
219270
u32 buf0 = buf[0].addr, buf1 = 0;
220271

221272
idx = q->head;
222-
q->head = (q->head + 1) % q->ndesc;
273+
next = (q->head + 1) % q->ndesc;
223274

224275
desc = &q->desc[idx];
225276
entry = &q->entry[idx];
226277

227-
if ((q->flags & MT_QFLAG_WED) &&
228-
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
229-
struct mt76_txwi_cache *t = txwi;
230-
int rx_token;
231-
232-
if (!t)
233-
return -ENOMEM;
234-
235-
rx_token = mt76_rx_token_consume(dev, (void *)skb, t,
236-
buf[0].addr);
237-
buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
238-
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) |
239-
MT_DMA_CTL_TO_HOST;
240-
} else {
241-
if (txwi) {
242-
q->entry[q->head].txwi = DMA_DUMMY_DATA;
243-
q->entry[q->head].skip_buf0 = true;
244-
}
245-
246-
if (buf[0].skip_unmap)
247-
entry->skip_buf0 = true;
248-
entry->skip_buf1 = i == nbufs - 1;
249-
250-
entry->dma_addr[0] = buf[0].addr;
251-
entry->dma_len[0] = buf[0].len;
252-
253-
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
254-
if (i < nbufs - 1) {
255-
entry->dma_addr[1] = buf[1].addr;
256-
entry->dma_len[1] = buf[1].len;
257-
buf1 = buf[1].addr;
258-
ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
259-
if (buf[1].skip_unmap)
260-
entry->skip_buf1 = true;
261-
}
262-
263-
if (i == nbufs - 1)
264-
ctrl |= MT_DMA_CTL_LAST_SEC0;
265-
else if (i == nbufs - 2)
266-
ctrl |= MT_DMA_CTL_LAST_SEC1;
278+
if (buf[0].skip_unmap)
279+
entry->skip_buf0 = true;
280+
entry->skip_buf1 = i == nbufs - 1;
281+
282+
entry->dma_addr[0] = buf[0].addr;
283+
entry->dma_len[0] = buf[0].len;
284+
285+
ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
286+
if (i < nbufs - 1) {
287+
entry->dma_addr[1] = buf[1].addr;
288+
entry->dma_len[1] = buf[1].len;
289+
buf1 = buf[1].addr;
290+
ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len);
291+
if (buf[1].skip_unmap)
292+
entry->skip_buf1 = true;
267293
}
268294

295+
if (i == nbufs - 1)
296+
ctrl |= MT_DMA_CTL_LAST_SEC0;
297+
else if (i == nbufs - 2)
298+
ctrl |= MT_DMA_CTL_LAST_SEC1;
299+
269300
WRITE_ONCE(desc->buf0, cpu_to_le32(buf0));
270301
WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
271302
WRITE_ONCE(desc->info, cpu_to_le32(info));
272303
WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
273304

305+
q->head = next;
274306
q->queued++;
275307
}
276308

@@ -577,17 +609,9 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
577609
spin_lock_bh(&q->lock);
578610

579611
while (q->queued < q->ndesc - 1) {
580-
struct mt76_txwi_cache *t = NULL;
581612
struct mt76_queue_buf qbuf;
582613
void *buf = NULL;
583614

584-
if ((q->flags & MT_QFLAG_WED) &&
585-
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) {
586-
t = mt76_get_rxwi(dev);
587-
if (!t)
588-
break;
589-
}
590-
591615
buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC);
592616
if (!buf)
593617
break;
@@ -601,7 +625,12 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
601625
qbuf.addr = addr + offset;
602626
qbuf.len = len - offset;
603627
qbuf.skip_unmap = false;
604-
mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t);
628+
if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
629+
dma_unmap_single(dev->dma_dev, addr, len,
630+
DMA_FROM_DEVICE);
631+
skb_free_frag(buf);
632+
break;
633+
}
605634
frames++;
606635
}
607636

drivers/net/wireless/mediatek/mt76/mt7915/mmio.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,13 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
653653

654654
desc->buf0 = cpu_to_le32(phy_addr);
655655
token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr);
656+
if (token < 0) {
657+
dma_unmap_single(dev->mt76.dma_dev, phy_addr,
658+
wed->wlan.rx_size, DMA_TO_DEVICE);
659+
skb_free_frag(ptr);
660+
goto unmap;
661+
}
662+
656663
desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
657664
token));
658665
desc++;

drivers/net/wireless/mediatek/mt76/tx.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -764,11 +764,12 @@ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
764764
spin_lock_bh(&dev->rx_token_lock);
765765
token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
766766
GFP_ATOMIC);
767+
if (token >= 0) {
768+
t->ptr = ptr;
769+
t->dma_addr = phys;
770+
}
767771
spin_unlock_bh(&dev->rx_token_lock);
768772

769-
t->ptr = ptr;
770-
t->dma_addr = phys;
771-
772773
return token;
773774
}
774775
EXPORT_SYMBOL_GPL(mt76_rx_token_consume);

drivers/net/wireless/rndis_wlan.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
696696
struct rndis_query *get;
697697
struct rndis_query_c *get_c;
698698
} u;
699-
int ret, buflen;
700-
int resplen, respoffs, copylen;
699+
int ret;
700+
size_t buflen, resplen, respoffs, copylen;
701701

702702
buflen = *len + sizeof(*u.get);
703703
if (buflen < CONTROL_BUFFER_SIZE)
@@ -732,22 +732,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
732732

733733
if (respoffs > buflen) {
734734
/* Device returned data offset outside buffer, error. */
735-
netdev_dbg(dev->net, "%s(%s): received invalid "
736-
"data offset: %d > %d\n", __func__,
737-
oid_to_string(oid), respoffs, buflen);
735+
netdev_dbg(dev->net,
736+
"%s(%s): received invalid data offset: %zu > %zu\n",
737+
__func__, oid_to_string(oid), respoffs, buflen);
738738

739739
ret = -EINVAL;
740740
goto exit_unlock;
741741
}
742742

743-
if ((resplen + respoffs) > buflen) {
744-
/* Device would have returned more data if buffer would
745-
* have been big enough. Copy just the bits that we got.
746-
*/
747-
copylen = buflen - respoffs;
748-
} else {
749-
copylen = resplen;
750-
}
743+
copylen = min(resplen, buflen - respoffs);
751744

752745
if (copylen > *len)
753746
copylen = *len;

net/mac80211/iface.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2197,7 +2197,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
21972197

21982198
ret = cfg80211_register_netdevice(ndev);
21992199
if (ret) {
2200-
ieee80211_if_free(ndev);
22012200
free_netdev(ndev);
22022201
return ret;
22032202
}

0 commit comments

Comments
 (0)