mt76: update Mediatek's mt76 driver

This version is based on
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
24d479d26b25bce5faea3ddd9fa8f3a6c3129ea7 ( tag: v6.19-rc6 ).

Notable change: license got switched from ISC to BSD-3-Clause-Clear.
util.h is now imported from upstream given it is no longer GPL-only.
See the upstream repository 909675fd4344f73aad5f75f123bd271ada2ab9fb
and a96fed2825d8dfb068bf640419c619b5f2df4218.

For us the new version should also help with page pools and DMA32.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Bjoern A. Zeeb
2026-01-23 13:52:47 +00:00
217 changed files with 4217 additions and 1650 deletions
@@ -0,0 +1,48 @@
/*-
* Copyright (c) 2026 Bjoern A. Zeeb
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H
#define _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H
#include <linux/kernel.h> /* pr_debug */
enum airoha_npu_wlan_get_cmd {
__dummy_airoha_npu_wlan_get_cmd,
};
enum airoha_npu_wlan_set_cmd {
__dummy_airoha_npu_wlan_set_cmd,
};
struct airoha_npu {
};
struct airoha_npu_rx_dma_desc {
};
struct airoha_npu_tx_dma_desc {
};
static __inline int
airoha_npu_wlan_send_msg(void *npu, int ifindex,
enum airoha_npu_wlan_set_cmd cmd, void *val, size_t len, gfp_t gfp)
{
pr_debug("%s: TODO\n", __func__);
return (-EOPNOTSUPP);
}
static __inline int
airoha_npu_wlan_get_msg(void *npu, int ifindex,
enum airoha_npu_wlan_get_cmd cmd, void *val, size_t len, gfp_t gfp)
{
pr_debug("%s: TODO\n", __func__);
return (-EOPNOTSUPP);
}
static __inline void
airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q)
{
pr_debug("%s: TODO\n", __func__);
}
#endif /* _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H */
@@ -1,5 +1,5 @@
/*-
* Copyright (c) 2022-2025 Bjoern A. Zeeb
* Copyright (c) 2022-2026 Bjoern A. Zeeb
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -37,7 +37,13 @@ mtk_wed_device_active(struct mtk_wed_device *dev __unused)
static inline bool
mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
{
pr_debug("%s: TODO\n", __func__);
return (false);
}
static inline bool
mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused)
{
pr_debug("%s: TODO\n", __func__);
return (false);
}
@@ -66,6 +72,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
{
return (false);
}
static inline bool
mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused)
{
return (false);
}
#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
#endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */
+51
View File
@@ -0,0 +1,51 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config MT76_CORE
tristate
select PAGE_POOL
config MT76_LEDS
bool
depends on MT76_CORE
depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS
default y
config MT76_USB
tristate
depends on MT76_CORE
config MT76_SDIO
tristate
depends on MT76_CORE
config MT76x02_LIB
tristate
select MT76_CORE
config MT76x02_USB
tristate
select MT76_USB
config MT76_CONNAC_LIB
tristate
select MT76_CORE
config MT792x_LIB
tristate
select MT76_CONNAC_LIB
config MT792x_USB
tristate
select MT76_USB
config MT76_NPU
bool
depends on MT76_CORE
source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7915/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7996/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7925/Kconfig"
+48
View File
@@ -0,0 +1,48 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
obj-$(CONFIG_MT76_CORE) += mt76.o
obj-$(CONFIG_MT76_USB) += mt76-usb.o
obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o
obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o
obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
obj-$(CONFIG_MT76_CONNAC_LIB) += mt76-connac-lib.o
obj-$(CONFIG_MT792x_LIB) += mt792x-lib.o
obj-$(CONFIG_MT792x_USB) += mt792x-usb.o
mt76-y := \
mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \
tx.o agg-rx.o mcu.o wed.o scan.o channel.o
mt76-$(CONFIG_MT76_NPU) += npu.o
mt76-$(CONFIG_PCI) += pci.o
mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt76-usb-y := usb.o usb_trace.o
mt76-sdio-y := sdio.o sdio_txrx.o
CFLAGS_trace.o := -I$(src)
CFLAGS_usb_trace.o := -I$(src)
CFLAGS_mt76x02_trace.o := -I$(src)
CFLAGS_mt792x_trace.o := -I$(src)
mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \
mt76x02_txrx.o mt76x02_trace.o mt76x02_debugfs.o \
mt76x02_dfs.o mt76x02_beacon.o
mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o
mt792x-lib-y := mt792x_core.o mt792x_mac.o mt792x_trace.o \
mt792x_debugfs.o mt792x_dma.o
mt792x-lib-$(CONFIG_ACPI) += mt792x_acpi_sar.o
mt792x-usb-y := mt792x_usb.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
obj-$(CONFIG_MT7603E) += mt7603/
obj-$(CONFIG_MT7615_COMMON) += mt7615/
obj-$(CONFIG_MT7915E) += mt7915/
obj-$(CONFIG_MT7921_COMMON) += mt7921/
obj-$(CONFIG_MT7996E) += mt7996/
obj-$(CONFIG_MT7925_COMMON) += mt7925/
+3 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Felix Fietkau <nbd@nbd.name>
*/
@@ -173,6 +173,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames)
if (ackp == IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
return;
if (wcid->def_wcid)
wcid = wcid->def_wcid;
tid = rcu_dereference(wcid->aggr[tidno]);
if (!tid)
return;
+10 -5
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2024 Felix Fietkau <nbd@nbd.name>
*/
@@ -314,21 +314,24 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
kfree(mlink);
}
static void mt76_roc_complete(struct mt76_phy *phy)
void mt76_roc_complete(struct mt76_phy *phy)
{
struct mt76_vif_link *mlink = phy->roc_link;
struct mt76_dev *dev = phy->dev;
if (!phy->roc_vif)
return;
if (mlink)
mlink->mvif->roc_phy = NULL;
if (phy->main_chandef.chan)
if (phy->main_chandef.chan &&
!test_bit(MT76_MCU_RESET, &dev->phy.state))
mt76_set_channel(phy, &phy->main_chandef, false);
mt76_put_vif_phy_link(phy, phy->roc_vif, phy->roc_link);
phy->roc_vif = NULL;
phy->roc_link = NULL;
ieee80211_remain_on_channel_expired(phy->hw);
if (!test_bit(MT76_MCU_RESET, &dev->phy.state))
ieee80211_remain_on_channel_expired(phy->hw);
}
void mt76_roc_complete_work(struct work_struct *work)
@@ -351,6 +354,7 @@ void mt76_abort_roc(struct mt76_phy *phy)
mt76_roc_complete(phy);
mutex_unlock(&dev->mutex);
}
EXPORT_SYMBOL_GPL(mt76_abort_roc);
int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_channel *chan, int duration,
@@ -368,7 +372,8 @@ int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mutex);
if (phy->roc_vif || dev->scan.phy == phy) {
if (phy->roc_vif || dev->scan.phy == phy ||
test_bit(MT76_MCU_RESET, &dev->phy.state)) {
ret = -EBUSY;
goto out;
}
+3 -3
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -93,9 +93,9 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
{
int i;
seq_printf(file, "%10s:", str);
seq_printf(file, "%16s:", str);
for (i = 0; i < len; i++)
seq_printf(file, " %2d", val[i]);
seq_printf(file, " %4d", val[i]);
seq_puts(file, "\n");
}
EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
+222 -80
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -11,37 +11,6 @@
#include "mt76.h"
#include "dma.h"
#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
#define Q_READ(_q, _field) ({ \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
u32 _val; \
if ((_q)->flags & MT_QFLAG_WED) \
_val = mtk_wed_device_reg_read((_q)->wed, \
((_q)->wed_regs + \
_offset)); \
else \
_val = readl(&(_q)->regs->_field); \
_val; \
})
#define Q_WRITE(_q, _field, _val) do { \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
if ((_q)->flags & MT_QFLAG_WED) \
mtk_wed_device_reg_write((_q)->wed, \
((_q)->wed_regs + _offset), \
_val); \
else \
writel(_val, &(_q)->regs->_field); \
} while (0)
#else
#define Q_READ(_q, _field) readl(&(_q)->regs->_field)
#define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field)
#endif
static struct mt76_txwi_cache *
mt76_alloc_txwi(struct mt76_dev *dev)
{
@@ -189,25 +158,62 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
}
EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
static void
mt76_dma_queue_magic_cnt_init(struct mt76_dev *dev, struct mt76_queue *q)
{
if (!mt76_queue_is_wed_rro(q))
return;
q->magic_cnt = 0;
if (mt76_queue_is_wed_rro_ind(q)) {
struct mt76_wed_rro_desc *rro_desc;
u32 data1 = FIELD_PREP(RRO_IND_DATA1_MAGIC_CNT_MASK,
MT_DMA_WED_IND_CMD_CNT - 1);
int i;
rro_desc = (struct mt76_wed_rro_desc *)q->desc;
for (i = 0; i < q->ndesc; i++) {
struct mt76_wed_rro_ind *cmd;
cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
cmd->data1 = cpu_to_le32(data1);
}
} else if (mt76_queue_is_wed_rro_rxdmad_c(q)) {
struct mt76_rro_rxdmad_c *dmad = (void *)q->desc;
u32 data3 = FIELD_PREP(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK,
MT_DMA_MAGIC_CNT - 1);
int i;
for (i = 0; i < q->ndesc; i++)
dmad[i].data3 = cpu_to_le32(data3);
}
}
static void
mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
{
Q_WRITE(q, desc_base, q->desc_dma);
if (q->flags & MT_QFLAG_WED_RRO_EN)
if ((q->flags & MT_QFLAG_WED_RRO_EN) && !mt76_npu_device_active(dev))
Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc);
else
Q_WRITE(q, ring_size, q->ndesc);
if (mt76_queue_is_npu_tx(q)) {
writel(q->desc_dma, &q->regs->desc_base);
writel(q->ndesc, &q->regs->ring_size);
}
q->head = Q_READ(q, dma_idx);
q->tail = q->head;
}
void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
bool reset_idx)
void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
bool reset_idx)
{
if (!q || !q->ndesc)
return;
if (!mt76_queue_is_wed_rro_ind(q)) {
if (!mt76_queue_is_wed_rro_ind(q) &&
!mt76_queue_is_wed_rro_rxdmad_c(q) && !mt76_queue_is_npu(q)) {
int i;
/* clear descriptors */
@@ -215,27 +221,26 @@ void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
}
mt76_dma_queue_magic_cnt_init(dev, q);
if (reset_idx) {
Q_WRITE(q, cpu_idx, 0);
if (mt76_queue_is_emi(q))
*q->emi_cpu_idx = 0;
else
Q_WRITE(q, cpu_idx, 0);
Q_WRITE(q, dma_idx, 0);
}
mt76_dma_sync_idx(dev, q);
}
void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
{
__mt76_dma_queue_reset(dev, q, true);
}
static int
mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, void *data)
{
struct mt76_queue_entry *entry = &q->entry[q->head];
struct mt76_txwi_cache *txwi = NULL;
u32 buf1 = 0, ctrl, info = 0;
struct mt76_desc *desc;
int idx = q->head;
u32 buf1 = 0, ctrl;
int rx_token;
if (mt76_queue_is_wed_rro_ind(q)) {
@@ -244,6 +249,9 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
rro_desc = (struct mt76_wed_rro_desc *)q->desc;
data = &rro_desc[q->head];
goto done;
} else if (mt76_queue_is_wed_rro_rxdmad_c(q)) {
data = &q->desc[q->head];
goto done;
}
desc = &q->desc[q->head];
@@ -252,7 +260,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
buf1 = FIELD_PREP(MT_DMA_CTL_SDP0_H, buf->addr >> 32);
#endif
if (mt76_queue_is_wed_rx(q)) {
if (mt76_queue_is_wed_rx(q) || mt76_queue_is_wed_rro_data(q)) {
txwi = mt76_get_rxwi(dev);
if (!txwi)
return -ENOMEM;
@@ -265,12 +273,26 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
ctrl |= MT_DMA_CTL_TO_HOST;
txwi->qid = q - dev->q_rx;
}
if (mt76_queue_is_wed_rro_msdu_pg(q) &&
dev->drv->rx_rro_add_msdu_page) {
if (dev->drv->rx_rro_add_msdu_page(dev, q, buf->addr, data))
return -ENOMEM;
}
if (q->flags & MT_QFLAG_WED_RRO_EN) {
info |= FIELD_PREP(MT_DMA_MAGIC_MASK, q->magic_cnt);
if ((q->head + 1) == q->ndesc)
q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_MAGIC_CNT;
}
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);
WRITE_ONCE(desc->info, cpu_to_le32(info));
done:
entry->dma_addr[0] = buf->addr;
@@ -379,7 +401,10 @@ static void
mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
wmb();
Q_WRITE(q, cpu_idx, q->head);
if (mt76_queue_is_emi(q))
*q->emi_cpu_idx = cpu_to_le16(q->head);
else
Q_WRITE(q, cpu_idx, q->head);
}
static void
@@ -399,6 +424,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
while (q->queued > 0 && q->tail != last) {
mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
mt76_npu_txdesc_cleanup(q, q->tail);
mt76_queue_tx_complete(dev, q, &entry);
if (entry.txwi) {
@@ -422,16 +448,62 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
wake_up(&dev->tx_wait);
}
static void *
mt76_dma_get_rxdmad_c_buf(struct mt76_dev *dev, struct mt76_queue *q,
int idx, int *len, bool *more)
{
struct mt76_queue_entry *e = &q->entry[idx];
struct mt76_rro_rxdmad_c *dmad = e->buf;
u32 data1 = le32_to_cpu(dmad->data1);
u32 data2 = le32_to_cpu(dmad->data2);
struct mt76_txwi_cache *t;
u16 rx_token_id;
u8 ind_reason;
void *buf;
rx_token_id = FIELD_GET(RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK, data2);
t = mt76_rx_token_release(dev, rx_token_id);
if (!t)
return ERR_PTR(-EAGAIN);
q = &dev->q_rx[t->qid];
dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
SKB_WITH_OVERHEAD(q->buf_size),
page_pool_get_dma_dir(q->page_pool));
if (len)
*len = FIELD_GET(RRO_RXDMAD_DATA1_SDL0_MASK, data1);
if (more)
*more = !FIELD_GET(RRO_RXDMAD_DATA1_LS_MASK, data1);
buf = t->ptr;
ind_reason = FIELD_GET(RRO_RXDMAD_DATA2_IND_REASON_MASK, data2);
if (ind_reason == MT_DMA_WED_IND_REASON_REPEAT ||
ind_reason == MT_DMA_WED_IND_REASON_OLDPKT) {
mt76_put_page_pool_buf(buf, false);
buf = ERR_PTR(-EAGAIN);
}
t->ptr = NULL;
t->dma_addr = 0;
mt76_put_rxwi(dev, t);
return buf;
}
static void *
mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
int *len, u32 *info, bool *more, bool *drop)
int *len, u32 *info, bool *more, bool *drop, bool flush)
{
struct mt76_queue_entry *e = &q->entry[idx];
struct mt76_desc *desc = &q->desc[idx];
u32 ctrl, desc_info, buf1;
void *buf = e->buf;
if (mt76_queue_is_wed_rro_ind(q))
if (mt76_queue_is_wed_rro_rxdmad_c(q) && !flush)
buf = mt76_dma_get_rxdmad_c_buf(dev, q, idx, len, more);
if (mt76_queue_is_wed_rro(q))
goto done;
ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
@@ -486,20 +558,50 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
if (!q->queued)
return NULL;
if (mt76_queue_is_wed_rro_data(q))
return NULL;
if (mt76_queue_is_wed_rro_data(q) || mt76_queue_is_wed_rro_msdu_pg(q))
goto done;
if (!mt76_queue_is_wed_rro_ind(q)) {
if (mt76_queue_is_wed_rro_ind(q)) {
struct mt76_wed_rro_ind *cmd;
u8 magic_cnt;
if (flush)
goto done;
cmd = q->entry[idx].buf;
magic_cnt = FIELD_GET(RRO_IND_DATA1_MAGIC_CNT_MASK,
le32_to_cpu(cmd->data1));
if (magic_cnt != q->magic_cnt)
return NULL;
if (q->tail == q->ndesc - 1)
q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_WED_IND_CMD_CNT;
} else if (mt76_queue_is_wed_rro_rxdmad_c(q)) {
struct mt76_rro_rxdmad_c *dmad;
u16 magic_cnt;
if (flush)
goto done;
dmad = q->entry[idx].buf;
magic_cnt = FIELD_GET(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK,
le32_to_cpu(dmad->data3));
if (magic_cnt != q->magic_cnt)
return NULL;
if (q->tail == q->ndesc - 1)
q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_MAGIC_CNT;
} else {
if (flush)
q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
return NULL;
}
done:
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
}
static int
@@ -557,6 +659,10 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
if (test_bit(MT76_RESET, &phy->state))
goto free_skb;
/* TODO: Take into account unlinear skbs */
if (mt76_npu_device_active(dev) && skb_linearize(skb))
goto free_skb;
t = mt76_get_txwi(dev);
if (!t)
goto free_skb;
@@ -604,6 +710,9 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q,
if (ret < 0)
goto unmap;
if (mt76_npu_device_active(dev))
return mt76_npu_dma_add_buf(phy, q, skb, &tx_info.buf[1], txwi);
return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
tx_info.info, tx_info.skb, t);
@@ -650,7 +759,8 @@ mt76_dma_rx_fill_buf(struct mt76_dev *dev, struct mt76_queue *q,
void *buf = NULL;
int offset;
if (mt76_queue_is_wed_rro_ind(q))
if (mt76_queue_is_wed_rro_ind(q) ||
mt76_queue_is_wed_rro_rxdmad_c(q))
goto done;
buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
@@ -680,9 +790,6 @@ int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
{
int frames;
if (!q->ndesc)
return 0;
spin_lock_bh(&q->lock);
frames = mt76_dma_rx_fill_buf(dev, q, allow_direct);
spin_unlock_bh(&q->lock);
@@ -708,27 +815,23 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
q->ndesc = n_desc;
q->buf_size = bufsize;
q->hw_idx = idx;
q->dev = dev;
if (mt76_queue_is_wed_rro_ind(q))
size = sizeof(struct mt76_wed_rro_desc);
else if (mt76_queue_is_npu_tx(q))
size = sizeof(struct airoha_npu_tx_dma_desc);
else if (mt76_queue_is_npu_rx(q))
size = sizeof(struct airoha_npu_rx_dma_desc);
else
size = sizeof(struct mt76_desc);
size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc)
: sizeof(struct mt76_desc);
q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size,
&q->desc_dma, GFP_KERNEL);
if (!q->desc)
return -ENOMEM;
if (mt76_queue_is_wed_rro_ind(q)) {
struct mt76_wed_rro_desc *rro_desc;
int i;
rro_desc = (struct mt76_wed_rro_desc *)q->desc;
for (i = 0; i < q->ndesc; i++) {
struct mt76_wed_rro_ind *cmd;
cmd = (struct mt76_wed_rro_ind *)&rro_desc[i];
cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1;
}
}
mt76_dma_queue_magic_cnt_init(dev, q);
size = q->ndesc * sizeof(*q->entry);
q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
if (!q->entry)
@@ -738,6 +841,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
if (ret)
return ret;
mt76_npu_queue_setup(dev, q);
ret = mt76_wed_dma_setup(dev, q, false);
if (ret)
return ret;
@@ -748,7 +852,10 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
return 0;
}
mt76_dma_queue_reset(dev, q);
/* HW specific driver is supposed to reset brand-new EMI queues since
* it needs to set cpu index pointer.
*/
mt76_dma_queue_reset(dev, q, !mt76_queue_is_emi(q));
return 0;
}
@@ -762,6 +869,11 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
if (!q->ndesc)
return;
if (mt76_queue_is_npu(q)) {
mt76_npu_queue_cleanup(dev, q);
return;
}
do {
spin_lock_bh(&q->lock);
buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more, NULL);
@@ -791,7 +903,8 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
if (!q->ndesc)
return;
if (!mt76_queue_is_wed_rro_ind(q)) {
if (!mt76_queue_is_wed_rro_ind(q) &&
!mt76_queue_is_wed_rro_rxdmad_c(q) && !mt76_queue_is_npu(q)) {
int i;
for (i = 0; i < q->ndesc; i++)
@@ -811,7 +924,10 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
return;
mt76_dma_sync_idx(dev, q);
mt76_dma_rx_fill_buf(dev, q, false);
if (mt76_queue_is_npu(q))
mt76_npu_fill_rx_queue(dev, q);
else
mt76_dma_rx_fill(dev, q, false);
}
static void
@@ -855,8 +971,9 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
bool allow_direct = !mt76_queue_is_wed_rx(q);
bool more;
if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
mt76_queue_is_wed_tx_free(q)) {
if ((q->flags & MT_QFLAG_WED_RRO_EN) ||
(IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
mt76_queue_is_wed_tx_free(q))) {
dma_idx = Q_READ(q, dma_idx);
check_ddone = true;
}
@@ -878,6 +995,20 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
if (!data)
break;
if (PTR_ERR(data) == -EAGAIN) {
done++;
continue;
}
if (mt76_queue_is_wed_rro_ind(q) && dev->drv->rx_rro_ind_process)
dev->drv->rx_rro_ind_process(dev, data);
if (mt76_queue_is_wed_rro(q) &&
!mt76_queue_is_wed_rro_rxdmad_c(q)) {
done++;
continue;
}
if (drop)
goto free_frag;
@@ -955,6 +1086,15 @@ int mt76_dma_rx_poll(struct napi_struct *napi, int budget)
}
EXPORT_SYMBOL_GPL(mt76_dma_rx_poll);
static void
mt76_dma_rx_queue_init(struct mt76_dev *dev, enum mt76_rxq_id qid,
int (*poll)(struct napi_struct *napi, int budget))
{
netif_napi_add(dev->napi_dev, &dev->napi[qid], poll);
mt76_dma_rx_fill_buf(dev, &dev->q_rx[qid], false);
napi_enable(&dev->napi[qid]);
}
static int
mt76_dma_init(struct mt76_dev *dev,
int (*poll)(struct napi_struct *napi, int budget))
@@ -987,9 +1127,10 @@ mt76_dma_init(struct mt76_dev *dev,
init_completion(&dev->mmio.wed_reset_complete);
mt76_for_each_q_rx(dev, i) {
netif_napi_add(dev->napi_dev, &dev->napi[i], poll);
mt76_dma_rx_fill_buf(dev, &dev->q_rx[i], false);
napi_enable(&dev->napi[i]);
if (mt76_queue_is_wed_rro(&dev->q_rx[i]))
continue;
mt76_dma_rx_queue_init(dev, i, poll);
}
return 0;
@@ -1002,6 +1143,7 @@ static const struct mt76_queue_ops mt76_dma_ops = {
.tx_queue_skb_raw = mt76_dma_tx_queue_skb_raw,
.tx_queue_skb = mt76_dma_tx_queue_skb,
.tx_cleanup = mt76_dma_tx_cleanup,
.rx_queue_init = mt76_dma_rx_queue_init,
.rx_cleanup = mt76_dma_rx_cleanup,
.rx_reset = mt76_dma_rx_reset,
.kick = mt76_dma_kick_queue,
+92 -6
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -31,7 +31,12 @@
#define MT_DMA_CTL_PN_CHK_FAIL BIT(13)
#define MT_DMA_CTL_VER_MASK BIT(7)
#define MT_DMA_RRO_EN BIT(13)
#define MT_DMA_SDP0 GENMASK(15, 0)
#define MT_DMA_TOKEN_ID GENMASK(31, 16)
#define MT_DMA_MAGIC_MASK GENMASK(31, 28)
#define MT_DMA_RRO_EN BIT(13)
#define MT_DMA_MAGIC_CNT 16
#define MT_DMA_WED_IND_CMD_CNT 8
#define MT_DMA_WED_IND_REASON GENMASK(15, 12)
@@ -41,6 +46,73 @@
#define MT_FCE_INFO_LEN 4
#define MT_RX_RXWI_LEN 32
#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)
#define Q_READ(_q, _field) ({ \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
u32 _val; \
if ((_q)->flags & MT_QFLAG_WED) \
_val = mtk_wed_device_reg_read((_q)->wed, \
((_q)->wed_regs + \
_offset)); \
else \
_val = readl(&(_q)->regs->_field); \
_val; \
})
#define Q_WRITE(_q, _field, _val) do { \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
if ((_q)->flags & MT_QFLAG_WED) \
mtk_wed_device_reg_write((_q)->wed, \
((_q)->wed_regs + _offset), \
_val); \
else \
writel(_val, &(_q)->regs->_field); \
} while (0)
#elif IS_ENABLED(CONFIG_MT76_NPU)
#define Q_READ(_q, _field) ({ \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
u32 _val = 0; \
if ((_q)->flags & MT_QFLAG_NPU) { \
struct airoha_npu *npu; \
\
rcu_read_lock(); \
npu = rcu_dereference(q->dev->mmio.npu); \
if (npu) \
regmap_read(npu->regmap, \
((_q)->wed_regs + _offset), &_val); \
rcu_read_unlock(); \
} else { \
_val = readl(&(_q)->regs->_field); \
} \
_val; \
})
#define Q_WRITE(_q, _field, _val) do { \
u32 _offset = offsetof(struct mt76_queue_regs, _field); \
if ((_q)->flags & MT_QFLAG_NPU) { \
struct airoha_npu *npu; \
\
rcu_read_lock(); \
npu = rcu_dereference(q->dev->mmio.npu); \
if (npu) \
regmap_write(npu->regmap, \
((_q)->wed_regs + _offset), _val); \
rcu_read_unlock(); \
} else { \
writel(_val, &(_q)->regs->_field); \
} \
} while (0)
#else
#define Q_READ(_q, _field) readl(&(_q)->regs->_field)
#define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field)
#endif
struct mt76_desc {
__le32 buf0;
__le32 ctrl;
@@ -53,6 +125,21 @@ struct mt76_wed_rro_desc {
__le32 buf1;
} __packed __aligned(4);
/* data1 */
#define RRO_RXDMAD_DATA1_LS_MASK BIT(30)
#define RRO_RXDMAD_DATA1_SDL0_MASK GENMASK(29, 16)
/* data2 */
#define RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK GENMASK(31, 16)
#define RRO_RXDMAD_DATA2_IND_REASON_MASK GENMASK(15, 12)
/* data3 */
#define RRO_RXDMAD_DATA3_MAGIC_CNT_MASK GENMASK(31, 28)
struct mt76_rro_rxdmad_c {
__le32 data0;
__le32 data1;
__le32 data2;
__le32 data3;
};
enum mt76_qsel {
MT_QSEL_MGMT,
MT_QSEL_HCCA,
@@ -81,14 +168,13 @@ void mt76_dma_attach(struct mt76_dev *dev);
void mt76_dma_cleanup(struct mt76_dev *dev);
int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
bool allow_direct);
void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
bool reset_idx);
void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q);
void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q,
bool reset_idx);
static inline void
mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
dev->queue_ops->reset_q(dev, q);
dev->queue_ops->reset_q(dev, q, true);
if (mtk_wed_device_active(&dev->mmio.wed))
mt76_wed_dma_setup(dev, q, true);
}
+66 -21
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -175,14 +175,17 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len)
#endif
}
void
int
mt76_eeprom_override(struct mt76_phy *phy)
{
struct mt76_dev *dev = phy->dev;
#if defined(CONFIG_OF)
struct device_node *np = dev->dev->of_node;
int err;
of_get_mac_address(np, phy->macaddr);
err = of_get_mac_address(np, phy->macaddr);
if (err == -EPROBE_DEFER)
return err;
if (!is_valid_ether_addr(phy->macaddr)) {
#endif
@@ -193,6 +196,8 @@ mt76_eeprom_override(struct mt76_phy *phy)
#if defined(CONFIG_OF)
}
#endif
return 0;
}
EXPORT_SYMBOL_GPL(mt76_eeprom_override);
@@ -269,6 +274,19 @@ mt76_get_of_array(struct device_node *np, char *name, size_t *len, int min)
return prop->value;
}
static const s8 *
mt76_get_of_array_s8(struct device_node *np, char *name, size_t *len, int min)
{
struct property *prop = of_find_property(np, name, NULL);
if (!prop || !prop->value || prop->length < min)
return NULL;
*len = prop->length;
return prop->value;
}
#endif
struct device_node *
@@ -313,7 +331,7 @@ mt76_get_txs_delta(struct device_node *np, u8 nss)
}
static void
mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const s8 *data,
s8 target_power, s8 nss_delta, s8 *max_power)
{
int i;
@@ -322,30 +340,29 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data,
return;
for (i = 0; i < pwr_len; i++) {
pwr[i] = min_t(s8, target_power,
be32_to_cpu(data[i]) + nss_delta);
pwr[i] = min_t(s8, target_power, data[i] + nss_delta);
*max_power = max(*max_power, pwr[i]);
}
}
static void
mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
const __be32 *data, size_t len, s8 target_power,
s8 nss_delta, s8 *max_power)
const s8 *data, size_t len, s8 target_power,
s8 nss_delta)
{
int i, cur;
s8 max_power = -128;
if (!data)
return;
len /= 4;
cur = be32_to_cpu(data[0]);
cur = data[0];
for (i = 0; i < pwr_num; i++) {
if (len < pwr_len + 1)
break;
mt76_apply_array_limit(pwr + pwr_len * i, pwr_len, data + 1,
target_power, nss_delta, max_power);
target_power, nss_delta, &max_power);
if (--cur > 0)
continue;
@@ -354,7 +371,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
if (!len)
break;
cur = be32_to_cpu(data[0]);
cur = data[0];
}
}
#endif
@@ -367,7 +384,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
struct mt76_dev *dev = phy->dev;
#if defined(CONFIG_OF)
struct device_node *np;
const __be32 *val;
const s8 *val;
char name[16];
#endif
u32 mcs_rates = dev->drv->mcs_rates;
@@ -379,12 +396,17 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
s8 max_power = 0;
#if defined(CONFIG_OF)
s8 txs_delta;
s8 max_power_backoff = -127;
s8 txs_delta;
int n_chains = hweight16(phy->chainmask);
s8 target_power_combine = target_power + mt76_tx_power_path_delta(n_chains);
#endif
if (!mcs_rates)
mcs_rates = 10;
memset(dest, target_power, sizeof(*dest));
memset(dest, target_power, sizeof(*dest) - sizeof(dest->path));
memset(&dest->path, 0, sizeof(dest->path));
if (!IS_ENABLED(CONFIG_OF))
return target_power;
@@ -419,24 +441,47 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
txs_delta = mt76_get_txs_delta(np, hweight16(phy->chainmask));
val = mt76_get_of_array(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
val = mt76_get_of_array_s8(np, "rates-cck", &len, ARRAY_SIZE(dest->cck));
mt76_apply_array_limit(dest->cck, ARRAY_SIZE(dest->cck), val,
target_power, txs_delta, &max_power);
val = mt76_get_of_array(np, "rates-ofdm",
&len, ARRAY_SIZE(dest->ofdm));
val = mt76_get_of_array_s8(np, "rates-ofdm",
&len, ARRAY_SIZE(dest->ofdm));
mt76_apply_array_limit(dest->ofdm, ARRAY_SIZE(dest->ofdm), val,
target_power, txs_delta, &max_power);
val = mt76_get_of_array(np, "rates-mcs", &len, mcs_rates + 1);
val = mt76_get_of_array_s8(np, "rates-mcs", &len, mcs_rates + 1);
mt76_apply_multi_array_limit(dest->mcs[0], ARRAY_SIZE(dest->mcs[0]),
ARRAY_SIZE(dest->mcs), val, len,
target_power, txs_delta, &max_power);
target_power, txs_delta);
val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
val = mt76_get_of_array_s8(np, "rates-ru", &len, ru_rates + 1);
mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
ARRAY_SIZE(dest->ru), val, len,
target_power, txs_delta, &max_power);
target_power, txs_delta);
max_power_backoff = max_power;
val = mt76_get_of_array_s8(np, "paths-cck", &len, ARRAY_SIZE(dest->path.cck));
mt76_apply_array_limit(dest->path.cck, ARRAY_SIZE(dest->path.cck), val,
target_power_combine, txs_delta, &max_power_backoff);
val = mt76_get_of_array_s8(np, "paths-ofdm", &len, ARRAY_SIZE(dest->path.ofdm));
mt76_apply_array_limit(dest->path.ofdm, ARRAY_SIZE(dest->path.ofdm), val,
target_power_combine, txs_delta, &max_power_backoff);
val = mt76_get_of_array_s8(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest->path.ofdm_bf));
mt76_apply_array_limit(dest->path.ofdm_bf, ARRAY_SIZE(dest->path.ofdm_bf), val,
target_power_combine, txs_delta, &max_power_backoff);
val = mt76_get_of_array_s8(np, "paths-ru", &len, ARRAY_SIZE(dest->path.ru[0]) + 1);
mt76_apply_multi_array_limit(dest->path.ru[0], ARRAY_SIZE(dest->path.ru[0]),
ARRAY_SIZE(dest->path.ru), val, len,
target_power_combine, txs_delta);
val = mt76_get_of_array_s8(np, "paths-ru-bf", &len, ARRAY_SIZE(dest->path.ru_bf[0]) + 1);
mt76_apply_multi_array_limit(dest->path.ru_bf[0], ARRAY_SIZE(dest->path.ru_bf[0]),
ARRAY_SIZE(dest->path.ru_bf), val, len,
target_power_combine, txs_delta);
#endif
return max_power;
+63 -2
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -652,6 +652,8 @@ int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q)
case MT_RXQ_MAIN:
case MT_RXQ_BAND1:
case MT_RXQ_BAND2:
case MT_RXQ_NPU0:
case MT_RXQ_NPU1:
pp_params.pool_size = 256;
break;
default:
@@ -846,6 +848,7 @@ void mt76_free_device(struct mt76_dev *dev)
destroy_workqueue(dev->wq);
dev->wq = NULL;
}
mt76_npu_deinit(dev);
ieee80211_free_hw(dev->hw);
}
EXPORT_SYMBOL_GPL(mt76_free_device);
@@ -856,6 +859,9 @@ static void mt76_reset_phy(struct mt76_phy *phy)
return;
INIT_LIST_HEAD(&phy->tx_list);
phy->num_sta = 0;
phy->chanctx = NULL;
mt76_roc_complete(phy);
}
void mt76_reset_device(struct mt76_dev *dev)
@@ -1267,6 +1273,8 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
mstat = *((struct mt76_rx_status *)skb->cb);
memset(status, 0, sizeof(*status));
skb->priority = mstat.qos_ctl & IEEE80211_QOS_CTL_TID_MASK;
status->flag = mstat.flag;
status->freq = mstat.freq;
status->enc_flags = mstat.enc_flags;
@@ -1582,7 +1590,8 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
mt76_check_sta(dev, skb);
if (mtk_wed_device_active(&dev->mmio.wed))
if (mtk_wed_device_active(&dev->mmio.wed) ||
mt76_npu_device_active(dev))
__skb_queue_tail(&frames, skb);
else
mt76_rx_aggr_reorder(skb, &frames);
@@ -2096,3 +2105,55 @@ void mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif)
mt76_abort_roc(mvif->roc_phy);
}
EXPORT_SYMBOL_GPL(mt76_vif_cleanup);
u16 mt76_select_links(struct ieee80211_vif *vif, int max_active_links)
{
unsigned long usable_links = ieee80211_vif_usable_links(vif);
struct {
u8 link_id;
enum nl80211_band band;
} data[IEEE80211_MLD_MAX_NUM_LINKS];
unsigned int link_id;
int i, n_data = 0;
u16 sel_links = 0;
if (!ieee80211_vif_is_mld(vif))
return 0;
if (vif->active_links == usable_links)
return vif->active_links;
rcu_read_lock();
for_each_set_bit(link_id, &usable_links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_bss_conf *link_conf;
link_conf = rcu_dereference(vif->link_conf[link_id]);
if (WARN_ON_ONCE(!link_conf))
continue;
data[n_data].link_id = link_id;
data[n_data].band = link_conf->chanreq.oper.chan->band;
n_data++;
}
rcu_read_unlock();
for (i = 0; i < n_data; i++) {
int j;
if (!(BIT(data[i].link_id) & vif->active_links))
continue;
sel_links = BIT(data[i].link_id);
for (j = 0; j < n_data; j++) {
if (data[i].band != data[j].band) {
sel_links |= BIT(data[j].link_id);
if (hweight16(sel_links) == max_active_links)
break;
}
}
break;
}
return sel_links;
}
EXPORT_SYMBOL_GPL(mt76_select_links);
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+15 -5
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -41,20 +41,30 @@ static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset,
const void *data, int len)
{
int i;
for (i = 0; i < ALIGN(len, 4); i += 4)
#if defined(__linux__)
__iowrite32_copy(dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4));
writel(get_unaligned_le32(data + i),
dev->mmio.regs + offset + i);
#elif defined(__FreeBSD__)
__iowrite32_copy((u8 *)dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4));
writel(get_unaligned_le32((const u8 *)data + i),
(u8 *)dev->mmio.regs + offset + i);
#endif
}
static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset,
void *data, int len)
{
int i;
for (i = 0; i < ALIGN(len, 4); i += 4)
#if defined(__linux__)
__ioread32_copy(data, dev->mmio.regs + offset, DIV_ROUND_UP(len, 4));
put_unaligned_le32(readl(dev->mmio.regs + offset + i),
data + i);
#elif defined(__FreeBSD__)
__ioread32_copy(data, (u8 *)dev->mmio.regs + offset, DIV_ROUND_UP(len, 4));
put_unaligned_le32(readl((u8 *)dev->mmio.regs + offset + i),
(u8 *)data + i);
#endif
}
+214 -18
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -13,6 +13,7 @@
#include <linux/leds.h>
#include <linux/usb.h>
#include <linux/average.h>
#include <linux/soc/airoha/airoha_offload.h>
#include <linux/soc/mediatek/mtk_wed.h>
#if defined(__FreeBSD__)
#include <linux/wait.h>
@@ -40,6 +41,8 @@
#define MT_QFLAG_WED BIT(5)
#define MT_QFLAG_WED_RRO BIT(6)
#define MT_QFLAG_WED_RRO_EN BIT(7)
#define MT_QFLAG_EMI_EN BIT(8)
#define MT_QFLAG_NPU BIT(9)
#define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \
FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
@@ -52,6 +55,13 @@
#define MT_WED_RRO_Q_DATA(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_DATA, _n)
#define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n)
#define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0)
#define MT_WED_RRO_Q_RXDMAD_C __MT_WED_RRO_Q(MT76_WED_RRO_Q_RXDMAD_C, 0)
#define __MT_NPU_Q(_type, _n) (MT_QFLAG_NPU | \
FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
FIELD_PREP(MT_QFLAG_WED_RING, _n))
#define MT_NPU_Q_TX(_n) __MT_NPU_Q(MT76_WED_Q_TX, _n)
#define MT_NPU_Q_RX(_n) __MT_NPU_Q(MT76_WED_Q_RX, _n)
struct mt76_dev;
struct mt76_phy;
@@ -78,6 +88,13 @@ enum mt76_wed_type {
MT76_WED_RRO_Q_DATA,
MT76_WED_RRO_Q_MSDU_PG,
MT76_WED_RRO_Q_IND,
MT76_WED_RRO_Q_RXDMAD_C,
};
enum mt76_hwrro_mode {
MT76_HWRRO_OFF,
MT76_HWRRO_V3,
MT76_HWRRO_V3_1,
};
struct mt76_bus_ops {
@@ -136,6 +153,9 @@ enum mt76_rxq_id {
MT_RXQ_TXFREE_BAND1,
MT_RXQ_TXFREE_BAND2,
MT_RXQ_RRO_IND,
MT_RXQ_RRO_RXDMAD_C,
MT_RXQ_NPU0,
MT_RXQ_NPU1,
__MT_RXQ_MAX
};
@@ -239,8 +259,12 @@ struct mt76_queue {
u8 buf_offset;
u16 flags;
u8 magic_cnt;
__le16 *emi_cpu_idx;
struct mtk_wed_device *wed;
struct mt76_dev *dev;
u32 wed_regs;
dma_addr_t desc_dma;
@@ -293,11 +317,15 @@ struct mt76_queue_ops {
void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q,
bool flush);
void (*rx_queue_init)(struct mt76_dev *dev, enum mt76_rxq_id qid,
int (*poll)(struct napi_struct *napi, int budget));
void (*rx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q);
void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q,
bool reset_idx);
};
enum mt76_phy_type {
@@ -405,15 +433,16 @@ struct mt76_txq {
bool aggr;
};
/* data0 */
#define RRO_IND_DATA0_IND_REASON_MASK GENMASK(31, 28)
#define RRO_IND_DATA0_START_SEQ_MASK GENMASK(27, 16)
#define RRO_IND_DATA0_SEQ_ID_MASK GENMASK(11, 0)
/* data1 */
#define RRO_IND_DATA1_MAGIC_CNT_MASK GENMASK(31, 29)
#define RRO_IND_DATA1_IND_COUNT_MASK GENMASK(12, 0)
struct mt76_wed_rro_ind {
u32 se_id : 12;
u32 rsv : 4;
u32 start_sn : 12;
u32 ind_reason : 4;
u32 ind_cnt : 13;
u32 win_sz : 3;
u32 rsv2 : 13;
u32 magic_cnt : 3;
__le32 data0;
__le32 data1;
};
struct mt76_txwi_cache {
@@ -424,6 +453,8 @@ struct mt76_txwi_cache {
struct sk_buff *skb;
void *ptr;
};
u8 qid;
};
struct mt76_rx_tid {
@@ -540,6 +571,10 @@ struct mt76_driver_ops {
void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q);
void (*rx_rro_ind_process)(struct mt76_dev *dev, void *data);
int (*rx_rro_add_msdu_page)(struct mt76_dev *dev, struct mt76_queue *q,
dma_addr_t p, void *data);
void (*sta_ps)(struct mt76_dev *dev, struct ieee80211_sta *sta,
bool ps);
@@ -689,6 +724,11 @@ struct mt76_mmio {
struct mtk_wed_device wed_hif2;
struct completion wed_reset;
struct completion wed_reset_complete;
struct airoha_ppe_dev __rcu *ppe_dev;
struct airoha_npu __rcu *npu;
phys_addr_t phy_addr;
int npu_type;
};
struct mt76_rx_status {
@@ -917,6 +957,7 @@ struct mt76_dev {
struct mt76_queue q_rx[__MT_RXQ_MAX];
const struct mt76_queue_ops *queue_ops;
int tx_dma_idx[4];
enum mt76_hwrro_mode hwrro_mode;
struct mt76_worker tx_worker;
struct napi_struct tx_napi;
@@ -925,6 +966,7 @@ struct mt76_dev {
struct idr token;
u16 wed_token_count;
u16 token_count;
u16 token_start;
u16 token_size;
spinlock_t rx_token_lock;
@@ -1095,6 +1137,14 @@ struct mt76_power_limits {
s8 mcs[4][10];
s8 ru[7][12];
s8 eht[16][16];
struct {
s8 cck[4];
s8 ofdm[4];
s8 ofdm_bf[4];
s8 ru[7][10];
s8 ru_bf[7][10];
} path;
};
struct mt76_ethtool_worker_info {
@@ -1221,6 +1271,7 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,
#define mt76_tx_queue_skb(dev, ...) (dev)->mt76.queue_ops->tx_queue_skb(&((dev)->mphy), __VA_ARGS__)
#define mt76_queue_rx_reset(dev, ...) (dev)->mt76.queue_ops->rx_reset(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_rx_init(dev, ...) (dev)->mt76.queue_ops->rx_queue_init(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_rx_cleanup(dev, ...) (dev)->mt76.queue_ops->rx_cleanup(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_reset(dev, ...) (dev)->mt76.queue_ops->reset_q(&((dev)->mt76), __VA_ARGS__)
@@ -1233,6 +1284,15 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q,
#define mt76_dereference(p, dev) \
rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex))
static inline struct mt76_dev *mt76_wed_to_dev(struct mtk_wed_device *wed)
{
#ifdef CONFIG_NET_MEDIATEK_SOC_WED
if (wed->wlan.hif2)
return container_of(wed, struct mt76_dev, mmio.wed_hif2);
#endif /* CONFIG_NET_MEDIATEK_SOC_WED */
return container_of(wed, struct mt76_dev, mmio.wed);
}
static inline struct mt76_wcid *
__mt76_wcid_ptr(struct mt76_dev *dev, u16 idx)
{
@@ -1275,7 +1335,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
s8 *val, int len);
int mt76_eeprom_init(struct mt76_dev *dev, int len);
void mt76_eeprom_override(struct mt76_phy *phy);
int mt76_eeprom_override(struct mt76_phy *phy);
int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len);
int mt76_get_of_data_from_nvmem(struct mt76_dev *dev, void *eep,
const char *cell_name, int len);
@@ -1579,6 +1639,109 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len);
#ifdef CONFIG_MT76_NPU
void mt76_npu_check_ppe(struct mt76_dev *dev, struct sk_buff *skb,
u32 info);
int mt76_npu_dma_add_buf(struct mt76_phy *phy, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_queue_buf *buf,
void *txwi_ptr);
int mt76_npu_rx_queue_init(struct mt76_dev *dev, struct mt76_queue *q);
int mt76_npu_fill_rx_queue(struct mt76_dev *dev, struct mt76_queue *q);
void mt76_npu_queue_cleanup(struct mt76_dev *dev, struct mt76_queue *q);
void mt76_npu_disable_irqs(struct mt76_dev *dev);
int mt76_npu_init(struct mt76_dev *dev, phys_addr_t phy_addr, int type);
void mt76_npu_deinit(struct mt76_dev *dev);
void mt76_npu_queue_setup(struct mt76_dev *dev, struct mt76_queue *q);
void mt76_npu_txdesc_cleanup(struct mt76_queue *q, int index);
int mt76_npu_net_setup_tc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct net_device *dev, enum tc_setup_type type,
void *type_data);
#else
static inline void mt76_npu_check_ppe(struct mt76_dev *dev,
struct sk_buff *skb, u32 info)
{
}
static inline int mt76_npu_dma_add_buf(struct mt76_phy *phy,
struct mt76_queue *q,
struct sk_buff *skb,
struct mt76_queue_buf *buf,
void *txwi_ptr)
{
return -EOPNOTSUPP;
}
static inline int mt76_npu_fill_rx_queue(struct mt76_dev *dev,
struct mt76_queue *q)
{
return 0;
}
static inline void mt76_npu_queue_cleanup(struct mt76_dev *dev,
struct mt76_queue *q)
{
}
static inline void mt76_npu_disable_irqs(struct mt76_dev *dev)
{
}
static inline int mt76_npu_init(struct mt76_dev *dev, phys_addr_t phy_addr,
int type)
{
return 0;
}
static inline void mt76_npu_deinit(struct mt76_dev *dev)
{
}
static inline void mt76_npu_queue_setup(struct mt76_dev *dev,
struct mt76_queue *q)
{
}
static inline void mt76_npu_txdesc_cleanup(struct mt76_queue *q,
int index)
{
}
static inline int mt76_npu_net_setup_tc(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct net_device *dev,
enum tc_setup_type type,
void *type_data)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_MT76_NPU */
static inline bool mt76_npu_device_active(struct mt76_dev *dev)
{
return !!rcu_access_pointer(dev->mmio.npu);
}
static inline bool mt76_ppe_device_active(struct mt76_dev *dev)
{
return !!rcu_access_pointer(dev->mmio.ppe_dev);
}
static inline int mt76_npu_send_msg(struct airoha_npu *npu, int ifindex,
enum airoha_npu_wlan_set_cmd cmd,
u32 val, gfp_t gfp)
{
return airoha_npu_wlan_send_msg(npu, ifindex, cmd, &val, sizeof(val),
gfp);
}
static inline int mt76_npu_get_msg(struct airoha_npu *npu, int ifindex,
enum airoha_npu_wlan_get_cmd cmd,
u32 *val, gfp_t gfp)
{
return airoha_npu_wlan_get_msg(npu, ifindex, cmd, val, sizeof(*val),
gfp);
}
static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
{
#ifdef CONFIG_NL80211_TESTMODE
@@ -1624,6 +1787,7 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
void mt76_scan_work(struct work_struct *work);
void mt76_abort_scan(struct mt76_dev *dev);
void mt76_roc_complete_work(struct work_struct *work);
void mt76_roc_complete(struct mt76_phy *phy);
void mt76_abort_roc(struct mt76_phy *phy);
struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
struct ieee80211_vif *vif);
@@ -1797,21 +1961,51 @@ static inline bool mt76_queue_is_wed_rro_ind(struct mt76_queue *q)
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_IND;
}
static inline bool mt76_queue_is_wed_rro_rxdmad_c(struct mt76_queue *q)
{
return mt76_queue_is_wed_rro(q) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_RXDMAD_C;
}
static inline bool mt76_queue_is_wed_rro_data(struct mt76_queue *q)
{
return mt76_queue_is_wed_rro(q) &&
(FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA ||
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_MSDU_PG);
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_RRO_Q_DATA;
}
static inline bool mt76_queue_is_wed_rro_msdu_pg(struct mt76_queue *q)
{
return mt76_queue_is_wed_rro(q) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) ==
MT76_WED_RRO_Q_MSDU_PG;
}
static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
{
if (!(q->flags & MT_QFLAG_WED))
return false;
return (q->flags & MT_QFLAG_WED) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
}
return FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX ||
mt76_queue_is_wed_rro_ind(q) || mt76_queue_is_wed_rro_data(q);
static inline bool mt76_queue_is_emi(struct mt76_queue *q)
{
return q->flags & MT_QFLAG_EMI_EN;
}
static inline bool mt76_queue_is_npu(struct mt76_queue *q)
{
return q->flags & MT_QFLAG_NPU;
}
static inline bool mt76_queue_is_npu_tx(struct mt76_queue *q)
{
return mt76_queue_is_npu(q) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TX;
}
static inline bool mt76_queue_is_npu_rx(struct mt76_queue *q)
{
return mt76_queue_is_npu(q) &&
FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
}
struct mt76_txwi_cache *
@@ -1835,7 +2029,8 @@ mt76_get_page_pool_buf(struct mt76_queue *q, u32 *offset, u32 size)
{
struct page *page;
page = page_pool_dev_alloc_frag(q->page_pool, offset, size);
page = page_pool_alloc_frag(q->page_pool, offset, size,
GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
if (!page)
return NULL;
@@ -1891,6 +2086,7 @@ mt76_vif_init(struct ieee80211_vif *vif, struct mt76_vif_data *mvif)
}
void mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif);
u16 mt76_select_links(struct ieee80211_vif *vif, int max_active_links);
static inline struct mt76_vif_link *
mt76_vif_link(struct mt76_dev *dev, struct ieee80211_vif *vif, int link_id)
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config MT7603E
tristate "MediaTek MT7603E (PCIe) and MT76x8 WLAN support"
select MT76_CORE
depends on MAC80211
depends on PCI
help
This adds support for MT7603E PCIe wireless devices and the WLAN core
on MT7628/MT7688 SoC devices. This family supports IEEE 802.11n 2x2
to 300Mbps PHY rate
To compile this driver as a module, choose M here.
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
obj-$(CONFIG_MT7603E) += mt7603e.o
mt7603e-y := \
pci.o soc.o main.o init.o mcu.o \
core.o dma.o mac.o eeprom.o \
beacon.o debugfs.o
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include "mt7603.h"
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include "mt7603.h"
#include "../trace.h"
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include "mt7603.h"
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include "mt7603.h"
#include "mac.h"
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/of.h>
#include "mt7603.h"
@@ -182,7 +182,6 @@ int mt7603_eeprom_init(struct mt7603_dev *dev)
dev->mphy.antenna_mask = 1;
dev->mphy.chainmask = dev->mphy.antenna_mask;
mt76_eeprom_override(&dev->mphy);
return 0;
return mt76_eeprom_override(&dev->mphy);
}
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
#ifndef __MT7603_EEPROM_H
#define __MT7603_EEPROM_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/etherdevice.h>
#include "mt7603.h"
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/etherdevice.h>
#include <linux/timekeeping.h>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
#ifndef __MT7603_MAC_H
#define __MT7603_MAC_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/firmware.h>
#include "mt7603.h"
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
#ifndef __MT7603_MCU_H
#define __MT7603_MCU_H
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
#ifndef __MT7603_H
#define __MT7603_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/kernel.h>
#include <linux/module.h>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
#ifndef __MT7603_REGS_H
#define __MT7603_REGS_H
+2 -2
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include <linux/kernel.h>
#include <linux/module.h>
@@ -48,7 +48,7 @@ mt76_wmac_probe(struct platform_device *pdev)
return 0;
error:
ieee80211_free_hw(mt76_hw(dev));
mt76_free_device(mdev);
return ret;
}
@@ -0,0 +1,56 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config MT7615_COMMON
tristate
select WANT_DEV_COREDUMP
select MT76_CONNAC_LIB
config MT7615E
tristate "MediaTek MT7615E and MT7663E (PCIe) support"
select MT7615_COMMON
depends on MAC80211
depends on PCI
help
This adds support for MT7615-based PCIe wireless devices,
which support concurrent dual-band operation at both 5GHz
and 2.4GHz, IEEE 802.11ac 4x4:4SS 1733Mbps PHY rate, wave2
MU-MIMO up to 4 users/group and 160MHz channels.
To compile this driver as a module, choose M here.
config MT7622_WMAC
bool "MT7622 (SoC) WMAC support"
depends on MT7615E
depends on ARCH_MEDIATEK || COMPILE_TEST
select REGMAP
default y
help
This adds support for the built-in WMAC on MT7622 SoC devices
which has the same feature set as a MT7615, but limited to
2.4 GHz only.
config MT7663_USB_SDIO_COMMON
tristate
select MT7615_COMMON
config MT7663U
tristate "MediaTek MT7663U (USB) support"
select MT76_USB
select MT7663_USB_SDIO_COMMON
depends on MAC80211
depends on USB
help
This adds support for MT7663U 802.11ac 2x2:2 wireless devices.
To compile this driver as a module, choose M here.
config MT7663S
tristate "MediaTek MT7663S (SDIO) support"
select MT76_SDIO
select MT7663_USB_SDIO_COMMON
depends on MAC80211
depends on MMC
help
This adds support for MT7663S 802.11ac 2x2:2 wireless devices.
To compile this driver as a module, choose M here.
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: ISC
# SPDX-License-Identifier: BSD-3-Clause-Clear
obj-$(CONFIG_MT7615_COMMON) += mt7615-common.o
obj-$(CONFIG_MT7615E) += mt7615e.o
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
#include "mt7615.h"
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
@@ -366,8 +366,6 @@ int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr)
#endif
ETH_ALEN);
mt76_eeprom_override(&dev->mphy);
return 0;
return mt76_eeprom_override(&dev->mphy);
}
EXPORT_SYMBOL_GPL(mt7615_eeprom_init);
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2019 MediaTek Inc. */
#ifndef __MT7615_EEPROM_H
+5 -2
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Roy Luo <royluo@google.com>
@@ -576,7 +576,10 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
ETH_ALEN);
mphy->macaddr[0] |= 2;
mphy->macaddr[0] ^= BIT(7);
mt76_eeprom_override(mphy);
ret = mt76_eeprom_override(mphy);
if (ret)
return ret;
/* second phy can only handle 5 GHz */
mphy->cap.has_5ghz = true;
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2019 MediaTek Inc. */
#ifndef __MT7615_MAC_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Roy Luo <royluo@google.com>
+4 -2
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Roy Luo <royluo@google.com>
@@ -878,8 +878,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,
WTBL_RESET_AND_SET, NULL,
&wskb);
if (IS_ERR(wtbl_hdr))
if (IS_ERR(wtbl_hdr)) {
dev_kfree_skb(sskb);
return PTR_ERR(wtbl_hdr);
}
if (enable) {
mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta,
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2019 MediaTek Inc. */
#ifndef __MT7615_MCU_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc. */
#include <linux/kernel.h>
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2019 MediaTek Inc. */
#ifndef __MT7615_H
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Roy Luo <royluo@google.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2019 MediaTek Inc. */
#ifndef __MT7615_REGS_H
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc.
*
* Author: Felix Fietkau <nbd@nbd.name>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Ryder Lee <ryder.lee@mediatek.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
#include "mt7615.h"
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2019 MediaTek Inc.
*
* Author: Felix Fietkau <nbd@nbd.name>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc.
*
* Author: Lorenzo Bianconi <lorenzo@kernel.org>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2020 MediaTek Inc. */
#ifndef __MT76_CONNAC_H
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2022 MediaTek Inc. */
#ifndef __MT76_CONNAC2_MAC_H
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2023 MediaTek Inc. */
#include "mt76_connac.h"
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2023 MediaTek Inc. */
#ifndef __MT76_CONNAC3_MAC_H
@@ -294,6 +294,13 @@ enum tx_frag_idx {
#define MT_TXP_BUF_LEN GENMASK(11, 0)
#define MT_TXP_DMA_ADDR_H GENMASK(15, 12)
#define MT_TXP0_TOKEN_ID0 GENMASK(14, 0)
#define MT_TXP0_TOKEN_ID0_VALID_MASK BIT(15)
#define MT_TXP1_TID_ADDBA GENMASK(14, 12)
#define MT_TXP3_ML0_MASK BIT(15)
#define MT_TXP3_DMA_ADDR_H GENMASK(13, 12)
#define MT_TX_RATE_STBC BIT(14)
#define MT_TX_RATE_NSS GENMASK(13, 10)
#define MT_TX_RATE_MODE GENMASK(9, 6)
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc. */
#include "mt76_connac.h"
@@ -297,16 +297,18 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy,
struct ieee80211_bss_conf *conf,
bool beacon, bool mcast)
{
struct mt76_vif_link *mvif = mt76_vif_conf_link(mphy->dev, conf->vif, conf);
struct cfg80211_chan_def *chandef = mvif->ctx ?
&mvif->ctx->def : &mphy->chandef;
u8 nss = 0, mode = 0, band = chandef->chan->band;
int rateidx = 0, mcast_rate;
int offset = 0;
u8 nss = 0, mode = 0, band = NL80211_BAND_2GHZ;
int rateidx = 0, offset = 0, mcast_rate;
struct cfg80211_chan_def *chandef;
struct mt76_vif_link *mvif;
if (!conf)
goto legacy;
mvif = mt76_vif_conf_link(mphy->dev, conf->vif, conf);
chandef = mvif->ctx ? &mvif->ctx->def : &mphy->chandef;
band = chandef->chan->band;
if (is_mt7921(mphy->dev)) {
rateidx = ffs(conf->basic_rates) - 1;
goto legacy;
@@ -584,8 +586,9 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
bool multicast = ieee80211_is_data(hdr->frame_control) &&
is_multicast_ether_addr(hdr->addr1);
u16 rate = mt76_connac2_mac_tx_rate_val(mphy, &vif->bss_conf, beacon,
multicast);
u16 rate = mt76_connac2_mac_tx_rate_val(mphy,
vif ? &vif->bss_conf : NULL,
beacon, multicast);
u32 val = MT_TXD6_FIXED_BW;
/* hardware won't add HTC for mgmt/ctrl frame */
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/* Copyright (C) 2020 MediaTek Inc. */
#include <linux/firmware.h>
@@ -1662,6 +1662,31 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
return err;
}
if (enable && vif->bss_conf.bssid_indicator) {
struct {
struct {
u8 bss_idx;
u8 pad[3];
} __packed hdr;
struct bss_info_uni_mbssid mbssid;
} mbssid_req = {
.hdr = {
.bss_idx = mvif->idx,
},
.mbssid = {
.tag = cpu_to_le16(UNI_BSS_INFO_11V_MBSSID),
.len = cpu_to_le16(sizeof(struct bss_info_uni_mbssid)),
.max_indicator = vif->bss_conf.bssid_indicator,
.mbss_idx = vif->bss_conf.bssid_index,
},
};
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
&mbssid_req, sizeof(mbssid_req), true);
if (err < 0)
return err;
}
return mt76_connac_mcu_uni_set_chctx(phy, mvif, ctx);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
@@ -1949,7 +1974,11 @@ int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
.resp_type = 0,
};
memcpy(req.data, "assert", 7);
#if defined(__linux__)
strscpy(req.data, "assert");
#elif defined(__FreeBSD__)
strscpy(req.data, "assert", sizeof(req.data));
#endif
return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
&req, sizeof(req), false);
@@ -2994,7 +3023,7 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
}
hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
dev_info(dev->dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
dev_info(dev->dev, "WM Firmware Version: %.10s, Build Time: %.15s",
hdr->fw_ver, hdr->build_date);
ret = mt76_connac_mcu_send_ram_firmware(dev, hdr, fw->data, false);
@@ -3023,7 +3052,7 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
}
hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
dev_info(dev->dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
dev_info(dev->dev, "WA Firmware Version: %.10s, Build Time: %.15s",
hdr->fw_ver, hdr->build_date);
ret = mt76_connac_mcu_send_ram_firmware(dev, hdr, fw->data, true);
@@ -3099,7 +3128,7 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
}
hdr = (const void *)fw->data;
dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s",
be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/* Copyright (C) 2020 MediaTek Inc. */
#ifndef __MT76_CONNAC_MCU_H
@@ -1066,6 +1066,7 @@ enum {
MCU_UNI_EVENT_ROC = 0x27,
MCU_UNI_EVENT_TX_DONE = 0x2d,
MCU_UNI_EVENT_THERMAL = 0x35,
MCU_UNI_EVENT_RSSI_MONITOR = 0x41,
MCU_UNI_EVENT_NIC_CAPAB = 0x43,
MCU_UNI_EVENT_WED_RRO = 0x57,
MCU_UNI_EVENT_PER_STA_INFO = 0x6d,
@@ -1304,6 +1305,7 @@ enum {
MCU_UNI_CMD_THERMAL = 0x35,
MCU_UNI_CMD_VOW = 0x37,
MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
MCU_UNI_CMD_RSSI_MONITOR = 0x41,
MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
MCU_UNI_CMD_RRO = 0x57,
MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
@@ -0,0 +1,29 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config MT76x2_COMMON
tristate
select MT76x02_LIB
config MT76x2E
tristate "MediaTek MT76x2E (PCIe) support"
select MT76x2_COMMON
depends on MAC80211
depends on PCI
help
This adds support for MT7612/MT7602/MT7662-based PCIe wireless
devices, which comply with IEEE 802.11ac standards and support
2SS to 866Mbit/s PHY rate.
To compile this driver as a module, choose M here.
config MT76x2U
tristate "MediaTek MT76x2U (USB) support"
select MT76x2_COMMON
select MT76x02_USB
depends on MAC80211
depends on USB
help
This adds support for MT7612U-based USB 3.0 wireless dongles,
which comply with IEEE 802.11ac standards and support 2SS to
866Mbit/s PHY rate.
To compile this driver as a module, choose M here.
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o
obj-$(CONFIG_MT76x2E) += mt76x2e.o
obj-$(CONFIG_MT76x2U) += mt76x2u.o
mt76x2-common-y := \
eeprom.o mac.o init.o phy.o mcu.o
mt76x2e-y := \
pci.o pci_main.o pci_init.o pci_mcu.o \
pci_phy.o
mt76x2u-y := \
usb.o usb_init.o usb_main.o usb_mac.o usb_mcu.o \
usb_phy.o
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -499,7 +499,9 @@ int mt76x2_eeprom_init(struct mt76x02_dev *dev)
mt76x02_eeprom_parse_hw_cap(dev);
mt76x2_eeprom_get_macaddr(dev);
mt76_eeprom_override(&dev->mphy);
ret = mt76_eeprom_override(&dev->mphy);
if (ret)
return ret;
dev->mphy.macaddr[0] &= ~BIT(1);
return 0;
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
+1 -1
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: ISC
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: ISC */
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
/*
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
*/

Some files were not shown because too many files have changed in this diff Show More