Skip to content

Commit 48fab5b

Browse files
moore-brosnbd168
authored andcommitted
mt76: mt7921: introduce mt7921s support
Introduce support for mt7921s 802.11ax (Wi-Fi 6) 2x2:2SS chipset. Tested-by: Deren Wu <[email protected]> Co-developed-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Sean Wang <[email protected]> Signed-off-by: Felix Fietkau <[email protected]>
1 parent fe0195f commit 48fab5b

File tree

11 files changed

+637
-15
lines changed

11 files changed

+637
-15
lines changed

drivers/net/wireless/mediatek/mt76/mt7921/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,13 @@ config MT7921E
1313
This adds support for MT7921E 802.11ax 2x2:2SS wireless devices.
1414

1515
To compile this driver as a module, choose M here.
16+
17+
config MT7921S
18+
tristate "MediaTek MT7921S (SDIO) support"
19+
select MT76_SDIO
20+
select MT7921_COMMON
21+
depends on MAC80211
22+
help
23+
This adds support for MT7921S 802.11ax 2x2:2SS wireless devices.
24+
25+
To compile this driver as a module, choose M here.

drivers/net/wireless/mediatek/mt76/mt7921/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
obj-$(CONFIG_MT7921_COMMON) += mt7921-common.o
44
obj-$(CONFIG_MT7921E) += mt7921e.o
5+
obj-$(CONFIG_MT7921S) += mt7921s.o
56

67
CFLAGS_trace.o := -I$(src)
78

89
mt7921-common-y := mac.o mcu.o main.o init.o debugfs.o trace.o
910
mt7921-common-$(CONFIG_NL80211_TESTMODE) += testmode.o
1011
mt7921e-y := pci.o pci_mac.o pci_mcu.o dma.o
12+
mt7921s-y := sdio.o sdio_mac.o sdio_mcu.o

drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,20 @@ static int mt7921_chip_reset(void *data, u64 val)
413413

414414
DEFINE_DEBUGFS_ATTRIBUTE(fops_reset, NULL, mt7921_chip_reset, "%lld\n");
415415

416+
static int
417+
mt7921s_sched_quota_read(struct seq_file *s, void *data)
418+
{
419+
struct mt7921_dev *dev = dev_get_drvdata(s->private);
420+
struct mt76_sdio *sdio = &dev->mt76.sdio;
421+
422+
seq_printf(s, "pse_data_quota\t%d\n", sdio->sched.pse_data_quota);
423+
seq_printf(s, "ple_data_quota\t%d\n", sdio->sched.ple_data_quota);
424+
seq_printf(s, "pse_mcu_quota\t%d\n", sdio->sched.pse_mcu_quota);
425+
seq_printf(s, "sched_deficit\t%d\n", sdio->sched.deficit);
426+
427+
return 0;
428+
}
429+
416430
int mt7921_init_debugfs(struct mt7921_dev *dev)
417431
{
418432
struct dentry *dir;
@@ -436,6 +450,8 @@ int mt7921_init_debugfs(struct mt7921_dev *dev)
436450
debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
437451
mt7921_pm_stats);
438452
debugfs_create_file("deep-sleep", 0600, dir, dev, &fops_ds);
439-
453+
if (mt76_is_sdio(&dev->mt76))
454+
debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
455+
mt7921s_sched_quota_read);
440456
return 0;
441457
}

drivers/net/wireless/mediatek/mt76/mt7921/init.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,15 @@ int mt7921_register_device(struct mt7921_dev *dev)
231231
dev->pm.idle_timeout = MT7921_PM_TIMEOUT;
232232
dev->pm.stats.last_wake_event = jiffies;
233233
dev->pm.stats.last_doze_event = jiffies;
234-
dev->pm.enable = true;
235-
dev->pm.ds_enable = true;
234+
235+
/* TODO: mt7921s run sleep mode on default */
236+
if (mt76_is_mmio(&dev->mt76)) {
237+
dev->pm.enable = true;
238+
dev->pm.ds_enable = true;
239+
}
240+
241+
if (mt76_is_sdio(&dev->mt76))
242+
hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE;
236243

237244
ret = mt7921_init_hardware(dev);
238245
if (ret)

drivers/net/wireless/mediatek/mt76/mt7921/mac.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,8 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
843843
struct ieee80211_vif *vif = info->control.vif;
844844
struct mt76_phy *mphy = &dev->mphy;
845845
u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
846+
bool is_mmio = mt76_is_mmio(&dev->mt76);
847+
u32 sz_txd = is_mmio ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
846848
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
847849
u16 tx_count = 15;
848850
u32 val;
@@ -858,15 +860,15 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
858860
p_fmt = MT_TX_TYPE_FW;
859861
q_idx = MT_LMAC_BCN0;
860862
} else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
861-
p_fmt = MT_TX_TYPE_CT;
863+
p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
862864
q_idx = MT_LMAC_ALTX0;
863865
} else {
864-
p_fmt = MT_TX_TYPE_CT;
866+
p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
865867
q_idx = wmm_idx * MT7921_MAX_WMM_SETS +
866868
mt7921_lmac_mapping(dev, skb_get_queue_mapping(skb));
867869
}
868870

869-
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) |
871+
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
870872
FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
871873
FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
872874
txwi[0] = cpu_to_le32(val);
@@ -1384,12 +1386,18 @@ void mt7921_pm_wake_work(struct work_struct *work)
13841386
mphy = dev->phy.mt76;
13851387

