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/module.h>
36 #include <linux/version.h>
37 #include <linux/pci.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 #include <linux/delay.h>
41 #include <linux/ethtool.h>
42 #include <linux/mii.h>
43 #include <linux/if_vlan.h>
44 #include <linux/crc32.h>
45 #include <linux/in.h>
46 #include <linux/ip.h>
47 #include <linux/tcp.h>
48 #include <linux/init.h>
49 #include <linux/rtnetlink.h>
50
51 #include <asm/uaccess.h>
52
53 #include "r8168.h"
54 #include "r8168_asf.h"
55 #include "rtl_eeprom.h"
56
rtl8168_asf_ioctl(struct net_device * dev,struct ifreq * ifr)57 int rtl8168_asf_ioctl(struct net_device *dev,
58 struct ifreq *ifr)
59 {
60 struct rtl8168_private *tp = netdev_priv(dev);
61 void *user_data = ifr->ifr_data;
62 struct asf_ioctl_struct asf_usrdata;
63 unsigned long flags;
64
65 if (tp->mcfg != CFG_METHOD_7 && tp->mcfg != CFG_METHOD_8)
66 return -EOPNOTSUPP;
67
68 if (copy_from_user(&asf_usrdata, user_data, sizeof(struct asf_ioctl_struct)))
69 return -EFAULT;
70
71 spin_lock_irqsave(&tp->lock, flags);
72
73 switch (asf_usrdata.offset) {
74 case HBPeriod:
75 rtl8168_asf_hbperiod(tp, asf_usrdata.arg, asf_usrdata.u.data);
76 break;
77 case WD8Timer:
78 break;
79 case WD16Rst:
80 rtl8168_asf_wd16rst(tp, asf_usrdata.arg, asf_usrdata.u.data);
81 break;
82 case WD8Rst:
83 rtl8168_asf_time_period(tp, asf_usrdata.arg, WD8Rst, asf_usrdata.u.data);
84 break;
85 case LSnsrPollCycle:
86 rtl8168_asf_time_period(tp, asf_usrdata.arg, LSnsrPollCycle, asf_usrdata.u.data);
87 break;
88 case ASFSnsrPollPrd:
89 rtl8168_asf_time_period(tp, asf_usrdata.arg, ASFSnsrPollPrd, asf_usrdata.u.data);
90 break;
91 case AlertReSendItvl:
92 rtl8168_asf_time_period(tp, asf_usrdata.arg, AlertReSendItvl, asf_usrdata.u.data);
93 break;
94 case SMBAddr:
95 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, SMBAddr, RW_ONE_BYTE, asf_usrdata.u.data);
96 break;
97 case ASFConfigR0:
98 rtl8168_asf_config_regs(tp, asf_usrdata.arg, ASFConfigR0, asf_usrdata.u.data);
99 break;
100 case ASFConfigR1:
101 rtl8168_asf_config_regs(tp, asf_usrdata.arg, ASFConfigR1, asf_usrdata.u.data);
102 break;
103 case ConsoleMA:
104 rtl8168_asf_console_mac(tp, asf_usrdata.arg, asf_usrdata.u.data);
105 break;
106 case ConsoleIP:
107 rtl8168_asf_ip_address(tp, asf_usrdata.arg, ConsoleIP, asf_usrdata.u.data);
108 break;
109 case IPAddr:
110 rtl8168_asf_ip_address(tp, asf_usrdata.arg, IPAddr, asf_usrdata.u.data);
111 break;
112 case UUID:
113 rtl8168_asf_rw_uuid(tp, asf_usrdata.arg, asf_usrdata.u.data);
114 break;
115 case IANA:
116 rtl8168_asf_rw_iana(tp, asf_usrdata.arg, asf_usrdata.u.data);
117 break;
118 case SysID:
119 rtl8168_asf_rw_systemid(tp, asf_usrdata.arg, asf_usrdata.u.data);
120 break;
121 case Community:
122 rtl8168_asf_community_string(tp, asf_usrdata.arg, asf_usrdata.u.string);
123 break;
124 case StringLength:
125 rtl8168_asf_community_string_len(tp, asf_usrdata.arg, asf_usrdata.u.data);
126 break;
127 case FmCapMsk:
128 rtl8168_asf_capability_masks(tp, asf_usrdata.arg, FmCapMsk, asf_usrdata.u.data);
129 break;
130 case SpCMDMsk:
131 rtl8168_asf_capability_masks(tp, asf_usrdata.arg, SpCMDMsk, asf_usrdata.u.data);
132 break;
133 case SysCapMsk:
134 rtl8168_asf_capability_masks(tp, asf_usrdata.arg, SysCapMsk, asf_usrdata.u.data);
135 break;
136 case RmtRstAddr:
137 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstAddr, RW_ONE_BYTE, asf_usrdata.u.data);
138 break;
139 case RmtRstCmd:
140 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstCmd, RW_ONE_BYTE, asf_usrdata.u.data);
141 break;
142 case RmtRstData:
143 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstData, RW_ONE_BYTE, asf_usrdata.u.data);
144 break;
145 case RmtPwrOffAddr:
146 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffAddr, RW_ONE_BYTE, asf_usrdata.u.data);
147 break;
148 case RmtPwrOffCmd:
149 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffCmd, RW_ONE_BYTE, asf_usrdata.u.data);
150 break;
151 case RmtPwrOffData:
152 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffData, RW_ONE_BYTE, asf_usrdata.u.data);
153 break;
154 case RmtPwrOnAddr:
155 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnAddr, RW_ONE_BYTE, asf_usrdata.u.data);
156 break;
157 case RmtPwrOnCmd:
158 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnCmd, RW_ONE_BYTE, asf_usrdata.u.data);
159 break;
160 case RmtPwrOnData:
161 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnData, RW_ONE_BYTE, asf_usrdata.u.data);
162 break;
163 case RmtPCRAddr:
164 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRAddr, RW_ONE_BYTE, asf_usrdata.u.data);
165 break;
166 case RmtPCRCmd:
167 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRCmd, RW_ONE_BYTE, asf_usrdata.u.data);
168 break;
169 case RmtPCRData:
170 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRData, RW_ONE_BYTE, asf_usrdata.u.data);
171 break;
172 case ASFSnsr0Addr:
173 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, ASFSnsr0Addr, RW_ONE_BYTE, asf_usrdata.u.data);
174 break;
175 case LSnsrAddr0:
176 rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, LSnsrAddr0, RW_ONE_BYTE, asf_usrdata.u.data);
177 break;
178 case KO:
179 /* Get/Set Key Operation */
180 rtl8168_asf_key_access(tp, asf_usrdata.arg, KO, asf_usrdata.u.data);
181 break;
182 case KA:
183 /* Get/Set Key Administrator */
184 rtl8168_asf_key_access(tp, asf_usrdata.arg, KA, asf_usrdata.u.data);
185 break;
186 case KG:
187 /* Get/Set Key Generation */
188 rtl8168_asf_key_access(tp, asf_usrdata.arg, KG, asf_usrdata.u.data);
189 break;
190 case KR:
191 /* Get/Set Key Random */
192 rtl8168_asf_key_access(tp, asf_usrdata.arg, KR, asf_usrdata.u.data);
193 break;
194 default:
195 spin_unlock_irqrestore(&tp->lock, flags);
196 return -EOPNOTSUPP;
197 }
198
199 spin_unlock_irqrestore(&tp->lock, flags);
200
201 if (copy_to_user(user_data, &asf_usrdata, sizeof(struct asf_ioctl_struct)))
202 return -EFAULT;
203
204 return 0;
205 }
206
rtl8168_asf_hbperiod(struct rtl8168_private * tp,int arg,unsigned int * data)207 void rtl8168_asf_hbperiod(struct rtl8168_private *tp, int arg, unsigned int *data)
208 {
209 if (arg == ASF_GET)
210 data[ASFHBPERIOD] = rtl8168_eri_read(tp, HBPeriod, RW_TWO_BYTES, ERIAR_ASF);
211 else if (arg == ASF_SET) {
212 rtl8168_eri_write(tp, HBPeriod, RW_TWO_BYTES, data[ASFHBPERIOD], ERIAR_ASF);
213 rtl8168_eri_write(tp, 0x1EC, RW_ONE_BYTE, 0x07, ERIAR_ASF);
214 }
215 }
216
rtl8168_asf_wd16rst(struct rtl8168_private * tp,int arg,unsigned int * data)217 void rtl8168_asf_wd16rst(struct rtl8168_private *tp, int arg, unsigned int *data)
218 {
219 data[ASFWD16RST] = rtl8168_eri_read(tp, WD16Rst, RW_TWO_BYTES, ERIAR_ASF);
220 }
221
rtl8168_asf_console_mac(struct rtl8168_private * tp,int arg,unsigned int * data)222 void rtl8168_asf_console_mac(struct rtl8168_private *tp, int arg, unsigned int *data)
223 {
224 int i;
225
226 if (arg == ASF_GET) {
227 for (i = 0; i < 6; i++)
228 data[i] = rtl8168_eri_read(tp, ConsoleMA + i, RW_ONE_BYTE, ERIAR_ASF);
229 } else if (arg == ASF_SET) {
230 for (i = 0; i < 6; i++)
231 rtl8168_eri_write(tp, ConsoleMA + i, RW_ONE_BYTE, data[i], ERIAR_ASF);
232
233 /* write the new console MAC address to EEPROM */
234 rtl8168_eeprom_write_sc(tp, 70, (data[1] << 8) | data[0]);
235 rtl8168_eeprom_write_sc(tp, 71, (data[3] << 8) | data[2]);
236 rtl8168_eeprom_write_sc(tp, 72, (data[5] << 8) | data[4]);
237 }
238 }
239
rtl8168_asf_ip_address(struct rtl8168_private * tp,int arg,int offset,unsigned int * data)240 void rtl8168_asf_ip_address(struct rtl8168_private *tp, int arg, int offset, unsigned int *data)
241 {
242 int i;
243 int eeprom_off = 0;
244
245 if (arg == ASF_GET) {
246 for (i = 0; i < 4; i++)
247 data[i] = rtl8168_eri_read(tp, offset + i, RW_ONE_BYTE, ERIAR_ASF);
248 } else if (arg == ASF_SET) {
249 for (i = 0; i < 4; i++)
250 rtl8168_eri_write(tp, offset + i, RW_ONE_BYTE, data[i], ERIAR_ASF);
251
252 if (offset == ConsoleIP)
253 eeprom_off = 73;
254 else if (offset == IPAddr)
255 eeprom_off = 75;
256
257 /* write the new IP address to EEPROM */
258 rtl8168_eeprom_write_sc(tp, eeprom_off, (data[1] << 8) | data[0]);
259 rtl8168_eeprom_write_sc(tp, eeprom_off + 1, (data[3] << 8) | data[2]);
260
261 }
262 }
263
rtl8168_asf_config_regs(struct rtl8168_private * tp,int arg,int offset,unsigned int * data)264 void rtl8168_asf_config_regs(struct rtl8168_private *tp, int arg, int offset, unsigned int *data)
265 {
266 unsigned int value;
267
268 if (arg == ASF_GET) {
269 data[ASFCAPABILITY] = (rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF) & data[ASFCONFIG]) ? FUNCTION_ENABLE : FUNCTION_DISABLE;
270 } else if (arg == ASF_SET) {
271 value = rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF);
272
273 if (data[ASFCAPABILITY] == FUNCTION_ENABLE)
274 value |= data[ASFCONFIG];
275 else if (data[ASFCAPABILITY] == FUNCTION_DISABLE)
276 value &= ~data[ASFCONFIG];
277
278 rtl8168_eri_write(tp, offset, RW_ONE_BYTE, value, ERIAR_ASF);
279 }
280 }
281
rtl8168_asf_capability_masks(struct rtl8168_private * tp,int arg,int offset,unsigned int * data)282 void rtl8168_asf_capability_masks(struct rtl8168_private *tp, int arg, int offset, unsigned int *data)
283 {
284 unsigned int len, bit_mask;
285
286 bit_mask = DISABLE_MASK;
287
288 if (offset == FmCapMsk) {
289 /* System firmware capabilities */
290 len = RW_FOUR_BYTES;
291 if (data[ASFCAPMASK] == FUNCTION_ENABLE)
292 bit_mask = FMW_CAP_MASK;
293 } else if (offset == SpCMDMsk) {
294 /* Special commands */
295 len = RW_TWO_BYTES;
296 if (data[ASFCAPMASK] == FUNCTION_ENABLE)
297 bit_mask = SPC_CMD_MASK;
298 } else {
299 /* System capability (offset == SysCapMsk)*/
300 len = RW_ONE_BYTE;
301 if (data[ASFCAPMASK] == FUNCTION_ENABLE)
302 bit_mask = SYS_CAP_MASK;
303 }
304
305 if (arg == ASF_GET)
306 data[ASFCAPMASK] = rtl8168_eri_read(tp, offset, len, ERIAR_ASF) ? FUNCTION_ENABLE : FUNCTION_DISABLE;
307 else /* arg == ASF_SET */
308 rtl8168_eri_write(tp, offset, len, bit_mask, ERIAR_ASF);
309 }
310
rtl8168_asf_community_string(struct rtl8168_private * tp,int arg,char * string)311 void rtl8168_asf_community_string(struct rtl8168_private *tp, int arg, char *string)
312 {
313 int i;
314
315 if (arg == ASF_GET) {
316 for (i = 0; i < COMMU_STR_MAX_LEN; i++)
317 string[i] = rtl8168_eri_read(tp, Community + i, RW_ONE_BYTE, ERIAR_ASF);
318 } else { /* arg == ASF_SET */
319 for (i = 0; i < COMMU_STR_MAX_LEN; i++)
320 rtl8168_eri_write(tp, Community + i, RW_ONE_BYTE, string[i], ERIAR_ASF);
321 }
322 }
323
rtl8168_asf_community_string_len(struct rtl8168_private * tp,int arg,unsigned int * data)324 void rtl8168_asf_community_string_len(struct rtl8168_private *tp, int arg, unsigned int *data)
325 {
326 if (arg == ASF_GET)
327 data[ASFCOMMULEN] = rtl8168_eri_read(tp, StringLength, RW_ONE_BYTE, ERIAR_ASF);
328 else /* arg == ASF_SET */
329 rtl8168_eri_write(tp, StringLength, RW_ONE_BYTE, data[ASFCOMMULEN], ERIAR_ASF);
330 }
331
rtl8168_asf_time_period(struct rtl8168_private * tp,int arg,int offset,unsigned int * data)332 void rtl8168_asf_time_period(struct rtl8168_private *tp, int arg, int offset, unsigned int *data)
333 {
334 int pos = 0;
335
336 if (offset == WD8Rst)
337 pos = ASFWD8RESET;
338 else if (offset == LSnsrPollCycle)
339 pos = ASFLSNRPOLLCYC;
340 else if (offset == ASFSnsrPollPrd)
341 pos = ASFSNRPOLLCYC;
342 else if (offset == AlertReSendItvl)
343 pos = ASFALERTRESND;
344
345 if (arg == ASF_GET)
346 data[pos] = rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF);
347 else /* arg == ASF_SET */
348 rtl8168_eri_write(tp, offset, RW_ONE_BYTE, data[pos], ERIAR_ASF);
349
350 }
351
rtl8168_asf_key_access(struct rtl8168_private * tp,int arg,int offset,unsigned int * data)352 void rtl8168_asf_key_access(struct rtl8168_private *tp, int arg, int offset, unsigned int *data)
353 {
354 int i, j;
355 int key_off = 0;
356
357 if (arg == ASF_GET) {
358 for (i = 0; i < KEY_LEN; i++)
359 data[i] = rtl8168_eri_read(tp, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, ERIAR_ASF);
360 } else {
361 if (offset == KO)
362 key_off = 162;
363 else if (offset == KA)
364 key_off = 172;
365 else if (offset == KG)
366 key_off = 182;
367 else if (offset == KR)
368 key_off = 192;
369
370 /* arg == ASF_SET */
371 for (i = 0; i < KEY_LEN; i++)
372 rtl8168_eri_write(tp, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, data[i], ERIAR_ASF);
373
374 /* write the new key to EEPROM */
375 for (i = 0, j = 19; i < 10; i++, j = j - 2)
376 rtl8168_eeprom_write_sc(tp, key_off + i, (data[j - 1] << 8) | data[j]);
377 }
378 }
379
rtl8168_asf_rw_hexadecimal(struct rtl8168_private * tp,int arg,int offset,int len,unsigned int * data)380 void rtl8168_asf_rw_hexadecimal(struct rtl8168_private *tp, int arg, int offset, int len, unsigned int *data)
381 {
382 if (arg == ASF_GET)
383 data[ASFRWHEXNUM] = rtl8168_eri_read(tp, offset, len, ERIAR_ASF);
384 else /* arg == ASF_SET */
385 rtl8168_eri_write(tp, offset, len, data[ASFRWHEXNUM], ERIAR_ASF);
386 }
387
rtl8168_asf_rw_systemid(struct rtl8168_private * tp,int arg,unsigned int * data)388 void rtl8168_asf_rw_systemid(struct rtl8168_private *tp, int arg, unsigned int *data)
389 {
390 int i;
391
392 if (arg == ASF_GET)
393 for (i = 0; i < SYSID_LEN ; i++)
394 data[i] = rtl8168_eri_read(tp, SysID + i, RW_ONE_BYTE, ERIAR_ASF);
395 else /* arg == ASF_SET */
396 for (i = 0; i < SYSID_LEN ; i++)
397 rtl8168_eri_write(tp, SysID + i, RW_ONE_BYTE, data[i], ERIAR_ASF);
398 }
399
rtl8168_asf_rw_iana(struct rtl8168_private * tp,int arg,unsigned int * data)400 void rtl8168_asf_rw_iana(struct rtl8168_private *tp, int arg, unsigned int *data)
401 {
402 int i;
403
404 if (arg == ASF_GET)
405 for (i = 0; i < RW_FOUR_BYTES; i++)
406 data[i] = rtl8168_eri_read(tp, IANA + i, RW_ONE_BYTE, ERIAR_ASF);
407 else /* arg == ASF_SET */
408 for (i = 0; i < RW_FOUR_BYTES; i++)
409 rtl8168_eri_write(tp, IANA + i, RW_ONE_BYTE, data[i], ERIAR_ASF);
410 }
411
rtl8168_asf_rw_uuid(struct rtl8168_private * tp,int arg,unsigned int * data)412 void rtl8168_asf_rw_uuid(struct rtl8168_private *tp, int arg, unsigned int *data)
413 {
414 int i, j;
415
416 if (arg == ASF_GET)
417 for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++)
418 data[j] = rtl8168_eri_read(tp, UUID + i, RW_ONE_BYTE, ERIAR_ASF);
419 else /* arg == ASF_SET */
420 for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++)
421 rtl8168_eri_write(tp, UUID + i, RW_ONE_BYTE, data[j], ERIAR_ASF);
422 }
423