From c190f15d6f4a112e795ac50391e8adc50a80fe91 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 28 Feb 2016 14:22:09 +0100 Subject: [PATCH] mt7603: add basic mt7628 support Signed-off-by: Felix Fietkau --- Makefile | 2 +- mt76.h | 6 ++++ mt7603.h | 16 ++++++++- mt7603_init.c | 2 +- mt7603_main.c | 17 +++++++++- mt7603_mcu.c | 15 ++++++--- mt7603_soc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 mt7603_soc.c diff --git a/Makefile b/Makefile index 6e2a6c99..5ec48c37 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,6 @@ mt76x2e-y := \ mt76x2_trace.o mt7603e-y := \ - mt7603_pci.o mt7603_main.o mt7603_init.o mt7603_mcu.o \ + mt7603_pci.o mt7603_soc.o mt7603_main.o mt7603_init.o mt7603_mcu.o \ mt7603_core.o mt7603_dma.o mt7603_mac.o mt7603_eeprom.o \ mt7603_beacon.o diff --git a/mt76.h b/mt76.h index eaf6c7f5..1a543311 100644 --- a/mt76.h +++ b/mt76.h @@ -239,11 +239,17 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); +static inline u16 mt76_chip(struct mt76_dev *dev) +{ + return dev->rev >> 16; +} + static inline u16 mt76_rev(struct mt76_dev *dev) { return dev->rev & 0xffff; } +#define mt76xx_chip(dev) mt76_chip(&((dev)->mt76)) #define mt76xx_rev(dev) mt76_rev(&((dev)->mt76)) #define mt76_init_queues(dev) (dev)->mt76.queue_ops->init(&((dev)->mt76)) diff --git a/mt7603.h b/mt7603.h index 825da457..69396a60 100644 --- a/mt7603.h +++ b/mt7603.h @@ -26,6 +26,8 @@ #define MT7603_FIRMWARE_E1 "mt7603_e1.bin" #define MT7603_FIRMWARE_E2 "mt7603_e2.bin" +#define MT7628_FIRMWARE_E1 "mt7628_e1.bin" +#define MT7628_FIRMWARE_E2 "mt7628_e2.bin" #define MT7603_EEPROM_SIZE 1024 @@ -38,7 +40,8 @@ enum { MT7603_REV_E1 = 0x00, - MT7603_REV_E2 = 0x10 + MT7603_REV_E2 = 0x10, + MT7628_REV_E1 = 0x8a00, }; enum mt7603_bw { @@ -138,6 +141,17 @@ struct mt7603_dev { extern const struct ieee80211_ops mt7603_ops; extern struct pci_driver mt7603_pci_driver; +extern struct platform_driver mt76_wmac_driver; + +static inline bool is_mt7603(struct mt7603_dev *dev) +{ + return mt76xx_chip(dev) == 0x7603; +} + +static inline bool is_mt7628(struct mt7603_dev *dev) +{ + return mt76xx_chip(dev) == 0x7628; +} /* need offset to prevent conflict with ampdu_ack_len */ #define MT_RATE_DRIVER_DATA_OFFSET 4 diff --git a/mt7603_init.c b/mt7603_init.c index ead1392b..3d986925 100644 --- a/mt7603_init.c +++ b/mt7603_init.c @@ -102,7 +102,7 @@ mt7603_dma_sched_init(struct mt7603_dev *dev) mt76_wr(dev, MT_RSV_MAX_THRESH, page_count); - if (mt76xx_rev(dev) < MT7603_REV_E2) { + if (is_mt7603(dev) && mt76xx_rev(dev) < MT7603_REV_E2) { mt76_wr(dev, MT_GROUP_THRESH(0), page_count); mt76_wr(dev, MT_BMAP_0, 0xffff); } else { diff --git a/mt7603_main.c b/mt7603_main.c index 419dc915..f5706863 100644 --- a/mt7603_main.c +++ b/mt7603_main.c @@ -12,6 +12,7 @@ */ #include +#include #include #include "mt7603.h" #include "mt7603_eeprom.h" @@ -527,12 +528,26 @@ MODULE_LICENSE("GPL"); static int __init mt7603_init(void) { - return pci_register_driver(&mt7603_pci_driver); + int ret; + + ret = platform_driver_register(&mt76_wmac_driver); + if (ret) + return ret; + +#ifdef CONFIG_PCI + ret = pci_register_driver(&mt7603_pci_driver); + if (ret) + platform_driver_unregister(&mt76_wmac_driver); +#endif + return ret; } static void __exit mt7603_exit(void) { +#ifdef CONFIG_PCI pci_unregister_driver(&mt7603_pci_driver); +#endif + platform_driver_unregister(&mt76_wmac_driver); } module_init(mt7603_init); diff --git a/mt7603_mcu.c b/mt7603_mcu.c index f2b8529d..d6895435 100644 --- a/mt7603_mcu.c +++ b/mt7603_mcu.c @@ -211,10 +211,17 @@ mt7603_load_firmware(struct mt7603_dev *dev) u32 addr, val; int ret; - if (mt76xx_rev(dev) < MT7603_REV_E2) - firmware = MT7603_FIRMWARE_E1; - else - firmware = MT7603_FIRMWARE_E2; + if (is_mt7628(dev)) { + if (mt76xx_rev(dev) == MT7628_REV_E1) + firmware = MT7628_FIRMWARE_E1; + else + firmware = MT7628_FIRMWARE_E2; + } else { + if (mt76xx_rev(dev) < MT7603_REV_E2) + firmware = MT7603_FIRMWARE_E1; + else + firmware = MT7603_FIRMWARE_E2; + } ret = request_firmware(&fw, firmware, dev->mt76.dev); if (ret) diff --git a/mt7603_soc.c b/mt7603_soc.c new file mode 100644 index 00000000..2dfc891a --- /dev/null +++ b/mt7603_soc.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2016 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include "mt7603.h" + +static int +mt76_wmac_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct mt7603_dev *dev; + void __iomem *mem_base; + int irq; + int ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get device IRQ\n"); + return irq; + } + + mem_base = devm_ioremap_resource(&pdev->dev, res); + if (!mem_base) { + dev_err(&pdev->dev, "Failed to get memory resource\n"); + return -EINVAL; + } + + dev = mt7603_alloc_device(&pdev->dev); + if (!dev) + return -ENOMEM; + + mt76_mmio_init(&dev->mt76, mem_base); + + dev->mt76.rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) | + (mt76_rr(dev, MT_HW_REV) & 0xff); + dev_printk(KERN_INFO, dev->mt76.dev, "ASIC revision: %04x\n", dev->mt76.rev); + + ret = devm_request_irq(dev->mt76.dev, irq, mt7603_irq_handler, + IRQF_SHARED, KBUILD_MODNAME, dev); + if (ret) + goto error; + + ret = mt7603_register_device(dev); + if (ret) + goto error; + + return 0; +error: + ieee80211_free_hw(mt76_hw(dev)); + return ret; +} + +static int +mt76_wmac_remove(struct platform_device *pdev) +{ + struct mt76_dev *mdev = platform_get_drvdata(pdev); + struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); + + mt7603_unregister_device(dev); + + return 0; +} + +static const struct of_device_id of_wmac_match[] = { + { .compatible = "mediatek,mt7628-wmac" }, + {}, +}; + +MODULE_DEVICE_TABLE(of, of_wmac_match); +MODULE_FIRMWARE(MT7628_FIRMWARE_E1); +MODULE_FIRMWARE(MT7628_FIRMWARE_E2); + +struct platform_driver mt76_wmac_driver = { + .probe = mt76_wmac_probe, + .remove = mt76_wmac_remove, + .driver = { + .name = "mt76_wmac", + .of_match_table = of_wmac_match, + }, +};