00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 static const char *version = "rhine.c v1.0.2 2004-10-29\n";
00022
00023
00024
00025
00026 #define W_MAX_TIMEOUT 0x0FFFU
00027
00028
00029 #define RX_BUF_LEN_IDX 3
00030 #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
00031
00032
00033 #define TX_BUF_SIZE 1536
00034 #define RX_BUF_SIZE 1536
00035
00036
00037
00038 #define TX_FIFO_THRESH 256
00039
00040
00041 #define RX_FIFO_THRESH 4
00042 #define RX_DMA_BURST 4
00043 #define TX_DMA_BURST 4
00044
00045
00046
00047 #define TX_TIMEOUT ((2000*HZ)/1000)
00048
00049 #include "etherboot.h"
00050 #include "nic.h"
00051 #include <gpxe/pci.h>
00052 #include <gpxe/ethernet.h>
00053
00054
00055
00056 #define byPAR0 ioaddr
00057 #define byRCR ioaddr + 6
00058 #define byTCR ioaddr + 7
00059 #define byCR0 ioaddr + 8
00060 #define byCR1 ioaddr + 9
00061 #define byISR0 ioaddr + 0x0c
00062 #define byISR1 ioaddr + 0x0d
00063 #define byIMR0 ioaddr + 0x0e
00064 #define byIMR1 ioaddr + 0x0f
00065 #define byMAR0 ioaddr + 0x10
00066 #define byMAR1 ioaddr + 0x11
00067 #define byMAR2 ioaddr + 0x12
00068 #define byMAR3 ioaddr + 0x13
00069 #define byMAR4 ioaddr + 0x14
00070 #define byMAR5 ioaddr + 0x15
00071 #define byMAR6 ioaddr + 0x16
00072 #define byMAR7 ioaddr + 0x17
00073 #define dwCurrentRxDescAddr ioaddr + 0x18
00074 #define dwCurrentTxDescAddr ioaddr + 0x1c
00075 #define dwCurrentRDSE0 ioaddr + 0x20
00076 #define dwCurrentRDSE1 ioaddr + 0x24
00077 #define dwCurrentRDSE2 ioaddr + 0x28
00078 #define dwCurrentRDSE3 ioaddr + 0x2c
00079 #define dwNextRDSE0 ioaddr + 0x30
00080 #define dwNextRDSE1 ioaddr + 0x34
00081 #define dwNextRDSE2 ioaddr + 0x38
00082 #define dwNextRDSE3 ioaddr + 0x3c
00083 #define dwCurrentTDSE0 ioaddr + 0x40
00084 #define dwCurrentTDSE1 ioaddr + 0x44
00085 #define dwCurrentTDSE2 ioaddr + 0x48
00086 #define dwCurrentTDSE3 ioaddr + 0x4c
00087 #define dwNextTDSE0 ioaddr + 0x50
00088 #define dwNextTDSE1 ioaddr + 0x54
00089 #define dwNextTDSE2 ioaddr + 0x58
00090 #define dwNextTDSE3 ioaddr + 0x5c
00091 #define dwCurrRxDMAPtr ioaddr + 0x60
00092 #define dwCurrTxDMAPtr ioaddr + 0x64
00093 #define byMPHY ioaddr + 0x6c
00094 #define byMIISR ioaddr + 0x6d
00095 #define byBCR0 ioaddr + 0x6e
00096 #define byBCR1 ioaddr + 0x6f
00097 #define byMIICR ioaddr + 0x70
00098 #define byMIIAD ioaddr + 0x71
00099 #define wMIIDATA ioaddr + 0x72
00100 #define byEECSR ioaddr + 0x74
00101 #define byTEST ioaddr + 0x75
00102 #define byGPIO ioaddr + 0x76
00103 #define byCFGA ioaddr + 0x78
00104 #define byCFGB ioaddr + 0x79
00105 #define byCFGC ioaddr + 0x7a
00106 #define byCFGD ioaddr + 0x7b
00107 #define wTallyCntMPA ioaddr + 0x7c
00108 #define wTallyCntCRC ioaddr + 0x7d
00109 #define bySTICKHW ioaddr + 0x83
00110 #define byWOLcrClr ioaddr + 0xA4
00111 #define byWOLcgClr ioaddr + 0xA7
00112 #define byPwrcsrClr ioaddr + 0xAC
00113
00114
00115
00116
00117
00118
00119
00120 #define RCR_RRFT2 0x80
00121 #define RCR_RRFT1 0x40
00122 #define RCR_RRFT0 0x20
00123 #define RCR_PROM 0x10
00124 #define RCR_AB 0x08
00125 #define RCR_AM 0x04
00126 #define RCR_AR 0x02
00127 #define RCR_SEP 0x01
00128
00129
00130
00131
00132
00133 #define TCR_RTSF 0x80
00134 #define TCR_RTFT1 0x40
00135 #define TCR_RTFT0 0x20
00136 #define TCR_OFSET 0x08
00137 #define TCR_LB1 0x04
00138 #define TCR_LB0 0x02
00139
00140
00141
00142
00143
00144 #define CR0_RDMD 0x40
00145 #define CR0_TDMD 0x20
00146 #define CR0_TXON 0x10
00147 #define CR0_RXON 0x08
00148 #define CR0_STOP 0x04
00149 #define CR0_STRT 0x02
00150 #define CR0_INIT 0x01
00151
00152
00153
00154
00155
00156
00157 #define CR1_SFRST 0x80
00158 #define CR1_RDMD1 0x40
00159 #define CR1_TDMD1 0x20
00160 #define CR1_KEYPAG 0x10
00161 #define CR1_DPOLL 0x08
00162 #define CR1_FDX 0x04
00163 #define CR1_ETEN 0x02
00164 #define CR1_EREN 0x01
00165
00166
00167
00168
00169
00170 #define CR_RDMD 0x0040
00171 #define CR_TDMD 0x0020
00172 #define CR_TXON 0x0010
00173 #define CR_RXON 0x0008
00174 #define CR_STOP 0x0004
00175 #define CR_STRT 0x0002
00176 #define CR_INIT 0x0001
00177 #define CR_SFRST 0x8000
00178 #define CR_RDMD1 0x4000
00179 #define CR_TDMD1 0x2000
00180 #define CR_KEYPAG 0x1000
00181 #define CR_DPOLL 0x0800
00182 #define CR_FDX 0x0400
00183 #define CR_ETEN 0x0200
00184 #define CR_EREN 0x0100
00185
00186
00187
00188
00189
00190 #define IMR0_CNTM 0x80
00191 #define IMR0_BEM 0x40
00192 #define IMR0_RUM 0x20
00193 #define IMR0_TUM 0x10
00194 #define IMR0_TXEM 0x08
00195 #define IMR0_RXEM 0x04
00196 #define IMR0_PTXM 0x02
00197 #define IMR0_PRXM 0x01
00198
00199
00200
00201 #define IMRShadow 0x5AFF
00202
00203
00204
00205
00206
00207 #define IMR1_INITM 0x80
00208 #define IMR1_SRCM 0x40
00209 #define IMR1_NBFM 0x10
00210 #define IMR1_PRAIM 0x08
00211 #define IMR1_RES0M 0x04
00212 #define IMR1_ETM 0x02
00213 #define IMR1_ERM 0x01
00214
00215
00216
00217
00218
00219 #define ISR_INITI 0x8000
00220 #define ISR_SRCI 0x4000
00221 #define ISR_ABTI 0x2000
00222 #define ISR_NORBF 0x1000
00223 #define ISR_PKTRA 0x0800
00224 #define ISR_RES0 0x0400
00225 #define ISR_ETI 0x0200
00226 #define ISR_ERI 0x0100
00227 #define ISR_CNT 0x0080
00228 #define ISR_BE 0x0040
00229 #define ISR_RU 0x0020
00230 #define ISR_TU 0x0010
00231 #define ISR_TXE 0x0008
00232 #define ISR_RXE 0x0004
00233 #define ISR_PTX 0x0002
00234 #define ISR_PRX 0x0001
00235
00236
00237
00238
00239
00240 #define ISR0_CNT 0x80
00241 #define ISR0_BE 0x40
00242 #define ISR0_RU 0x20
00243 #define ISR0_TU 0x10
00244 #define ISR0_TXE 0x08
00245 #define ISR0_RXE 0x04
00246 #define ISR0_PTX 0x02
00247 #define ISR0_PRX 0x01
00248
00249
00250
00251
00252
00253 #define ISR1_INITI 0x80
00254 #define ISR1_SRCI 0x40
00255 #define ISR1_NORBF 0x10
00256 #define ISR1_PKTRA 0x08
00257 #define ISR1_ETI 0x02
00258 #define ISR1_ERI 0x01
00259
00260
00261
00262 #define ISR_ABNORMAL ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
00263
00264
00265
00266
00267
00268 #define MIISR_MIIERR 0x08
00269 #define MIISR_MRERR 0x04
00270 #define MIISR_LNKFL 0x02
00271 #define MIISR_SPEED 0x01
00272
00273
00274
00275
00276
00277 #define MIICR_MAUTO 0x80
00278 #define MIICR_RCMD 0x40
00279 #define MIICR_WCMD 0x20
00280 #define MIICR_MDPM 0x10
00281 #define MIICR_MOUT 0x08
00282 #define MIICR_MDO 0x04
00283 #define MIICR_MDI 0x02
00284 #define MIICR_MDC 0x01
00285
00286
00287
00288
00289
00290 #define EECSR_EEPR 0x80
00291 #define EECSR_EMBP 0x40
00292 #define EECSR_AUTOLD 0x20
00293 #define EECSR_DPM 0x10
00294 #define EECSR_CS 0x08
00295 #define EECSR_SK 0x04
00296 #define EECSR_DI 0x02
00297 #define EECSR_DO 0x01
00298
00299
00300
00301
00302
00303 #define BCR0_CRFT2 0x20
00304 #define BCR0_CRFT1 0x10
00305 #define BCR0_CRFT0 0x08
00306 #define BCR0_DMAL2 0x04
00307 #define BCR0_DMAL1 0x02
00308 #define BCR0_DMAL0 0x01
00309
00310
00311
00312
00313
00314 #define BCR1_CTSF 0x20
00315 #define BCR1_CTFT1 0x10
00316 #define BCR1_CTFT0 0x08
00317 #define BCR1_POT2 0x04
00318 #define BCR1_POT1 0x02
00319 #define BCR1_POT0 0x01
00320
00321
00322
00323
00324
00325 #define CFGA_EELOAD 0x80
00326 #define CFGA_JUMPER 0x40
00327 #define CFGA_MTGPIO 0x08
00328 #define CFGA_T10EN 0x02
00329 #define CFGA_AUTO 0x01
00330
00331
00332
00333
00334
00335 #define CFGB_PD 0x80
00336 #define CFGB_POLEN 0x02
00337 #define CFGB_LNKEN 0x01
00338
00339
00340
00341
00342
00343 #define CFGC_M10TIO 0x80
00344 #define CFGC_M10POL 0x40
00345 #define CFGC_PHY1 0x20
00346 #define CFGC_PHY0 0x10
00347 #define CFGC_BTSEL 0x08
00348 #define CFGC_BPS2 0x04
00349 #define CFGC_BPS1 0x02
00350 #define CFGC_BPS0 0x01
00351
00352
00353
00354
00355
00356 #define CFGD_GPIOEN 0x80
00357 #define CFGD_DIAG 0x40
00358 #define CFGD_MAGIC 0x10
00359 #define CFGD_RANDOM 0x08
00360 #define CFGD_CFDX 0x04
00361 #define CFGD_CEREN 0x02
00362 #define CFGD_CETEN 0x01
00363
00364
00365 #define RSR_RERR 0x00000001
00366 #define RSR_CRC 0x00000002
00367 #define RSR_FAE 0x00000004
00368 #define RSR_FOV 0x00000008
00369 #define RSR_LONG 0x00000010
00370 #define RSR_RUNT 0x00000020
00371 #define RSR_SERR 0x00000040
00372 #define RSR_BUFF 0x00000080
00373 #define RSR_EDP 0x00000100
00374 #define RSR_STP 0x00000200
00375 #define RSR_CHN 0x00000400
00376 #define RSR_PHY 0x00000800
00377 #define RSR_BAR 0x00001000
00378 #define RSR_MAR 0x00002000
00379 #define RSR_RXOK 0x00008000
00380 #define RSR_ABNORMAL RSR_RERR+RSR_LONG+RSR_RUNT
00381
00382
00383 #define TSR_NCR0 0x00000001
00384 #define TSR_NCR1 0x00000002
00385 #define TSR_NCR2 0x00000004
00386 #define TSR_NCR3 0x00000008
00387 #define TSR_COLS 0x00000010
00388 #define TSR_CDH 0x00000080
00389 #define TSR_ABT 0x00000100
00390 #define TSR_OWC 0x00000200
00391 #define TSR_CRS 0x00000400
00392 #define TSR_UDF 0x00000800
00393 #define TSR_TBUFF 0x00001000
00394 #define TSR_SERR 0x00002000
00395 #define TSR_JAB 0x00004000
00396 #define TSR_TERR 0x00008000
00397 #define TSR_ABNORMAL TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
00398 #define TSR_OWN_BIT 0x80000000
00399
00400 #define CB_DELAY_LOOP_WAIT 10
00401
00402
00403 #define W_IMR_MASK_VALUE 0x1BFF
00404
00405
00406 #define PKT_TYPE_DIRECTED 0x0001
00407 #define PKT_TYPE_MULTICAST 0x0002
00408 #define PKT_TYPE_ALL_MULTICAST 0x0004
00409 #define PKT_TYPE_BROADCAST 0x0008
00410 #define PKT_TYPE_PROMISCUOUS 0x0020
00411 #define PKT_TYPE_LONG 0x2000
00412 #define PKT_TYPE_RUNT 0x4000
00413 #define PKT_TYPE_ERROR 0x8000
00414
00415
00416
00417 #define NIC_LB_NONE 0x00
00418 #define NIC_LB_INTERNAL 0x01
00419 #define NIC_LB_PHY 0x02
00420
00421 #define TX_RING_SIZE 2
00422 #define RX_RING_SIZE 2
00423 #define PKT_BUF_SZ 1536
00424
00425 #define PCI_REG_MODE3 0x53
00426 #define MODE3_MIION 0x04
00427
00428 enum rhine_revs {
00429 VT86C100A = 0x00,
00430 VTunknown0 = 0x20,
00431 VT6102 = 0x40,
00432 VT8231 = 0x50,
00433 VT8233 = 0x60,
00434 VT8235 = 0x74,
00435 VT8237 = 0x78,
00436 VTunknown1 = 0x7C,
00437 VT6105 = 0x80,
00438 VT6105_B0 = 0x83,
00439 VT6105L = 0x8A,
00440 VT6107 = 0x8C,
00441 VTunknown2 = 0x8E,
00442 VT6105M = 0x90,
00443 };
00444
00445
00446
00447 struct rhine_tx_desc
00448 {
00449 union VTC_tx_status_tag
00450 {
00451 struct
00452 {
00453 unsigned long ncro:1;
00454 unsigned long ncr1:1;
00455 unsigned long ncr2:1;
00456 unsigned long ncr3:1;
00457 unsigned long cols:1;
00458 unsigned long reserve_1:2;
00459 unsigned long cdh:1;
00460 unsigned long abt:1;
00461 unsigned long owc:1;
00462 unsigned long crs:1;
00463 unsigned long udf:1;
00464 unsigned long tbuff:1;
00465 unsigned long serr:1;
00466 unsigned long jab:1;
00467 unsigned long terr:1;
00468 unsigned long reserve_2:15;
00469 unsigned long own_bit:1;
00470 }
00471 bits;
00472 unsigned long lw;
00473 }
00474 tx_status;
00475
00476 union VTC_tx_ctrl_tag
00477 {
00478 struct
00479 {
00480 unsigned long tx_buf_size:11;
00481 unsigned long extend_tx_buf_size:4;
00482 unsigned long chn:1;
00483 unsigned long crc:1;
00484 unsigned long reserve_1:4;
00485 unsigned long stp:1;
00486 unsigned long edp:1;
00487 unsigned long ic:1;
00488 unsigned long reserve_2:8;
00489 }
00490 bits;
00491 unsigned long lw;
00492 }
00493 tx_ctrl;
00494
00495 unsigned long buf_addr_1:32;
00496 unsigned long buf_addr_2:32;
00497
00498 };
00499
00500 struct rhine_rx_desc
00501 {
00502 union VTC_rx_status_tag
00503 {
00504 struct
00505 {
00506 unsigned long rerr:1;
00507 unsigned long crc_error:1;
00508 unsigned long fae:1;
00509 unsigned long fov:1;
00510 unsigned long toolong:1;
00511 unsigned long runt:1;
00512 unsigned long serr:1;
00513 unsigned long buff:1;
00514 unsigned long edp:1;
00515 unsigned long stp:1;
00516 unsigned long chn:1;
00517 unsigned long phy:1;
00518 unsigned long bar:1;
00519 unsigned long mar:1;
00520 unsigned long reserve_1:1;
00521 unsigned long rxok:1;
00522 unsigned long frame_length:11;
00523 unsigned long reverve_2:4;
00524 unsigned long own_bit:1;
00525 }
00526 bits;
00527 unsigned long lw;
00528 }
00529 rx_status;
00530
00531 union VTC_rx_ctrl_tag
00532 {
00533 struct
00534 {
00535 unsigned long rx_buf_size:11;
00536 unsigned long extend_rx_buf_size:4;
00537 unsigned long reserved_1:17;
00538 }
00539 bits;
00540 unsigned long lw;
00541 }
00542 rx_ctrl;
00543
00544 unsigned long buf_addr_1:32;
00545 unsigned long buf_addr_2:32;
00546
00547 };
00548
00549 struct {
00550 char txbuf[TX_RING_SIZE * PKT_BUF_SZ + 32];
00551 char rxbuf[RX_RING_SIZE * PKT_BUF_SZ + 32];
00552 char txdesc[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
00553 char rxdesc[RX_RING_SIZE * sizeof (struct rhine_rx_desc) + 32];
00554 } rhine_buffers __shared;
00555
00556
00557 #define rhine_TOTAL_SIZE 0x80
00558
00559 #ifdef HAVE_DEVLIST
00560 struct netdev_entry rhine_drv =
00561 { "rhine", rhine_probe, rhine_TOTAL_SIZE, NULL };
00562 #endif
00563
00564 static int rhine_debug = 1;
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 #define NUM_TX_DESC 2
00657
00658 static struct rhine_private
00659 {
00660 char devname[8];
00661 const char *product_name;
00662 struct rhine_rx_desc *rx_ring;
00663 struct rhine_tx_desc *tx_ring;
00664 char *rx_buffs[RX_RING_SIZE];
00665 char *tx_buffs[TX_RING_SIZE];
00666
00667
00668
00669 int chip_id;
00670 int chip_revision;
00671 unsigned short ioaddr;
00672 unsigned int cur_rx, cur_tx;
00673 unsigned int dirty_rx, dirty_tx;
00674
00675 struct sk_buff *tx_skbuff[TX_RING_SIZE];
00676 unsigned char mc_filter[8];
00677 char phys[4];
00678 unsigned int tx_full:1;
00679 unsigned int full_duplex:1;
00680 unsigned int default_port:4;
00681 unsigned int media2:4;
00682 unsigned int medialock:1;
00683 unsigned int mediasense:1;
00684 }
00685 rhine;
00686
00687 static void rhine_probe1 (struct nic *nic, struct pci_device *pci, int ioaddr,
00688 int chip_id, int options);
00689 static int QueryAuto (int);
00690 static int ReadMII (int byMIIIndex, int);
00691 static void WriteMII (char, char, char, int);
00692 static void MIIDelay (void);
00693 static void rhine_init_ring (struct nic *dev);
00694 static void rhine_disable (struct nic *nic);
00695 static void rhine_reset (struct nic *nic);
00696 static int rhine_poll (struct nic *nic, int retreive);
00697 static void rhine_transmit (struct nic *nic, const char *d, unsigned int t,
00698 unsigned int s, const char *p);
00699 static void reload_eeprom(int ioaddr);
00700
00701
00702 static void reload_eeprom(int ioaddr)
00703 {
00704 int i;
00705 outb(0x20, byEECSR);
00706
00707 for (i = 0; i < 150; i++)
00708 if (! (inb(byEECSR) & 0x20))
00709 break;
00710 }
00711
00712 static void
00713 rhine_init_ring (struct nic *nic)
00714 {
00715 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
00716 int i;
00717
00718 tp->tx_full = 0;
00719 tp->cur_rx = tp->cur_tx = 0;
00720 tp->dirty_rx = tp->dirty_tx = 0;
00721
00722 for (i = 0; i < RX_RING_SIZE; i++)
00723 {
00724
00725 tp->rx_ring[i].rx_status.bits.own_bit = 1;
00726 tp->rx_ring[i].rx_ctrl.bits.rx_buf_size = 1536;
00727
00728 tp->rx_ring[i].buf_addr_1 = virt_to_bus (tp->rx_buffs[i]);
00729 tp->rx_ring[i].buf_addr_2 = virt_to_bus (&tp->rx_ring[i + 1]);
00730
00731 }
00732
00733
00734 tp->rx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->rx_ring[0]);
00735
00736
00737
00738
00739
00740 for (i = 0; i < TX_RING_SIZE; i++)
00741 {
00742
00743 tp->tx_ring[i].tx_status.lw = 0;
00744 tp->tx_ring[i].tx_ctrl.lw = 0x00e08000;
00745 tp->tx_ring[i].buf_addr_1 = virt_to_bus (tp->tx_buffs[i]);
00746 tp->tx_ring[i].buf_addr_2 = virt_to_bus (&tp->tx_ring[i + 1]);
00747
00748 }
00749
00750 tp->tx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->tx_ring[0]);
00751
00752 }
00753
00754 int
00755 QueryAuto (int ioaddr)
00756 {
00757 int byMIIIndex;
00758 int MIIReturn;
00759
00760 int advertising,mii_reg5;
00761 int negociated;
00762
00763 byMIIIndex = 0x04;
00764 MIIReturn = ReadMII (byMIIIndex, ioaddr);
00765 advertising=MIIReturn;
00766
00767 byMIIIndex = 0x05;
00768 MIIReturn = ReadMII (byMIIIndex, ioaddr);
00769 mii_reg5=MIIReturn;
00770
00771 negociated=mii_reg5 & advertising;
00772
00773 if ( (negociated & 0x100) || (negociated & 0x1C0) == 0x40 )
00774 return 1;
00775 else
00776 return 0;
00777
00778 }
00779
00780 int
00781 ReadMII (int byMIIIndex, int ioaddr)
00782 {
00783 int ReturnMII;
00784 char byMIIAdrbak;
00785 char byMIICRbak;
00786 char byMIItemp;
00787 unsigned long ct;
00788
00789 byMIIAdrbak = inb (byMIIAD);
00790 byMIICRbak = inb (byMIICR);
00791 outb (byMIICRbak & 0x7f, byMIICR);
00792 MIIDelay ();
00793
00794 outb (byMIIIndex, byMIIAD);
00795 MIIDelay ();
00796
00797 outb (inb (byMIICR) | 0x40, byMIICR);
00798
00799 byMIItemp = inb (byMIICR);
00800 byMIItemp = byMIItemp & 0x40;
00801
00802 ct = currticks();
00803 while (byMIItemp != 0 && ct + 2*1000 < currticks())
00804 {
00805 byMIItemp = inb (byMIICR);
00806 byMIItemp = byMIItemp & 0x40;
00807 }
00808 MIIDelay ();
00809
00810 ReturnMII = inw (wMIIDATA);
00811
00812 outb (byMIIAdrbak, byMIIAD);
00813 outb (byMIICRbak, byMIICR);
00814 MIIDelay ();
00815
00816 return (ReturnMII);
00817
00818 }
00819
00820 void
00821 WriteMII (char byMIISetByte, char byMIISetBit, char byMIIOP, int ioaddr)
00822 {
00823 int ReadMIItmp;
00824 int MIIMask;
00825 char byMIIAdrbak;
00826 char byMIICRbak;
00827 char byMIItemp;
00828 unsigned long ct;
00829
00830
00831 byMIIAdrbak = inb (byMIIAD);
00832
00833 byMIICRbak = inb (byMIICR);
00834 outb (byMIICRbak & 0x7f, byMIICR);
00835 MIIDelay ();
00836 outb (byMIISetByte, byMIIAD);
00837 MIIDelay ();
00838
00839 outb (inb (byMIICR) | 0x40, byMIICR);
00840
00841 byMIItemp = inb (byMIICR);
00842 byMIItemp = byMIItemp & 0x40;
00843
00844 ct = currticks();
00845 while (byMIItemp != 0 && ct + 2*1000 < currticks())
00846 {
00847 byMIItemp = inb (byMIICR);
00848 byMIItemp = byMIItemp & 0x40;
00849 }
00850 MIIDelay ();
00851
00852 ReadMIItmp = inw (wMIIDATA);
00853 MIIMask = 0x0001;
00854 MIIMask = MIIMask << byMIISetBit;
00855
00856
00857 if (byMIIOP == 0)
00858 {
00859 MIIMask = ~MIIMask;
00860 ReadMIItmp = ReadMIItmp & MIIMask;
00861 }
00862 else
00863 {
00864 ReadMIItmp = ReadMIItmp | MIIMask;
00865
00866 }
00867 outw (ReadMIItmp, wMIIDATA);
00868 MIIDelay ();
00869
00870 outb (inb (byMIICR) | 0x20, byMIICR);
00871 byMIItemp = inb (byMIICR);
00872 byMIItemp = byMIItemp & 0x20;
00873
00874 ct = currticks();
00875 while (byMIItemp != 0 && ct + 2*1000 < currticks())
00876 {
00877 byMIItemp = inb (byMIICR);
00878 byMIItemp = byMIItemp & 0x20;
00879 }
00880 MIIDelay ();
00881
00882 outb (byMIIAdrbak & 0x7f, byMIIAD);
00883 outb (byMIICRbak, byMIICR);
00884 MIIDelay ();
00885
00886 }
00887
00888 void
00889 MIIDelay (void)
00890 {
00891 int i;
00892 for (i = 0; i < 0x7fff; i++)
00893 {
00894 ( void ) inb (0x61);
00895 ( void ) inb (0x61);
00896 ( void ) inb (0x61);
00897 ( void ) inb (0x61);
00898 }
00899 }
00900
00901
00902 enum register_offsets {
00903 StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
00904 IntrStatus=0x0C, IntrEnable=0x0E,
00905 MulticastFilter0=0x10, MulticastFilter1=0x14,
00906 RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
00907 MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
00908 MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
00909 ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
00910 RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
00911 StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
00912 PwrcsrClr=0xAC,
00913 };
00914
00915
00916 enum intr_status_bits {
00917 IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
00918 IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0210,
00919 IntrPCIErr=0x0040,
00920 IntrStatsMax=0x0080, IntrRxEarly=0x0100,
00921 IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
00922 IntrTxAborted=0x2000, IntrLinkChange=0x4000,
00923 IntrRxWakeUp=0x8000,
00924 IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
00925 IntrTxDescRace=0x080000,
00926 IntrTxErrSummary=0x082218,
00927 };
00928 #define DEFAULT_INTR (IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | \
00929 IntrRxDropped | IntrRxNoBuf)
00930
00931
00932
00933
00934 void rhine_irq ( struct nic *nic, irq_action_t action ) {
00935 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
00936
00937 unsigned int intr_status;
00938
00939 switch ( action ) {
00940 case DISABLE :
00941 case ENABLE :
00942 intr_status = inw(nic->ioaddr + IntrStatus);
00943
00944
00945
00946
00947
00948 if( tp->chip_revision < 0x80 && tp->chip_revision >=0x40 )
00949 intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
00950 intr_status = (intr_status & ~DEFAULT_INTR);
00951 if ( action == ENABLE )
00952 intr_status = intr_status | DEFAULT_INTR;
00953 outw(intr_status, nic->ioaddr + IntrEnable);
00954 break;
00955 case FORCE :
00956 outw(0x0010, nic->ioaddr + 0x84);
00957 break;
00958 }
00959 }
00960
00961 static struct nic_operations rhine_operations;
00962
00963 static int
00964 rhine_probe ( struct nic *nic, struct pci_device *pci ) {
00965
00966 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
00967
00968 if (!pci->ioaddr)
00969 return 0;
00970
00971 rhine_probe1 (nic, pci, pci->ioaddr, pci->device, -1);
00972
00973 adjust_pci_device ( pci );
00974
00975 rhine_reset (nic);
00976
00977 nic->nic_op = &rhine_operations;
00978
00979 nic->irqno = pci->irq;
00980 nic->ioaddr = tp->ioaddr;
00981
00982 return 1;
00983 }
00984
00985 static void set_rx_mode(struct nic *nic __unused) {
00986 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
00987 unsigned char rx_mode;
00988 int ioaddr = tp->ioaddr;
00989
00990
00991 outl(0xffffffff, byMAR0);
00992 outl(0xffffffff, byMAR4);
00993 rx_mode = 0x0C;
00994
00995 outb(0x60 | rx_mode, byRCR );
00996 }
00997
00998 static void
00999 rhine_probe1 (struct nic *nic, struct pci_device *pci, int ioaddr, int chip_id, int options)
01000 {
01001 struct rhine_private *tp;
01002 static int did_version = 0;
01003 unsigned int i, ww;
01004 unsigned int timeout;
01005 int FDXFlag;
01006 int byMIIvalue, LineSpeed, MIICRbak;
01007 uint8_t revision_id;
01008 unsigned char mode3_reg;
01009
01010 if (rhine_debug > 0 && did_version++ == 0)
01011 printf ("%s",version);
01012
01013
01014 pci_read_config_byte(pci, PCI_REVISION, &revision_id);
01015
01016
01017 if (revision_id >= 0x40) {
01018 unsigned char byOrgValue;
01019
01020 if(rhine_debug > 0)
01021 printf("Enabling Sticky Bit Workaround for Chip_id: 0x%hX\n"
01022 , chip_id);
01023
01024 byOrgValue = inb(bySTICKHW);
01025 byOrgValue = byOrgValue & 0xFC;
01026 outb(byOrgValue, bySTICKHW);
01027
01028
01029
01030 outb(0x80, byWOLcgClr);
01031
01032 outb(0xFF, byWOLcrClr);
01033
01034 outb(0xFF, byPwrcsrClr);
01035
01036 }
01037
01038
01039 outw(CR_SFRST, byCR0);
01040
01041 if (revision_id <0x40) {
01042 udelay(10000);
01043 }
01044
01045
01046 for(ww = 0; ww < W_MAX_TIMEOUT; ww++) {
01047 if ((inw(byCR0) & CR_SFRST) == 0)
01048 break;
01049 }
01050
01051
01052 outb(0x20, byEECSR );
01053
01054
01055 if (revision_id >=0x40) {
01056
01057 mdelay(8);
01058
01059
01060
01061
01062
01063 outb(inb(byCFGA) & 0xFE, byCFGA);
01064 }
01065
01066
01067 if (revision_id >= 0x40) {
01068 pci_read_config_byte(pci, PCI_REG_MODE3, &mode3_reg);
01069 pci_write_config_byte(pci, PCI_REG_MODE3, mode3_reg|MODE3_MIION);
01070 }
01071
01072
01073
01074 outb(inb(byCFGD) & (~(CFGD_RANDOM | CFGD_CFDX | CFGD_CEREN | CFGD_CETEN)), byCFGD);
01075
01076
01077 reload_eeprom(ioaddr);
01078
01079
01080 for (i = 0; i < ETH_ALEN; i++)
01081 nic->node_addr[i] = inb (byPAR0 + i);
01082
01083 DBG ( "IO address %#hX Ethernet Address: %s\n", ioaddr, eth_ntoa ( nic->node_addr ) );
01084
01085
01086 WriteMII (0, 9, 1, ioaddr);
01087 printf ("Analyzing Media type,this may take several seconds... ");
01088 for (i = 0; i < 5; i++)
01089 {
01090
01091 timeout = currticks() + 2;
01092 for (timeout = currticks() + 2; currticks() < timeout;)
01093 ;
01094 if (ReadMII (1, ioaddr) & 0x0020)
01095 break;
01096 }
01097 printf ("OK.\n");
01098
01099 #if 0
01100
01101 printf("MII : Address %hhX ",inb(ioaddr+0x6c));
01102 {
01103 unsigned char st1,st2,adv1,adv2,l1,l2;
01104
01105 st1=ReadMII(1,ioaddr)>>8;
01106 st2=ReadMII(1,ioaddr)&0xFF;
01107 adv1=ReadMII(4,ioaddr)>>8;
01108 adv2=ReadMII(4,ioaddr)&0xFF;
01109 l1=ReadMII(5,ioaddr)>>8;
01110 l2=ReadMII(5,ioaddr)&0xFF;
01111 printf(" status 0x%hhX%hhX, advertising 0x%hhX%hhX, link 0x%hhX%hhX\n", st1,st2,adv1,adv2,l1,l2);
01112 }
01113 #endif
01114
01115
01116
01117 byMIIvalue = inb (ioaddr + 0x6d);
01118 LineSpeed = byMIIvalue & MIISR_SPEED;
01119 if (LineSpeed != 0)
01120 {
01121 printf ("Linespeed=10Mbs");
01122 }
01123 else
01124 {
01125 printf ("Linespeed=100Mbs");
01126 }
01127
01128 FDXFlag = QueryAuto (ioaddr);
01129 if (FDXFlag == 1)
01130 {
01131 printf (" Fullduplex\n");
01132 outw (CR_FDX, byCR0);
01133 }
01134 else
01135 {
01136 printf (" Halfduplex\n");
01137 }
01138
01139
01140
01141 if(chip_id == 0x3043)
01142 WriteMII (0x17, 1, 1, ioaddr);
01143
01144
01145 MIICRbak = inb (byMIICR);
01146 outb (MIICRbak & 0x7F, byMIICR);
01147 MIIDelay ();
01148 outb (0x41, byMIIAD);
01149 MIIDelay ();
01150
01151
01152 outb (MIICRbak | 0x80, byMIICR);
01153
01154 nic->priv_data = &rhine;
01155 tp = &rhine;
01156 tp->chip_id = chip_id;
01157 tp->ioaddr = ioaddr;
01158 tp->phys[0] = -1;
01159 tp->chip_revision = revision_id;
01160
01161
01162 if (options > 0)
01163 {
01164 tp->full_duplex = (options & 16) ? 1 : 0;
01165 tp->default_port = options & 15;
01166 if (tp->default_port)
01167 tp->medialock = 1;
01168 }
01169 return;
01170 }
01171
01172 static void
01173 rhine_disable ( struct nic *nic ) {
01174
01175 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
01176 int ioaddr = tp->ioaddr;
01177
01178 rhine_reset(nic);
01179
01180 printf ("rhine disable\n");
01181
01182 outb(0x60 | 0x01, byTCR);
01183
01184 outw(CR_STOP, byCR0);
01185 }
01186
01187
01188
01189
01190 static void
01191 rhine_reset (struct nic *nic)
01192 {
01193 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
01194 int ioaddr = tp->ioaddr;
01195 int i, j;
01196 int FDXFlag, CRbak;
01197 void *rx_ring_tmp;
01198 void *tx_ring_tmp;
01199 void *rx_bufs_tmp;
01200 void *tx_bufs_tmp;
01201 unsigned long rx_ring_tmp1;
01202 unsigned long tx_ring_tmp1;
01203 unsigned long rx_bufs_tmp1;
01204 unsigned long tx_bufs_tmp1;
01205
01206
01207
01208
01209
01210 tx_bufs_tmp = rhine_buffers.txbuf;
01211 tx_ring_tmp = rhine_buffers.txdesc;
01212 rx_bufs_tmp = rhine_buffers.rxbuf;
01213 rx_ring_tmp = rhine_buffers.rxdesc;
01214
01215
01216 rx_ring_tmp1 = virt_to_bus ( rx_ring_tmp );
01217 j = (rx_ring_tmp1 + 32) & (~0x1f);
01218
01219 tp->rx_ring = (struct rhine_rx_desc *) bus_to_virt (j);
01220
01221 tx_ring_tmp1 = virt_to_bus ( tx_ring_tmp );
01222 j = (tx_ring_tmp1 + 32) & (~0x1f);
01223 tp->tx_ring = (struct rhine_tx_desc *) bus_to_virt (j);
01224
01225
01226
01227 tx_bufs_tmp1 = virt_to_bus ( tx_bufs_tmp );
01228 j = (int) (tx_bufs_tmp1 + 32) & (~0x1f);
01229 tx_bufs_tmp = bus_to_virt (j);
01230
01231
01232 rx_bufs_tmp1 = virt_to_bus ( rx_bufs_tmp );
01233 j = (int) (rx_bufs_tmp1 + 32) & (~0x1f);
01234 rx_bufs_tmp = bus_to_virt (j);
01235
01236
01237 for (i = 0; i < RX_RING_SIZE; i++)
01238 {
01239 tp->rx_buffs[i] = (char *) rx_bufs_tmp;
01240
01241 rx_bufs_tmp += 1536;
01242 }
01243
01244 for (i = 0; i < TX_RING_SIZE; i++)
01245 {
01246 tp->tx_buffs[i] = (char *) tx_bufs_tmp;
01247
01248 tx_bufs_tmp += 1536;
01249 }
01250
01251
01252 outb (CR1_SFRST, byCR1);
01253 MIIDelay ();
01254
01255
01256 rhine_init_ring (nic);
01257
01258 outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
01259 outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);
01260
01261
01262 set_rx_mode(nic);
01263
01264
01265 outb (0x3e, byBCR0);
01266 outb (0x38, byBCR1);
01267 outb (0x2c, byRCR);
01268 outb (0x60, byTCR);
01269
01270 FDXFlag = QueryAuto (ioaddr);
01271 if (FDXFlag == 1)
01272 {
01273 outb (CFGD_CFDX, byCFGD);
01274 outw (CR_FDX, byCR0);
01275 }
01276
01277
01278 CRbak = inw (byCR0);
01279 CRbak = CRbak & 0xFFFB;
01280 outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);
01281
01282
01283 outw (0, byIMR0);
01284 }
01285
01286 #define IOSYNC do { inb(nic->ioaddr + StationAddr); } while (0)
01287
01288 static int
01289 rhine_poll (struct nic *nic, int retreive)
01290 {
01291 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
01292 int rxstatus, good = 0;;
01293
01294 if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)
01295 {
01296 unsigned int intr_status;
01297
01298 if(!retreive)
01299 return 1;
01300
01301 intr_status = inw(nic->ioaddr + IntrStatus);
01302
01303 #if 0
01304 if (tp->chip_id == 0x3065)
01305 intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
01306 #endif
01307
01308 if (intr_status & IntrTxDescRace)
01309 outb(0x08, nic->ioaddr + IntrStatus2);
01310 outw(intr_status & 0xffff, nic->ioaddr + IntrStatus);
01311 IOSYNC;
01312
01313 rxstatus = tp->rx_ring[tp->cur_rx].rx_status.lw;
01314 if ((rxstatus & 0x0300) != 0x0300)
01315 {
01316 printf("rhine_poll: bad status\n");
01317 }
01318 else if (rxstatus & (RSR_ABNORMAL))
01319 {
01320 printf ("rxerr[%X]\n", rxstatus);
01321 }
01322 else
01323 good = 1;
01324
01325 if (good)
01326 {
01327 nic->packetlen = tp->rx_ring[tp->cur_rx].rx_status.bits.frame_length;
01328 memcpy (nic->packet, tp->rx_buffs[tp->cur_rx], nic->packetlen);
01329
01330 }
01331 tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit = 1;
01332 tp->cur_rx++;
01333 tp->cur_rx = tp->cur_rx % RX_RING_SIZE;
01334 }
01335
01336 outw(DEFAULT_INTR & ~IntrRxDone, nic->ioaddr + IntrStatus);
01337
01338 IOSYNC;
01339
01340 return good;
01341 }
01342
01343 static void
01344 rhine_transmit (struct nic *nic,
01345 const char *d, unsigned int t, unsigned int s, const char *p)
01346 {
01347 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
01348 int ioaddr = tp->ioaddr;
01349 int entry;
01350 unsigned char CR1bak;
01351 unsigned char CR0bak;
01352 unsigned int nstype;
01353 unsigned long ct;
01354
01355
01356
01357
01358
01359
01360
01361 entry = tp->cur_tx % TX_RING_SIZE;
01362
01363 memcpy (tp->tx_buffs[entry], d, ETH_ALEN);
01364 memcpy (tp->tx_buffs[entry] + ETH_ALEN, nic->node_addr, ETH_ALEN);
01365
01366 nstype=htons(t);
01367 memcpy(tp->tx_buffs[entry] + 2 * ETH_ALEN, (char*)&nstype, 2);
01368
01369 memcpy (tp->tx_buffs[entry] + ETH_HLEN, p, s);
01370 s += ETH_HLEN;
01371 while (s < ETH_ZLEN)
01372 *((char *) tp->tx_buffs[entry] + (s++)) = 0;
01373
01374 tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = s;
01375
01376 tp->tx_ring[entry].tx_status.bits.own_bit = 1;
01377
01378
01379 CR1bak = inb (byCR1);
01380
01381 CR1bak = CR1bak | CR1_TDMD1;
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391 outb (CR1bak, byCR1);
01392 do
01393 {
01394 ct = currticks();
01395
01396 while((tp->tx_ring[entry].tx_status.bits.own_bit !=0) &&
01397 ct + 10*1000 < currticks())
01398 ;
01399
01400 if(tp->tx_ring[entry].tx_status.bits.terr == 0)
01401 break;
01402
01403 if(tp->tx_ring[entry].tx_status.bits.abt == 1)
01404 {
01405
01406 CR0bak = inb(byCR0);
01407 CR0bak = CR0bak|CR_TXON;
01408 outb(CR0bak,byCR0);
01409 }
01410 }while(0);
01411 tp->cur_tx++;
01412
01413
01414
01415
01416 }
01417
01418 static struct nic_operations rhine_operations = {
01419 .connect = dummy_connect,
01420 .poll = rhine_poll,
01421 .transmit = rhine_transmit,
01422 .irq = rhine_irq,
01423
01424 };
01425
01426 static struct pci_device_id rhine_nics[] = {
01427 PCI_ROM(0x1106, 0x3065, "dlink-530tx", "VIA 6102", 0),
01428 PCI_ROM(0x1106, 0x3106, "via-rhine-6105", "VIA 6105", 0),
01429 PCI_ROM(0x1106, 0x3043, "dlink-530tx-old", "VIA 3043", 0),
01430 PCI_ROM(0x1106, 0x3053, "via6105m", "VIA 6105M", 0),
01431 PCI_ROM(0x1106, 0x6100, "via-rhine-old", "VIA 86C100A", 0),
01432 };
01433
01434 PCI_DRIVER ( rhine_driver, rhine_nics, PCI_NO_CLASS );
01435
01436 DRIVER ( "VIA 86C100", nic_driver, pci_driver, rhine_driver,
01437 rhine_probe, rhine_disable );
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447