Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver.
3 : : *
4 : : * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw>
5 : : * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com>
6 : : * Copyright (c) a lot of people too. Please respect their work.
7 : : *
8 : : * See MAINTAINERS file for support contact information.
9 : : */
10 : :
11 : : #include <linux/delay.h>
12 : : #include <linux/firmware.h>
13 : :
14 : : #include "r8169_firmware.h"
15 : :
16 : : enum rtl_fw_opcode {
17 : : PHY_READ = 0x0,
18 : : PHY_DATA_OR = 0x1,
19 : : PHY_DATA_AND = 0x2,
20 : : PHY_BJMPN = 0x3,
21 : : PHY_MDIO_CHG = 0x4,
22 : : PHY_CLEAR_READCOUNT = 0x7,
23 : : PHY_WRITE = 0x8,
24 : : PHY_READCOUNT_EQ_SKIP = 0x9,
25 : : PHY_COMP_EQ_SKIPN = 0xa,
26 : : PHY_COMP_NEQ_SKIPN = 0xb,
27 : : PHY_WRITE_PREVIOUS = 0xc,
28 : : PHY_SKIPN = 0xd,
29 : : PHY_DELAY_MS = 0xe,
30 : : };
31 : :
32 : : struct fw_info {
33 : : u32 magic;
34 : : char version[RTL_VER_SIZE];
35 : : __le32 fw_start;
36 : : __le32 fw_len;
37 : : u8 chksum;
38 : : } __packed;
39 : :
40 : : #define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0])
41 : :
42 : 0 : static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
43 : : {
44 : 0 : const struct firmware *fw = rtl_fw->fw;
45 : 0 : struct fw_info *fw_info = (struct fw_info *)fw->data;
46 : 0 : struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
47 : :
48 [ # # ]: 0 : if (fw->size < FW_OPCODE_SIZE)
49 : : return false;
50 : :
51 [ # # ]: 0 : if (!fw_info->magic) {
52 : 0 : size_t i, size, start;
53 : 0 : u8 checksum = 0;
54 : :
55 [ # # ]: 0 : if (fw->size < sizeof(*fw_info))
56 : : return false;
57 : :
58 [ # # ]: 0 : for (i = 0; i < fw->size; i++)
59 : 0 : checksum += fw->data[i];
60 [ # # ]: 0 : if (checksum != 0)
61 : : return false;
62 : :
63 : 0 : start = le32_to_cpu(fw_info->fw_start);
64 [ # # ]: 0 : if (start > fw->size)
65 : : return false;
66 : :
67 : 0 : size = le32_to_cpu(fw_info->fw_len);
68 [ # # ]: 0 : if (size > (fw->size - start) / FW_OPCODE_SIZE)
69 : : return false;
70 : :
71 : 0 : strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
72 : :
73 : 0 : pa->code = (__le32 *)(fw->data + start);
74 : 0 : pa->size = size;
75 : : } else {
76 [ # # ]: 0 : if (fw->size % FW_OPCODE_SIZE)
77 : : return false;
78 : :
79 : 0 : strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
80 : :
81 : 0 : pa->code = (__le32 *)fw->data;
82 : 0 : pa->size = fw->size / FW_OPCODE_SIZE;
83 : : }
84 : :
85 : : return true;
86 : : }
87 : :
88 : 0 : static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
89 : : {
90 : 0 : struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
91 : 0 : size_t index;
92 : :
93 [ # # ]: 0 : for (index = 0; index < pa->size; index++) {
94 : 0 : u32 action = le32_to_cpu(pa->code[index]);
95 : 0 : u32 val = action & 0x0000ffff;
96 : 0 : u32 regno = (action & 0x0fff0000) >> 16;
97 : :
98 [ # # # # : 0 : switch (action >> 28) {
# # ]
99 : : case PHY_READ:
100 : : case PHY_DATA_OR:
101 : : case PHY_DATA_AND:
102 : : case PHY_CLEAR_READCOUNT:
103 : : case PHY_WRITE:
104 : : case PHY_WRITE_PREVIOUS:
105 : : case PHY_DELAY_MS:
106 : : break;
107 : :
108 : 0 : case PHY_MDIO_CHG:
109 [ # # ]: 0 : if (val > 1)
110 : 0 : goto out;
111 : : break;
112 : :
113 : 0 : case PHY_BJMPN:
114 [ # # ]: 0 : if (regno > index)
115 : 0 : goto out;
116 : : break;
117 : 0 : case PHY_READCOUNT_EQ_SKIP:
118 [ # # ]: 0 : if (index + 2 >= pa->size)
119 : 0 : goto out;
120 : : break;
121 : 0 : case PHY_COMP_EQ_SKIPN:
122 : : case PHY_COMP_NEQ_SKIPN:
123 : : case PHY_SKIPN:
124 [ # # ]: 0 : if (index + 1 + regno >= pa->size)
125 : 0 : goto out;
126 : : break;
127 : :
128 : 0 : default:
129 : 0 : dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
130 : 0 : return false;
131 : : }
132 : : }
133 : :
134 : : return true;
135 : 0 : out:
136 : 0 : dev_err(rtl_fw->dev, "Out of range of firmware\n");
137 : 0 : return false;
138 : : }
139 : :
140 : 0 : void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
141 : : {
142 : 0 : struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
143 : 0 : rtl_fw_write_t fw_write = rtl_fw->phy_write;
144 : 0 : rtl_fw_read_t fw_read = rtl_fw->phy_read;
145 : 0 : int predata = 0, count = 0;
146 : 0 : size_t index;
147 : :
148 [ # # ]: 0 : for (index = 0; index < pa->size; index++) {
149 : 0 : u32 action = le32_to_cpu(pa->code[index]);
150 : 0 : u32 data = action & 0x0000ffff;
151 : 0 : u32 regno = (action & 0x0fff0000) >> 16;
152 : 0 : enum rtl_fw_opcode opcode = action >> 28;
153 : :
154 [ # # ]: 0 : if (!action)
155 : : break;
156 : :
157 [ # # # # : 0 : switch (opcode) {
# # # # #
# # # #
# ]
158 : 0 : case PHY_READ:
159 : 0 : predata = fw_read(tp, regno);
160 : 0 : count++;
161 : 0 : break;
162 : 0 : case PHY_DATA_OR:
163 : 0 : predata |= data;
164 : 0 : break;
165 : 0 : case PHY_DATA_AND:
166 : 0 : predata &= data;
167 : 0 : break;
168 : 0 : case PHY_BJMPN:
169 : 0 : index -= (regno + 1);
170 : 0 : break;
171 : 0 : case PHY_MDIO_CHG:
172 [ # # ]: 0 : if (data) {
173 : 0 : fw_write = rtl_fw->mac_mcu_write;
174 : 0 : fw_read = rtl_fw->mac_mcu_read;
175 : : } else {
176 : 0 : fw_write = rtl_fw->phy_write;
177 : 0 : fw_read = rtl_fw->phy_read;
178 : : }
179 : :
180 : : break;
181 : 0 : case PHY_CLEAR_READCOUNT:
182 : 0 : count = 0;
183 : 0 : break;
184 : 0 : case PHY_WRITE:
185 : 0 : fw_write(tp, regno, data);
186 : 0 : break;
187 : 0 : case PHY_READCOUNT_EQ_SKIP:
188 [ # # ]: 0 : if (count == data)
189 : 0 : index++;
190 : : break;
191 : 0 : case PHY_COMP_EQ_SKIPN:
192 [ # # ]: 0 : if (predata == data)
193 : 0 : index += regno;
194 : : break;
195 : 0 : case PHY_COMP_NEQ_SKIPN:
196 [ # # ]: 0 : if (predata != data)
197 : 0 : index += regno;
198 : : break;
199 : 0 : case PHY_WRITE_PREVIOUS:
200 : 0 : fw_write(tp, regno, predata);
201 : 0 : break;
202 : 0 : case PHY_SKIPN:
203 : 0 : index += regno;
204 : 0 : break;
205 : 0 : case PHY_DELAY_MS:
206 : 0 : msleep(data);
207 : 0 : break;
208 : : }
209 : 0 : }
210 : 0 : }
211 : :
212 : 0 : void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
213 : : {
214 : 0 : release_firmware(rtl_fw->fw);
215 : 0 : }
216 : :
217 : 0 : int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
218 : : {
219 : 0 : int rc;
220 : :
221 : 0 : rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
222 [ # # ]: 0 : if (rc < 0)
223 : 0 : goto out;
224 : :
225 [ # # # # ]: 0 : if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
226 : 0 : release_firmware(rtl_fw->fw);
227 : 0 : rc = -EINVAL;
228 : 0 : goto out;
229 : : }
230 : :
231 : : return 0;
232 : 0 : out:
233 : 0 : dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
234 : : rtl_fw->fw_name, rc);
235 : 0 : return rc;
236 : : }
|