via-rhine.c

Go to the documentation of this file.
00001 /* rhine.c:Fast Ethernet driver for Linux. */
00002 /*
00003         Adapted 09-jan-2000 by Paolo Marini (paolom@prisma-eng.it)
00004 
00005         originally written by Donald Becker.
00006 
00007         This software may be used and distributed according to the terms
00008         of the GNU Public License (GPL), incorporated herein by reference.
00009         Drivers derived from this code also fall under the GPL and must retain
00010         this authorship and copyright notice.
00011 
00012         Under no circumstances are the authors responsible for
00013         the proper functioning of this software, nor do the authors assume any
00014         responsibility for damages incurred with its use.
00015 
00016         This driver is designed for the VIA VT86C100A Rhine-II PCI Fast Ethernet
00017         controller.
00018 
00019 */
00020 
00021 static const char *version = "rhine.c v1.0.2 2004-10-29\n";
00022 
00023 /* A few user-configurable values. */
00024 
00025 // max time out delay time
00026 #define W_MAX_TIMEOUT   0x0FFFU
00027 
00028 /* Size of the in-memory receive ring. */
00029 #define RX_BUF_LEN_IDX  3       /* 0==8K, 1==16K, 2==32K, 3==64K */
00030 #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
00031 
00032 /* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
00033 #define TX_BUF_SIZE     1536
00034 #define RX_BUF_SIZE     1536
00035 
00036 /* PCI Tuning Parameters
00037    Threshold is bytes transferred to chip before transmission starts. */
00038 #define TX_FIFO_THRESH 256      /* In bytes, rounded down to 32 byte units. */
00039 
00040 /* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024. */
00041 #define RX_FIFO_THRESH  4       /* Rx buffer level before first PCI xfer.  */
00042 #define RX_DMA_BURST    4       /* Maximum PCI burst, '4' is 256 bytes */
00043 #define TX_DMA_BURST    4
00044 
00045 /* Operational parameters that usually are not changed. */
00046 /* Time in jiffies before concluding the transmitter is hung. */
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 /* define all ioaddr */
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 /*---------------------  Exioaddr Definitions -------------------------*/
00115 
00116 /*
00117  * Bits in the RCR register
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  * Bits in the TCR register
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    /* loopback[1] */
00138 #define TCR_LB0                 0x02    /* loopback[0] */
00139 
00140 /*
00141  * Bits in the CR0 register
00142  */
00143 
00144 #define CR0_RDMD                0x40    /* rx descriptor polling demand */
00145 #define CR0_TDMD                0x20    /* tx descriptor polling demand */
00146 #define CR0_TXON                0x10
00147 #define CR0_RXON                0x08
00148 #define CR0_STOP                0x04    /* stop NIC, default = 1 */
00149 #define CR0_STRT                0x02    /* start NIC */
00150 #define CR0_INIT                0x01    /* start init process */
00151 
00152 
00153 /*
00154  * Bits in the CR1 register
00155  */
00156 
00157 #define CR1_SFRST               0x80    /* software reset */
00158 #define CR1_RDMD1               0x40    /* RDMD1 */
00159 #define CR1_TDMD1               0x20    /* TDMD1 */
00160 #define CR1_KEYPAG              0x10    /* turn on par/key */
00161 #define CR1_DPOLL               0x08    /* disable rx/tx auto polling */
00162 #define CR1_FDX                 0x04    /* full duplex mode */
00163 #define CR1_ETEN                0x02    /* early tx mode */
00164 #define CR1_EREN                0x01    /* early rx mode */
00165 
00166 /*
00167  * Bits in the CR register
00168  */
00169 
00170 #define CR_RDMD                 0x0040  /* rx descriptor polling demand */
00171 #define CR_TDMD                 0x0020  /* tx descriptor polling demand */
00172 #define CR_TXON                 0x0010
00173 #define CR_RXON                 0x0008
00174 #define CR_STOP                 0x0004  /* stop NIC, default = 1 */
00175 #define CR_STRT                 0x0002  /* start NIC */
00176 #define CR_INIT                 0x0001  /* start init process */
00177 #define CR_SFRST                0x8000  /* software reset */
00178 #define CR_RDMD1                0x4000  /* RDMD1 */
00179 #define CR_TDMD1                0x2000  /* TDMD1 */
00180 #define CR_KEYPAG               0x1000  /* turn on par/key */
00181 #define CR_DPOLL                0x0800  /* disable rx/tx auto polling */
00182 #define CR_FDX                  0x0400  /* full duplex mode */
00183 #define CR_ETEN                 0x0200  /* early tx mode */
00184 #define CR_EREN                 0x0100  /* early rx mode */
00185 
00186 /*
00187  * Bits in the IMR0 register
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 /* define imrshadow */
00200 
00201 #define IMRShadow               0x5AFF
00202 
00203 /*
00204  * Bits in the IMR1 register
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  * Bits in the ISR register
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  * Bits in the ISR0 register
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  * Bits in the ISR1 register
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 /* ISR ABNORMAL CONDITION */
00261 
00262 #define ISR_ABNORMAL ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
00263 
00264 /*
00265  * Bits in the MIISR register
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  * Bits in the MIICR register
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  * Bits in the EECSR register
00288  */
00289 
00290 #define EECSR_EEPR              0x80    /* eeprom programed status, 73h means programed */
00291 #define EECSR_EMBP              0x40    /* eeprom embeded programming */
00292 #define EECSR_AUTOLD            0x20    /* eeprom content reload */
00293 #define EECSR_DPM               0x10    /* eeprom direct programming */
00294 #define EECSR_CS                0x08    /* eeprom CS pin */
00295 #define EECSR_SK                0x04    /* eeprom SK pin */
00296 #define EECSR_DI                0x02    /* eeprom DI pin */
00297 #define EECSR_DO                0x01    /* eeprom DO pin */
00298 
00299 /*
00300  * Bits in the BCR0 register
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  * Bits in the BCR1 register
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  * Bits in the CFGA register
00323  */
00324 
00325 #define CFGA_EELOAD             0x80    /* enable eeprom embeded and direct programming */
00326 #define CFGA_JUMPER             0x40
00327 #define CFGA_MTGPIO             0x08
00328 #define CFGA_T10EN              0x02
00329 #define CFGA_AUTO               0x01
00330 
00331 /*
00332  * Bits in the CFGB register
00333  */
00334 
00335 #define CFGB_PD                 0x80
00336 #define CFGB_POLEN              0x02
00337 #define CFGB_LNKEN              0x01
00338 
00339 /*
00340  * Bits in the CFGC register
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    /* bootrom select[2] */
00349 #define CFGC_BPS1               0x02    /* bootrom select[1] */
00350 #define CFGC_BPS0               0x01    /* bootrom select[0] */
00351 
00352 /*
00353  * Bits in the CFGD register
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 /* Bits in RSR */
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 /* Bits in TSR */
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      /* 10ms */
00401 /* enabled mask value of irq */
00402 
00403 #define W_IMR_MASK_VALUE        0x1BFF  /* initial value of IMR */
00404 
00405 /* Ethernet address filter type */
00406 #define PKT_TYPE_DIRECTED       0x0001  /* obsolete, directed address is always accepted */
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  /* accept error packets, e.g. CRC error */
00414 
00415 /* Loopback mode */
00416 
00417 #define NIC_LB_NONE             0x00
00418 #define NIC_LB_INTERNAL         0x01
00419 #define NIC_LB_PHY              0x02    /* MII or Internal-10BaseT loopback */
00420 
00421 #define TX_RING_SIZE            2
00422 #define RX_RING_SIZE            2
00423 #define PKT_BUF_SZ              1536    /* Size of each temporary Rx buffer. */
00424 
00425 #define PCI_REG_MODE3           0x53
00426 #define MODE3_MIION             0x04    /* in PCI_REG_MOD3 OF PCI space */
00427 
00428 enum rhine_revs {
00429     VT86C100A       = 0x00,
00430     VTunknown0      = 0x20,
00431     VT6102          = 0x40,
00432     VT8231          = 0x50, /* Integrated MAC */
00433     VT8233          = 0x60, /* Integrated MAC */
00434     VT8235          = 0x74, /* Integrated MAC */
00435     VT8237          = 0x78, /* Integrated MAC */
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 /* Transmit and receive descriptors definition */
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 /* The I/O extent. */
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                                 Theory of Operation
00568 
00569 I. Board Compatibility
00570 
00571 This driver is designed for the VIA 86c100A Rhine-II PCI Fast Ethernet
00572 controller.
00573 
00574 II. Board-specific settings
00575 
00576 Boards with this chip are functional only in a bus-master PCI slot.
00577 
00578 Many operational settings are loaded from the EEPROM to the Config word at
00579 offset 0x78.  This driver assumes that they are correct.
00580 If this driver is compiled to use PCI memory space operations the EEPROM
00581 must be configured to enable memory ops.
00582 
00583 III. Driver operation
00584 
00585 IIIa. Ring buffers
00586 
00587 This driver uses two statically allocated fixed-size descriptor lists
00588 formed into rings by a branch from the final descriptor to the beginning of
00589 the list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.
00590 
00591 IIIb/c. Transmit/Receive Structure
00592 
00593 This driver attempts to use a zero-copy receive and transmit scheme.
00594 
00595 Alas, all data buffers are required to start on a 32 bit boundary, so
00596 the driver must often copy transmit packets into bounce buffers.
00597 
00598 The driver allocates full frame size skbuffs for the Rx ring buffers at
00599 open() time and passes the skb->data field to the chip as receive data
00600 buffers.  When an incoming frame is less than RX_COPYBREAK bytes long,
00601 a fresh skbuff is allocated and the frame is copied to the new skbuff.
00602 When the incoming frame is larger, the skbuff is passed directly up the
00603 protocol stack.  Buffers consumed this way are replaced by newly allocated
00604 skbuffs in the last phase of netdev_rx().
00605 
00606 The RX_COPYBREAK value is chosen to trade-off the memory wasted by
00607 using a full-sized skbuff for small frames vs. the copying costs of larger
00608 frames.  New boards are typically used in generously configured machines
00609 and the underfilled buffers have negligible impact compared to the benefit of
00610 a single allocation size, so the default value of zero results in never
00611 copying packets.  When copying is done, the cost is usually mitigated by using
00612 a combined copy/checksum routine.  Copying also preloads the cache, which is
00613 most useful with small frames.
00614 
00615 Since the VIA chips are only able to transfer data to buffers on 32 bit
00616 boundaries, the the IP header at offset 14 in an ethernet frame isn't
00617 longword aligned for further processing.  Copying these unaligned buffers
00618 has the beneficial effect of 16-byte aligning the IP header.
00619 
00620 IIId. Synchronization
00621 
00622 The driver runs as two independent, single-threaded flows of control.  One
00623 is the send-packet routine, which enforces single-threaded use by the
00624 dev->tbusy flag.  The other thread is the interrupt handler, which is single
00625 threaded by the hardware and interrupt handling software.
00626 
00627 The send packet thread has partial control over the Tx ring and 'dev->tbusy'
00628 flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
00629 queue slot is empty, it clears the tbusy flag when finished otherwise it sets
00630 the 'lp->tx_full' flag.
00631 
00632 The interrupt handler has exclusive control over the Rx ring and records stats
00633 from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
00634 empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
00635 clears both the tx_full and tbusy flags.
00636 
00637 IV. Notes
00638 
00639 IVb. References
00640 
00641 Preliminary VT86C100A manual from http://www.via.com.tw/
00642 http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
00643 http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
00644 
00645 IVc. Errata
00646 
00647 The VT86C100A manual is not reliable information.
00648 The chip does not handle unaligned transmit or receive buffers, resulting
00649 in significant performance degradation for bounce buffer copies on transmit
00650 and unaligned IP headers on receive.
00651 The chip does not pad to minimum transmit length.
00652 
00653 */
00654 
00655 /* The rest of these values should never change. */
00656 #define NUM_TX_DESC     2       /* Number of Tx descriptor registers. */
00657 
00658 static struct rhine_private
00659 {
00660     char devname[8];            /* Used only for kernel debugging. */
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     /* temporary Rx buffers. */
00668 
00669     int chip_id;
00670     int chip_revision;
00671     unsigned short ioaddr;
00672     unsigned int cur_rx, cur_tx;        /* The next free and used entries */
00673     unsigned int dirty_rx, dirty_tx;
00674     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
00675     struct sk_buff *tx_skbuff[TX_RING_SIZE];
00676     unsigned char mc_filter[8]; /* Current multicast filter. */
00677     char phys[4];               /* MII device addresses. */
00678     unsigned int tx_full:1;     /* The Tx queue is full. */
00679     unsigned int full_duplex:1; /* Full-duplex operation requested. */
00680     unsigned int default_port:4;        /* Last dev->if_port value. */
00681     unsigned int media2:4;      /* Secondary monitored media port. */
00682     unsigned int medialock:1;   /* Don't sense media type. */
00683     unsigned int mediasense:1;  /* Media sensing in progress. */
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         /* Typically 2 cycles to reload. */
00707         for (i = 0; i < 150; i++)
00708                 if (! (inb(byEECSR) & 0x20))
00709                         break;
00710 }
00711 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
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         /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->rx_ring[i].buf_addr_1,tp->rx_ring[i].buf_addr_2); */
00731     }
00732     /* Mark the last entry as wrapping the ring. */
00733     /* tp->rx_ring[i-1].rx_ctrl.bits.rx_buf_size =1518; */
00734     tp->rx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->rx_ring[0]);
00735     /*printf("[%d]buf1=%hX,buf2=%hX",i-1,tp->rx_ring[i-1].buf_addr_1,tp->rx_ring[i-1].buf_addr_2); */
00736 
00737     /* The Tx buffer descriptor is filled in as needed, but we
00738        do need to clear the ownership bit. */
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         /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i].buf_addr_1,tp->tx_ring[i].buf_addr_2); */
00748     }
00749 
00750     tp->tx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->tx_ring[0]);
00751     /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i-1].buf_addr_1,tp->tx_ring[i-1].buf_addr_2); */
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 /* Offsets to the device registers. */
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 /* Bits in the interrupt status/mask registers. */
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,        /* mapped from IntrStatus2 */
00926         IntrTxErrSummary=0x082218,
00927 };
00928 #define DEFAULT_INTR (IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | \
00929                    IntrRxDropped | IntrRxNoBuf) 
00930 
00931 /***************************************************************************
00932  IRQ - PXE IRQ Handler
00933 ***************************************************************************/
00934 void rhine_irq ( struct nic *nic, irq_action_t action ) {
00935     struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
00936     /* Enable interrupts by setting the interrupt mask. */
00937     unsigned int intr_status;
00938 
00939     switch ( action ) {
00940         case DISABLE :
00941         case ENABLE :
00942             intr_status = inw(nic->ioaddr + IntrStatus);
00943             /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
00944 
00945             /* added comment by guard */
00946             /* For supporting VT6107, please use revision id to recognize different chips in driver */
00947             // if (tp->chip_id == 0x3065)
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         /* ! IFF_PROMISC */
00991         outl(0xffffffff, byMAR0);
00992         outl(0xffffffff, byMAR4);
00993         rx_mode = 0x0C;
00994 
00995         outb(0x60 /* thresh */ | 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; /* Already printed version info. */
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     // get revision id.
01014     pci_read_config_byte(pci, PCI_REVISION, &revision_id);
01015 
01016     /* D-Link provided reset code (with comment additions) */
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         /* clear sticky bit before reset & read ethernet address */
01024         byOrgValue = inb(bySTICKHW);
01025         byOrgValue = byOrgValue & 0xFC;
01026         outb(byOrgValue, bySTICKHW);
01027 
01028         /* (bits written are cleared?) */
01029         /* disable force PME-enable */
01030         outb(0x80, byWOLcgClr);
01031         /* disable power-event config bit */
01032         outb(0xFF, byWOLcrClr);
01033         /* clear power status (undocumented in vt6102 docs?) */
01034         outb(0xFF, byPwrcsrClr);
01035         
01036     }
01037 
01038     /* Reset the chip to erase previous misconfiguration. */
01039     outw(CR_SFRST, byCR0);
01040     // if vt3043 delay after reset
01041     if (revision_id <0x40) {
01042        udelay(10000);
01043     }
01044     // polling till software reset complete
01045     // W_MAX_TIMEOUT is the timeout period
01046     for(ww = 0; ww < W_MAX_TIMEOUT; ww++) {
01047         if ((inw(byCR0) & CR_SFRST) == 0)
01048                 break;
01049         }
01050 
01051     // issue AUTOLoad in EECSR to reload eeprom
01052     outb(0x20, byEECSR );
01053 
01054     // if vt3065 delay after reset
01055     if (revision_id >=0x40) {
01056         // delay 8ms to let MAC stable
01057         mdelay(8);
01058         /*
01059          * for 3065D, EEPROM reloaded will cause bit 0 in MAC_REG_CFGA
01060          * turned on.  it makes MAC receive magic packet
01061          * automatically. So, we turn it off. (D-Link)
01062          */
01063          outb(inb(byCFGA) & 0xFE, byCFGA);
01064     }
01065 
01066     /* turn on bit2 in PCI configuration register 0x53 , only for 3065*/
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     /* back off algorithm ,disable the right-most 4-bit off CFGD*/
01074     outb(inb(byCFGD) & (~(CFGD_RANDOM | CFGD_CFDX | CFGD_CEREN | CFGD_CETEN)), byCFGD);
01075 
01076     /* reload eeprom */
01077     reload_eeprom(ioaddr);
01078 
01079     /* Perhaps this should be read from the EEPROM? */
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     /* restart MII auto-negotiation */
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         /* need to wait 1 millisecond - we will round it up to 50-100ms */
01091         timeout = currticks() + 2;
01092         for (timeout = currticks() + 2; currticks() < timeout;)
01093             /* nothing */;
01094         if (ReadMII (1, ioaddr) & 0x0020)
01095             break;
01096     }
01097     printf ("OK.\n");
01098 
01099 #if 0
01100         /* JJM : for Debug */
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     /* query MII to know LineSpeed,duplex mode */
01117     byMIIvalue = inb (ioaddr + 0x6d);
01118     LineSpeed = byMIIvalue & MIISR_SPEED;
01119     if (LineSpeed != 0)                                         //JJM
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     /* set MII 10 FULL ON, only apply in vt3043 */
01141     if(chip_id == 0x3043)
01142         WriteMII (0x17, 1, 1, ioaddr);
01143 
01144     /* turn on MII link change */
01145     MIICRbak = inb (byMIICR);
01146     outb (MIICRbak & 0x7F, byMIICR);
01147     MIIDelay ();
01148     outb (0x41, byMIIAD);
01149     MIIDelay ();
01150 
01151     /* while((inb(byMIIAD)&0x20)==0) ; */
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     /* The lower four bits are the media type. */
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     /* Switch to loopback mode to avoid hardware races. */
01182     outb(0x60 | 0x01, byTCR);
01183     /* Stop the chip's Tx and Rx processes. */
01184     outw(CR_STOP, byCR0);
01185 }
01186 
01187 /**************************************************************************
01188 ETH_RESET - Reset adapter
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     /* printf ("rhine_reset\n"); */
01207     /* Soft reset the chip. */
01208     /*outb(CmdReset, ioaddr + ChipCmd); */
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     /* tune RD TD 32 byte alignment */
01216     rx_ring_tmp1 = virt_to_bus ( rx_ring_tmp );
01217     j = (rx_ring_tmp1 + 32) & (~0x1f);
01218     /* printf ("txring[%d]", j); */
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     /* printf ("rxring[%X]", j); */
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     /* printf ("txb[%X]", j); */
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     /* printf ("rxb[%X][%X]", rx_bufs_tmp1, j); */
01236 
01237     for (i = 0; i < RX_RING_SIZE; i++)
01238     {
01239         tp->rx_buffs[i] = (char *) rx_bufs_tmp;
01240         /* printf("r[%X]",tp->rx_buffs[i]); */
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         /* printf("t[%X]",tp->tx_buffs[i]);  */
01248         tx_bufs_tmp += 1536;
01249     }
01250 
01251     /* software reset */
01252     outb (CR1_SFRST, byCR1);
01253     MIIDelay ();
01254 
01255     /* printf ("init ring"); */
01256     rhine_init_ring (nic);
01257     /*write TD RD Descriptor to MAC */
01258     outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
01259     outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);
01260 
01261     /* Setup Multicast */       
01262     set_rx_mode(nic);
01263 
01264     /* set TCR RCR threshold to store and forward*/
01265     outb (0x3e, byBCR0);
01266     outb (0x38, byBCR1);
01267     outb (0x2c, byRCR);
01268     outb (0x60, byTCR);
01269     /* Set Fulldupex */
01270     FDXFlag = QueryAuto (ioaddr);
01271     if (FDXFlag == 1)
01272     {
01273         outb (CFGD_CFDX, byCFGD);
01274         outw (CR_FDX, byCR0);
01275     }
01276 
01277     /* KICK NIC to WORK */
01278     CRbak = inw (byCR0);
01279     CRbak = CRbak & 0xFFFB;     /* not CR_STOP */
01280     outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);
01281 
01282     /* disable all known interrupt */
01283     outw (0, byIMR0);
01284 }
01285 /* Beware of PCI posted writes */
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         /* There is a packet ready */
01298         if(!retreive)
01299             return 1;
01300 
01301         intr_status = inw(nic->ioaddr + IntrStatus);
01302         /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
01303 #if 0
01304         if (tp->chip_id == 0x3065)
01305           intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
01306 #endif
01307         /* Acknowledge all of the current interrupt sources ASAP. */
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             /* printf ("Packet RXed\n"); */
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         /* Acknowledge all of the current interrupt sources ASAP. */
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     /*printf ("rhine_transmit\n"); */
01357     /* setup ethernet header */
01358 
01359 
01360     /* Calculate the next Tx descriptor entry. */
01361     entry = tp->cur_tx % TX_RING_SIZE;
01362 
01363     memcpy (tp->tx_buffs[entry], d, ETH_ALEN);  /* dst */
01364     memcpy (tp->tx_buffs[entry] + ETH_ALEN, nic->node_addr, ETH_ALEN);  /* src */
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     /*printf("tdsw=[%X]",tp->tx_ring[entry].tx_status.lw); */
01383     /*printf("tdcw=[%X]",tp->tx_ring[entry].tx_ctrl.lw); */
01384     /*printf("tdbuf1=[%X]",tp->tx_ring[entry].buf_addr_1); */
01385     /*printf("tdbuf2=[%X]",tp->tx_ring[entry].buf_addr_2); */
01386     /*printf("td1=[%X]",inl(dwCurrentTDSE0)); */
01387     /*printf("td2=[%X]",inl(dwCurrentTDSE1)); */
01388     /*printf("td3=[%X]",inl(dwCurrentTDSE2)); */
01389     /*printf("td4=[%X]",inl(dwCurrentTDSE3)); */
01390 
01391     outb (CR1bak, byCR1);
01392     do
01393     {
01394         ct = currticks();
01395         /* Wait until transmit is finished or timeout*/
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             // turn on TX
01406             CR0bak = inb(byCR0);
01407             CR0bak = CR0bak|CR_TXON;
01408             outb(CR0bak,byCR0);
01409         }
01410     }while(0);
01411     tp->cur_tx++;
01412 
01413     /*outw(IMRShadow,byIMR0); */
01414     /*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */
01415     /*tp->tx_skbuff[entry] = 0; */
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),              /* Rhine-I 86c100a */
01430 PCI_ROM(0x1106, 0x3053, "via6105m",        "VIA 6105M", 0),
01431 PCI_ROM(0x1106, 0x6100, "via-rhine-old",   "VIA 86C100A", 0),   /* Rhine-II */
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 /* EOF via-rhine.c */
01440 
01441 /*
01442  * Local variables:
01443  *  c-basic-offset: 8
01444  *  c-indent-level: 8
01445  *  tab-width: 8
01446  * End:
01447  */

Generated on Tue Apr 6 20:01:04 2010 for gPXE by  doxygen 1.5.7.1