13861388
if (!mt7921_mcu_drv_pmctrl(dev)) {
1389+
struct mt76_dev *mdev = &dev->mt76;
13871390
int i;
13881391

1389-
mt76_for_each_q_rx(&dev->mt76, i)
1390-
napi_schedule(&dev->mt76.napi[i]);
1391-
mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);
1392-
mt7921_mcu_tx_cleanup(dev);
1392+
if (mt76_is_sdio(mdev)) {
1393+
mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);
1394+
mt76_worker_schedule(&mdev->sdio.txrx_worker);
1395+
} else {
1396+
mt76_for_each_q_rx(mdev, i)
1397+
napi_schedule(&mdev->napi[i]);
1398+
mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);
1399+
mt7921_mcu_tx_cleanup(dev);
1400+
}
13931401
if (test_bit(MT76_STATE_RUNNING, &mphy->state))
13941402
ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
13951403
MT7921_WATCHDOG_TIME);

drivers/net/wireless/mediatek/mt76/mt7921/mac.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ enum tx_mcu_port_q_idx {
199199

200200
#define MT_TXD_SIZE (8 * 4)
201201

202+
#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4)
203+
#define MT_SDIO_TAIL_SIZE 8
204+
#define MT_SDIO_HDR_SIZE 4
205+
202206
#define MT_TXD0_Q_IDX GENMASK(31, 25)
203207
#define MT_TXD0_PKT_FMT GENMASK(24, 23)
204208
#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)

drivers/net/wireless/mediatek/mt76/mt7921/mcu.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,9 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
650650
{
651651
const struct mt7921_patch_hdr *hdr;
652652
const struct firmware *fw = NULL;
653-
int i, ret, sem;
653+
int i, ret, sem, max_len;
654+
655+
max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096;
654656

655657
sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
656658
switch (sem) {
@@ -706,7 +708,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
706708
}
707709

708710
ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
709-
dl, len, 4096);
711+
dl, len, max_len);
710712
if (ret) {
711713
dev_err(dev->mt76.dev, "Failed to send patch\n");
712714
goto out;
@@ -753,9 +755,11 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
753755
const struct mt7921_fw_trailer *hdr,
754756
const u8 *data, bool is_wa)
755757
{
756-
int i, offset = 0;
758+
int i, offset = 0, max_len;
757759
u32 override = 0, option = 0;
758760

761+
max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096;
762+
759763
for (i = 0; i < hdr->n_region; i++) {
760764
const struct mt7921_fw_region *region;
761765
int err;
@@ -778,7 +782,7 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
778782
}
779783

780784
err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
781-
data + offset, len, 4096);
785+
data + offset, len, max_len);
782786
if (err) {
783787
dev_err(dev->mt76.dev, "Failed to send firmware.\n");
784788
return err;
@@ -851,7 +855,7 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
851855
int ret;
852856

853857
ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
854-
if (ret) {
858+
if (ret && mt76_is_mmio(&dev->mt76)) {
855859
dev_dbg(dev->mt76.dev, "Firmware is already download\n");
856860
goto fw_loaded;
857861
}

drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,29 @@
4747
#define MT7921_SKU_MAX_DELTA_IDX MT7921_SKU_RATE_NUM
4848
#define MT7921_SKU_TABLE_SIZE (MT7921_SKU_RATE_NUM + 1)
4949

50+
#define MT7921_SDIO_HDR_TX_BYTES GENMASK(15, 0)
51+
#define MT7921_SDIO_HDR_PKT_TYPE GENMASK(17, 16)
52+
53+
enum mt7921_sdio_pkt_type {
54+
MT7921_SDIO_TXD,
55+
MT7921_SDIO_DATA,
56+
MT7921_SDIO_CMD,
57+
MT7921_SDIO_FWDL,
58+
};
59+
60+
struct mt7921_sdio_intr {
61+
u32 isr;
62+
struct {
63+
u32 wtqcr[16];
64+
} tx;
65+
struct {
66+
u16 num[2];
67+
u16 len0[16];
68+
u16 len1[128];
69+
} rx;
70+
u32 rec_mb[2];
71+
} __packed;
72+
5073
#define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2)
5174
#define to_rcpi(rssi) (2 * (rssi) + 220)
5275

@@ -321,6 +344,17 @@ static inline void mt7921_mcu_tx_cleanup(struct mt7921_dev *dev)
321344
mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], false);
322345
}
323346

347+
static inline void mt7921_skb_add_sdio_hdr(struct sk_buff *skb,
348+
enum mt7921_sdio_pkt_type type)
349+
{
350+
u32 hdr;
351+
352+
hdr = FIELD_PREP(MT7921_SDIO_HDR_TX_BYTES, skb->len + sizeof(hdr)) |
353+
FIELD_PREP(MT7921_SDIO_HDR_PKT_TYPE, type);
354+
355+
put_unaligned_le32(hdr, skb_push(skb, sizeof(hdr)));
356+
}
357+
324358
int mt7921_mac_init(struct mt7921_dev *dev);
325359
bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask);
326360
void mt7921_mac_reset_counters(struct mt7921_phy *phy);
@@ -394,4 +428,13 @@ int mt7921e_mcu_init(struct mt7921_dev *dev);
394428
int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev);
395429
int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev);
396430

431+
int mt7921s_mcu_init(struct mt7921_dev *dev);
432+
int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev);
433+
int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev);
434+
int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
435+
enum mt76_txq_id qid, struct mt76_wcid *wcid,
436+
struct ieee80211_sta *sta,
437+
struct mt76_tx_info *tx_info);
438+
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
439+
bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
397440
#endif

0 commit comments

Comments
 (0)