• 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/init.h>
36 #include <linux/module.h>
37 #include <linux/version.h>
38 #include <linux/ethtool.h>
39 #include <linux/netdevice.h>
40 #include <linux/delay.h>
41 
42 #include <asm/io.h>
43 
44 #include "r8168.h"
45 #include "rtl_eeprom.h"
46 
47 //-------------------------------------------------------------------
48 //rtl8168_eeprom_type():
49 //  tell the eeprom type
50 //return value:
51 //  0: the eeprom type is 93C46
52 //  1: the eeprom type is 93C56 or 93C66
53 //-------------------------------------------------------------------
rtl8168_eeprom_type(struct rtl8168_private * tp)54 void rtl8168_eeprom_type(struct rtl8168_private *tp)
55 {
56         u16 magic = 0;
57 
58         if (tp->mcfg == CFG_METHOD_DEFAULT)
59                 goto out_no_eeprom;
60 
61         if(RTL_R8(tp, 0xD2)&0x04) {
62                 //not support
63                 //tp->eeprom_type = EEPROM_TWSI;
64                 //tp->eeprom_len = 256;
65                 goto out_no_eeprom;
66         } else if(RTL_R32(tp, RxConfig) & RxCfg_9356SEL) {
67                 tp->eeprom_type = EEPROM_TYPE_93C56;
68                 tp->eeprom_len = 256;
69         } else {
70                 tp->eeprom_type = EEPROM_TYPE_93C46;
71                 tp->eeprom_len = 128;
72         }
73 
74         magic = rtl8168_eeprom_read_sc(tp, 0);
75 
76 out_no_eeprom:
77         if ((magic != 0x8129) && (magic != 0x8128)) {
78                 tp->eeprom_type = EEPROM_TYPE_NONE;
79                 tp->eeprom_len = 0;
80         }
81 }
82 
rtl8168_eeprom_cleanup(struct rtl8168_private * tp)83 void rtl8168_eeprom_cleanup(struct rtl8168_private *tp)
84 {
85         u8 x;
86 
87         x = RTL_R8(tp, Cfg9346);
88         x &= ~(Cfg9346_EEDI | Cfg9346_EECS);
89 
90         RTL_W8(tp, Cfg9346, x);
91 
92         rtl8168_raise_clock(tp, &x);
93         rtl8168_lower_clock(tp, &x);
94 }
95 
rtl8168_eeprom_cmd_done(struct rtl8168_private * tp)96 int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp)
97 {
98         u8 x;
99         int i;
100 
101         rtl8168_stand_by(tp);
102 
103         for (i = 0; i < 50000; i++) {
104                 x = RTL_R8(tp, Cfg9346);
105 
106                 if (x & Cfg9346_EEDO) {
107                         udelay(RTL_CLOCK_RATE * 2 * 3);
108                         return 0;
109                 }
110                 udelay(1);
111         }
112 
113         return -1;
114 }
115 
116 //-------------------------------------------------------------------
117 //rtl8168_eeprom_read_sc():
118 //  read one word from eeprom
119 //-------------------------------------------------------------------
rtl8168_eeprom_read_sc(struct rtl8168_private * tp,u16 reg)120 u16 rtl8168_eeprom_read_sc(struct rtl8168_private *tp, u16 reg)
121 {
122         int addr_sz = 6;
123         u8 x;
124         u16 data;
125 
126         if(tp->eeprom_type == EEPROM_TYPE_NONE) {
127                 return -1;
128         }
129 
130         if (tp->eeprom_type==EEPROM_TYPE_93C46)
131                 addr_sz = 6;
132         else if (tp->eeprom_type==EEPROM_TYPE_93C56)
133                 addr_sz = 8;
134 
135         x = Cfg9346_EEM1 | Cfg9346_EECS;
136         RTL_W8(tp, Cfg9346, x);
137 
138         rtl8168_shift_out_bits(tp, RTL_EEPROM_READ_OPCODE, 3);
139         rtl8168_shift_out_bits(tp, reg, addr_sz);
140 
141         data = rtl8168_shift_in_bits(tp);
142 
143         rtl8168_eeprom_cleanup(tp);
144 
145         RTL_W8(tp, Cfg9346, 0);
146 
147         return data;
148 }
149 
150 //-------------------------------------------------------------------
151 //rtl8168_eeprom_write_sc():
152 //  write one word to a specific address in the eeprom
153 //-------------------------------------------------------------------
rtl8168_eeprom_write_sc(struct rtl8168_private * tp,u16 reg,u16 data)154 void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data)
155 {
156         u8 x;
157         int addr_sz = 6;
158         int w_dummy_addr = 4;
159 
160         if(tp->eeprom_type == EEPROM_TYPE_NONE) {
161                 return ;
162         }
163 
164         if (tp->eeprom_type==EEPROM_TYPE_93C46) {
165                 addr_sz = 6;
166                 w_dummy_addr = 4;
167         } else if (tp->eeprom_type==EEPROM_TYPE_93C56) {
168                 addr_sz = 8;
169                 w_dummy_addr = 6;
170         }
171 
172         x = Cfg9346_EEM1 | Cfg9346_EECS;
173         RTL_W8(tp, Cfg9346, x);
174 
175         rtl8168_shift_out_bits(tp, RTL_EEPROM_EWEN_OPCODE, 5);
176         rtl8168_shift_out_bits(tp, reg, w_dummy_addr);
177         rtl8168_stand_by(tp);
178 
179         rtl8168_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3);
180         rtl8168_shift_out_bits(tp, reg, addr_sz);
181         if (rtl8168_eeprom_cmd_done(tp) < 0) {
182                 return;
183         }
184         rtl8168_stand_by(tp);
185 
186         rtl8168_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3);
187         rtl8168_shift_out_bits(tp, reg, addr_sz);
188         rtl8168_shift_out_bits(tp, data, 16);
189         if (rtl8168_eeprom_cmd_done(tp) < 0) {
190                 return;
191         }
192         rtl8168_stand_by(tp);
193 
194         rtl8168_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5);
195         rtl8168_shift_out_bits(tp, reg, w_dummy_addr);
196 
197         rtl8168_eeprom_cleanup(tp);
198         RTL_W8(tp, Cfg9346, 0);
199 }
200 
rtl8168_raise_clock(struct rtl8168_private * tp,u8 * x)201 void rtl8168_raise_clock(struct rtl8168_private *tp, u8 *x)
202 {
203         *x = *x | Cfg9346_EESK;
204         RTL_W8(tp, Cfg9346, *x);
205         udelay(RTL_CLOCK_RATE);
206 }
207 
rtl8168_lower_clock(struct rtl8168_private * tp,u8 * x)208 void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x)
209 {
210 
211         *x = *x & ~Cfg9346_EESK;
212         RTL_W8(tp, Cfg9346, *x);
213         udelay(RTL_CLOCK_RATE);
214 }
215 
rtl8168_shift_out_bits(struct rtl8168_private * tp,int data,int count)216 void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count)
217 {
218         u8 x;
219         int  mask;
220 
221         mask = 0x01 << (count - 1);
222         x = RTL_R8(tp, Cfg9346);
223         x &= ~(Cfg9346_EEDI | Cfg9346_EEDO);
224 
225         do {
226                 if (data & mask)
227                         x |= Cfg9346_EEDI;
228                 else
229                         x &= ~Cfg9346_EEDI;
230 
231                 RTL_W8(tp, Cfg9346, x);
232                 udelay(RTL_CLOCK_RATE);
233                 rtl8168_raise_clock(tp, &x);
234                 rtl8168_lower_clock(tp, &x);
235                 mask = mask >> 1;
236         } while(mask);
237 
238         x &= ~Cfg9346_EEDI;
239         RTL_W8(tp, Cfg9346, x);
240 }
241 
rtl8168_shift_in_bits(struct rtl8168_private * tp)242 u16 rtl8168_shift_in_bits(struct rtl8168_private *tp)
243 {
244         u8 x;
245         u16 d, i;
246 
247         x = RTL_R8(tp, Cfg9346);
248         x &= ~(Cfg9346_EEDI | Cfg9346_EEDO);
249 
250         d = 0;
251 
252         for (i = 0; i < 16; i++) {
253                 d = d << 1;
254                 rtl8168_raise_clock(tp, &x);
255 
256                 x = RTL_R8(tp, Cfg9346);
257                 x &= ~Cfg9346_EEDI;
258 
259                 if (x & Cfg9346_EEDO)
260                         d |= 1;
261 
262                 rtl8168_lower_clock(tp, &x);
263         }
264 
265         return d;
266 }
267 
rtl8168_stand_by(struct rtl8168_private * tp)268 void rtl8168_stand_by(struct rtl8168_private *tp)
269 {
270         u8 x;
271 
272         x = RTL_R8(tp, Cfg9346);
273         x &= ~(Cfg9346_EECS | Cfg9346_EESK);
274         RTL_W8(tp, Cfg9346, x);
275         udelay(RTL_CLOCK_RATE);
276 
277         x |= Cfg9346_EECS;
278         RTL_W8(tp, Cfg9346, x);
279 }
280 
rtl8168_set_eeprom_sel_low(struct rtl8168_private * tp)281 void rtl8168_set_eeprom_sel_low(struct rtl8168_private *tp)
282 {
283         RTL_W8(tp, Cfg9346, Cfg9346_EEM1);
284         RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK);
285 
286         udelay(20);
287 
288         RTL_W8(tp, Cfg9346, Cfg9346_EEM1);
289 }
290