Browse Source

Jan Kiszka provided a patch for the smc9000 for missing phy-setup

tags/v0.9.3
Timothy Legge 19 years ago
parent
commit
95967adc8c
3 changed files with 564 additions and 1 deletions
  1. 2
    0
      LOG
  2. 448
    1
      src/drivers/net/smc9000.c
  3. 114
    0
      src/drivers/net/smc9000.h

+ 2
- 0
LOG View File

@@ -2868,3 +2868,5 @@ driver
2868 2868
 that it supports the Gigabit nVidia NICs
2869 2869
 
2870 2870
 + Timothy Legge fixed relocation issues with the eepro driver
2871
+
2872
++ Jan Kiszka provided a patch for the smc9000 for missing phy-setup

+ 448
- 1
src/drivers/net/smc9000.c View File

@@ -29,9 +29,16 @@
29 29
 #define LINUX_OUT_MACROS 1
30 30
 #define SMC9000_DEBUG    0
31 31
 
32
+#if SMC9000_DEBUG > 1
33
+#define PRINTK2 printf
34
+#else
35
+#define PRINTK2(args...)
36
+#endif
37
+
32 38
 #include "etherboot.h"
33 39
 #include "nic.h"
34 40
 #include "isa.h"
41
+#include "timer.h"
35 42
 #include "smc9000.h"
36 43
 
37 44
 # define _outb outb
@@ -47,11 +54,449 @@ static const char       *chip_ids[ 15 ] =  {
47 54
    NULL,
48 55
    /* 7 */ "SMC91C100",
49 56
    /* 8 */ "SMC91C100FD",
50
-   NULL, NULL, NULL,
57
+   /* 9 */ "SMC91C11xFD",
58
+   NULL, NULL,
51 59
    NULL, NULL, NULL
52 60
 };
53 61
 static const char      smc91c96_id[] = "SMC91C96";
54 62
 
