mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
add basic stub driver for mt7603
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
EXTRA_CFLAGS += -Werror
|
||||
|
||||
obj-m := mt76.o mt76x2e.o
|
||||
obj-m := mt76.o mt76x2e.o mt7603e.o
|
||||
|
||||
mt76-y := \
|
||||
mmio.o util.o trace.o
|
||||
@@ -12,3 +12,6 @@ mt76x2e-y := \
|
||||
mt76x2_trace.o
|
||||
|
||||
mt76x2e-$(CONFIG_OF) += mt76x2_of.o
|
||||
|
||||
mt7603e-y := \
|
||||
mt7603_pci.o mt7603_main.o mt7603_init.o mt7603_mcu.o
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MT7603_H
|
||||
#define __MT7603_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include "mt76.h"
|
||||
#include "mt7603_regs.h"
|
||||
|
||||
#define MT7603_FIRMWARE_E1 "mt7603_e1.bin"
|
||||
#define MT7603_FIRMWARE_E2 "mt7603_e2.bin"
|
||||
|
||||
struct mt7603_dev {
|
||||
struct mt76_dev mt76;
|
||||
struct device *dev;
|
||||
|
||||
u32 rev;
|
||||
};
|
||||
|
||||
extern const struct ieee80211_ops mt7603_ops;
|
||||
struct mt7603_dev *mt7603_alloc_device(struct device *pdev);
|
||||
int mt7603_mcu_init(struct mt7603_dev *dev);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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 "mt7603.h"
|
||||
|
||||
struct mt7603_dev *mt7603_alloc_device(struct device *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw;
|
||||
struct mt7603_dev *dev;
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(*dev), &mt7603_ops);
|
||||
if (!hw)
|
||||
return NULL;
|
||||
|
||||
dev = hw->priv;
|
||||
dev->dev = pdev;
|
||||
dev->mt76.hw = hw;
|
||||
|
||||
return dev;
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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 "mt7603.h"
|
||||
|
||||
static int
|
||||
mt7603_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_stop(struct ieee80211_hw *hw)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
|
||||
unsigned int *total_flags, u64 multicast)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info, u32 changed)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const u8 *mac)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta,u16 tid, u16 *ssn, u8 buf_size,
|
||||
bool amsdu)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
}
|
||||
|
||||
static void mt7603_set_coverage_class(struct ieee80211_hw *hw,
|
||||
s16 coverage_class)
|
||||
{
|
||||
}
|
||||
|
||||
static void mt7603_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
}
|
||||
|
||||
static void mt7603_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||
u16 tids, int nframes,
|
||||
enum ieee80211_frame_release_type reason,
|
||||
bool more_data)
|
||||
{
|
||||
}
|
||||
|
||||
const struct ieee80211_ops mt7603_ops = {
|
||||
.tx = mt7603_tx,
|
||||
.start = mt7603_start,
|
||||
.stop = mt7603_stop,
|
||||
.add_interface = mt7603_add_interface,
|
||||
.remove_interface = mt7603_remove_interface,
|
||||
.config = mt7603_config,
|
||||
.configure_filter = mt7603_configure_filter,
|
||||
.bss_info_changed = mt7603_bss_info_changed,
|
||||
.sta_add = mt7603_sta_add,
|
||||
.sta_remove = mt7603_sta_remove,
|
||||
.sta_notify = mt7603_sta_notify,
|
||||
.set_key = mt7603_set_key,
|
||||
.conf_tx = mt7603_conf_tx,
|
||||
.sw_scan_start = mt7603_sw_scan,
|
||||
.sw_scan_complete = mt7603_sw_scan_complete,
|
||||
.flush = mt7603_flush,
|
||||
.ampdu_action = mt7603_ampdu_action,
|
||||
.get_txpower = mt7603_get_txpower,
|
||||
.wake_tx_queue = mt7603_wake_tx_queue,
|
||||
.sta_rate_tbl_update = mt7603_sta_rate_tbl_update,
|
||||
.release_buffered_frames = mt7603_release_buffered_frames,
|
||||
.set_coverage_class = mt7603_set_coverage_class,
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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 <linux/firmware.h>
|
||||
#include "mt7603.h"
|
||||
|
||||
struct mt7603_fw_trailer {
|
||||
char fw_ver[10];
|
||||
char build_date[15];
|
||||
__le32 dl_len;
|
||||
} __packed;
|
||||
|
||||
static int
|
||||
mt7603_load_firmware(struct mt7603_dev *dev)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
const struct mt7603_fw_trailer *hdr;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = request_firmware(&fw, MT7603_FIRMWARE_E1, dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!fw || !fw->data || fw->size < sizeof(*hdr))
|
||||
goto error;
|
||||
|
||||
hdr = (const struct mt7603_fw_trailer *) (fw->data + fw->size - sizeof(*hdr));
|
||||
|
||||
dev_info(dev->dev, "Firmware Version: %.10s\n", hdr->fw_ver);
|
||||
dev_info(dev->dev, "Build Time: %.15s\n", hdr->build_date);
|
||||
|
||||
val = mt76_rr(dev, MT_MCU_PCIE_REMAP_1);
|
||||
mt76_wr(dev, MT_MCU_PCIE_REMAP_1,
|
||||
MT76_SET(MT_MCU_PCIE_REMAP_1_OFFSET, 0x1400));
|
||||
mt76_wr(dev, MT_PCIE_REMAP_BASE_1 + 0x12498, 0x5);
|
||||
mt76_wr(dev, MT_PCIE_REMAP_BASE_1 + 0x12498, 0x5);
|
||||
udelay(1);
|
||||
|
||||
mt76_wr(dev, MT_MCU_PCIE_REMAP_1,
|
||||
MT76_SET(MT_MCU_PCIE_REMAP_1_BASE, 0x2940));
|
||||
|
||||
mt76_wr(dev, MT_MCU_PCIE_REMAP_2,
|
||||
MT76_SET(MT_MCU_PCIE_REMAP_2_BASE, 0x1001));
|
||||
|
||||
/* switch to bypass mode */
|
||||
mt76_rmw(dev, MT_SCH_4, MT_SCH_4_FORCE_QID,
|
||||
MT_SCH_4_BYPASS | MT76_SET(MT_SCH_4_FORCE_QID, 5));
|
||||
|
||||
val = mt76_rr(dev, MT_TOP_MISC2);
|
||||
if (val & BIT(1)) {
|
||||
dev_info(dev->dev, "Firmware already running!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!mt76_poll(dev, MT_TOP_MISC2, BIT(0), BIT(0), 500)) {
|
||||
dev_err(dev->dev, "Timeout waiting for ROM code to become ready\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
printk("Invalid firmware\n");
|
||||
release_firmware(fw);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int mt7603_mcu_init(struct mt7603_dev *dev)
|
||||
{
|
||||
return mt7603_load_firmware(dev);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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 <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "mt7603.h"
|
||||
|
||||
static const struct pci_device_id mt76pci_device_table[] = {
|
||||
{ PCI_DEVICE(0x14c3, 0x7603) },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int
|
||||
mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct mt7603_dev *dev;
|
||||
int ret;
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev = mt7603_alloc_device(&pdev->dev);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
dev->rev = mt76_rr(dev, MT_ASIC_VERSION);
|
||||
dev_printk(KERN_INFO, dev->dev, "ASIC revision: %08x\n", dev->rev);
|
||||
|
||||
ret = mt7603_mcu_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void
|
||||
mt76pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt7603_dev *dev = pci_get_drvdata(pdev);
|
||||
|
||||
ieee80211_free_hw(mt76_hw(dev));
|
||||
}
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, mt76pci_device_table);
|
||||
MODULE_FIRMWARE(MT7603_FIRMWARE_E1);
|
||||
MODULE_FIRMWARE(MT7603_FIRMWARE_E2);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct pci_driver mt76pci_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = mt76pci_device_table,
|
||||
.probe = mt76pci_probe,
|
||||
.remove = mt76pci_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(mt76pci_driver);
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Felix Fietkau <[email protected]>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MT7603_REGS_H
|
||||
#define __MT7603_REGS_H
|
||||
|
||||
#define MT_TOP_MISC2 0x1134
|
||||
|
||||
#define MT_MCU_BASE 0x2000
|
||||
#define MT_MCU(ofs) (MT_MCU_BASE + (ofs))
|
||||
|
||||
#define MT_MCU_PCIE_REMAP_1 MT_MCU(0x500)
|
||||
#define MT_MCU_PCIE_REMAP_1_OFFSET GENMASK(17, 0)
|
||||
#define MT_MCU_PCIE_REMAP_1_BASE GENMASK(31, 18)
|
||||
|
||||
#define MT_MCU_PCIE_REMAP_2 MT_MCU(0x504)
|
||||
#define MT_MCU_PCIE_REMAP_2_OFFSET GENMASK(18, 0)
|
||||
#define MT_MCU_PCIE_REMAP_2_BASE GENMASK(31, 19)
|
||||
|
||||
#define MT_HIF_BASE 0x4000
|
||||
#define MT_HIF(ofs) (MT_HIF_BASE + (ofs))
|
||||
|
||||
#define MT_ASIC_VERSION MT_HIF(0x000)
|
||||
|
||||
#define MT_SCH_1 MT_HIF(0x588)
|
||||
#define MT_SCH_2 MT_HIF(0x58c)
|
||||
#define MT_SCH_3 MT_HIF(0x590)
|
||||
|
||||
#define MT_SCH_4 MT_HIF(0x594)
|
||||
#define MT_SCH_4_FORCE_QID GENMASK(4, 0)
|
||||
#define MT_SCH_4_BYPASS BIT(5)
|
||||
|
||||
#define MT_PCIE_REMAP_BASE_1 0x40000
|
||||
#define MT_PCIE_REMAP_BASE_2 0x80000
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user