[BPI-R64] mt7622 mac80211 WiFi driver

Interesting find, I guess this only affects mt7622 wmac but not mt7615?

@moore any info on this?

Right,this patch is only for mt7622,but i guess for mt7615 there should be a similar way as mt7622 uses mt7615 core


The four antennas on the board are all for MT7622 WiFi, could you explain more that what did you mean about “how does the board decides which device uses which antenna”?

I’ve tested the latest driver, and it can use rate MCS31 (4 antennas).

root@OpenWrt:/# iw phy | grep Antennas
        Available Antennas: TX 0xf RX 0xf
        Configured Antennas: TX 0xf RX 0xf

root@OpenWrt:/# iw dev wlan0 station dump
Station 2c:fd:a1:ce:5e:a9 (on wlan0)
        inactive time:  8 ms
        rx bytes:       12685717
        rx packets:     169384
        tx bytes:       812461366
        tx packets:     271666
        tx retries:     75596
        tx failed:      150
        rx drop misc:   1
        signal:         -43 [-43, -60, -44, -44] dBm
        signal avg:     -43 [-43, -59, -44, -44] dBm
        tx bitrate:     288.9 MBit/s MCS 31 short GI
        tx duration:    41637653 us
        rx bitrate:     288.9 MBit/s MCS 31 short GI
        rx duration:    1901454 us
1 Like

Needs the MCS31 mode enabled? How?

is your latest branch fixed to use 4 antennas?

i don’t know if i need additional patches to enable all 4 antennas…thats why i asked how to enable the mode to check

what he meant is to test the speed directly. If the speed of a single antenna is about 100Mbps, the speed of four antennas is more than 200Mbps.

there are two problems with MT7622 wifi, right? first is 6db, and second is antenna. isn’t it repair on your branch?

6db seems to depend on eeprom which cannot be loaded currently without mtd (my file-aproach was denied to be implemented). Antenna i don’t know how to check/set the mcs31 mode.

i can only fix if i know how to do it :slight_smile:

how can I judge that my board has successfully loaded eeprom? i have no errors in the startup log? but " txpower 6.00 dBm"

by default eeprom from card is loaded…an this is stuck by 6dbm…to use higher txpower vyou need to load other eeprom with the tx-bytes set to 21db

Txpower and the number of tx antenna are both load from eeprom. You can try to manually set “tx_mask” variable in mt7615_eeprom_parse_hw_cap() to 4, to see if you can get 4 antennas working.

can you help me to add code for loading eeprom-file from rootfs? instead of mtd partition? imho this should be similar

i know it is loaded from mtd, i want to know how to check the load is successful, because my boot log has no eeprom errors.

does no error mean that the load was successful? but I deleted all mtd used to save eeprom. still no startup error. dd if=/dev/zero of=/dev/mmcblk1p4 dd if=/dev/zero of=/dev/mmcblk1p5

As i said,by default eeprom is read from card itself (imho called efuse). Additionaly mtd can be used. I guess read from mtd is done here (common code for all mt76 wireless devices):


So you can add debug code here to check

your commands here on my r2 with mt7615

root@bpi-r2:~# iw phy | grep Antennas                                           
        Available Antennas: TX 0xf RX 0xf                                       
        Configured Antennas: TX 0xf RX 0xf                                      
root@bpi-r2:~# iw dev wlan0 station dump                                        

first is same output as yours, last one is empty, i guess i need to be connected to a AP to see output, right? can i open an IP with mcs31 enabled?

have not tried yet the code-change in this file (tx_mask = 4):


can you help me getting eeprom-data loaded from file?


first is same output as yours, last one is empty, i guess i need to be connected to a AP to see output, right? can i open an IP with mcs31 enabled?

Yes. MCS31 is already enabled in HT mode. For VHT mode, you can see up to 4 spatial streams and MCS9. If you have two mt7615 NICs, you can run each of them with AP and STA mode.

can you help me getting eeprom-data loaded from file?

I will do it when I have time.

How do i set this without openwrt? I guess it needs to be set in hostapd setup anyhow

I think it is possible to add such code, otherwise loading a configuration file is too troublesome, I tested it and the loading is no problem, compatible with existing code.

// SPDX-License-Identifier: ISC
 * Copyright (C) 2016 Felix Fietkau <[email protected]>
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/etherdevice.h>
#include "mt76.h"