63
+/*------------------------------------------------------------
64
+ . Reads a register from the MII Management serial interface
65
+ .-------------------------------------------------------------*/
66
+static word smc_read_phy_register(int ioaddr, byte phyaddr, byte phyreg)
67
+{
68
+    int oldBank;
69
+    unsigned int i;
70
+    byte mask;
71
+    word mii_reg;
72
+    byte bits[64];
73
+    int clk_idx = 0;
74
+    int input_idx;
75
+    word phydata;
76
+
77
+    // 32 consecutive ones on MDO to establish sync
78
+    for (i = 0; i < 32; ++i)
79
+        bits[clk_idx++] = MII_MDOE | MII_MDO;
80
+
81
+    // Start code <01>
82
+    bits[clk_idx++] = MII_MDOE;
83
+    bits[clk_idx++] = MII_MDOE | MII_MDO;
84
+
85
+    // Read command <10>
86
+    bits[clk_idx++] = MII_MDOE | MII_MDO;
87
+    bits[clk_idx++] = MII_MDOE;
88
+
89
+    // Output the PHY address, msb first
90
+    mask = (byte)0x10;
91
+    for (i = 0; i < 5; ++i)
92
+    {
93
+        if (phyaddr & mask)
94
+            bits[clk_idx++] = MII_MDOE | MII_MDO;
95
+        else
96
+            bits[clk_idx++] = MII_MDOE;
97
+
98
+        // Shift to next lowest bit
99
+        mask >>= 1;
100
+    }
101
+
102
+    // Output the phy register number, msb first
103
+    mask = (byte)0x10;
104
+    for (i = 0; i < 5; ++i)
105
+    {
106
+        if (phyreg & mask)
107
+            bits[clk_idx++] = MII_MDOE | MII_MDO;
108
+        else
109
+            bits[clk_idx++] = MII_MDOE;
110
+
111
+        // Shift to next lowest bit
112
+        mask >>= 1;
113
+    }
114
+
115
+    // Tristate and turnaround (2 bit times)
116
+    bits[clk_idx++] = 0;
117
+    //bits[clk_idx++] = 0;
118
+
119
+    // Input starts at this bit time
120
+    input_idx = clk_idx;
121
+
122
+    // Will input 16 bits
123
+    for (i = 0; i < 16; ++i)
124
+        bits[clk_idx++] = 0;
125
+
126
+    // Final clock bit
127
+    bits[clk_idx++] = 0;
128
+
129
+    // Save the current bank
130
+    oldBank = inw( ioaddr+BANK_SELECT );
131
+
132
+    // Select bank 3
133
+    SMC_SELECT_BANK(ioaddr, 3);
134
+
135
+    // Get the current MII register value
136
+    mii_reg = inw( ioaddr+MII_REG );
137
+
138
+    // Turn off all MII Interface bits
139
+    mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
140
+
141
+    // Clock all 64 cycles
142
+    for (i = 0; i < sizeof(bits); ++i)
143
+    {
144
+        // Clock Low - output data
145
+        outw( mii_reg | bits[i], ioaddr+MII_REG );
146
+        udelay(50);
147
+
148
+
149
+        // Clock Hi - input data
150
+        outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
151
+        udelay(50);
152
+        bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
153
+    }
154
+
155
+    // Return to idle state
156
+    // Set clock to low, data to low, and output tristated
157
+    outw( mii_reg, ioaddr+MII_REG );
158
+    udelay(50);
159
+
160
+    // Restore original bank select
161
+    SMC_SELECT_BANK(ioaddr, oldBank);
162
+
163
+    // Recover input data
164
+    phydata = 0;
165
+    for (i = 0; i < 16; ++i)
166
+    {
167
+        phydata <<= 1;
168
+
169
+        if (bits[input_idx++] & MII_MDI)
170
+            phydata |= 0x0001;
171
+    }
172
+
173
+#if (SMC_DEBUG > 2 )
174
+        printf("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
175
+               phyaddr, phyreg, phydata);
176
+#endif
177
+
178
+        return(phydata);
179
+}
180
+
181
+
182
+/*------------------------------------------------------------
183
+ . Writes a register to the MII Management serial interface
184
+ .-------------------------------------------------------------*/
185
+static void smc_write_phy_register(int ioaddr,
186
+                                   byte phyaddr, byte phyreg, word phydata)
187
+{
188
+    int oldBank;
189
+    unsigned int i;
190
+    word mask;
191
+    word mii_reg;
192
+    byte bits[65];
193
+    int clk_idx = 0;
194
+
195
+    // 32 consecutive ones on MDO to establish sync
196
+    for (i = 0; i < 32; ++i)
197
+        bits[clk_idx++] = MII_MDOE | MII_MDO;
198
+
199
+    // Start code <01>
200
+    bits[clk_idx++] = MII_MDOE;
201
+    bits[clk_idx++] = MII_MDOE | MII_MDO;
202
+
203
+    // Write command <01>
204
+    bits[clk_idx++] = MII_MDOE;
205
+    bits[clk_idx++] = MII_MDOE | MII_MDO;
206
+
207
+    // Output the PHY address, msb first
208
+    mask = (byte)0x10;
209
+    for (i = 0; i < 5; ++i)
210
+    {
211
+        if (phyaddr & mask)
212
+            bits[clk_idx++] = MII_MDOE | MII_MDO;
213
+        else
214
+            bits[clk_idx++] = MII_MDOE;
215
+
216
+                // Shift to next lowest bit
217
+        mask >>= 1;
218
+    }
219
+
220
+    // Output the phy register number, msb first
221
+    mask = (byte)0x10;
222
+    for (i = 0; i < 5; ++i)
223
+    {
224
+        if (phyreg & mask)
225
+            bits[clk_idx++] = MII_MDOE | MII_MDO;
226
+        else
227
+            bits[clk_idx++] = MII_MDOE;
228
+
229
+        // Shift to next lowest bit
230
+        mask >>= 1;
231
+    }
232
+
233
+    // Tristate and turnaround (2 bit times)
234
+    bits[clk_idx++] = 0;
235
+    bits[clk_idx++] = 0;
236
+
237
+    // Write out 16 bits of data, msb first
238
+    mask = 0x8000;
239
+    for (i = 0; i < 16; ++i)
240
+    {
241
+        if (phydata & mask)
242
+            bits[clk_idx++] = MII_MDOE | MII_MDO;
243
+        else
244
+            bits[clk_idx++] = MII_MDOE;
245
+
246
+        // Shift to next lowest bit
247
+        mask >>= 1;
248
+    }
249
+
250
+    // Final clock bit (tristate)
251
+    bits[clk_idx++] = 0;
252
+
253
+    // Save the current bank
254
+    oldBank = inw( ioaddr+BANK_SELECT );
255
+
256
+    // Select bank 3
257
+    SMC_SELECT_BANK(ioaddr, 3);
258
+
259
+    // Get the current MII register value
260
+    mii_reg = inw( ioaddr+MII_REG );
261
+
262
+    // Turn off all MII Interface bits
263
+    mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
264
+
265
+    // Clock all cycles
266
+    for (i = 0; i < sizeof(bits); ++i)
267
+    {
268
+        // Clock Low - output data
269
+        outw( mii_reg | bits[i], ioaddr+MII_REG );
270
+        udelay(50);
271
+
272
+
273
+        // Clock Hi - input data
274
+        outw( mii_reg | bits[i] | MII_MCLK, ioaddr+MII_REG );
275
+        udelay(50);
276
+        bits[i] |= inw( ioaddr+MII_REG ) & MII_MDI;
277
+    }
278
+
279
+    // Return to idle state
280
+    // Set clock to low, data to low, and output tristated
281
+    outw( mii_reg, ioaddr+MII_REG );
282
+    udelay(50);
283
+
284
+    // Restore original bank select
285
+    SMC_SELECT_BANK(ioaddr, oldBank);
286
+
287
+#if (SMC_DEBUG > 2 )
288
+        printf("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
289
+               phyaddr, phyreg, phydata);
290
+#endif
291
+}
292
+
293
+
294
+/*------------------------------------------------------------
295
+ . Finds and reports the PHY address
296
+ .-------------------------------------------------------------*/
297
+static int smc_detect_phy(int ioaddr, byte *pphyaddr)
298
+{
299
+    word phy_id1;
300
+    word phy_id2;
301
+    int phyaddr;
302
+    int found = 0;
303
+
304
+    // Scan all 32 PHY addresses if necessary
305
+    for (phyaddr = 0; phyaddr < 32; ++phyaddr)
306
+    {
307
+        // Read the PHY identifiers
308
+        phy_id1  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG);
309
+        phy_id2  = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG);
310
+
311
+        // Make sure it is a valid identifier
312
+        if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
313
+             (phy_id1 > 0x0000) && (phy_id1 < 0xffff))
314
+        {
315
+            if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000))
316
+            {
317
+                // Save the PHY's address
318
+                *pphyaddr = phyaddr;
319
+                found = 1;
320
+                break;
321
+            }
322
+        }
323
+    }
324
+
325
+    if (!found)
326
+    {
327
+        printf("No PHY found\n");
328
+        return(0);
329
+    }
330
+
331
+    // Set the PHY type
332
+    if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) )
333
+    {
334
+        printf("PHY=LAN83C183 (LAN91C111 Internal)\n");
335
+    }
336
+
337
+    if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) )
338
+    {
339
+        printf("PHY=LAN83C180\n");
340
+    }
341
+
342
+    return(1);
343
+}
344
+
345
+/*------------------------------------------------------------
346
+ . Configures the specified PHY using Autonegotiation. Calls
347
+ . smc_phy_fixed() if the user has requested a certain config.
348
+ .-------------------------------------------------------------*/
349
+static void smc_phy_configure(int ioaddr)
350
+{
351
+    int timeout;
352
+    byte phyaddr;
353
+    word my_phy_caps; // My PHY capabilities
354
+    word my_ad_caps; // My Advertised capabilities
355
+    word status;
356
+    int failed = 0;
357
+    int rpc_cur_mode = RPC_DEFAULT;
358
+    int lastPhy18;
359
+
360
+    // Find the address and type of our phy
361
+    if (!smc_detect_phy(ioaddr, &phyaddr))
362
+    {
363
+        return;
364
+    }
365
+
366
+    // Reset the PHY, setting all other bits to zero
367
+    smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
368
+
369
+    // Wait for the reset to complete, or time out
370
+    timeout = 6; // Wait up to 3 seconds
371
+    while (timeout--)
372
+    {
373
+        if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
374
+              & PHY_CNTL_RST))
375
+        {
376
+            // reset complete
377
+            break;
378
+        }
379
+
380
+        mdelay(500); // wait 500 millisecs
381
+    }
382
+
383
+    if (timeout < 1)
384
+    {
385
+        PRINTK2("PHY reset timed out\n");
386
+        return;
387
+    }
388
+
389
+    // Read PHY Register 18, Status Output
390
+    lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
391
+
392
+    // Enable PHY Interrupts (for register 18)
393
+    // Interrupts listed here are disabled
394
+    smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG,
395
+                           PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
396
+                                   PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
397
+                                   PHY_INT_SPDDET | PHY_INT_DPLXDET);
398
+
399
+    /* Configure the Receive/Phy Control register */
400
+    SMC_SELECT_BANK(ioaddr, 0);
401
+    outw( rpc_cur_mode, ioaddr + RPC_REG );
402
+
403
+    // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
404
+    my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
405
+    my_ad_caps  = PHY_AD_CSMA; // I am CSMA capable
406
+
407
+    if (my_phy_caps & PHY_STAT_CAP_T4)
408
+        my_ad_caps |= PHY_AD_T4;
409
+
410
+    if (my_phy_caps & PHY_STAT_CAP_TXF)
411
+        my_ad_caps |= PHY_AD_TX_FDX;
412
+
413
+    if (my_phy_caps & PHY_STAT_CAP_TXH)
414
+        my_ad_caps |= PHY_AD_TX_HDX;
415
+
416
+    if (my_phy_caps & PHY_STAT_CAP_TF)
417
+        my_ad_caps |= PHY_AD_10_FDX;
418
+
419
+    if (my_phy_caps & PHY_STAT_CAP_TH)
420
+        my_ad_caps |= PHY_AD_10_HDX;
421
+
422
+    // Update our Auto-Neg Advertisement Register
423
+    smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
424
+
425
+    PRINTK2("phy caps=%x\n", my_phy_caps);
426
+    PRINTK2("phy advertised caps=%x\n", my_ad_caps);
427
+
428
+    // Restart auto-negotiation process in order to advertise my caps
429
+    smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
430
+                            PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
431
+
432
+    // Wait for the auto-negotiation to complete.  This may take from
433
+    // 2 to 3 seconds.
434
+    // Wait for the reset to complete, or time out
435
+    timeout = 20; // Wait up to 10 seconds
436
+    while (timeout--)
437
+    {
438
+        status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
439
+        if (status & PHY_STAT_ANEG_ACK)
440
+        {
441
+            // auto-negotiate complete
442
+            break;
443
+        }
444
+
445
+        mdelay(500); // wait 500 millisecs
446
+
447
+        // Restart auto-negotiation if remote fault
448
+        if (status & PHY_STAT_REM_FLT)
449
+        {
450
+            PRINTK2("PHY remote fault detected\n");
451
+
452
+            // Restart auto-negotiation
453
+            PRINTK2("PHY restarting auto-negotiation\n");
454
+            smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
455
+                                    PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST |
456
+                                    PHY_CNTL_SPEED | PHY_CNTL_DPLX);
457
+        }
458
+    }
459
+
460
+    if (timeout < 1)
461
+    {
462
+        PRINTK2("PHY auto-negotiate timed out\n");
463
+        failed = 1;
464
+    }
465
+
466
+    // Fail if we detected an auto-negotiate remote fault
467
+    if (status & PHY_STAT_REM_FLT)
468
+    {
469
+        PRINTK2("PHY remote fault detected\n");
470
+        failed = 1;
471
+    }
472
+
473
+    // Set our sysctl parameters to match auto-negotiation results
474
+    if ( lastPhy18 & PHY_INT_SPDDET )
475
+    {
476
+        PRINTK2("PHY 100BaseT\n");
477
+        rpc_cur_mode |= RPC_SPEED;
478
+    }
479
+    else
480
+    {
481
+        PRINTK2("PHY 10BaseT\n");
482
+        rpc_cur_mode &= ~RPC_SPEED;
483
+    }
484
+
485
+    if ( lastPhy18 & PHY_INT_DPLXDET )
486
+    {
487
+        PRINTK2("PHY Full Duplex\n");
488
+        rpc_cur_mode |= RPC_DPLX;
489
+    }
490
+    else
491
+    {
492
+        PRINTK2("PHY Half Duplex\n");
493
+        rpc_cur_mode &= ~RPC_DPLX;
494
+    }
495
+
496
+    // Re-Configure the Receive/Phy Control register
497
+    outw( rpc_cur_mode, ioaddr + RPC_REG );
498
+}
499
+
55 500
 /*
56 501
  * Function: smc_reset( int ioaddr )
57 502
  * Purpose:
@@ -476,6 +921,8 @@ static int smc9000_probe ( struct nic *nic, struct isa_device *isa ) {
476 921
 	   nic->ioaddr + CONFIG );
477 922
    }
478 923
 
924
+   smc_phy_configure(nic->ioaddr);
925
+ 
479 926
    nic->nic_op	= &smc9000_operations;
480 927
    return 1;
481 928
 }

+ 114
- 0
src/drivers/net/smc9000.h View File

@@ -91,6 +91,24 @@ typedef unsigned long int		dword;
91 91
 #define	MCR		10
92 92
 /* 12 is reserved */
