Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / net / wireless / mediatek / mt76 / mt76x2 / pci_mcu.c
1 /*
2  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/firmware.h>
19 #include <linux/delay.h>
20
21 #include "mt76x2.h"
22 #include "mcu.h"
23 #include "eeprom.h"
24
25 static int
26 mt76pci_load_rom_patch(struct mt76x02_dev *dev)
27 {
28         const struct firmware *fw = NULL;
29         struct mt76x02_patch_header *hdr;
30         bool rom_protect = !is_mt7612(dev);
31         int len, ret = 0;
32         __le32 *cur;
33         u32 patch_mask, patch_reg;
34
35         if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
36                 dev_err(dev->mt76.dev,
37                         "Could not get hardware semaphore for ROM PATCH\n");
38                 return -ETIMEDOUT;
39         }
40
41         if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
42                 patch_mask = BIT(0);
43                 patch_reg = MT_MCU_CLOCK_CTL;
44         } else {
45                 patch_mask = BIT(1);
46                 patch_reg = MT_MCU_COM_REG0;
47         }
48
49         if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
50                 dev_info(dev->mt76.dev, "ROM patch already applied\n");
51                 goto out;
52         }
53
54         ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev);
55         if (ret)
56                 goto out;
57
58         if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
59                 ret = -EIO;
60                 dev_err(dev->mt76.dev, "Failed to load firmware\n");
61                 goto out;
62         }
63
64         hdr = (struct mt76x02_patch_header *)fw->data;
65         dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
66
67         mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET);
68
69         cur = (__le32 *) (fw->data + sizeof(*hdr));
70         len = fw->size - sizeof(*hdr);
71         mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len);
72
73         mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
74
75         /* Trigger ROM */
76         mt76_wr(dev, MT_MCU_INT_LEVEL, 4);
77
78         if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) {
79                 dev_err(dev->mt76.dev, "Failed to load ROM patch\n");
80                 ret = -ETIMEDOUT;
81         }
82
83 out:
84         /* release semaphore */
85         if (rom_protect)
86                 mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
87         release_firmware(fw);
88         return ret;
89 }
90
91 static int
92 mt76pci_load_firmware(struct mt76x02_dev *dev)
93 {
94         const struct firmware *fw;
95         const struct mt76x02_fw_header *hdr;
96         int len, ret;
97         __le32 *cur;
98         u32 offset, val;
99
100         ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev);
101         if (ret)
102                 return ret;
103
104         if (!fw || !fw->data || fw->size < sizeof(*hdr))
105                 goto error;
106
107         hdr = (const struct mt76x02_fw_header *)fw->data;
108
109         len = sizeof(*hdr);
110         len += le32_to_cpu(hdr->ilm_len);
111         len += le32_to_cpu(hdr->dlm_len);
112
113         if (fw->size != len)
114                 goto error;
115
116         val = le16_to_cpu(hdr->fw_ver);
117         dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
118                  (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
119
120         val = le16_to_cpu(hdr->build_ver);
121         dev_info(dev->mt76.dev, "Build: %x\n", val);
122         dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
123
124         cur = (__le32 *) (fw->data + sizeof(*hdr));
125         len = le32_to_cpu(hdr->ilm_len);
126
127         mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET);
128         mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len);
129
130         cur += len / sizeof(*cur);
131         len = le32_to_cpu(hdr->dlm_len);
132
133         if (mt76xx_rev(dev) >= MT76XX_REV_E3)
134                 offset = MT_MCU_DLM_ADDR_E3;
135         else
136                 offset = MT_MCU_DLM_ADDR;
137
138         mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET);
139         mt76_wr_copy(dev, offset, cur, len);
140
141         mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
142
143         val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2);
144         if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1)
145                 mt76_set(dev, MT_MCU_COM_REG0, BIT(30));
146
147         /* trigger firmware */
148         mt76_wr(dev, MT_MCU_INT_LEVEL, 2);
149         if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) {
150                 dev_err(dev->mt76.dev, "Firmware failed to start\n");
151                 release_firmware(fw);
152                 return -ETIMEDOUT;
153         }
154
155         mt76x02_set_ethtool_fwver(dev, hdr);
156         dev_info(dev->mt76.dev, "Firmware running!\n");
157
158         release_firmware(fw);
159
160         return ret;
161
162 error:
163         dev_err(dev->mt76.dev, "Invalid firmware\n");
164         release_firmware(fw);
165         return -ENOENT;
166 }
167
168 static int
169 mt76pci_mcu_restart(struct mt76_dev *mdev)
170 {
171         struct mt76x02_dev *dev;
172         int ret;
173
174         dev = container_of(mdev, struct mt76x02_dev, mt76);
175
176         mt76x02_mcu_cleanup(dev);
177         mt76x2_mac_reset(dev, true);
178
179         ret = mt76pci_load_firmware(dev);
180         if (ret)
181                 return ret;
182
183         mt76_wr(dev, MT_WPDMA_RST_IDX, ~0);
184
185         return 0;
186 }
187
188 int mt76x2_mcu_init(struct mt76x02_dev *dev)
189 {
190         static const struct mt76_mcu_ops mt76x2_mcu_ops = {
191                 .mcu_restart = mt76pci_mcu_restart,
192                 .mcu_send_msg = mt76x02_mcu_msg_send,
193         };
194         int ret;
195
196         dev->mt76.mcu_ops = &mt76x2_mcu_ops;
197
198         ret = mt76pci_load_rom_patch(dev);
199         if (ret)
200                 return ret;
201
202         ret = mt76pci_load_firmware(dev);
203         if (ret)
204                 return ret;
205
206         mt76x02_mcu_function_select(dev, Q_SELECT, 1);
207         return 0;
208 }