static int
mt76_get_of_file(struct mt76_dev *dev, int len)
#if defined(CONFIG_OF)
	struct device_node *np = dev->dev->of_node;
	const char *fname;
	struct file *fp;
	loff_t pos=0;
	char path[64]="/lib/firmware/";
	ssize_t ret;
	if (!np)
		return -ENOENT;
	ret = of_property_read_string(np, "mediatek,rf-conf", &fname);
	if (!np)
		return -EINVAL;
	if((strlen(path)+strlen(fname)) > sizeof(path)){
		dev_info(dev->dev,"Erro 'mediatek,rf-conf' too long\n");
		return -EINVAL;
	dev_info(dev->dev,"Find 'mediatek,rf-conf' : %s\n",path);
	fp = filp_open(path, O_RDWR, 0);
	if (IS_ERR(fp)) {
		dev_info(dev->dev,"Open File Faile : %s\n",path);
		return -ENOENT;
	ret = kernel_read(fp, dev->eeprom.data, len, &pos);
	if(ret < len){
		dev_info(dev->dev,"Read File ERR, count %ld\n",ret);
		ret = -ENOENT;
	filp_close(fp, 0);
	dev_info(dev->dev,"Read File OK, count %ld\n",ret);
	return 0;
	return -ENOENT;

static int
mt76_get_of_eeprom(struct mt76_dev *dev, int len)
#if defined(CONFIG_OF) && defined(CONFIG_MTD)
	struct device_node *np = dev->dev->of_node;
	struct mtd_info *mtd;
	const __be32 *list;
	const char *part;
	phandle phandle;
	int offset = 0;
	int size;
	size_t retlen;
	int ret;
	if (!np)
		return -ENOENT;
	list = of_get_property(np, "mediatek,mtd-eeprom", &size);
	if (!list)
		return -ENOENT;

	phandle = be32_to_cpup(list++);
	if (!phandle)
		return -ENOENT;

	np = of_find_node_by_phandle(phandle);
	if (!np)
		return -EINVAL;

	part = of_get_property(np, "label", NULL);
	if (!part)
		part = np->name;

	mtd = get_mtd_device_nm(part);
	if (IS_ERR(mtd)) {
		ret =  PTR_ERR(mtd);
		goto out_put_node;
	if (size <= sizeof(*list)) {
		ret = -EINVAL;
		goto out_put_node;
	offset = be32_to_cpup(list);
	ret = mtd_read(mtd, offset, len, &retlen, dev->eeprom.data);
	if (ret)
		goto out_put_node;
	if (retlen < len) {
		ret = -EINVAL;
		goto out_put_node;
	return ret;
	return -ENOENT;

mt76_eeprom_override(struct mt76_dev *dev)
#ifdef CONFIG_OF
	struct device_node *np = dev->dev->of_node;
	const u8 *mac;

	if (!np)

	mac = of_get_mac_address(np);
	if (!IS_ERR_OR_NULL(mac))
		memcpy(dev->macaddr, mac, ETH_ALEN);

	if (!is_valid_ether_addr(dev->macaddr)) {
			 "Invalid MAC address, using random address %pM\n",

mt76_eeprom_init(struct mt76_dev *dev, int len)
	dev->eeprom.size = len;
	dev->eeprom.data = devm_kzalloc(dev->dev, len, GFP_KERNEL);
	if (!dev->eeprom.data)
		return -ENOMEM;
	return (!mt76_get_of_file(dev, len)) || (!mt76_get_of_eeprom(dev, len));//mtd priority mt76

device treexx.dts

&wmac {
	mediatek,rf-conf = "mt7622_rf_conf.bin";
	status = "okay";

eeprom.bin copy to /lib/firmware/mt7622_rf_conf.bin

root@MT7622:~# dmesg | grep mt7622
[    1.237929] rtc_mt7622 10212800.rtc: registered as rtc0
[    2.171585] rtc_mt7622 10212800.rtc: setting system clock to 2000-01-01T00:00:01 UTC (946684801)
[    5.520073] mt7622_wmac 18000000.wmac: ASIC revision: 76220010
[    5.562880] mt7622_wmac 18000000.wmac: Find 'mediatek,rf-conf' : /lib/firmware/mt7622_rf_conf.bin
[    5.622651] mt7622_wmac 18000000.wmac: Read File OK, count 1024
[    5.666614] mt7622_wmac 18000000.wmac: MAC addr = 00:0c:43:26:60:00
[    5.721189] mt7622_wmac 18000000.wmac: N9 Firmware Version: _reserved_, Build Time: 20190801210351
[    5.856793] mt7622_wmac 18000000.wmac: Firmware init done
[    5.902582] mt7622_wmac 18000000.wmac: Driver own success

can it be added to your branch?