7
7
#include <linux/phy.h>
8
8
#include "lan743x_main.h"
9
9
#include "lan743x_ethtool.h"
10
+ #include <linux/sched.h>
11
+ #include <linux/iopoll.h>
10
12
11
13
/* eeprom */
12
14
#define LAN743X_EEPROM_MAGIC (0x74A5)
19
21
#define OTP_INDICATOR_1 (0xF3)
20
22
#define OTP_INDICATOR_2 (0xF7)
21
23
24
+ #define LOCK_TIMEOUT_MAX_CNT (100) // 1 sec (10 msce * 100)
25
+
26
+ #define LAN743X_CSR_READ_OP (offset ) lan743x_csr_read(adapter, offset)
27
+
22
28
static int lan743x_otp_power_up (struct lan743x_adapter * adapter )
23
29
{
24
30
u32 reg_value ;
@@ -149,6 +155,63 @@ static int lan743x_otp_write(struct lan743x_adapter *adapter, u32 offset,
149
155
return 0 ;
150
156
}
151
157
158
+ static int lan743x_hs_syslock_acquire (struct lan743x_adapter * adapter ,
159
+ u16 timeout )
160
+ {
161
+ u16 timeout_cnt = 0 ;
162
+ u32 val ;
163
+
164
+ do {
165
+ spin_lock (& adapter -> eth_syslock_spinlock );
166
+ if (adapter -> eth_syslock_acquire_cnt == 0 ) {
167
+ lan743x_csr_write (adapter , ETH_SYSTEM_SYS_LOCK_REG ,
168
+ SYS_LOCK_REG_ENET_SS_LOCK_ );
169
+ val = lan743x_csr_read (adapter ,
170
+ ETH_SYSTEM_SYS_LOCK_REG );
171
+ if (val & SYS_LOCK_REG_ENET_SS_LOCK_ ) {
172
+ adapter -> eth_syslock_acquire_cnt ++ ;
173
+ WARN_ON (adapter -> eth_syslock_acquire_cnt == 0 );
174
+ spin_unlock (& adapter -> eth_syslock_spinlock );
175
+ break ;
176
+ }
177
+ } else {
178
+ adapter -> eth_syslock_acquire_cnt ++ ;
179
+ WARN_ON (adapter -> eth_syslock_acquire_cnt == 0 );
180
+ spin_unlock (& adapter -> eth_syslock_spinlock );
181
+ break ;
182
+ }
183
+
184
+ spin_unlock (& adapter -> eth_syslock_spinlock );
185
+
186
+ if (timeout_cnt ++ < timeout )
187
+ usleep_range (10000 , 11000 );
188
+ else
189
+ return - ETIMEDOUT ;
190
+ } while (true);
191
+
192
+ return 0 ;
193
+ }
194
+
195
+ static void lan743x_hs_syslock_release (struct lan743x_adapter * adapter )
196
+ {
197
+ u32 val ;
198
+
199
+ spin_lock (& adapter -> eth_syslock_spinlock );
200
+ WARN_ON (adapter -> eth_syslock_acquire_cnt == 0 );
201
+
202
+ if (adapter -> eth_syslock_acquire_cnt ) {
203
+ adapter -> eth_syslock_acquire_cnt -- ;
204
+ if (adapter -> eth_syslock_acquire_cnt == 0 ) {
205
+ lan743x_csr_write (adapter , ETH_SYSTEM_SYS_LOCK_REG , 0 );
206
+ val = lan743x_csr_read (adapter ,
207
+ ETH_SYSTEM_SYS_LOCK_REG );
208
+ WARN_ON ((val & SYS_LOCK_REG_ENET_SS_LOCK_ ) != 0 );
209
+ }
210
+ }
211
+
212
+ spin_unlock (& adapter -> eth_syslock_spinlock );
213
+ }
214
+
152
215
static int lan743x_eeprom_wait (struct lan743x_adapter * adapter )
153
216
{
154
217
unsigned long start_time = jiffies ;
@@ -263,6 +326,100 @@ static int lan743x_eeprom_write(struct lan743x_adapter *adapter,
263
326
return 0 ;
264
327
}
265
328
329
+ static int lan743x_hs_eeprom_cmd_cmplt_chk (struct lan743x_adapter * adapter )
330
+ {
331
+ u32 val ;
332
+
333
+ return readx_poll_timeout (LAN743X_CSR_READ_OP , HS_E2P_CMD , val ,
334
+ (!(val & HS_E2P_CMD_EPC_BUSY_ ) ||
335
+ (val & HS_E2P_CMD_EPC_TIMEOUT_ )),
336
+ 50 , 10000 );
337
+ }
338
+
339
+ static int lan743x_hs_eeprom_read (struct lan743x_adapter * adapter ,
340
+ u32 offset , u32 length , u8 * data )
341
+ {
342
+ int retval ;
343
+ u32 val ;
344
+ int i ;
345
+
346
+ retval = lan743x_hs_syslock_acquire (adapter , LOCK_TIMEOUT_MAX_CNT );
347
+ if (retval < 0 )
348
+ return retval ;
349
+
350
+ retval = lan743x_hs_eeprom_cmd_cmplt_chk (adapter );
351
+ lan743x_hs_syslock_release (adapter );
352
+ if (retval < 0 )
353
+ return retval ;
354
+
355
+ for (i = 0 ; i < length ; i ++ ) {
356
+ retval = lan743x_hs_syslock_acquire (adapter ,
357
+ LOCK_TIMEOUT_MAX_CNT );
358
+ if (retval < 0 )
359
+ return retval ;
360
+
361
+ val = HS_E2P_CMD_EPC_BUSY_ | HS_E2P_CMD_EPC_CMD_READ_ ;
362
+ val |= (offset & HS_E2P_CMD_EPC_ADDR_MASK_ );
363
+ lan743x_csr_write (adapter , HS_E2P_CMD , val );
364
+ retval = lan743x_hs_eeprom_cmd_cmplt_chk (adapter );
365
+ if (retval < 0 ) {
366
+ lan743x_hs_syslock_release (adapter );
367
+ return retval ;
368
+ }
369
+
370
+ val = lan743x_csr_read (adapter , HS_E2P_DATA );
371
+
372
+ lan743x_hs_syslock_release (adapter );
373
+
374
+ data [i ] = val & 0xFF ;
375
+ offset ++ ;
376
+ }
377
+
378
+ return 0 ;
379
+ }
380
+
381
+ static int lan743x_hs_eeprom_write (struct lan743x_adapter * adapter ,
382
+ u32 offset , u32 length , u8 * data )
383
+ {
384
+ int retval ;
385
+ u32 val ;
386
+ int i ;
387
+
388
+ retval = lan743x_hs_syslock_acquire (adapter , LOCK_TIMEOUT_MAX_CNT );
389
+ if (retval < 0 )
390
+ return retval ;
391
+
392
+ retval = lan743x_hs_eeprom_cmd_cmplt_chk (adapter );
393
+ lan743x_hs_syslock_release (adapter );
394
+ if (retval < 0 )
395
+ return retval ;
396
+
397
+ for (i = 0 ; i < length ; i ++ ) {
398
+ retval = lan743x_hs_syslock_acquire (adapter ,
399
+ LOCK_TIMEOUT_MAX_CNT );
400
+ if (retval < 0 )
401
+ return retval ;
402
+
403
+ /* Fill data register */
404
+ val = data [i ];
405
+ lan743x_csr_write (adapter , HS_E2P_DATA , val );
406
+
407
+ /* Send "write" command */
408
+ val = HS_E2P_CMD_EPC_BUSY_ | HS_E2P_CMD_EPC_CMD_WRITE_ ;
409
+ val |= (offset & HS_E2P_CMD_EPC_ADDR_MASK_ );
410
+ lan743x_csr_write (adapter , HS_E2P_CMD , val );
411
+
412
+ retval = lan743x_hs_eeprom_cmd_cmplt_chk (adapter );
413
+ lan743x_hs_syslock_release (adapter );
414
+ if (retval < 0 )
415
+ return retval ;
416
+
417
+ offset ++ ;
418
+ }
419
+
420
+ return 0 ;
421
+ }
422
+
266
423
static void lan743x_ethtool_get_drvinfo (struct net_device * netdev ,
267
424
struct ethtool_drvinfo * info )
268
425
{
@@ -304,10 +461,16 @@ static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
304
461
struct lan743x_adapter * adapter = netdev_priv (netdev );
305
462
int ret = 0 ;
306
463
307
- if (adapter -> flags & LAN743X_ADAPTER_FLAG_OTP )
464
+ if (adapter -> flags & LAN743X_ADAPTER_FLAG_OTP ) {
308
465
ret = lan743x_otp_read (adapter , ee -> offset , ee -> len , data );
309
- else
310
- ret = lan743x_eeprom_read (adapter , ee -> offset , ee -> len , data );
466
+ } else {
467
+ if (adapter -> is_pci11x1x )
468
+ ret = lan743x_hs_eeprom_read (adapter , ee -> offset ,
469
+ ee -> len , data );
470
+ else
471
+ ret = lan743x_eeprom_read (adapter , ee -> offset ,
472
+ ee -> len , data );
473
+ }
311
474
312
475
return ret ;
313
476
}
@@ -326,8 +489,13 @@ static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
326
489
}
327
490
} else {
328
491
if (ee -> magic == LAN743X_EEPROM_MAGIC ) {
329
- ret = lan743x_eeprom_write (adapter , ee -> offset ,
330
- ee -> len , data );
492
+ if (adapter -> is_pci11x1x )
493
+ ret = lan743x_hs_eeprom_write (adapter ,
494
+ ee -> offset ,
495
+ ee -> len , data );
496
+ else
497
+ ret = lan743x_eeprom_write (adapter , ee -> offset ,
498
+ ee -> len , data );
331
499
}
332
500
}
333
501
0 commit comments