93 93
 
94
+// Receive/Phy Control Register
95
+/* BANK 0  */
96
+#define RPC_REG         0x000A
97
+#define RPC_SPEED       0x2000  // When 1 PHY is in 100Mbps mode.
98
+#define RPC_DPLX        0x1000  // When 1 PHY is in Full-Duplex Mode
99
+#define RPC_ANEG        0x0800  // When 1 PHY is in Auto-Negotiate Mode
100
+#define RPC_LSXA_SHFT   5       // Bits to shift LS2A,LS1A,LS0A to lsb
101
+#define RPC_LSXB_SHFT   2       // Bits to get LS2B,LS1B,LS0B to lsb
102
+#define RPC_LED_100_10  (0x00)  // LED = 100Mbps OR's with 10Mbps link detect
103
+#define RPC_LED_RES     (0x01)  // LED = Reserved
104
+#define RPC_LED_10      (0x02)  // LED = 10Mbps link detect
105
+#define RPC_LED_FD      (0x03)  // LED = Full Duplex Mode
106
+#define RPC_LED_TX_RX   (0x04)  // LED = TX or RX packet occurred
107
+#define RPC_LED_100     (0x05)  // LED = 100Mbps link dectect
108
+#define RPC_LED_TX      (0x06)  // LED = TX packet occurred
109
+#define RPC_LED_RX      (0x07)  // LED = RX packet occurred
110
+#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
111
+
94 112
 /* BANK 1 */
95 113
 #define CONFIG			0
96 114
 #define CFG_AUI_SELECT		0x100
@@ -151,6 +169,13 @@ typedef unsigned long int		dword;
151 169
 #define	MGMT		8
152 170
 #define	REVISION	10 /* ( hi: chip id   low: rev # ) */
153 171
 
172
+// Management Interface Register (MII)
173
+#define MII_REG         0x0008
174
+#define MII_MSK_CRS100  0x4000 // Disables CRS100 detection during tx half dup
175
+#define MII_MDOE        0x0008 // MII Output Enable
176
+#define MII_MCLK        0x0004 // MII Clock, pin MDCLK
177
+#define MII_MDI         0x0002 // MII Input, pin MDI
178
+#define MII_MDO         0x0001 // MII Output, pin MDO
154 179
 
155 180
 /* this is NOT on SMC9192 */
156 181
 #define	ERCV		12
@@ -186,6 +211,95 @@ typedef unsigned long int		dword;
186 211
 #define RS_ERRORS	(RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
187 212
 
188 213
 
214
+// PHY Register Addresses (LAN91C111 Internal PHY)
215
+
216
+// PHY Control Register
217
+#define PHY_CNTL_REG            0x00
218
+#define PHY_CNTL_RST            0x8000  // 1=PHY Reset
219
+#define PHY_CNTL_LPBK           0x4000  // 1=PHY Loopback
220
+#define PHY_CNTL_SPEED          0x2000  // 1=100Mbps, 0=10Mpbs
221
+#define PHY_CNTL_ANEG_EN        0x1000 // 1=Enable Auto negotiation
222
+#define PHY_CNTL_PDN            0x0800  // 1=PHY Power Down mode
223
+#define PHY_CNTL_MII_DIS        0x0400  // 1=MII 4 bit interface disabled
224
+#define PHY_CNTL_ANEG_RST       0x0200 // 1=Reset Auto negotiate
225
+#define PHY_CNTL_DPLX           0x0100  // 1=Full Duplex, 0=Half Duplex
226
+#define PHY_CNTL_COLTST         0x0080  // 1= MII Colision Test
227
+
228
+// PHY Status Register
229
+#define PHY_STAT_REG            0x01
230
+#define PHY_STAT_CAP_T4         0x8000  // 1=100Base-T4 capable
231
+#define PHY_STAT_CAP_TXF        0x4000  // 1=100Base-X full duplex capable
232
+#define PHY_STAT_CAP_TXH        0x2000  // 1=100Base-X half duplex capable
233
+#define PHY_STAT_CAP_TF         0x1000  // 1=10Mbps full duplex capable
234
+#define PHY_STAT_CAP_TH         0x0800  // 1=10Mbps half duplex capable
235
+#define PHY_STAT_CAP_SUPR       0x0040  // 1=recv mgmt frames with not preamble
236
+#define PHY_STAT_ANEG_ACK       0x0020  // 1=ANEG has completed
237
+#define PHY_STAT_REM_FLT        0x0010  // 1=Remote Fault detected
238
+#define PHY_STAT_CAP_ANEG       0x0008  // 1=Auto negotiate capable
239
+#define PHY_STAT_LINK           0x0004  // 1=valid link
240
+#define PHY_STAT_JAB            0x0002  // 1=10Mbps jabber condition
241
+#define PHY_STAT_EXREG          0x0001  // 1=extended registers implemented
242
+
243
+// PHY Identifier Registers
244
+#define PHY_ID1_REG             0x02    // PHY Identifier 1
245
+#define PHY_ID2_REG             0x03    // PHY Identifier 2
246
+
247
+// PHY Auto-Negotiation Advertisement Register
248
+#define PHY_AD_REG              0x04
249
+#define PHY_AD_NP               0x8000  // 1=PHY requests exchange of Next Page
250
+#define PHY_AD_ACK              0x4000  // 1=got link code word from remote
251
+#define PHY_AD_RF               0x2000  // 1=advertise remote fault
252
+#define PHY_AD_T4               0x0200  // 1=PHY is capable of 100Base-T4
253
+#define PHY_AD_TX_FDX           0x0100  // 1=PHY is capable of 100Base-TX FDPLX
254
+#define PHY_AD_TX_HDX           0x0080  // 1=PHY is capable of 100Base-TX HDPLX
255
+#define PHY_AD_10_FDX           0x0040  // 1=PHY is capable of 10Base-T FDPLX
256
+#define PHY_AD_10_HDX           0x0020  // 1=PHY is capable of 10Base-T HDPLX
257
+#define PHY_AD_CSMA             0x0001  // 1=PHY is capable of 802.3 CMSA
258
+
259
+// PHY Auto-negotiation Remote End Capability Register
260
+#define PHY_RMT_REG             0x05
261
+// Uses same bit definitions as PHY_AD_REG
262
+
263
+// PHY Configuration Register 1
264
+#define PHY_CFG1_REG            0x10
265
+#define PHY_CFG1_LNKDIS         0x8000  // 1=Rx Link Detect Function disabled
266
+#define PHY_CFG1_XMTDIS         0x4000  // 1=TP Transmitter Disabled
267
+#define PHY_CFG1_XMTPDN         0x2000  // 1=TP Transmitter Powered Down
268
+#define PHY_CFG1_BYPSCR         0x0400  // 1=Bypass scrambler/descrambler
269
+#define PHY_CFG1_UNSCDS         0x0200  // 1=Unscramble Idle Reception Disable
270
+#define PHY_CFG1_EQLZR          0x0100  // 1=Rx Equalizer Disabled
271
+#define PHY_CFG1_CABLE          0x0080  // 1=STP(150ohm), 0=UTP(100ohm)
272
+#define PHY_CFG1_RLVL0          0x0040  // 1=Rx Squelch level reduced by 4.5db
273
+#define PHY_CFG1_TLVL_SHIFT     2       // Transmit Output Level Adjust
274
+#define PHY_CFG1_TLVL_MASK      0x003C
275
+#define PHY_CFG1_TRF_MASK       0x0003  // Transmitter Rise/Fall time
276
+
277
+
278
+// PHY Configuration Register 2
279
+#define PHY_CFG2_REG            0x11
280
+#define PHY_CFG2_APOLDIS        0x0020  // 1=Auto Polarity Correction disabled
281
+#define PHY_CFG2_JABDIS         0x0010  // 1=Jabber disabled
282
+#define PHY_CFG2_MREG           0x0008  // 1=Multiple register access (MII mgt)
283
+#define PHY_CFG2_INTMDIO        0x0004  // 1=Interrupt signaled with MDIO pulseo
284
+
285
+// PHY Status Output (and Interrupt status) Register
286
+#define PHY_INT_REG             0x12    // Status Output (Interrupt Status)
287
+#define PHY_INT_INT             0x8000  // 1=bits have changed since last read
288
+#define PHY_INT_LNKFAIL         0x4000  // 1=Link Not detected
289
+#define PHY_INT_LOSSSYNC        0x2000  // 1=Descrambler has lost sync
290
+#define PHY_INT_CWRD            0x1000  // 1=Invalid 4B5B code detected on rx
291
+#define PHY_INT_SSD             0x0800  // 1=No Start Of Stream detected on rx
292
+#define PHY_INT_ESD             0x0400  // 1=No End Of Stream detected on rx
293
+#define PHY_INT_RPOL            0x0200  // 1=Reverse Polarity detected
294
+#define PHY_INT_JAB             0x0100  // 1=Jabber detected
295
+#define PHY_INT_SPDDET          0x0080  // 1=100Base-TX mode, 0=10Base-T mode
296
+#define PHY_INT_DPLXDET         0x0040  // 1=Device in Full Duplex
297
+
298
+// PHY Interrupt/Status Mask Register
299
+#define PHY_MASK_REG            0x13    // Interrupt Mask
300
+// Uses the same bit definitions as PHY_INT_REG
301
+
302
+
189 303
 /*-------------------------------------------------------------------------
190 304
  *  I define some macros to make it easier to do somewhat common
191 305
  * or slightly complicated, repeated tasks.

Loading…
Cancel
Save