--- /dev/null
+From 0e31738ef78a814fcd2a55f2d57a21d322794da1 Mon Sep 17 00:00:00 2001
+From: Mathias Kresin <dev@kresin.me>
+Date: Fri, 26 Aug 2016 09:16:53 +0200
+Subject: rt2x00: add support for mac addr from device tree
+
+On some devices the EEPROMs of Ralink Wi-Fi chips have a default Ralink
+MAC address set (RT3062F: 00:0C:43:30:62:00, RT3060F:
+00:0C:43:30:60:00). Using multiple of these devices in the same network
+can cause nasty issues.
+
+Allow to override the MAC in the EEPROM with (a known good) one set in
+the device tree to bypass the issue.
+
+Signed-off-by: Mathias Kresin <dev@kresin.me>
+---
+ drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 5 +----
+ drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 5 +----
+ drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 5 +----
+ drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +----
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
+ drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 16 ++++++++++++++++
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 5 +----
+ drivers/net/wireless/ralink/rt2x00/rt73usb.c | 5 +----
+ 8 files changed, 23 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
+@@ -1459,10 +1459,7 @@ static int rt2400pci_validate_eeprom(str
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
+@@ -1585,10 +1585,7 @@ static int rt2500pci_validate_eeprom(str
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
+@@ -1349,10 +1349,7 @@ static int rt2500usb_validate_eeprom(str
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -7531,10 +7531,7 @@ static int rt2800_validate_eeprom(struct
+ * Start validation of the data that has been read.
+ */
+ mac = rt2800_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &word);
+ if (word == 0xffff) {
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -1416,6 +1416,7 @@ static inline void rt2x00debug_dump_fram
+ */
+ u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif);
++void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr);
+
+ /*
+ * Interrupt context handlers.
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -26,6 +26,8 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/log2.h>
++#include <linux/of.h>
++#include <linux/of_net.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00lib.h"
+@@ -931,6 +933,21 @@ static void rt2x00lib_rate(struct ieee80
+ entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
+ }
+
++void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
++{
++ const char *mac_addr;
++
++ mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
++ if (mac_addr)
++ ether_addr_copy(eeprom_mac_addr, mac_addr);
++
++ if (!is_valid_ether_addr(eeprom_mac_addr)) {
++ eth_random_addr(eeprom_mac_addr);
++ rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", eeprom_mac_addr);
++ }
++}
++EXPORT_SYMBOL_GPL(rt2x00lib_set_mac_address);
++
+ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
+ struct hw_mode_spec *spec)
+ {
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -2413,10 +2413,7 @@ static int rt61pci_validate_eeprom(struc
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
+--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
+@@ -1766,10 +1766,7 @@ static int rt73usb_validate_eeprom(struc
+ * Start validation of the data that has been read.
+ */
+ mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+- if (!is_valid_ether_addr(mac)) {
+- eth_random_addr(mac);
+- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
+- }
++ rt2x00lib_set_mac_address(rt2x00dev, mac);
+
+ rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+ if (word == 0xffff) {
--- /dev/null
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+@@ -936,7 +936,12 @@ static void rt2x00lib_rate(struct ieee80
+ void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
+ {
+ const char *mac_addr;
+-
++ struct rt2x00_platform_data *pdata;
++
++ pdata = rt2x00dev->dev->platform_data;
++ if (pdata)
++ ether_addr_copy(pdata->mac_address, eeprom_mac_addr);
++
+ mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
+ if (mac_addr)
+ ether_addr_copy(eeprom_mac_addr, mac_addr);
+--- a/include/linux/rt2x00_platform.h
++++ b/include/linux/rt2x00_platform.h
+@@ -14,6 +14,7 @@
+
+ struct rt2x00_platform_data {
+ char *eeprom_file_name;
++ const u8 *mac_address;
+
+ int disable_2ghz;
+ int disable_5ghz;
+++ /dev/null
---- a/include/linux/rt2x00_platform.h
-+++ b/include/linux/rt2x00_platform.h
-@@ -14,6 +14,7 @@
-
- struct rt2x00_platform_data {
- char *eeprom_file_name;
-+ const u8 *mac_address;
-
- int disable_2ghz;
- int disable_5ghz;
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -931,6 +931,18 @@ static void rt2x00lib_rate(struct ieee80
- entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE;
- }
-
-+const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev)
-+{
-+ struct rt2x00_platform_data *pdata;
-+
-+ pdata = rt2x00dev->dev->platform_data;
-+ if (!pdata)
-+ return NULL;
-+
-+ return pdata->mac_address;
-+}
-+EXPORT_SYMBOL_GPL(rt2x00lib_get_mac_address);
-+
- static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
- struct hw_mode_spec *spec)
- {
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -1416,6 +1416,7 @@ static inline void rt2x00debug_dump_fram
- */
- u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif);
-+const u8 *rt2x00lib_get_mac_address(struct rt2x00_dev *rt2x00dev);
-
- /*
- * Interrupt context handlers.
---- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
-@@ -2392,6 +2392,7 @@ static int rt61pci_validate_eeprom(struc
- u32 reg;
- u16 word;
- u8 *mac;
-+ const u8 *pdata_mac;
- s8 value;
-
- rt2x00mmio_register_read(rt2x00dev, E2PROM_CSR, ®);
-@@ -2412,7 +2413,11 @@ static int rt61pci_validate_eeprom(struc
- /*
- * Start validation of the data that has been read.
- */
-+ pdata_mac = rt2x00lib_get_mac_address(rt2x00dev);
- mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
-+ if (pdata_mac)
-+ memcpy(mac, pdata_mac, 6);
-+
- if (!is_valid_ether_addr(mac)) {
- eth_random_addr(mac);
- rt2x00_eeprom_dbg(rt2x00dev, "MAC: %pM\n", mac);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -26,6 +26,7 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/log2.h>
-+#include <linux/of.h>
-
- #include "rt2x00.h"
- #include "rt2x00lib.h"
-@@ -951,6 +952,16 @@ static int rt2x00lib_probe_hw_modes(stru
+@@ -961,6 +961,16 @@ static int rt2x00lib_probe_hw_modes(stru
struct ieee80211_rate *rates;
unsigned int num_rates;
unsigned int i;
rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
-@@ -7675,6 +7708,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7672,6 +7705,7 @@ static int rt2800_init_eeprom(struct rt2
* RT53xx: defined in "EEPROM_CHIP_ID" field
*/
if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
-@@ -7770,7 +7804,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7767,7 +7801,8 @@ static int rt2800_init_eeprom(struct rt2
/*
* Detect if this device has Bluetooth co-existence.
*/
__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
/*
-@@ -7799,6 +7834,22 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7796,6 +7831,22 @@ static int rt2800_init_eeprom(struct rt2
EIRP_MAX_TX_POWER_LIMIT)
__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
case RT5390:
rt2800_init_rfcsr_5390(rt2x00dev);
break;
-@@ -7577,6 +7679,12 @@ static int rt2800_validate_eeprom(struct
+@@ -7574,6 +7676,12 @@ static int rt2800_validate_eeprom(struct
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2872)) {
/*
-@@ -7715,6 +7823,8 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7712,6 +7820,8 @@ static int rt2800_init_eeprom(struct rt2
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
else if (rt2x00_rt(rt2x00dev, RT3883))
rf = RF3853;
else
rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
-@@ -7734,6 +7844,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7731,6 +7841,7 @@ static int rt2800_init_eeprom(struct rt2
case RF3320:
case RF3322:
case RF3853:
case RF5360:
case RF5362:
case RF5370:
-@@ -8291,6 +8402,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8288,6 +8399,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3290:
case RF3320:
case RF3322:
case RF5360:
case RF5362:
case RF5370:
-@@ -8430,6 +8542,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8427,6 +8539,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3070:
case RF3290:
case RF3853:
case RF5360:
case RF5362:
case RF5370:
-@@ -8470,6 +8583,7 @@ static int rt2800_probe_rt(struct rt2x00
+@@ -8467,6 +8580,7 @@ static int rt2800_probe_rt(struct rt2x00
case RT3572:
case RT3593:
case RT3883:
#include "rt2x00.h"
#include "rt2800lib.h"
-@@ -7934,6 +7935,17 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7931,6 +7932,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1283,7 +1283,7 @@ static inline void rt2x00lib_set_if_comb
+@@ -1292,7 +1292,7 @@ static inline void rt2x00lib_set_if_comb
*/
if_limit = &rt2x00dev->if_limits_ap;
if_limit->max = rt2x00dev->ops->max_ap_intf;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
-@@ -7818,10 +7818,11 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7815,10 +7815,11 @@ static int rt2800_init_eeprom(struct rt2
* RT53xx: defined in "EEPROM_CHIP_ID" field
*/
if (rt2x00_rt(rt2x00dev, RT3290) ||
/*
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -144,7 +144,8 @@ static void rt2x00lib_intf_scheduled_ite
+@@ -145,7 +145,8 @@ static void rt2x00lib_intf_scheduled_ite
if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
mutex_lock(&intf->beacon_skb_mutex);
mutex_unlock(&intf->beacon_skb_mutex);
}
}
-@@ -207,6 +208,7 @@ static void rt2x00lib_beaconupdate_iter(
+@@ -208,6 +209,7 @@ static void rt2x00lib_beaconupdate_iter(
struct ieee80211_vif *vif)
{
struct rt2x00_dev *rt2x00dev = data;
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC &&
-@@ -220,7 +222,8 @@ static void rt2x00lib_beaconupdate_iter(
+@@ -221,7 +223,8 @@ static void rt2x00lib_beaconupdate_iter(
* never be called for USB devices.
*/
WARN_ON(rt2x00_is_usb(rt2x00dev));
break;
case RT5392:
rt2800_init_rfcsr_5392(rt2x00dev);
-@@ -7859,6 +8798,7 @@ static int rt2800_init_eeprom(struct rt2
+@@ -7856,6 +8795,7 @@ static int rt2800_init_eeprom(struct rt2
case RF5390:
case RF5392:
case RF5592:
break;
default:
rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n",
-@@ -8427,6 +9367,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8424,6 +9364,7 @@ static int rt2800_probe_hw_mode(struct r
case RF5372:
case RF5390:
case RF5392:
spec->num_channels = 14;
if (spec->clk_is_20mhz)
spec->channels = rf_vals_xtal20mhz_3x;
-@@ -8567,6 +9508,7 @@ static int rt2800_probe_hw_mode(struct r
+@@ -8564,6 +9505,7 @@ static int rt2800_probe_hw_mode(struct r
case RF5372:
case RF5390:
case RF5392: