|
@@ -169,6 +169,15 @@ enum register_offsets {
|
169
|
169
|
|
170
|
170
|
};
|
171
|
171
|
|
|
172
|
+/* the values for the 'magic' registers above (PGSEL=1) */
|
|
173
|
+#define PMDCSR_VAL 0x189c /* enable preferred adaptation circuitry */
|
|
174
|
+#define TSTDAT_VAL 0x0
|
|
175
|
+#define DSPCFG_VAL 0x5040
|
|
176
|
+#define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */
|
|
177
|
+#define DSPCFG_LOCK 0x20 /* coefficient lock bit in DSPCFG */
|
|
178
|
+#define DSPCFG_COEF 0x1000 /* see coefficient (in TSTDAT) bit in DSPCFG */
|
|
179
|
+#define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */
|
|
180
|
+
|
172
|
181
|
/* Bit in ChipCmd.
|
173
|
182
|
*/
|
174
|
183
|
enum ChipCmdBits {
|
|
@@ -181,6 +190,20 @@ enum ChipCmdBits {
|
181
|
190
|
TxOn = 0x01
|
182
|
191
|
};
|
183
|
192
|
|
|
193
|
+enum ChipConfig_bits {
|
|
194
|
+ CfgPhyDis = 0x200,
|
|
195
|
+ CfgPhyRst = 0x400,
|
|
196
|
+ CfgExtPhy = 0x1000,
|
|
197
|
+ CfgAnegEnable = 0x2000,
|
|
198
|
+ CfgAneg100 = 0x4000,
|
|
199
|
+ CfgAnegFull = 0x8000,
|
|
200
|
+ CfgAnegDone = 0x8000000,
|
|
201
|
+ CfgFullDuplex = 0x20000000,
|
|
202
|
+ CfgSpeed100 = 0x40000000,
|
|
203
|
+ CfgLink = 0x80000000,
|
|
204
|
+};
|
|
205
|
+
|
|
206
|
+
|
184
|
207
|
/* Bits in the RxMode register.
|
185
|
208
|
*/
|
186
|
209
|
enum rx_mode_bits {
|
|
@@ -328,6 +351,41 @@ static void nat_reset ( struct natsemi_nic *nat ) {
|
328
|
351
|
outl ( SavedClkRun, nat->ioaddr + ClkRun );
|
329
|
352
|
}
|
330
|
353
|
|
|
354
|
+static void do_cable_magic ( struct net_device *netdev ) {
|
|
355
|
+ struct natsemi_nic *nat = netdev->priv;
|
|
356
|
+ uint16_t data;
|
|
357
|
+ /*
|
|
358
|
+ * 100 MBit links with short cables can trip an issue with the chip.
|
|
359
|
+ * The problem manifests as lots of CRC errors and/or flickering
|
|
360
|
+ * activity LED while idle. This process is based on instructions
|
|
361
|
+ * from engineers at National.
|
|
362
|
+ */
|
|
363
|
+ if (inl(nat->ioaddr + ChipConfig) & CfgSpeed100) {
|
|
364
|
+
|
|
365
|
+ outw(1, nat->ioaddr + PGSEL);
|
|
366
|
+ /*
|
|
367
|
+ * coefficient visibility should already be enabled via
|
|
368
|
+ * DSPCFG | 0x1000
|
|
369
|
+ */
|
|
370
|
+ data = inw(nat->ioaddr + TSTDAT) & 0xff;
|
|
371
|
+ /*
|
|
372
|
+ * the value must be negative, and within certain values
|
|
373
|
+ * (these values all come from National)
|
|
374
|
+ */
|
|
375
|
+ if (!(data & 0x80) || ((data >= 0xd8) && (data <= 0xff))) {
|
|
376
|
+
|
|
377
|
+ /* the bug has been triggered - fix the coefficient */
|
|
378
|
+ outw(TSTDAT_FIXED, nat->ioaddr + TSTDAT);
|
|
379
|
+ /* lock the value */
|
|
380
|
+ data = inw(nat->ioaddr + DSPCFG);
|
|
381
|
+ //np->dspcfg = data | DSPCFG_LOCK;
|
|
382
|
+ outw(data | DSPCFG_LOCK , nat->ioaddr + DSPCFG);
|
|
383
|
+ }
|
|
384
|
+ outw(0, nat->ioaddr + PGSEL);
|
|
385
|
+ }
|
|
386
|
+
|
|
387
|
+}
|
|
388
|
+
|
331
|
389
|
/*
|
332
|
390
|
* Open NIC
|
333
|
391
|
*
|
|
@@ -401,13 +459,13 @@ static int nat_open ( struct net_device *netdev ) {
|
401
|
459
|
* Configure for standard, in-spec Ethernet.
|
402
|
460
|
*/
|
403
|
461
|
if ( inl ( nat->ioaddr + ChipConfig ) & 0x20000000 ) { /* Full duplex */
|
404
|
|
- tx_config = 0xD0801002|0xC0000000;
|
405
|
|
- DBG("Full duplex\n");
|
406
|
|
- rx_config = 0x10000020|0x10000000;;
|
|
462
|
+ tx_config = 0xD0801002 | 0xC0000000;
|
|
463
|
+ DBG ( "Full duplex\n" );
|
|
464
|
+ rx_config = 0x10000020 | 0x10000000;
|
407
|
465
|
} else {
|
408
|
|
- tx_config = 0x10801002& ~0xC0000000;;
|
409
|
|
- DBG("Half duplex\n");
|
410
|
|
- rx_config = 0x0020& ~0x10000000;;;
|
|
466
|
+ tx_config = 0x10801002 & ~0xC0000000;
|
|
467
|
+ DBG ( "Half duplex\n" );
|
|
468
|
+ rx_config = 0x0020 & ~0x10000000;
|
411
|
469
|
}
|
412
|
470
|
outl ( tx_config, nat->ioaddr + TxConfig );
|
413
|
471
|
outl ( rx_config, nat->ioaddr + RxConfig );
|
|
@@ -415,6 +473,12 @@ static int nat_open ( struct net_device *netdev ) {
|
415
|
473
|
/*start the receiver
|
416
|
474
|
*/
|
417
|
475
|
outl ( RxOn, nat->ioaddr + ChipCmd );
|
|
476
|
+
|
|
477
|
+ /* lines 1586 linux-natsemi.c uses cable magic
|
|
478
|
+ * testing this feature is required or not
|
|
479
|
+ */
|
|
480
|
+ do_cable_magic ( netdev );
|
|
481
|
+
|
418
|
482
|
|
419
|
483
|
/* mask the interrupts. note interrupt is not enabled here
|
420
|
484
|
*/
|