3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #undef CONFIG_DRV_RTL8139
29 #ifdef CONFIG_DRV_RTL8139
40 #define RTL8139_VENDORID 0x10ec
41 #define RTL8139_DEVICEID 0x8139
43 /* RTL8139C register definitions */
44 #define RTL8139_IDR0 0x00 /* Mac address */
45 #define RTL8139_MAR0 0x08 /* Multicast filter */
46 #define RTL8139_TXSTATUS0 0x10 /* Transmit status (4 32bit regs) */
47 #define RTL8139_TXSTATUS1 0x14 /* Transmit status (4 32bit regs) */
48 #define RTL8139_TXSTATUS2 0x18 /* Transmit status (4 32bit regs) */
49 #define RTL8139_TXSTATUS3 0x1c /* Transmit status (4 32bit regs) */
50 #define RTL8139_TXADDR0 0x20 /* Tx descriptors (also 4 32bit) */
51 #define RTL8139_TXADDR1 0x24 /* Tx descriptors (also 4 32bit) */
52 #define RTL8139_TXADDR2 0x28 /* Tx descriptors (also 4 32bit) */
53 #define RTL8139_TXADDR3 0x2c /* Tx descriptors (also 4 32bit) */
54 #define RTL8139_RXBUF 0x30 /* Receive buffer start address */
55 #define RTL8139_RXEARLYCNT 0x34 /* Early Rx byte count */
56 #define RTL8139_RXEARLYSTATUS 0x36 /* Early Rx status */
57 #define RTL8139_CHIPCMD 0x37 /* Command register */
58 #define RTL8139_RXBUFTAIL 0x38 /* Current address of packet read (queue tail) */
59 #define RTL8139_RXBUFHEAD 0x3A /* Current buffer address (queue head) */
60 #define RTL8139_INTRMASK 0x3C /* Interrupt mask */
61 #define RTL8139_INTRSTATUS 0x3E /* Interrupt status */
62 #define RTL8139_TXCONFIG 0x40 /* Tx config */
63 #define RTL8139_RXCONFIG 0x44 /* Rx config */
64 #define RTL8139_TIMER 0x48 /* A general purpose counter */
65 #define RTL8139_RXMISSED 0x4C /* 24 bits valid, write clears */
66 #define RTL8139_CFG9346 0x50 /* 93C46 command register */
67 #define RTL8139_CONFIG0 0x51 /* Configuration reg 0 */
68 #define RTL8139_CONFIG1 0x52 /* Configuration reg 1 */
69 #define RTL8139_TIMERINT 0x54 /* Timer interrupt register (32 bits) */
70 #define RTL8139_MEDIASTATUS 0x58 /* Media status register */
71 #define RTL8139_CONFIG3 0x59 /* Config register 3 */
72 #define RTL8139_CONFIG4 0x5A /* Config register 4 */
73 #define RTL8139_HLTCLK 0x5B /* Halted Clock */
74 #define RTL8139_MULTIINTR 0x5C /* Multiple interrupt select */
75 #define RTL8139_MII_TSAD 0x60 /* Transmit status of all descriptors (16 bits) */
76 #define RTL8139_MII_BMCR 0x62 /* Basic Mode Control Register (16 bits) */
77 #define RTL8139_MII_BMSR 0x64 /* Basic Mode Status Register (16 bits) */
78 #define RTL8139_AS_ADVERT 0x66 /* Auto-negotiation advertisement reg (16 bits) */
79 #define RTL8139_AS_LPAR 0x68 /* Auto-negotiation link partner reg (16 bits) */
80 #define RTL8139_AS_EXPANSION 0x6A /* Auto-negotiation expansion reg (16 bits) */
82 /* RTL8193C command bits; or these together and write teh resulting value
83 into CHIPCMD to execute it. */
84 #define RTL8139_CMD_RESET 0x10
85 #define RTL8139_CMD_RX_ENABLE 0x08
86 #define RTL8139_CMD_TX_ENABLE 0x04
87 #define RTL8139_CMD_RX_BUF_EMPTY 0x01
89 /* RTL8139C interrupt status bits */
90 #define RTL8139_INT_PCIERR 0x8000 /* PCI Bus error */
91 #define RTL8139_INT_TIMEOUT 0x4000 /* Set when TCTR reaches TimerInt value */
92 #define RTL8139_INT_RXFIFO_OVERFLOW 0x0040 /* Rx FIFO overflow */
93 #define RTL8139_INT_RXFIFO_UNDERRUN 0x0020 /* Packet underrun / link change */
94 #define RTL8139_INT_RXBUF_OVERFLOW 0x0010 /* Rx BUFFER overflow */
95 #define RTL8139_INT_TX_ERR 0x0008
96 #define RTL8139_INT_TX_OK 0x0004
97 #define RTL8139_INT_RX_ERR 0x0002
98 #define RTL8139_INT_RX_OK 0x0001
100 /* RTL8139C transmit status bits */
101 #define RTL8139_TX_CARRIER_LOST 0x80000000 /* Carrier sense lost */
102 #define RTL8139_TX_ABORTED 0x40000000 /* Transmission aborted */
103 #define RTL8139_TX_OUT_OF_WINDOW 0x20000000 /* Out of window collision */
104 #define RTL8139_TX_CARRIER_HBEAT 0x10000000 /* not sure */
105 #define RTL8139_TX_STATUS_OK 0x00008000 /* Status ok: a good packet was transmitted */
106 #define RTL8139_TX_UNDERRUN 0x00004000 /* Transmit FIFO underrun */
107 #define RTL8139_TX_HOST_OWNS 0x00002000 /* Set to 1 when DMA operation is completed */
108 #define RTL8139_TX_SIZE_MASK 0x00001fff /* Descriptor size mask */
110 #define RTL8139_TX_IFG0 0x1000000
111 #define RTL8139_TX_IFG1 0x2000000
112 #define RTL8139_TX_MXDMA2 0x400
113 #define RTL8139_TX_MXDMA1 0x200
115 /* RTL8139C receive status bits */
116 #define RTL8139_RX_MULTICAST 0x00008000 /* Multicast packet */
117 #define RTL8139_RX_PAM 0x00004000 /* Physical address matched */
118 #define RTL8139_RX_BROADCAST 0x00002000 /* Broadcast address matched */
119 #define RTL8139_RX_BAD_SYMBOL 0x00000020 /* Invalid symbol in 100TX packet */
120 #define RTL8139_RX_RUNT 0x00000010 /* Packet size is <64 bytes */
121 #define RTL8139_RX_TOO_LONG 0x00000008 /* Packet size is >4K bytes */
122 #define RTL8139_RX_CRC_ERR 0x00000004 /* CRC error */
123 #define RTL8139_RX_FRAME_ALIGN 0x00000002 /* Frame alignment error */
124 #define RTL8139_RX_STATUS_OK 0x00000001 /* Status ok: a good packet was received */
126 #define RTL8139_RX_RBLEN0 0x800
127 #define RTL8139_RX_MXDMA2 0x400
128 #define RTL8139_RX_MXDMA1 0x200
129 #define RTL8139_RX_AB 0x8
130 #define RTL8139_RX_AM 0x4
131 #define RTL8139_RX_APM 0x2
133 #define RTL8139_BMCR_FDUPLEX 0x0100
134 #define RTL8139_MSR_SPEED10 0x08
136 #define RTL8139_PM_ENABLE 0x01
137 #define RTL8139_PM_LWAKE 0x10
138 #define RTL8139_PM_LWPTN (1 << 2)
139 #define RTL8139_PM_SLEEP (1 << 1)
140 #define RTL8139_PM_PWRDN (1 << 0)
142 /* EEPROM_Ctrl bits. */
143 #define RTL8139_EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
144 #define RTL8139_EE_CS 0x08 /* EEPROM chip select. */
145 #define RTL8139_EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
146 #define RTL8139_EE_WRITE_0 0x00
147 #define RTL8139_EE_WRITE_1 0x02
148 #define RTL8139_EE_DATA_READ 0x01 /* EEPROM chip data out. */
149 #define RTL8139_EE_ENB (0x80 | RTL8139_EE_CS)
151 /* The EEPROM commands include the alway-set leading bit. */
152 #define RTL8139_EE_WRITE_CMD (5 << 6)
153 #define RTL8139_EE_READ_CMD (6 << 6)
154 #define RTL8139_EE_ERASE_CMD (7 << 6)
156 #define TAILREG_TO_TAIL(in) \
157 (unsigned short)(((unsigned)(in) + 16) % 0x10000)
159 #define TAIL_TO_TAILREG(in) \
160 (unsigned short)((unsigned)(in) - 16)
162 #define MYRT_INTS (RTL8139_INT_PCIERR | RTL8139_INT_RX_ERR | RTL8139_INT_RX_OK | \
163 RTL8139_INT_TX_ERR | RTL8139_INT_TX_OK | RTL8139_INT_RXBUF_OVERFLOW)
165 #define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
166 (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
167 #define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1)
169 #define RTL8139_CONFIG3_MAGIC (1 << 5)
171 #define RTL8139_MULTIINTR_CLEAR 0xf000
174 HasHltClk
= (1 << 0),
191 /* directly indexed by chip_t, above */
192 static const struct {
194 unsigned version
; /* from RTL8139C/RTL8139D docs */
196 } rtl_chip_info
[] = {
198 HW_REVID(1, 0, 0, 0, 0, 0, 0),
203 HW_REVID(1, 1, 0, 0, 0, 0, 0),
208 HW_REVID(1, 1, 1, 0, 0, 0, 0),
209 HasHltClk
, /* XXX undocumented? */
213 HW_REVID(1, 1, 1, 0, 0, 1, 0),
214 HasHltClk
, /* XXX undocumented? */
218 HW_REVID(1, 1, 1, 1, 0, 0, 0),
223 HW_REVID(1, 1, 1, 1, 1, 0, 0),
228 HW_REVID(1, 1, 1, 0, 1, 0, 0),
233 HW_REVID(1, 1, 1, 1, 0, 1, 0),
238 HW_REVID(1, 1, 1, 0, 1, 0, 1),
239 HasHltClk
/* XXX undocumented? */
244 HW_REVID(1, 1, 1, 0, 1, 1, 1),
249 /* rtl8139 device structure */
250 struct rtl8139_dev_t
{
253 unsigned short addr_io
;
258 unsigned char txbn_last
;
262 struct rtl8139_dev_t
*rtl8139_dev
;
263 static netdev_t
*ifdev
;
266 unsigned rtl8139_start (struct rtl8139_dev_t
*dev
);
267 unsigned rtl8139_int_rx (struct rtl8139_dev_t
*dev
);
268 unsigned rtl8139_int_tx (struct rtl8139_dev_t
*dev
);
269 bool rtl8139_acthandler (unsigned act
, char *block
, unsigned block_len
);
272 unsigned char rtl8139_read8 (struct rtl8139_dev_t
*dev
, unsigned short port
)
274 return inb (dev
->addr_io
+ port
);
277 void rtl8139_write8 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned char val
)
279 outb (dev
->addr_io
+ port
, val
);
282 unsigned short rtl8139_read16 (struct rtl8139_dev_t
*dev
, unsigned short port
)
284 return inw (dev
->addr_io
+ port
);
287 void rtl8139_write16 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned short val
)
289 outw (dev
->addr_io
+ port
, val
);
292 unsigned rtl8139_read32 (struct rtl8139_dev_t
*dev
, unsigned short port
)
294 return inl (dev
->addr_io
+ port
);
297 void rtl8139_write32 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned val
)
299 outl (dev
->addr_io
+ port
, val
);
302 /* READ/WRITE func */
303 unsigned rtl8139_read (char *buf
, unsigned len
)
305 return rtl8139_acthandler (DEV_ACT_READ
, buf
, len
);
308 unsigned rtl8139_write (char *buf
, unsigned len
)
310 return rtl8139_acthandler (DEV_ACT_WRITE
, buf
, len
);
314 /* Serial EEPROM section. */
315 static int rtl8139_eeprom_read (struct rtl8139_dev_t
*dev
, int location
)
318 unsigned int retval
= 0;
319 int read_cmd
= location
| RTL8139_EE_READ_CMD
;
321 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
& ~RTL8139_EE_CS
);
322 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
324 /* Shift the read command bits out. */
325 for (i
= 10; i
>= 0; i
--) {
326 int dataval
= (read_cmd
& (1 << i
)) ? RTL8139_EE_DATA_WRITE
: 0;
328 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| dataval
);
329 rtl8139_read8 (dev
, RTL8139_CFG9346
);
331 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| dataval
| RTL8139_EE_SHIFT_CLK
);
332 rtl8139_read8 (dev
, RTL8139_CFG9346
);
335 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
337 rtl8139_read8 (dev
, RTL8139_CFG9346
);
339 for (i
= 16; i
> 0; i
--) {
340 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| RTL8139_EE_SHIFT_CLK
);
341 rtl8139_read8 (dev
, RTL8139_CFG9346
);
343 retval
= (retval
<< 1) | ((rtl8139_read8 (dev
, RTL8139_CFG9346
) & RTL8139_EE_DATA_READ
) ? 1 : 0);
345 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
346 rtl8139_read8 (dev
, RTL8139_CFG9346
);
349 /* Terminate the EEPROM access. */
350 rtl8139_write8 (dev
, RTL8139_CFG9346
, ~RTL8139_EE_CS
);
355 /* detect rtl8139 device in PC */
356 pcidev_t
*rtl8139_detect ()
358 /* First detect network card - is connected to PCI bus ?*/
359 pcidev_t
*pcidev
= pcidev_find (RTL8139_VENDORID
, RTL8139_DEVICEID
);
367 /* reset rtl8139 device */
368 unsigned rtl8139_reset (struct rtl8139_dev_t
*dev
)
372 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RESET
);
374 /* wait until chip is ready */
375 for (i
= 0; i
< 1000; i
++) {
376 if (!(rtl8139_read8 (dev
, RTL8139_CHIPCMD
) & RTL8139_CMD_RESET
))
383 kprintf ("ERROR -> waiting for rtl8139 reset\n");
388 /* nic interrupt handler */
393 struct rtl8139_dev_t
*dev
= rtl8139_dev
;
395 unsigned short status
= rtl8139_read16 (dev
, RTL8139_INTRSTATUS
);
397 // disable interrupts
398 rtl8139_write16 (dev
, RTL8139_INTRMASK
, 0);
400 rtl8139_write16 (dev
, RTL8139_INTRSTATUS
, status
);
402 if (status
& RTL8139_INT_RX_OK
)
403 rtl8139_int_rx (dev
);
405 if (status
& RTL8139_INT_RX_ERR
)
406 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> read error :(\n");
408 if(status
& RTL8139_INT_RXBUF_OVERFLOW
) {
409 rtl8139_write32 (dev
, RTL8139_RXMISSED
, 0);
410 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)));
413 if (status
& RTL8139_INT_TX_OK
)
414 rtl8139_int_tx (dev
);
416 if (status
& RTL8139_INT_TX_ERR
)
417 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> write error:(\n");
419 //kprintf ("rtl8139 -> interrupt (0x%x)\n", status);
421 // reenable interrupts
422 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
427 /* rx descriptor structure */
428 typedef struct rx_entry
{
429 volatile unsigned short status
;
430 volatile unsigned short len
;
431 volatile unsigned char data
[1];
434 unsigned rtl8139_int_rx (struct rtl8139_dev_t
*dev
)
436 unsigned tail
= TAILREG_TO_TAIL (rtl8139_read16 (dev
, RTL8139_RXBUFTAIL
));
438 rx_entry
*entry
= (rx_entry
*)((unsigned char *) dev
->rxbuf
+ tail
);
445 unsigned l
= entry
->len
- 4; // minus the crc
447 if ((entry
->status
& RTL8139_RX_STATUS_OK
) == 0) {
448 // error, lets reset the card
449 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139_rx () -> rx error");
451 // stop the rx and tx and mask all interrupts
452 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RESET
);
453 rtl8139_write16 (dev
, RTL8139_INTRMASK
, 0x0);
455 // reset the rx pointers
456 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (0));
457 rtl8139_write16 (dev
, RTL8139_RXBUFHEAD
, 0x0);
460 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
462 // Enable RX/TX once more
463 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
468 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139_rx () -> packet too large for buffer (len %d, buf_len %ld)\n", l
, len
);
469 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAILREG_TO_TAIL (rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)));
473 if(tail
+ len
> 0xffff) {
474 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> packet wraps around\n");
475 //netdev_rx_add_queue (ifdev, (char *) &entry->data[0], 0x10000 - (tail + 4));
476 //netdev_rx_add_queue (ifdev, (char *) dev->rxbuf, l - (0x10000 - (tail + 4)));
478 //memcpy (buf, (const void *) &entry->data[0], l - (0x10000 - (tail + 4)));
479 //memcpy ((unsigned char *) buf + 0x10000 - (tail + 4), (const void *) dev->rxbuf, len - (0x10000 - (tail + 4)));
481 netdev_rx_add_queue (ifdev
, (char *) &entry
->data
[0], entry
->len
);
482 //memcpy (buf, (const void *) &entry->data[0], l);
485 // calculate the new tail
486 tail
= ((tail
+ entry
->len
+ 4 + 3) & ~3) % 0x10000;
488 //kprintf ("new tail at 0x%x, tailreg will say 0x%x\n", tail, TAIL_TO_TAILREG(tail));
490 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (tail
));
492 if(tail
!= rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)) {
493 // we're at last one more packet behind
499 unsigned rtl8139_tx (struct rtl8139_dev_t
*dev
, char *buf
, unsigned len
)
501 /* copy our buffer to txbuf */
502 memcpy ((char *) (dev
->txbuf
+ dev
->txbn
* 0x800), buf
, len
);
504 /* we need send crc too */
507 /* ethernet min. packet length is 64 with crc */
511 rtl8139_write32 (dev
, RTL8139_TXSTATUS0
+ dev
->txbn
* 4, len
| 0x80000);
513 if (++ dev
->txbn
>= 4)
519 unsigned rtl8139_int_tx (struct rtl8139_dev_t
*dev
)
524 for (i
= 0; i
< 4; i
++) {
525 if (i
> 0 && dev
->txbn_last
== dev
->txbn
)
528 txstat
= rtl8139_read32 (dev
, RTL8139_TXSTATUS0
+ dev
->txbn_last
* 4);
530 //kprintf ("txstat[%d] = 0x%x %u %u %u\n", dev->txbn_last, txstat, (txstat & RTL8139_TX_STATUS_OK) ? 1 : 0, (txstat & RTL8139_TX_UNDERRUN) ? 1 : 0, (txstat & RTL8139_TX_ABORTED) ? 1 : 0);
532 if((txstat
& (RTL8139_TX_STATUS_OK
| RTL8139_TX_UNDERRUN
| RTL8139_TX_ABORTED
)) == 0)
535 if(++ dev
->txbn_last
>= 4)
543 unsigned init_rtl8139 ()
547 pcidev_t
*pcidev
= rtl8139_detect ();
552 struct rtl8139_dev_t
*dev
= (struct rtl8139_dev_t
*) kmalloc (sizeof (struct rtl8139_dev_t
));
558 dev
->irq
= pcidev
->u
.h0
.interrupt_line
;
559 dev
->addr_io
= pcidev
->u
.h0
.base_registers
[0] & ~3;
564 pci_device_enable (pcidev
);
566 pci_device_adjust (pcidev
);
568 /* reset device now */
569 //rtl8139_reset (dev);
572 //rtl8139_write8 (dev, RTL8139_CONFIG1, 0x0);
574 /* go out from low-power mode */
575 rtl8139_write8 (dev
, RTL8139_HLTCLK
, 'R');
577 // check for broken hardware
578 unsigned respond
= rtl8139_read32 (dev
, RTL8139_TXCONFIG
);
580 if (respond
== 0xffffffff) {
581 kprintf ("rtl8139 -> Chip not respond, probably it's broken\n");
585 /* get mac address from ethernet */
586 if (rtl8139_eeprom_read (dev
, 0) != 0xffff) {
588 for (i
= 0; i
< 3; i
++)
589 m
[i
] = rtl8139_eeprom_read (dev
, i
+ 7);
591 memcpy (dev
->addr_mac
, &m
, sizeof (mac_addr_t
));
593 for (i
= 0; i
< 6; i
++)
594 dev
->addr_mac
[i
] = rtl8139_read8 (dev
, RTL8139_IDR0
+ i
);
597 unsigned char speed10
= rtl8139_read8 (dev
, RTL8139_MEDIASTATUS
) & RTL8139_MSR_SPEED10
;
598 unsigned short fullduplex
= rtl8139_read16 (dev
, RTL8139_MII_BMCR
) & RTL8139_BMCR_FDUPLEX
;
600 kprintf ("rtl8139 -> ethernet speed %sMbps %s-duplex\n", speed10
? "10" : "100", fullduplex
? "full" : "half");
602 /* identify chip attached to board */
603 unsigned version
= respond
& HW_REVID_MASK
;
604 for (i
= 0; i
< 10; i
++)
605 if (version
== rtl_chip_info
[i
].version
) {
610 kprintf ("rtl8139 -> identified chip type as '%s'\n", rtl_chip_info
[i
].name
);
615 if (dev
->chipset
>= CH_8139B
) {
616 unsigned char r2
= r
= rtl8139_read8 (dev
, RTL8139_CONFIG1
);
618 if ((rtl_chip_info
[dev
->chipset
].flags
& HasLWake
) && (r
& RTL8139_PM_LWAKE
))
619 r2
&= ~RTL8139_PM_LWAKE
;
621 r2
|= RTL8139_PM_ENABLE
;
624 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
625 rtl8139_write8 (dev
, RTL8139_CONFIG1
, r
);
626 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
629 if (rtl_chip_info
[dev
->chipset
].flags
& HasLWake
) {
630 r
= rtl8139_read8 (dev
, RTL8139_CONFIG4
);
631 if (r
& RTL8139_PM_LWPTN
) {
632 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
633 rtl8139_write8 (dev
, RTL8139_CONFIG4
, r
& ~RTL8139_PM_LWPTN
);
634 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
638 r
= rtl8139_read8 (dev
, RTL8139_CONFIG1
);
639 r
&= ~(RTL8139_PM_SLEEP
| RTL8139_PM_PWRDN
);
640 rtl8139_write8 (dev
, RTL8139_CONFIG1
, r
);
643 /* reset device now */
646 /* Put the chip into low-power mode. */
647 if (rtl_chip_info
[dev
->chipset
].flags
& HasHltClk
)
648 rtl8139_write8 (dev
, RTL8139_HLTCLK
, 'H'); /* 'R' would leave the clock running. */
650 /* set interrupt vector */
651 irq_install_handler (dev
->irq
, rtl8139_int
);
653 return rtl8139_start (dev
);
656 unsigned rtl8139_init_ring (struct rtl8139_dev_t
*dev
)
658 memset (dev
->rxbuf
, 0, 2048);
659 memset (dev
->txbuf
, 0, 4*2048);
664 unsigned rtl8139_start (struct rtl8139_dev_t
*dev
)
666 dev
->rxbuf
= (char *) 0x63000;
667 dev
->txbuf
= (char *) 0x66000;
669 rtl8139_init_ring (dev
);
671 /* Bring old chips out of low-power mode. */
672 if (rtl_chip_info
[dev
->chipset
].flags
& HasHltClk
)
673 rtl8139_write8 (dev
, RTL8139_HLTCLK
, 'R');
675 /* reset device now */
678 // enable writing to the config registers
679 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
682 //rtl8139_write8 (dev, RTL8139_CONFIG1, 0x0);
685 for (i
= 0; i
< 6; i
++)
686 rtl8139_write8 (dev
, RTL8139_IDR0
+ i
, dev
->addr_mac
[i
]);
688 // enable rx and tx functions
689 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
691 // set rx fifo threashold to 256bytes
692 rtl8139_write32 (dev
, RTL8139_RXCONFIG
, 0x00009c00);/*RTL8139_RX_RBLEN0 | RTL8139_RX_MXDMA2 | RTL8139_RX_MXDMA1 |
693 RTL8139_RX_AB | RTL8139_RX_AM | RTL8139_RX_APM);*/
695 // set tx fifo threashold to 256bytes
696 rtl8139_write32 (dev
, RTL8139_TXCONFIG
, 0x03000400);/*RTL8139_TX_IFG0 | RTL8139_TX_IFG1 | RTL8139_TX_MXDMA2 |
697 RTL8139_TX_MXDMA1);*/
699 // disable lan-wake and set the driver-loaded bit
700 rtl8139_write8 (dev
, RTL8139_CONFIG1
, (rtl8139_read8 (dev
, RTL8139_CONFIG1
) & ~0x30) | 0x20);
702 // enable fifo auto-clear
703 rtl8139_write8 (dev
, RTL8139_CONFIG4
, rtl8139_read8 (dev
, RTL8139_CONFIG4
) | 0x80);
705 // enable receiving broadcast and physical packets
706 rtl8139_write32 (dev
, RTL8139_RXCONFIG
, rtl8139_read32 (dev
, RTL8139_RXCONFIG
) | 0x0000000f);
709 rtl8139_write32 (dev
, RTL8139_RXBUF
, (unsigned) dev
->rxbuf
);
711 // go back to normal mode
712 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
715 rtl8139_write32 (dev
, RTL8139_TXADDR0
, (unsigned) dev
->txbuf
);
716 rtl8139_write32 (dev
, RTL8139_TXADDR1
, (unsigned) dev
->txbuf
+ 2*1024);
717 rtl8139_write32 (dev
, RTL8139_TXADDR2
, (unsigned) dev
->txbuf
+ 4*1024);
718 rtl8139_write32 (dev
, RTL8139_TXADDR3
, (unsigned) dev
->txbuf
+ 6*1024);
720 // reset rx missed counter
721 rtl8139_write32 (dev
, RTL8139_RXMISSED
, 0x0);
723 // filter all multicast packets
724 rtl8139_write32 (dev
, RTL8139_MAR0
, 0x0);
725 rtl8139_write32 (dev
, RTL8139_MAR0
+ 4, 0x0);
727 // no early-rx interrupts
728 rtl8139_write16 (dev
, RTL8139_MULTIINTR
, rtl8139_read16 (dev
, RTL8139_MULTIINTR
) & RTL8139_MULTIINTR_CLEAR
);
731 unsigned char chipstatus
= rtl8139_read8 (dev
, RTL8139_CHIPCMD
);
733 if (chipstatus
& RTL8139_CMD_TX_ENABLE
|| chipstatus
& RTL8139_CMD_RX_ENABLE
)
734 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
736 if (dev
->chipset
>= CH_8139B
) {
737 /* Disable magic packet scanning, which is enabled
738 * when PM is enabled in Config1. */
739 rtl8139_write8 (dev
, RTL8139_CONFIG3
, rtl8139_read8 (dev
, RTL8139_CONFIG3
) & ~RTL8139_CONFIG3_MAGIC
);
742 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
744 /* create new network device */
745 ifdev
= netdev_create (dev
->addr_mac
, &rtl8139_read
, &rtl8139_write
, dev
->addr_io
);
753 bool rtl8139_acthandler (unsigned act
, char *block
, unsigned block_len
)
758 return init_rtl8139 ();
769 return rtl8139_tx (rtl8139_dev
, block
, block_len
);