Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / drivers / net / rtl8169 / rtl8169.c
blobcf670b76445aaf5948b3d28405f2822718b4dc07
1 /*
2 * ZeX/OS
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/>.
21 #include <config.h>
22 #include <build.h>
24 #ifndef ARCH_i386
25 #undef CONFIG_DRV_RTL8169
26 #endif
28 #ifdef CONFIG_DRV_RTL8169
30 #include <system.h>
31 #include <string.h>
32 #include <arch/io.h>
33 #include <pci.h>
34 #include <task.h>
35 #include <net/eth.h>
36 #include <net/net.h>
38 /* PCI probe IDs */
39 #define RTL8169_VENDORID 0x10ec
40 #define RTL8169_DEVICEID 0x8169
41 #define RTL8169_DEVICEID2 0x8168
43 /* RTL8169 register definitions */
44 #define RTL8169_IDR0 0x00 /* Mac address */
45 #define RTL8169_MAR0 0x08 /* Multicast filter */
46 #define RTL8169_TXSTATUS0 0x10 /* Transmit status (4 32bit regs) */
47 #define RTL8169_TXSTATUS1 0x14 /* Transmit status (4 32bit regs) */
48 #define RTL8169_TXSTATUS2 0x18 /* Transmit status (4 32bit regs) */
49 #define RTL8169_TXSTATUS3 0x1c /* Transmit status (4 32bit regs) */
50 #define RTL8169_TXADDR0 0x20 /* Tx descriptors (also 4 32bit) */
51 #define RTL8169_TXADDR1 0x24 /* Tx descriptors (also 4 32bit) */
52 #define RTL8169_TXADDR2 0x28 /* Tx descriptors (also 4 32bit) */
53 #define RTL8169_TXADDR3 0x2c /* Tx descriptors (also 4 32bit) */
54 #define RTL8169_RXBUF 0x30 /* Receive buffer start address */
55 #define RTL8169_RXEARLYCNT 0x34 /* Early Rx byte count */
56 #define RTL8169_RXEARLYSTATUS 0x36 /* Early Rx status */
57 #define RTL8169_CHIPCMD 0x37 /* Command register */
58 #define RTL8169_RXBUFTAIL 0x38 /* Current address of packet read (queue tail) */
59 #define RTL8169_RXBUFHEAD 0x3A /* Current buffer address (queue head) */
60 #define RTL8169_INTRMASK 0x3C /* Interrupt mask */
61 #define RTL8169_INTRSTATUS 0x3E /* Interrupt status */
62 #define RTL8169_TXCONFIG 0x40 /* Tx config */
63 #define RTL8169_RXCONFIG 0x44 /* Rx config */
64 #define RTL8169_TIMER 0x48 /* A general purpose counter */
65 #define RTL8169_RXMISSED 0x4C /* 24 bits valid, write clears */
66 #define RTL8169_CFG9346 0x50 /* 93C46 command register */
67 #define RTL8169_CONFIG0 0x51 /* Configuration reg 0 */
68 #define RTL8169_CONFIG1 0x52 /* Configuration reg 1 */
69 #define RTL8169_TIMERINT 0x58 /* Timer interrupt register (32 bits) */
70 #define RTL8169_MEDIASTATUS 0x58 /* Media status register */
71 #define RTL8169_CONFIG3 0x59 /* Config register 3 */
72 #define RTL8169_CONFIG4 0x5A /* Config register 4 */
73 #define RTL8169_HLTCLK 0x5B /* Halted Clock */
74 #define RTL8169_MULTIINTR 0x5C /* Multiple interrupt select */
75 #define RTL8169_MII_TSAD 0x60 /* Transmit status of all descriptors (16 bits) */
76 #define RTL8169_MII_BMCR 0x62 /* Basic Mode Control Register (16 bits) */
77 #define RTL8169_MII_BMSR 0x64 /* Basic Mode Status Register (16 bits) */
78 #define RTL8169_AS_ADVERT 0x66 /* Auto-negotiation advertisement reg (16 bits) */
79 #define RTL8169_AS_LPAR 0x68 /* Auto-negotiation link partner reg (16 bits) */
80 #define RTL8169_AS_EXPANSION 0x6A /* Auto-negotiation expansion reg (16 bits) */
81 #define RTL8169_CCR 0xE0 /* */
82 #define RTL8169_TNPDS_LOW 0x20
83 #define RTL8169_TNPDS_HIGH 0x24
84 #define RTL8169_THPDS_LOW 0x28
85 #define RTL8169_THPDS_HIGH 0x2C
86 #define RTL8169_RDSAR_LOW 0xE4
87 #define RTL8169_RDSAR_HIGH 0xE8
88 #define RTL8169_RMS 0xDA
89 #define RTL8169_MTPS 0xEC
91 /* RTL8169 command bits; or these together and write teh resulting value
92 into CHIPCMD to execute it. */
93 #define RTL8169_CMD_RESET (1<<4)
94 #define RTL8169_CMD_RX_ENABLE 0x08
95 #define RTL8169_CMD_TX_ENABLE 0x04
96 #define RTL8169_CMD_RX_BUF_EMPTY 0x01
98 /* RTL8169 interrupt status bits */
99 #define RTL8169_INT_SYSERR (1<<15) /* PCI Bus error */
100 #define RTL8169_INT_TIMEOUT (1<<14) /* Set when TCTR reaches TimerInt value */
101 #define RTL8169_INT_SWINT (1<<8)
102 #define RTL8169_INT_TX_UNDERRUN (1<<7) /* Packet underrun */
103 #define RTL8169_INT_RX_OVERFLOW (1<<6) /* Rx BUFFER overflow */
104 #define RTL8169_INT_LINKCHG (1<<5) /* Link change */
105 #define RTL8169_INT_RX_UNDERRUN (1<<4) /* Packet underrun */
106 #define RTL8169_INT_TX_ERR (1<<3)
107 #define RTL8169_INT_TX_OK (1<<2)
108 #define RTL8169_INT_RX_ERR (1<<1)
109 #define RTL8169_INT_RX_OK (1<<0)
111 /* RTL8169 transmit status bits */
112 #define RTL8169_TX_CARRIER_LOST 0x80000000 /* Carrier sense lost */
113 #define RTL8169_TX_ABORTED 0x40000000 /* Transmission aborted */
114 #define RTL8169_TX_OUT_OF_WINDOW 0x20000000 /* Out of window collision */
115 #define RTL8169_TX_CARRIER_HBEAT 0x10000000 /* not sure */
116 #define RTL8169_TX_STATUS_OK 0x00008000 /* Status ok: a good packet was transmitted */
117 #define RTL8169_TX_UNDERRUN 0x00004000 /* Transmit FIFO underrun */
118 #define RTL8169_TX_HOST_OWNS 0x00002000 /* Set to 1 when DMA operation is completed */
119 #define RTL8169_TX_SIZE_MASK 0x00001fff /* Descriptor size mask */
121 #define RTL8169_TX_IFG0 0x1000000
122 #define RTL8169_TX_IFG1 0x2000000
123 #define RTL8169_TX_MXDMA2 0x400
124 #define RTL8169_TX_MXDMA1 0x200
126 /* RTL8169 receive status bits */
127 #define RTL8169_RX_MULTICAST 0x00008000 /* Multicast packet */
128 #define RTL8169_RX_PAM 0x00004000 /* Physical address matched */
129 #define RTL8169_RX_BROADCAST 0x00002000 /* Broadcast address matched */
130 #define RTL8169_RX_BAD_SYMBOL 0x00000020 /* Invalid symbol in 100TX packet */
131 #define RTL8169_RX_RUNT 0x00000010 /* Packet size is <64 bytes */
132 #define RTL8169_RX_TOO_LONG 0x00000008 /* Packet size is >4K bytes */
133 #define RTL8169_RX_CRC_ERR 0x00000004 /* CRC error */
134 #define RTL8169_RX_FRAME_ALIGN 0x00000002 /* Frame alignment error */
135 #define RTL8169_RX_STATUS_OK 0x00000001 /* Status ok: a good packet was received */
137 #define RTL8169_RX_RBLEN0 0x800
138 #define RTL8169_RX_MXDMA2 0x400
139 #define RTL8169_RX_MXDMA1 0x200
140 #define RTL8169_RX_AB 0x8
141 #define RTL8169_RX_AM 0x4
142 #define RTL8169_RX_APM 0x2
144 /* CONFIG */
145 #define RTL8169_CFG9346_LOCK 0x00
146 #define RTL8169_CFG9346_UNLOCK 0xc0
148 /* RTL8169 descriptors length in bytes */
149 #define RTL8169_DESC_LEN 16
151 /* RTL8169 descriptors settings */
152 #define RTL8169_TX_DESC 64
153 #define RTL8169_RX_DESC 256
155 #define BUFSIZE_PER_FRAME 2048
157 #define RXDESC(r, num) ((dev)->rxdesc[num])
158 #define TXDESC(r, num) ((dev)->txdesc[num])
159 #define RXDESC_PHYS(r, num) ((dev)->rxdesc_phys + (num) * sizeof(rtl8169_rx_desc))
160 #define TXDESC_PHYS(r, num) ((dev)->txdesc_phys + (num) * sizeof(rtl8169_tx_desc))
161 #define RXBUF(r, num) (&(dev)->rxbuf[(num) * BUFSIZE_PER_FRAME])
162 #define TXBUF(r, num) (&(dev)->txbuf[(num) * BUFSIZE_PER_FRAME])
164 enum mac_version {
165 RTL_GIGA_MAC_VER_01 = 0x01, // 8169
166 RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
167 RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
168 RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
169 RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
170 RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
171 RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
172 RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
173 RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
174 RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ?
175 RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ?
176 RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec
177 RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf
178 RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP
179 RTL_GIGA_MAC_VER_19 = 0x13, // 8168C
180 RTL_GIGA_MAC_VER_20 = 0x14 // 8168C
183 #define _R(NAME,MAC,MASK) \
184 { .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
186 static const struct {
187 const char *name;
188 unsigned char mac_version;
189 unsigned RxConfigMask; /* Clears the bits supported by this chip */
190 } rtl_chip_info[] = {
191 _R("RTL8169", RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
192 _R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
193 _R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
194 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
195 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
196 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
197 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
198 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
199 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
200 _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
201 _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139
202 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E
203 _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E
204 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E
205 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E
206 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880) // PCI-E
208 #undef _R
210 enum cfg_version {
211 RTL_CFG_0 = 0x00,
212 RTL_CFG_1,
213 RTL_CFG_2
216 struct rtl8169_tx_desc {
217 unsigned short frame_len;
218 unsigned short flags;
219 unsigned vlan;
220 unsigned tx_buffer_low;
221 unsigned tx_buffer_high;
224 struct rtl8169_rx_desc {
225 union {
226 unsigned short buffer_size; /* rx command */
227 unsigned short frame_len; /* rx status - top 2 bits are checksum offload flags */
229 unsigned short flags;
230 unsigned vlan;
231 unsigned rx_buffer_low;
232 unsigned rx_buffer_high;
235 /* descriptor bits */
236 #define RTL_DESC_OWN (1<<15)
237 #define RTL_DESC_EOR (1<<14)
238 #define RTL_DESC_FS (1<<13)
239 #define RTL_DESC_LS (1<<12)
241 /* rtl8169 device structure */
242 struct rtl8169_dev_t {
243 unsigned char irq;
244 pcidev_t *pcidev;
245 unsigned short addr_io;
246 mac_addr_t addr_mac;
247 char *txbuf;
248 char *rxbuf;
250 struct rtl8169_tx_desc *txdesc;
251 unsigned txdesc_phys;
252 int tx_idx_free; // first free descriptor (owned by us)
253 int tx_idx_full; // first full descriptor (owned by the NIC)
255 struct rtl8169_rx_desc *rxdesc;
256 unsigned rxdesc_phys;
257 int rx_idx_free; // first free descriptor (owned by us)
258 int rx_idx_full; // first full descriptor (owned by the NIC)
261 struct rtl8169_dev_t *rtl8169_dev;
262 static netdev_t *ifdev;
264 /* prototypes */
265 unsigned rtl8169_start (struct rtl8169_dev_t *dev);
266 unsigned rtl8169_int_rx (struct rtl8169_dev_t *dev, unsigned short status);
267 unsigned rtl8169_int_tx (struct rtl8169_dev_t *dev, unsigned short status);
268 bool rtl8169_acthandler (unsigned act, char *block, unsigned block_len);
270 /* I/O operations */
271 unsigned char rtl8169_read8 (struct rtl8169_dev_t *dev, unsigned short port)
273 return inb (dev->addr_io + port);
276 void rtl8169_write8 (struct rtl8169_dev_t *dev, unsigned short port, unsigned char val)
278 outb (dev->addr_io + port, val);
281 unsigned short rtl8169_read16 (struct rtl8169_dev_t *dev, unsigned short port)
283 return inw (dev->addr_io + port);
286 void rtl8169_write16 (struct rtl8169_dev_t *dev, unsigned short port, unsigned short val)
288 outw (dev->addr_io + port, val);
291 unsigned rtl8169_read32 (struct rtl8169_dev_t *dev, unsigned short port)
293 return inl (dev->addr_io + port);
296 void rtl8169_write32 (struct rtl8169_dev_t *dev, unsigned short port, unsigned val)
298 outl (dev->addr_io + port, val);
301 /* READ/WRITE func */
302 unsigned rtl8169_read (char *buf, unsigned len)
304 return rtl8169_acthandler (DEV_ACT_READ, buf, len);
307 unsigned rtl8169_write (char *buf, unsigned len)
309 return rtl8169_acthandler (DEV_ACT_WRITE, buf, len);
312 /* detect rtl8169 device in PC */
313 pcidev_t *rtl8169_detect ()
315 /* First detect network card - is connected to PCI bus ?*/
316 pcidev_t *pcidev;
318 pcidev = pcidev_find (RTL8169_VENDORID, RTL8169_DEVICEID);
320 if (!pcidev)
321 pcidev = pcidev_find (RTL8169_VENDORID, RTL8169_DEVICEID2);
322 else
323 return 0;
325 return pcidev;
328 /* reset rtl8169 device */
329 unsigned rtl8169_reset (struct rtl8169_dev_t *dev)
331 rtl8169_write8 (dev, RTL8169_CHIPCMD, RTL8169_CMD_RESET);
333 while (rtl8169_read8 (dev, RTL8169_CHIPCMD) & RTL8169_CMD_RESET) {
334 kprintf ("waiting for rtl8169 reset :)\n");
335 timer_wait (50);
338 return 1;
341 /* nic interrupt handler */
342 void rtl8169_int ()
344 struct rtl8169_dev_t *dev = rtl8169_dev;
346 unsigned short status = rtl8169_read16 (dev, RTL8169_INTRSTATUS);
348 kprintf ("rtl8169_int ()\n");
350 if (!status)
351 return;
353 if (status & (RTL8169_INT_RX_OK | RTL8169_INT_RX_ERR | RTL8169_INT_RX_UNDERRUN | RTL8169_INT_RX_OVERFLOW))
354 rtl8169_int_rx (dev, status);
356 if (status & (RTL8169_INT_TX_OK | RTL8169_INT_TX_ERR | RTL8169_INT_TX_UNDERRUN))
357 rtl8169_int_tx (dev, status);
359 rtl8169_write16 (dev, RTL8169_INTRSTATUS, status);
362 unsigned rtl8169_int_rx (struct rtl8169_dev_t *dev, unsigned short status)
364 kprintf ("rtl8169_int_rx (): 0x%x\n", status);
366 return 1;
369 unsigned rtl8169_tx (struct rtl8169_dev_t *dev, char *buf, unsigned len)
372 return 1;
375 unsigned rtl8169_int_tx (struct rtl8169_dev_t *dev, unsigned short status)
377 kprintf ("rtl8169_int_tx (): 0x%x\n", status);
379 return 1;
382 /* INIT sequence */
383 unsigned init_rtl8169 ()
385 unsigned i = 0;
387 pcidev_t *pcidev = rtl8169_detect ();
389 if (!pcidev)
390 return 0;
392 struct rtl8169_dev_t *dev = (struct rtl8169_dev_t *) kmalloc (sizeof (struct rtl8169_dev_t));
394 if (!dev)
395 return 0;
397 /* get irq id */
398 dev->irq = pcidev->u.h0.interrupt_line;
399 dev->addr_io = pcidev->u.h0.base_registers[0];
401 kprintf ("dev->irq: %d\ndev->addr_io: 0x%x\n", dev->irq, dev->addr_io);
403 timer_wait (5000);
405 /* reset device now */
406 rtl8169_reset (dev);
408 // get mac address from ethernet
409 for (i = 0; i < 6; i ++) {
410 dev->addr_mac[i] = rtl8169_read8 (dev, RTL8169_IDR0 + i);
413 rtl8169_dev = dev;
415 return rtl8169_start (dev);
418 unsigned rtl8169_start (struct rtl8169_dev_t *dev)
420 int i;
422 dev->rxdesc_phys = 0x51000;
423 dev->txdesc_phys = 0x69000;
425 dev->rxdesc = (struct rtl8169_rx_desc *) dev->rxdesc_phys;
426 dev->txdesc = (struct rtl8169_tx_desc *) dev->txdesc_phys;
428 rtl8169_write8 (dev, RTL8169_CFG9346, RTL8169_CFG9346_UNLOCK);
430 /* some kind of magic */
431 unsigned short r = rtl8169_read16 (dev, RTL8169_CCR);
432 rtl8169_write16 (dev, RTL8169_CCR, r);
433 r = rtl8169_read16 (dev, RTL8169_CCR);
434 rtl8169_write16 (dev, RTL8169_CCR, r | 0x3);
436 /* set up the rx/tx descriptors */
437 for (i = 0; i < RTL8169_RX_DESC; i ++) {
438 unsigned physaddr = (unsigned) RXBUF (dev, i);
440 dev->rxdesc[i].rx_buffer_low = physaddr;
441 dev->rxdesc[i].rx_buffer_high = 0;
442 dev->rxdesc[i].frame_len = BUFSIZE_PER_FRAME;
443 dev->rxdesc[i].flags = RTL_DESC_OWN | ((i == (RTL8169_RX_DESC - 1)) ? RTL_DESC_EOR : 0);
446 for (i = 0; i < RTL8169_TX_DESC; i ++) {
447 unsigned physaddr = (unsigned) TXBUF (r, i);
449 dev->txdesc[i].tx_buffer_low = physaddr;
450 dev->txdesc[i].tx_buffer_high = 0;
451 dev->txdesc[i].frame_len = 0; // will need to be filled in when transmitting
452 dev->txdesc[i].flags = (i == (RTL8169_TX_DESC - 1)) ? RTL_DESC_EOR : 0;
455 /* set up our index pointers */
456 dev->rx_idx_free = 0;
457 dev->rx_idx_full = 0;
458 dev->tx_idx_free = 0;
459 dev->tx_idx_full = 0;
461 /* point the nic at the descriptors */
462 rtl8169_write32 (dev, RTL8169_TNPDS_LOW, dev->txdesc_phys);
463 rtl8169_write32 (dev, RTL8169_TNPDS_HIGH, 0);
464 rtl8169_write32 (dev, RTL8169_RDSAR_LOW, dev->rxdesc_phys);
465 rtl8169_write32 (dev, RTL8169_RDSAR_HIGH, 0);
467 rtl8169_write8 (dev, RTL8169_CFG9346, RTL8169_CFG9346_LOCK);
469 rtl8169_read8 (dev, RTL8169_INTRMASK);
471 /* mask all interrupts */
472 rtl8169_write32 (dev, RTL8169_INTRMASK, 0);
474 /* set up the rx state */
475 /* 1024 byte dma threshold, 1024 dma max burst, CRC calc 8 byte+, accept all packets */
476 rtl8169_write32 (dev, RTL8169_RXCONFIG, (1 << 16) | (6 << 13) | (6 << 8) | (0xf << 0));
477 rtl8169_write16 (dev, RTL8169_CCR, rtl8169_read16 (dev, RTL8169_CCR) | (1 << 5)); // rx checksum enable
478 rtl8169_write16 (dev, RTL8169_RMS, 1518); // rx mtu
480 /* set up the tx state */
481 rtl8169_write32 (dev, RTL8169_TXCONFIG, (rtl8169_read16 (dev, RTL8169_TXCONFIG) & ~0x1ff) | (6 << 8)); /* 1024 max burst dma*/
482 rtl8169_write8 (dev, RTL8169_MTPS, 0x3f); /* max tx packet size (must be careful to not actually transmit more than mtu) */
484 /* set interrupt vector */
485 irq_install_handler (dev->irq, rtl8169_int);
487 /* clear all pending interrupts */
488 rtl8169_write16 (dev, RTL8169_INTRSTATUS, 0xffff);
490 /* unmask interesting interrupts */
491 rtl8169_write16 (dev, RTL8169_INTRMASK, RTL8169_INT_SYSERR | RTL8169_INT_LINKCHG | RTL8169_INT_TX_ERR | RTL8169_INT_TX_OK | RTL8169_INT_RX_ERR | RTL8169_INT_RX_OK | RTL8169_INT_RX_OVERFLOW);
493 timer_wait (500);
495 unsigned short status = rtl8169_read16 (dev, RTL8169_INTRSTATUS);
497 kprintf ("rtl8169_status: 0x%x\n", status);
499 timer_wait (2000);
501 /* create new network device */
502 ifdev = netdev_create (dev->addr_mac, &rtl8169_read, &rtl8169_write, dev->addr_io);
504 if (!ifdev)
505 return 0;
507 ifdev->irq = dev->irq;
509 return 1;
512 bool rtl8169_acthandler (unsigned act, char *block, unsigned block_len)
514 switch (act) {
515 case DEV_ACT_INIT:
517 return init_rtl8169 ();
519 break;
520 case DEV_ACT_READ:
523 return 1;
525 break;
526 case DEV_ACT_WRITE:
528 return rtl8169_tx (rtl8169_dev, block, block_len);
530 break;
533 return 0;
535 #endif