add basic stub driver for mt7603

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2015-12-06 19:54:32 +01:00
parent b0f76bb5d9
commit e3dec20ce3
7 changed files with 458 additions and 1 deletions
+4 -1
View File
@@ -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
+35
View File
@@ -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
+30
View File
@@ -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
View File
@@ -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,
};
+87
View File
@@ -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);
}
+83
View File
@@ -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);
+46
View File
@@ -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