1 --- a/arch/mips/ath79/dev-wmac.c
2 +++ b/arch/mips/ath79/dev-wmac.c
3 @@ -139,6 +139,137 @@ static void qca955x_wmac_setup(void)
4 ath79_wmac_data.is_clk_25mhz = true;
8 +ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data)
13 + __raw_readl(base + AR9300_OTP_BASE + (4 * addr));
15 + val = __raw_readl(base + AR9300_OTP_STATUS);
16 + if ((val & AR9300_OTP_STATUS_TYPE) == AR9300_OTP_STATUS_VALID)
25 + *data = __raw_readl(base + AR9300_OTP_READ_DATA);
30 +ar93xx_wmac_otp_read(void __iomem *base, int addr, u8 *dest, int len)
35 + for (i = 0; i < len; i++) {
36 + int offset = 8 * ((addr - i) % 4);
38 + if (!ar93xx_wmac_otp_read_word(base, (addr - i) / 4, &data))
41 + dest[i] = (data >> offset) & 0xff;
48 +ar93xx_wmac_otp_uncompress(void __iomem *base, int addr, int len, u8 *dest,
49 + int dest_start, int dest_len)
53 + int end = addr - len;
56 + while (addr > end) {
57 + if (!ar93xx_wmac_otp_read(base, addr, hdr, 2))
63 + if (offset <= dest_start + dest_len &&
64 + offset + len >= dest_start) {
65 + int data_offset = 0;
66 + int dest_offset = 0;
69 + if (offset < dest_start)
70 + data_offset = dest_start - offset;
72 + dest_offset = offset - dest_start;
74 + copy_len = len - data_offset;
75 + if (copy_len > dest_len - dest_offset)
76 + copy_len = dest_len - dest_offset;
78 + ar93xx_wmac_otp_read(base, addr - data_offset,
82 + dest_bytes += copy_len;
86 + return !!dest_bytes;
89 +bool __init ar93xx_wmac_read_mac_address(u8 *dest)
96 + u8 *hdr = (u8 *) &hdr_u32;
97 + u8 mac[6] = { 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 };
98 + int mac_start = 2, mac_end = 8;
100 + BUG_ON(!soc_is_ar933x() && !soc_is_ar934x());
101 + base = ioremap_nocache(AR933X_WMAC_BASE, AR933X_WMAC_SIZE);
102 + while (addr > sizeof(hdr)) {
103 + if (!ar93xx_wmac_otp_read(base, addr, hdr, sizeof(hdr)))
106 + if (hdr_u32 == 0 || hdr_u32 == ~0)
109 + len = (hdr[1] << 4) | (hdr[2] >> 4);
112 + switch (hdr[0] >> 5) {
117 + ar93xx_wmac_otp_read(base, addr - mac_start, mac, 6);
121 + ret |= ar93xx_wmac_otp_uncompress(base, addr, len, mac,
133 + memcpy(dest, mac, 6);
138 void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
141 --- a/arch/mips/ath79/dev-wmac.h
142 +++ b/arch/mips/ath79/dev-wmac.h
144 #define _ATH79_DEV_WMAC_H
146 void ath79_register_wmac(u8 *cal_data, u8 *mac_addr);
147 +bool ar93xx_wmac_read_mac_address(u8 *dest);
149 #endif /* _ATH79_DEV_WMAC_H */
150 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
151 +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
153 #define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
154 #define QCA955X_GMAC_SIZE 0x40
156 +#define AR9300_OTP_BASE 0x14000
157 +#define AR9300_OTP_STATUS 0x15f18
158 +#define AR9300_OTP_STATUS_TYPE 0x7
159 +#define AR9300_OTP_STATUS_VALID 0x4
160 +#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
161 +#define AR9300_OTP_STATUS_SM_BUSY 0x1
162 +#define AR9300_OTP_READ_DATA 0x15f1c