• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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