xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/realtek/r8168/r8168_firmware.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 ################################################################################
4 #
5 # r8168 is the Linux device driver released for Realtek Gigabit Ethernet
6 # controllers with PCI-Express interface.
7 #
8 # Copyright(c) 2021 Realtek Semiconductor Corp. All rights reserved.
9 #
10 # This program is free software; you can redistribute it and/or modify it
11 # under the terms of the GNU General Public License as published by the Free
12 # Software Foundation; either version 2 of the License, or (at your option)
13 # any later version.
14 #
15 # This program is distributed in the hope that it will be useful, but WITHOUT
16 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18 # more details.
19 #
20 # You should have received a copy of the GNU General Public License along with
21 # this program; if not, see <http://www.gnu.org/licenses/>.
22 #
23 # Author:
24 # Realtek NIC software team <nicfae@realtek.com>
25 # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
26 #
27 ################################################################################
28 */
29 
30 /************************************************************************************
31  *  This product is covered by one or more of the following patents:
32  *  US6,570,884, US6,115,776, and US6,327,625.
33  ***********************************************************************************/
34 
35 #include <linux/version.h>
36 #include <linux/delay.h>
37 #include <linux/firmware.h>
38 
39 #include "r8168_firmware.h"
40 
41 enum rtl_fw_opcode {
42         PHY_READ		= 0x0,
43         PHY_DATA_OR		= 0x1,
44         PHY_DATA_AND		= 0x2,
45         PHY_BJMPN		= 0x3,
46         PHY_MDIO_CHG		= 0x4,
47         PHY_CLEAR_READCOUNT	= 0x7,
48         PHY_WRITE		= 0x8,
49         PHY_READCOUNT_EQ_SKIP	= 0x9,
50         PHY_COMP_EQ_SKIPN	= 0xa,
51         PHY_COMP_NEQ_SKIPN	= 0xb,
52         PHY_WRITE_PREVIOUS	= 0xc,
53         PHY_SKIPN		= 0xd,
54         PHY_DELAY_MS		= 0xe,
55 };
56 
57 struct fw_info {
58         u32	magic;
59         char	version[RTL8168_VER_SIZE];
60         __le32	fw_start;
61         __le32	fw_len;
62         u8	chksum;
63 } __packed;
64 
65 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)
66 #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
67 #endif
68 #define FW_OPCODE_SIZE sizeof_field(struct rtl8168_fw_phy_action, code[0])
69 
rtl8168_fw_format_ok(struct rtl8168_fw * rtl_fw)70 static bool rtl8168_fw_format_ok(struct rtl8168_fw *rtl_fw)
71 {
72         const struct firmware *fw = rtl_fw->fw;
73         struct fw_info *fw_info = (struct fw_info *)fw->data;
74         struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action;
75 
76         if (fw->size < FW_OPCODE_SIZE)
77                 return false;
78 
79         if (!fw_info->magic) {
80                 size_t i, size, start;
81                 u8 checksum = 0;
82 
83                 if (fw->size < sizeof(*fw_info))
84                         return false;
85 
86                 for (i = 0; i < fw->size; i++)
87                         checksum += fw->data[i];
88                 if (checksum != 0)
89                         return false;
90 
91                 start = le32_to_cpu(fw_info->fw_start);
92                 if (start > fw->size)
93                         return false;
94 
95                 size = le32_to_cpu(fw_info->fw_len);
96                 if (size > (fw->size - start) / FW_OPCODE_SIZE)
97                         return false;
98 
99                 strscpy(rtl_fw->version, fw_info->version, RTL8168_VER_SIZE);
100 
101                 pa->code = (__le32 *)(fw->data + start);
102                 pa->size = size;
103         } else {
104                 if (fw->size % FW_OPCODE_SIZE)
105                         return false;
106 
107                 strscpy(rtl_fw->version, rtl_fw->fw_name, RTL8168_VER_SIZE);
108 
109                 pa->code = (__le32 *)fw->data;
110                 pa->size = fw->size / FW_OPCODE_SIZE;
111         }
112 
113         return true;
114 }
115 
rtl8168_fw_data_ok(struct rtl8168_fw * rtl_fw)116 static bool rtl8168_fw_data_ok(struct rtl8168_fw *rtl_fw)
117 {
118         struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action;
119         size_t index;
120 
121         for (index = 0; index < pa->size; index++) {
122                 u32 action = le32_to_cpu(pa->code[index]);
123                 u32 val = action & 0x0000ffff;
124                 u32 regno = (action & 0x0fff0000) >> 16;
125 
126                 switch (action >> 28) {
127                 case PHY_READ:
128                 case PHY_DATA_OR:
129                 case PHY_DATA_AND:
130                 case PHY_CLEAR_READCOUNT:
131                 case PHY_WRITE:
132                 case PHY_WRITE_PREVIOUS:
133                 case PHY_DELAY_MS:
134                         break;
135 
136                 case PHY_MDIO_CHG:
137                         if (val > 1)
138                                 goto out;
139                         break;
140 
141                 case PHY_BJMPN:
142                         if (regno > index)
143                                 goto out;
144                         break;
145                 case PHY_READCOUNT_EQ_SKIP:
146                         if (index + 2 >= pa->size)
147                                 goto out;
148                         break;
149                 case PHY_COMP_EQ_SKIPN:
150                 case PHY_COMP_NEQ_SKIPN:
151                 case PHY_SKIPN:
152                         if (index + 1 + regno >= pa->size)
153                                 goto out;
154                         break;
155 
156                 default:
157                         dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action);
158                         return false;
159                 }
160         }
161 
162         return true;
163 out:
164         dev_err(rtl_fw->dev, "Out of range of firmware\n");
165         return false;
166 }
167 
rtl8168_fw_write_firmware(struct rtl8168_private * tp,struct rtl8168_fw * rtl_fw)168 void rtl8168_fw_write_firmware(struct rtl8168_private *tp, struct rtl8168_fw *rtl_fw)
169 {
170         struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action;
171         rtl8168_fw_write_t fw_write = rtl_fw->phy_write;
172         rtl8168_fw_read_t fw_read = rtl_fw->phy_read;
173         int predata = 0, count = 0;
174         size_t index;
175 
176         for (index = 0; index < pa->size; index++) {
177                 u32 action = le32_to_cpu(pa->code[index]);
178                 u32 data = action & 0x0000ffff;
179                 u32 regno = (action & 0x0fff0000) >> 16;
180                 enum rtl_fw_opcode opcode = action >> 28;
181 
182                 if (!action)
183                         break;
184 
185                 switch (opcode) {
186                 case PHY_READ:
187                         predata = fw_read(tp, regno);
188                         count++;
189                         break;
190                 case PHY_DATA_OR:
191                         predata |= data;
192                         break;
193                 case PHY_DATA_AND:
194                         predata &= data;
195                         break;
196                 case PHY_BJMPN:
197                         index -= (regno + 1);
198                         break;
199                 case PHY_MDIO_CHG:
200                         if (data) {
201                                 fw_write = rtl_fw->mac_mcu_write;
202                                 fw_read = rtl_fw->mac_mcu_read;
203                         } else {
204                                 fw_write = rtl_fw->phy_write;
205                                 fw_read = rtl_fw->phy_read;
206                         }
207 
208                         break;
209                 case PHY_CLEAR_READCOUNT:
210                         count = 0;
211                         break;
212                 case PHY_WRITE:
213                         fw_write(tp, regno, data);
214                         break;
215                 case PHY_READCOUNT_EQ_SKIP:
216                         if (count == data)
217                                 index++;
218                         break;
219                 case PHY_COMP_EQ_SKIPN:
220                         if (predata == data)
221                                 index += regno;
222                         break;
223                 case PHY_COMP_NEQ_SKIPN:
224                         if (predata != data)
225                                 index += regno;
226                         break;
227                 case PHY_WRITE_PREVIOUS:
228                         fw_write(tp, regno, predata);
229                         break;
230                 case PHY_SKIPN:
231                         index += regno;
232                         break;
233                 case PHY_DELAY_MS:
234                         mdelay(data);
235                         break;
236                 }
237         }
238 }
239 
rtl8168_fw_release_firmware(struct rtl8168_fw * rtl_fw)240 void rtl8168_fw_release_firmware(struct rtl8168_fw *rtl_fw)
241 {
242         release_firmware(rtl_fw->fw);
243 }
244 
rtl8168_fw_request_firmware(struct rtl8168_fw * rtl_fw)245 int rtl8168_fw_request_firmware(struct rtl8168_fw *rtl_fw)
246 {
247         int rc;
248 
249         rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev);
250         if (rc < 0)
251                 goto out;
252 
253         if (!rtl8168_fw_format_ok(rtl_fw) || !rtl8168_fw_data_ok(rtl_fw)) {
254                 release_firmware(rtl_fw->fw);
255                 rc = -EINVAL;
256                 goto out;
257         }
258 
259         return 0;
260 out:
261         dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n",
262                 rtl_fw->fw_name, rc);
263         return rc;
264 }
265