• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
rtl_fw_format_ok(struct rtl_fw * rtl_fw)42 static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw)
43 {
44 	const struct firmware *fw = rtl_fw->fw;
45 	struct fw_info *fw_info = (struct fw_info *)fw->data;
46 	struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
47 
48 	if (fw->size < FW_OPCODE_SIZE)
49 		return false;
50 
51 	if (!fw_info->magic) {
52 		size_t i, size, start;
53 		u8 checksum = 0;
54 
55 		if (fw->size < sizeof(*fw_info))
56 			return false;
57 
58 		for (i = 0; i < fw->size; i++)
59 			checksum += fw->data[i];
60 		if (checksum != 0)
61 			return false;
62 
63 		start = le32_to_cpu(fw_info->fw_start);
64 		if (start > fw->size)
65 			return false;
66 
67 		size = le32_to_cpu(fw_info->fw_len);
68 		if (size > (fw->size - start) / FW_OPCODE_SIZE)
69 			return false;
70 
71 		strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE);
72 
73 		pa->code = (__le32 *)(fw->data + start);
74 		pa->size = size;
75 	} else {
76 		if (fw->size % FW_OPCODE_SIZE)
77 			return false;
78 
79 		strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE);
80 
81 		pa->code = (__le32 *)fw->data;
82 		pa->size = fw->size / FW_OPCODE_SIZE;
83 	}
84 
85 	return true;
86 }
87 
rtl_fw_data_ok(struct rtl_fw * rtl_fw)88 static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw)
89 {
90 	struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
91 	size_t index;
92 
93 	for (index = 0; index < pa->size; index++) {
94 		u32 action = le32_to_cpu(pa->code[index]);
95 		u32 val = action & 0x0000ffff;
96 		u32 regno = (action & 0x0fff0000) >> 16;
97 
98 		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 		case PHY_MDIO_CHG:
109 			if (val > 1)
110 				goto out;
111 			break;
112 
113 		case PHY_BJMPN:
114 			if (regno > index)
115 				goto out;
116 			break;
117 		case PHY_READCOUNT_EQ_SKIP:
118 			if (index + 2 >= pa->size)
119 				goto out;
120 			break;
121 		case PHY_COMP_EQ_SKIPN:
122 		case PHY_COMP_NEQ_SKIPN:
123 		case PHY_SKIPN:
124 			if (index + 1 + regno >= pa->size)
125 				goto out;
126 			break;
127 
128 		default:
129 			dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
130 			return false;
131 		}
132 	}
133 
134 	return true;
135 out:
136 	dev_err(rtl_fw->dev, "Out of range of firmware\n");
137 	return false;
138 }
139 
rtl_fw_write_firmware(struct rtl8169_private * tp,struct rtl_fw * rtl_fw)140 void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
141 {
142 	struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
143 	rtl_fw_write_t fw_write = rtl_fw->phy_write;
144 	rtl_fw_read_t fw_read = rtl_fw->phy_read;
145 	int predata = 0, count = 0;
146 	size_t index;
147 
148 	for (index = 0; index < pa->size; index++) {
149 		u32 action = le32_to_cpu(pa->code[index]);
150 		u32 data = action & 0x0000ffff;
151 		u32 regno = (action & 0x0fff0000) >> 16;
152 		enum rtl_fw_opcode opcode = action >> 28;
153 
154 		if (!action)
155 			break;
156 
157 		switch (opcode) {
158 		case PHY_READ:
159 			predata = fw_read(tp, regno);
160 			count++;
161 			break;
162 		case PHY_DATA_OR:
163 			predata |= data;
164 			break;
165 		case PHY_DATA_AND:
166 			predata &= data;
167 			break;
168 		case PHY_BJMPN:
169 			index -= (regno + 1);
170 			break;
171 		case PHY_MDIO_CHG:
172 			if (data) {
173 				fw_write = rtl_fw->mac_mcu_write;
174 				fw_read = rtl_fw->mac_mcu_read;
175 			} else {
176 				fw_write = rtl_fw->phy_write;
177 				fw_read = rtl_fw->phy_read;
178 			}
179 
180 			break;
181 		case PHY_CLEAR_READCOUNT:
182 			count = 0;
183 			break;
184 		case PHY_WRITE:
185 			fw_write(tp, regno, data);
186 			break;
187 		case PHY_READCOUNT_EQ_SKIP:
188 			if (count == data)
189 				index++;
190 			break;
191 		case PHY_COMP_EQ_SKIPN:
192 			if (predata == data)
193 				index += regno;
194 			break;
195 		case PHY_COMP_NEQ_SKIPN:
196 			if (predata != data)
197 				index += regno;
198 			break;
199 		case PHY_WRITE_PREVIOUS:
200 			fw_write(tp, regno, predata);
201 			break;
202 		case PHY_SKIPN:
203 			index += regno;
204 			break;
205 		case PHY_DELAY_MS:
206 			msleep(data);
207 			break;
208 		}
209 	}
210 }
211 
rtl_fw_release_firmware(struct rtl_fw * rtl_fw)212 void rtl_fw_release_firmware(struct rtl_fw *rtl_fw)
213 {
214 	release_firmware(rtl_fw->fw);
215 }
216 
rtl_fw_request_firmware(struct rtl_fw * rtl_fw)217 int rtl_fw_request_firmware(struct rtl_fw *rtl_fw)
218 {
219 	int rc;
220 
221 	rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
222 	if (rc < 0)
223 		goto out;
224 
225 	if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) {
226 		release_firmware(rtl_fw->fw);
227 		rc = -EINVAL;
228 		goto out;
229 	}
230 
231 	return 0;
232 out:
233 	dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
234 		rtl_fw->fw_name, rc);
235 	return rc;
236 }
237