3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #undef CONFIG_DRV_RTL8139
28 #ifdef CONFIG_DRV_RTL8139
39 #define RTL8139_VENDORID 0x10ec
40 #define RTL8139_DEVICEID 0x8139
42 /* RTL8139C register definitions */
43 #define RTL8139_IDR0 0x00 /* Mac address */
44 #define RTL8139_MAR0 0x08 /* Multicast filter */
45 #define RTL8139_TXSTATUS0 0x10 /* Transmit status (4 32bit regs) */
46 #define RTL8139_TXSTATUS1 0x14 /* Transmit status (4 32bit regs) */
47 #define RTL8139_TXSTATUS2 0x18 /* Transmit status (4 32bit regs) */
48 #define RTL8139_TXSTATUS3 0x1c /* Transmit status (4 32bit regs) */
49 #define RTL8139_TXADDR0 0x20 /* Tx descriptors (also 4 32bit) */
50 #define RTL8139_TXADDR1 0x24 /* Tx descriptors (also 4 32bit) */
51 #define RTL8139_TXADDR2 0x28 /* Tx descriptors (also 4 32bit) */
52 #define RTL8139_TXADDR3 0x2c /* Tx descriptors (also 4 32bit) */
53 #define RTL8139_RXBUF 0x30 /* Receive buffer start address */
54 #define RTL8139_RXEARLYCNT 0x34 /* Early Rx byte count */
55 #define RTL8139_RXEARLYSTATUS 0x36 /* Early Rx status */
56 #define RTL8139_CHIPCMD 0x37 /* Command register */
57 #define RTL8139_RXBUFTAIL 0x38 /* Current address of packet read (queue tail) */
58 #define RTL8139_RXBUFHEAD 0x3A /* Current buffer address (queue head) */
59 #define RTL8139_INTRMASK 0x3C /* Interrupt mask */
60 #define RTL8139_INTRSTATUS 0x3E /* Interrupt status */
61 #define RTL8139_TXCONFIG 0x40 /* Tx config */
62 #define RTL8139_RXCONFIG 0x44 /* Rx config */
63 #define RTL8139_TIMER 0x48 /* A general purpose counter */
64 #define RTL8139_RXMISSED 0x4C /* 24 bits valid, write clears */
65 #define RTL8139_CFG9346 0x50 /* 93C46 command register */
66 #define RTL8139_CONFIG0 0x51 /* Configuration reg 0 */
67 #define RTL8139_CONFIG1 0x52 /* Configuration reg 1 */
68 #define RTL8139_TIMERINT 0x54 /* Timer interrupt register (32 bits) */
69 #define RTL8139_MEDIASTATUS 0x58 /* Media status register */
70 #define RTL8139_CONFIG3 0x59 /* Config register 3 */
71 #define RTL8139_CONFIG4 0x5A /* Config register 4 */
72 #define RTL8139_HLTCLK 0x5B /* Halted Clock */
73 #define RTL8139_MULTIINTR 0x5C /* Multiple interrupt select */
74 #define RTL8139_MII_TSAD 0x60 /* Transmit status of all descriptors (16 bits) */
75 #define RTL8139_MII_BMCR 0x62 /* Basic Mode Control Register (16 bits) */
76 #define RTL8139_MII_BMSR 0x64 /* Basic Mode Status Register (16 bits) */
77 #define RTL8139_AS_ADVERT 0x66 /* Auto-negotiation advertisement reg (16 bits) */
78 #define RTL8139_AS_LPAR 0x68 /* Auto-negotiation link partner reg (16 bits) */
79 #define RTL8139_AS_EXPANSION 0x6A /* Auto-negotiation expansion reg (16 bits) */
81 /* RTL8193C command bits; or these together and write teh resulting value
82 into CHIPCMD to execute it. */
83 #define RTL8139_CMD_RESET 0x10
84 #define RTL8139_CMD_RX_ENABLE 0x08
85 #define RTL8139_CMD_TX_ENABLE 0x04
86 #define RTL8139_CMD_RX_BUF_EMPTY 0x01
88 /* RTL8139C interrupt status bits */
89 #define RTL8139_INT_PCIERR 0x8000 /* PCI Bus error */
90 #define RTL8139_INT_TIMEOUT 0x4000 /* Set when TCTR reaches TimerInt value */
91 #define RTL8139_INT_RXFIFO_OVERFLOW 0x0040 /* Rx FIFO overflow */
92 #define RTL8139_INT_RXFIFO_UNDERRUN 0x0020 /* Packet underrun / link change */
93 #define RTL8139_INT_RXBUF_OVERFLOW 0x0010 /* Rx BUFFER overflow */
94 #define RTL8139_INT_TX_ERR 0x0008
95 #define RTL8139_INT_TX_OK 0x0004
96 #define RTL8139_INT_RX_ERR 0x0002
97 #define RTL8139_INT_RX_OK 0x0001
99 /* RTL8139C transmit status bits */
100 #define RTL8139_TX_CARRIER_LOST 0x80000000 /* Carrier sense lost */
101 #define RTL8139_TX_ABORTED 0x40000000 /* Transmission aborted */
102 #define RTL8139_TX_OUT_OF_WINDOW 0x20000000 /* Out of window collision */
103 #define RTL8139_TX_CARRIER_HBEAT 0x10000000 /* not sure */
104 #define RTL8139_TX_STATUS_OK 0x00008000 /* Status ok: a good packet was transmitted */
105 #define RTL8139_TX_UNDERRUN 0x00004000 /* Transmit FIFO underrun */
106 #define RTL8139_TX_HOST_OWNS 0x00002000 /* Set to 1 when DMA operation is completed */
107 #define RTL8139_TX_SIZE_MASK 0x00001fff /* Descriptor size mask */
109 #define RTL8139_TX_IFG0 0x1000000
110 #define RTL8139_TX_IFG1 0x2000000
111 #define RTL8139_TX_MXDMA2 0x400
112 #define RTL8139_TX_MXDMA1 0x200
114 /* RTL8139C receive status bits */
115 #define RTL8139_RX_MULTICAST 0x00008000 /* Multicast packet */
116 #define RTL8139_RX_PAM 0x00004000 /* Physical address matched */
117 #define RTL8139_RX_BROADCAST 0x00002000 /* Broadcast address matched */
118 #define RTL8139_RX_BAD_SYMBOL 0x00000020 /* Invalid symbol in 100TX packet */
119 #define RTL8139_RX_RUNT 0x00000010 /* Packet size is <64 bytes */
120 #define RTL8139_RX_TOO_LONG 0x00000008 /* Packet size is >4K bytes */
121 #define RTL8139_RX_CRC_ERR 0x00000004 /* CRC error */
122 #define RTL8139_RX_FRAME_ALIGN 0x00000002 /* Frame alignment error */
123 #define RTL8139_RX_STATUS_OK 0x00000001 /* Status ok: a good packet was received */
125 #define RTL8139_RX_RBLEN0 0x800
126 #define RTL8139_RX_MXDMA2 0x400
127 #define RTL8139_RX_MXDMA1 0x200
128 #define RTL8139_RX_AB 0x8
129 #define RTL8139_RX_AM 0x4
130 #define RTL8139_RX_APM 0x2
132 #define RTL8139_BMCR_FDUPLEX 0x0100
133 #define RTL8139_MSR_SPEED10 0x08
135 #define RTL8139_PM_ENABLE 0x01
136 #define RTL8139_PM_LWAKE 0x10
137 #define RTL8139_PM_LWPTN (1 << 2)
138 #define RTL8139_PM_SLEEP (1 << 1)
139 #define RTL8139_PM_PWRDN (1 << 0)
141 /* EEPROM_Ctrl bits. */
142 #define RTL8139_EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
143 #define RTL8139_EE_CS 0x08 /* EEPROM chip select. */
144 #define RTL8139_EE_DATA_WRITE 0x02 /* EEPROM chip data in. */
145 #define RTL8139_EE_WRITE_0 0x00
146 #define RTL8139_EE_WRITE_1 0x02
147 #define RTL8139_EE_DATA_READ 0x01 /* EEPROM chip data out. */
148 #define RTL8139_EE_ENB (0x80 | RTL8139_EE_CS)
150 /* The EEPROM commands include the alway-set leading bit. */
151 #define RTL8139_EE_WRITE_CMD (5 << 6)
152 #define RTL8139_EE_READ_CMD (6 << 6)
153 #define RTL8139_EE_ERASE_CMD (7 << 6)
155 #define TAILREG_TO_TAIL(in) \
156 (unsigned short)(((unsigned)(in) + 16) % 0x10000)
158 #define TAIL_TO_TAILREG(in) \
159 (unsigned short)((unsigned)(in) - 16)
161 #define MYRT_INTS (RTL8139_INT_PCIERR | RTL8139_INT_RX_ERR | RTL8139_INT_RX_OK | \
162 RTL8139_INT_TX_ERR | RTL8139_INT_TX_OK | RTL8139_INT_RXBUF_OVERFLOW)
164 #define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
165 (b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
166 #define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1)
169 HasHltClk
= (1 << 0),
186 /* directly indexed by chip_t, above */
187 static const struct {
189 unsigned version
; /* from RTL8139C/RTL8139D docs */
191 } rtl_chip_info
[] = {
193 HW_REVID(1, 0, 0, 0, 0, 0, 0),
198 HW_REVID(1, 1, 0, 0, 0, 0, 0),
203 HW_REVID(1, 1, 1, 0, 0, 0, 0),
204 HasHltClk
, /* XXX undocumented? */
208 HW_REVID(1, 1, 1, 0, 0, 1, 0),
209 HasHltClk
, /* XXX undocumented? */
213 HW_REVID(1, 1, 1, 1, 0, 0, 0),
218 HW_REVID(1, 1, 1, 1, 1, 0, 0),
223 HW_REVID(1, 1, 1, 0, 1, 0, 0),
228 HW_REVID(1, 1, 1, 1, 0, 1, 0),
233 HW_REVID(1, 1, 1, 0, 1, 0, 1),
234 HasHltClk
/* XXX undocumented? */
239 HW_REVID(1, 1, 1, 0, 1, 1, 1),
244 /* rtl8139 device structure */
245 struct rtl8139_dev_t
{
248 unsigned short addr_io
;
253 unsigned char txbn_last
;
257 struct rtl8139_dev_t
*rtl8139_dev
;
258 static netdev_t
*ifdev
;
261 unsigned rtl8139_start (struct rtl8139_dev_t
*dev
);
262 unsigned rtl8139_int_rx (struct rtl8139_dev_t
*dev
);
263 unsigned rtl8139_int_tx (struct rtl8139_dev_t
*dev
);
264 bool rtl8139_acthandler (unsigned act
, char *block
, unsigned block_len
);
267 unsigned char rtl8139_read8 (struct rtl8139_dev_t
*dev
, unsigned short port
)
269 return inb (dev
->addr_io
+ port
);
272 void rtl8139_write8 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned char val
)
274 outb (dev
->addr_io
+ port
, val
);
277 unsigned short rtl8139_read16 (struct rtl8139_dev_t
*dev
, unsigned short port
)
279 return inw (dev
->addr_io
+ port
);
282 void rtl8139_write16 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned short val
)
284 outw (dev
->addr_io
+ port
, val
);
287 unsigned rtl8139_read32 (struct rtl8139_dev_t
*dev
, unsigned short port
)
289 return inl (dev
->addr_io
+ port
);
292 void rtl8139_write32 (struct rtl8139_dev_t
*dev
, unsigned short port
, unsigned val
)
294 outl (dev
->addr_io
+ port
, val
);
297 /* READ/WRITE func */
298 unsigned rtl8139_read (char *buf
, unsigned len
)
300 return rtl8139_acthandler (DEV_ACT_READ
, buf
, len
);
303 unsigned rtl8139_write (char *buf
, unsigned len
)
305 return rtl8139_acthandler (DEV_ACT_WRITE
, buf
, len
);
309 /* Serial EEPROM section. */
310 static int rtl8139_eeprom_read (struct rtl8139_dev_t
*dev
, int location
)
313 unsigned int retval
= 0;
314 int read_cmd
= location
| RTL8139_EE_READ_CMD
;
316 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
& ~RTL8139_EE_CS
);
317 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
319 /* Shift the read command bits out. */
320 for (i
= 10; i
>= 0; i
--) {
321 int dataval
= (read_cmd
& (1 << i
)) ? RTL8139_EE_DATA_WRITE
: 0;
323 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| dataval
);
324 rtl8139_read8 (dev
, RTL8139_CFG9346
);
326 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| dataval
| RTL8139_EE_SHIFT_CLK
);
327 rtl8139_read8 (dev
, RTL8139_CFG9346
);
330 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
332 rtl8139_read8 (dev
, RTL8139_CFG9346
);
334 for (i
= 16; i
> 0; i
--) {
335 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
| RTL8139_EE_SHIFT_CLK
);
336 rtl8139_read8 (dev
, RTL8139_CFG9346
);
338 retval
= (retval
<< 1) | ((rtl8139_read8 (dev
, RTL8139_CFG9346
) & RTL8139_EE_DATA_READ
) ? 1 : 0);
340 rtl8139_write8 (dev
, RTL8139_CFG9346
, RTL8139_EE_ENB
);
341 rtl8139_read8 (dev
, RTL8139_CFG9346
);
344 /* Terminate the EEPROM access. */
345 rtl8139_write8 (dev
, RTL8139_CFG9346
, ~RTL8139_EE_CS
);
350 /* detect rtl8139 device in PC */
351 pcidev_t
*rtl8139_detect ()
353 /* First detect network card - is connected to PCI bus ?*/
354 pcidev_t
*pcidev
= pcidev_find (RTL8139_VENDORID
, RTL8139_DEVICEID
);
362 /* reset rtl8139 device */
363 unsigned rtl8139_reset (struct rtl8139_dev_t
*dev
)
367 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RESET
);
369 /* wait until chip is ready */
370 for (i
= 0; i
< 1000; i
++) {
371 if (!(rtl8139_read8 (dev
, RTL8139_CHIPCMD
) & RTL8139_CMD_RESET
))
378 kprintf ("ERROR -> waiting for rtl8139 reset\n");
383 /* nic interrupt handler */
388 struct rtl8139_dev_t
*dev
= rtl8139_dev
;
390 unsigned short status
= rtl8139_read16 (dev
, RTL8139_INTRSTATUS
);
392 // disable interrupts
393 rtl8139_write16 (dev
, RTL8139_INTRMASK
, 0);
395 rtl8139_write16 (dev
, RTL8139_INTRSTATUS
, status
);
397 if (status
& RTL8139_INT_RX_OK
)
398 rtl8139_int_rx (dev
);
400 if (status
& RTL8139_INT_RX_ERR
)
401 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> read error :(\n");
403 if(status
& RTL8139_INT_RXBUF_OVERFLOW
) {
404 rtl8139_write32 (dev
, RTL8139_RXMISSED
, 0);
405 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)));
408 if (status
& RTL8139_INT_TX_OK
)
409 rtl8139_int_tx (dev
);
411 if (status
& RTL8139_INT_TX_ERR
)
412 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> write error:(\n");
414 kprintf ("rtl8139 -> interrupt (0x%x)\n", status
);
416 // reenable interrupts
417 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
422 /* rx descriptor structure */
423 typedef struct rx_entry
{
424 volatile unsigned short status
;
425 volatile unsigned short len
;
426 volatile unsigned char data
[1];
429 unsigned rtl8139_int_rx (struct rtl8139_dev_t
*dev
)
431 unsigned tail
= TAILREG_TO_TAIL (rtl8139_read16 (dev
, RTL8139_RXBUFTAIL
));
433 rx_entry
*entry
= (rx_entry
*)((unsigned char *) dev
->rxbuf
+ tail
);
440 unsigned l
= entry
->len
- 4; // minus the crc
442 if ((entry
->status
& RTL8139_RX_STATUS_OK
) == 0) {
443 // error, lets reset the card
444 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139_rx () -> rx error");
446 // stop the rx and tx and mask all interrupts
447 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RESET
);
448 rtl8139_write16 (dev
, RTL8139_INTRMASK
, 0x0);
450 // reset the rx pointers
451 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (0));
452 rtl8139_write16 (dev
, RTL8139_RXBUFHEAD
, 0x0);
455 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
457 // Enable RX/TX once more
458 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
463 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139_rx () -> packet too large for buffer (len %d, buf_len %ld)\n", l
, len
);
464 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAILREG_TO_TAIL (rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)));
468 if(tail
+ len
> 0xffff) {
469 DPRINT (DBG_DRIVER
| DBG_ETH
, "rtl8139 -> packet wraps around\n");
470 //netdev_rx_add_queue (ifdev, (char *) &entry->data[0], 0x10000 - (tail + 4));
471 //netdev_rx_add_queue (ifdev, (char *) dev->rxbuf, l - (0x10000 - (tail + 4)));
473 //memcpy (buf, (const void *) &entry->data[0], l - (0x10000 - (tail + 4)));
474 //memcpy ((unsigned char *) buf + 0x10000 - (tail + 4), (const void *) dev->rxbuf, len - (0x10000 - (tail + 4)));
476 netdev_rx_add_queue (ifdev
, (char *) &entry
->data
[0], entry
->len
);
477 //memcpy (buf, (const void *) &entry->data[0], l);
480 // calculate the new tail
481 tail
= ((tail
+ entry
->len
+ 4 + 3) & ~3) % 0x10000;
483 //kprintf ("new tail at 0x%x, tailreg will say 0x%x\n", tail, TAIL_TO_TAILREG(tail));
485 rtl8139_write16 (dev
, RTL8139_RXBUFTAIL
, TAIL_TO_TAILREG (tail
));
487 if(tail
!= rtl8139_read16 (dev
, RTL8139_RXBUFHEAD
)) {
488 // we're at last one more packet behind
494 unsigned rtl8139_tx (struct rtl8139_dev_t
*dev
, char *buf
, unsigned len
)
496 /* copy our buffer to txbuf */
497 memcpy ((char *) (dev
->txbuf
+ dev
->txbn
* 0x800), buf
, len
);
499 /* we need send crc too */
502 /* ethernet min. packet length is 64 with crc */
506 rtl8139_write32 (dev
, RTL8139_TXSTATUS0
+ dev
->txbn
* 4, len
| 0x80000);
508 if (++ dev
->txbn
>= 4)
514 unsigned rtl8139_int_tx (struct rtl8139_dev_t
*dev
)
519 for (i
= 0; i
< 4; i
++) {
520 if (i
> 0 && dev
->txbn_last
== dev
->txbn
)
523 txstat
= rtl8139_read32 (dev
, RTL8139_TXSTATUS0
+ dev
->txbn_last
* 4);
525 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);
527 if((txstat
& (RTL8139_TX_STATUS_OK
| RTL8139_TX_UNDERRUN
| RTL8139_TX_ABORTED
)) == 0)
530 if(++ dev
->txbn_last
>= 4)
538 unsigned init_rtl8139 ()
542 pcidev_t
*pcidev
= rtl8139_detect ();
547 struct rtl8139_dev_t
*dev
= (struct rtl8139_dev_t
*) kmalloc (sizeof (struct rtl8139_dev_t
));
553 dev
->irq
= pcidev
->u
.h0
.interrupt_line
;
554 dev
->addr_io
= pcidev
->u
.h0
.base_registers
[0] & ~3;
559 pci_device_enable (pcidev
);
561 pci_device_adjust (pcidev
);
563 /* reset device now */
564 //rtl8139_reset (dev);
567 rtl8139_write8 (dev
, RTL8139_CONFIG1
, 0x0);
569 /* go out from low-power mode */
570 rtl8139_write8 (dev
, RTL8139_HLTCLK
, 'R');
572 // check for broken hardware
573 unsigned respond
= rtl8139_read32 (dev
, RTL8139_TXCONFIG
);
575 if (respond
== 0xffffffff) {
576 kprintf ("rtl8139 -> Chip not respond, probably it's broken\n");
580 /* get mac address from ethernet */
581 if (rtl8139_eeprom_read (dev
, 0) != 0xffff) {
583 for (i
= 0; i
< 3; i
++)
584 m
[i
] = rtl8139_eeprom_read (dev
, i
+ 7);
586 memcpy (dev
->addr_mac
, &m
, sizeof (mac_addr_t
));
588 for (i
= 0; i
< 6; i
++)
589 dev
->addr_mac
[i
] = rtl8139_read8 (dev
, RTL8139_IDR0
+ i
);
592 unsigned char speed10
= rtl8139_read8 (dev
, RTL8139_MEDIASTATUS
) & RTL8139_MSR_SPEED10
;
593 unsigned short fullduplex
= rtl8139_read16 (dev
, RTL8139_MII_BMCR
) & RTL8139_BMCR_FDUPLEX
;
595 kprintf ("rtl8139 -> ethernet speed %sMbps %s-duplex\n", speed10
? "10" : "100", fullduplex
? "full" : "half");
597 /* identify chip attached to board */
598 unsigned version
= respond
& HW_REVID_MASK
;
599 for (i
= 0; i
< 10; i
++)
600 if (version
== rtl_chip_info
[i
].version
) {
605 kprintf ("rtl8139 -> identified chip type as '%s'\n", rtl_chip_info
[i
].name
);
610 if (dev
->chipset
>= CH_8139B
) {
611 unsigned char r2
= r
= rtl8139_read8 (dev
, RTL8139_CONFIG1
);
613 if ((rtl_chip_info
[dev
->chipset
].flags
& HasLWake
) && (r
& RTL8139_PM_LWAKE
))
614 r2
&= ~RTL8139_PM_LWAKE
;
616 r2
|= RTL8139_PM_ENABLE
;
619 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
620 rtl8139_write8 (dev
, RTL8139_CONFIG1
, r
);
621 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
624 if (rtl_chip_info
[dev
->chipset
].flags
& HasLWake
) {
625 r
= rtl8139_read8 (dev
, RTL8139_CONFIG4
);
626 if (r
& RTL8139_PM_LWPTN
) {
627 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
628 rtl8139_write8 (dev
, RTL8139_CONFIG4
, r
& ~RTL8139_PM_LWPTN
);
629 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
633 r
= rtl8139_read8 (dev
, RTL8139_CONFIG1
);
634 r
&= ~(RTL8139_PM_SLEEP
| RTL8139_PM_PWRDN
);
635 rtl8139_write8 (dev
, RTL8139_CONFIG1
, r
);
638 /* reset device now */
641 /* set interrupt vector */
642 irq_install_handler (dev
->irq
, rtl8139_int
);
644 return rtl8139_start (dev
);
647 unsigned rtl8139_start (struct rtl8139_dev_t
*dev
)
649 /* Put the chip into low-power mode. */
650 if (rtl_chip_info
[dev
->chipset
].flags
& HasHltClk
)
651 rtl8139_write8 (dev
, RTL8139_HLTCLK
, 'R'); /* 'R' would leave the clock running. */
653 /* reset device now */
656 // enable writing to the config registers
657 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0xc0);
660 rtl8139_write8 (dev
, RTL8139_CONFIG1
, 0x0);
663 for (i
= 0; i
< 6; i
++)
664 rtl8139_write8 (dev
, RTL8139_IDR0
+ i
, dev
->addr_mac
[i
]);
666 // enable rx and tx functions
667 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
669 // set rx fifo threashold to 256bytes
670 rtl8139_write32 (dev
, RTL8139_RXCONFIG
, 0x00009c00);/*RTL8139_RX_RBLEN0 | RTL8139_RX_MXDMA2 | RTL8139_RX_MXDMA1 |
671 RTL8139_RX_AB | RTL8139_RX_AM | RTL8139_RX_APM);*/
673 // set tx fifo threashold to 256bytes
674 rtl8139_write32 (dev
, RTL8139_TXCONFIG
, 0x03000400);/*RTL8139_TX_IFG0 | RTL8139_TX_IFG1 | RTL8139_TX_MXDMA2 |
675 RTL8139_TX_MXDMA1);*/
677 // disable lan-wake and set the driver-loaded bit
678 rtl8139_write8 (dev
, RTL8139_CONFIG1
, (rtl8139_read8 (dev
, RTL8139_CONFIG1
) & ~0x30) | 0x20);
680 // enable fifo auto-clear
681 rtl8139_write8 (dev
, RTL8139_CONFIG4
, rtl8139_read8 (dev
, RTL8139_CONFIG4
) | 0x80);
683 // enable receiving broadcast and physical packets
684 rtl8139_write32 (dev
, RTL8139_RXCONFIG
, rtl8139_read32 (dev
, RTL8139_RXCONFIG
) | 0x0000000f);
686 // go back to normal mode
687 rtl8139_write8 (dev
, RTL8139_CFG9346
, 0x0);
690 dev
->rxbuf
= (char *) 0x51000;
692 rtl8139_write32 (dev
, RTL8139_RXBUF
, (unsigned) dev
->rxbuf
);
695 dev
->txbuf
= (char *) 0x59000;
697 rtl8139_write32 (dev
, RTL8139_TXADDR0
, (unsigned) dev
->txbuf
);
698 rtl8139_write32 (dev
, RTL8139_TXADDR1
, (unsigned) dev
->txbuf
+ 2*1024);
699 rtl8139_write32 (dev
, RTL8139_TXADDR2
, (unsigned) dev
->txbuf
+ 4*1024);
700 rtl8139_write32 (dev
, RTL8139_TXADDR3
, (unsigned) dev
->txbuf
+ 6*1024);
702 // reset rx missed counter
703 rtl8139_write32 (dev
, RTL8139_RXMISSED
, 0x0);
705 // filter all multicast packets
706 rtl8139_write32 (dev
, RTL8139_MAR0
, 0x0);
707 rtl8139_write32 (dev
, RTL8139_MAR0
+ 4, 0x0);
709 // disable all multi-interrupts
710 rtl8139_write16 (dev
, RTL8139_MULTIINTR
, 0x0);
713 unsigned char chipstatus
= rtl8139_read8 (dev
, RTL8139_CHIPCMD
);
715 if (chipstatus
& RTL8139_CMD_TX_ENABLE
|| chipstatus
& RTL8139_CMD_RX_ENABLE
)
716 rtl8139_write8 (dev
, RTL8139_CHIPCMD
, RTL8139_CMD_RX_ENABLE
| RTL8139_CMD_TX_ENABLE
);
718 //rtl8139_write8 (dev, RTL8139_CFG9346, 0);
720 rtl8139_write16 (dev
, RTL8139_INTRMASK
, MYRT_INTS
);
722 /* create new network device */
723 ifdev
= netdev_create (dev
->addr_mac
, &rtl8139_read
, &rtl8139_write
, dev
->addr_io
);
731 bool rtl8139_acthandler (unsigned act
, char *block
, unsigned block_len
)
736 return init_rtl8139 ();
747 return rtl8139_tx (rtl8139_dev
, block
, block_len
);