1 /* Realtek RTL8169 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
4 * Permission to use, copy, modify and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies, and that both the
7 * copyright notice and this permission notice appear in supporting documentation.
9 * Marcus Overhagen makes no representations about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS
14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <KernelExport.h>
26 #include <driver_settings.h>
27 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
28 #include <net/if_media.h>
38 static int32 gOpenMask
= 0;
42 read_settings(rtl8169_device
*device
)
48 handle
= load_driver_settings("rtl8169");
52 param
= get_driver_parameter(handle
, "mtu", "-1", "-1");
54 if (mtu
>= 50 && mtu
<= 1500)
55 device
->maxframesize
= mtu
+ 14;
57 dprintf("rtl8169: unsupported mtu setting '%s' ignored\n", param
);
59 param
= get_driver_parameter(handle
, "rx_buffer_count", "-1", "-1");
61 if (count
>= 2 && count
<= 1024)
62 device
->rxBufferCount
= count
;
64 dprintf("rtl8169: unsupported rx_buffer_count setting '%s' ignored\n", param
);
66 param
= get_driver_parameter(handle
, "tx_buffer_count", "-1", "-1");
68 if (count
>= 2 && count
<= 1024)
69 device
->txBufferCount
= count
;
71 dprintf("rtl8169: unsupported tx_buffer_count setting '%s' ignored\n", param
);
73 unload_driver_settings(handle
);
78 write_phy_reg(rtl8169_device
*device
, int reg
, uint16 value
)
81 write32(REG_PHYAR
, 0x80000000 | (reg
& 0x1f) << 16 | value
);
83 for (i
= 0; i
< 2000; i
++) {
84 if ((read32(REG_PHYAR
) & 0x80000000) == 0)
92 read_phy_reg(rtl8169_device
*device
, int reg
)
96 write32(REG_PHYAR
, (reg
& 0x1f) << 16);
98 for (i
= 0; i
< 2000; i
++) {
99 v
= read32(REG_PHYAR
);
109 write_phy_reg_bit(rtl8169_device
*device
, int reg
, int bitnum
, int bitval
)
111 uint16 val
= read_phy_reg(device
, reg
);
113 val
|= (1 << bitnum
);
115 val
&= ~(1 << bitnum
);
116 write_phy_reg(device
, reg
, val
);
121 phy_config(rtl8169_device
*device
)
123 TRACE("phy_config()\n");
125 if (device
->phy_version
== 0 || device
->phy_version
== 1) {
127 TRACE("performing phy init\n");
128 // XXX this should probably not be done if the phy wasn't
129 // identified, but BSD does it too for mac_version == 0 (=> phy_version also 0)
130 // doing the same as the BSD and Linux driver here
131 // see IEE 802.3-2002 (is also uses decimal numbers when refering
132 // to the registers, as do we). Added a little documentation
133 write_phy_reg(device
, 31, 0x0001); // vendor specific (enter programming mode?)
134 write_phy_reg(device
, 21, 0x1000); // vendor specific
135 write_phy_reg(device
, 24, 0x65c7); // vendor specific
136 write_phy_reg_bit(device
, 4, 11, 0); // reset T (T=toggle) bit in reg 4 (ability)
137 val
= read_phy_reg(device
, 4) & 0x0fff; // get only the message code fields
138 write_phy_reg(device
, 4, val
); // and write them back. this clears the page and makes it unformatted (see 37.2.4.3.1)
139 write_phy_reg(device
, 3, 0x00a1); // assign 32 bit phy identifier high word
140 write_phy_reg(device
, 2, 0x0008); // assign 32 bit phy identifier low word
141 write_phy_reg(device
, 1, 0x1020); // set status: 10 MBit full duplex and auto negotiation completed
142 write_phy_reg(device
, 0, 0x1000); // reset the phy!
143 write_phy_reg_bit(device
, 4, 11, 1); // set toggle bit high
144 write_phy_reg_bit(device
, 4, 11, 0); // set toggle bit low => this is a toggle
145 val
= (read_phy_reg(device
, 4) & 0x0fff) | 0x7000; // set ack1, ack2, indicate formatted page
146 write_phy_reg(device
, 4, val
); // write the value from above
147 write_phy_reg(device
, 3, 0xff41); // assign another
148 write_phy_reg(device
, 2, 0xde60); // 32 bit phy identifier
149 write_phy_reg(device
, 1, 0x0140); // phy will accept management frames with preamble suppressed, extended capability in reg 15
150 write_phy_reg(device
, 0, 0x0077); //
151 write_phy_reg_bit(device
, 4, 11, 1); // set toggle bit high
152 write_phy_reg_bit(device
, 4, 11, 0); // set toggle bit low => this is a toggle
153 val
= ( read_phy_reg(device
, 4) & 0x0fff) | 0xa000;
154 write_phy_reg(device
, 4, val
); //
155 write_phy_reg(device
, 3, 0xdf01); // assign another
156 write_phy_reg(device
, 2, 0xdf20); // 32 bit phy identifier
157 write_phy_reg(device
, 1, 0xff95); // phy will do 100Mbit and 10Mbit in full and half duplex, something reserved and
158 // remote fault detected, link is up and extended capability in reg 15
159 write_phy_reg(device
, 0, 0xfa00); // select 10 MBit, disable auto neg., half duplex normal operation
160 write_phy_reg_bit(device
, 4, 11, 1); // set toggle bit high
161 write_phy_reg_bit(device
, 4, 11, 0); // set toggle bit low => this is a toggle
162 val
= ( read_phy_reg(device
, 4) & 0x0fff) | 0xb000;
163 write_phy_reg(device
, 4, val
); // write capabilites
164 write_phy_reg(device
, 3, 0xff41); // assign another
165 write_phy_reg(device
, 2, 0xde20); // 32 bit phy identifier
166 write_phy_reg(device
, 1, 0x0140); // phy will accept management frames with preamble suppressed, extended capability in reg 15
167 write_phy_reg(device
, 0, 0x00bb); // write status
168 write_phy_reg_bit(device
, 4, 11, 1); // set toggle bit high
169 write_phy_reg_bit(device
, 4, 11, 0); // set toggle bit low => this is a toggle
170 val
= ( read_phy_reg(device
, 4) & 0x0fff) | 0xf000;
171 write_phy_reg(device
, 4, val
); //w 4 15 12 f
172 write_phy_reg(device
, 3, 0xdf01); // assign another
173 write_phy_reg(device
, 2, 0xdf20); // 32 bit phy identifier
174 write_phy_reg(device
, 1, 0xff95); // write capabilites
175 write_phy_reg(device
, 0, 0xbf00); // write status
176 write_phy_reg_bit(device
, 4, 11, 1); // set toggle bit high
177 write_phy_reg_bit(device
, 4, 11, 0); // set toggle bit low => this is a toggle
178 write_phy_reg(device
, 31, 0x0000); // vendor specific (leave programming mode?)
181 write_phy_reg(device
, 4, 0x01e1); // 10/100 capability
182 write_phy_reg(device
, 9, 0x0200); // 1000 capability
183 write_phy_reg(device
, 0, 0x1200); // enable auto negotiation and restart it
188 dump_phy_stat(rtl8169_device
*device
)
190 uint32 v
= read8(REG_PHY_STAT
);
191 if (v
& PHY_STAT_EnTBI
) {
192 uint32 tbi
= read32(REG_TBICSR
);
193 TRACE("TBI mode active\n");
194 if (tbi
& TBICSR_ResetTBI
)
195 TRACE("TBICSR_ResetTBI\n");
196 if (tbi
& TBICSR_TBILoopBack
)
197 TRACE("TBICSR_TBILoopBack\n");
198 if (tbi
& TBICSR_TBINWEn
)
199 TRACE("TBICSR_TBINWEn\n");
200 if (tbi
& TBICSR_TBIReNW
)
201 TRACE("TBICSR_TBIReNW\n");
202 if (tbi
& TBICSR_TBILinkOk
)
203 TRACE("TBICSR_TBILinkOk\n");
204 if (tbi
& TBICSR_NWComplete
)
205 TRACE("TBICSR_NWComplete\n");
207 TRACE("TBI mode NOT active\n");
208 if (v
& PHY_STAT_1000MF
)
209 TRACE("PHY_STAT_1000MF\n");
210 if (v
& PHY_STAT_100M
)
211 TRACE("PHY_STAT_100M\n");
212 if (v
& PHY_STAT_10M
)
213 TRACE("PHY_STAT_10M\n");
215 if (v
& PHY_STAT_TxFlow
)
216 TRACE("PHY_STAT_TxFlow\n");
217 if (v
& PHY_STAT_RxFlow
)
218 TRACE("PHY_STAT_RxFlow\n");
219 if (v
& PHY_STAT_LinkSts
)
220 TRACE("PHY_STAT_LinkSts\n");
221 if (v
& PHY_STAT_FullDup
)
222 TRACE("PHY_STAT_FullDup\n");
227 print_link_status(rtl8169_device
*device
)
229 uint32 phy
= read8(REG_PHY_STAT
);
230 if (phy
& PHY_STAT_EnTBI
) {
231 if (read32(REG_TBICSR
) & TBICSR_TBILinkOk
)
232 PRINT("Link active, 1000 Mbit Full Duplex (TBI mode)\n");
234 PRINT("Link not active (TBI mode)\n");
236 if (phy
& PHY_STAT_LinkSts
) {
237 if (phy
& PHY_STAT_1000MF
)
238 PRINT("Link active, 1000 Mbit Full Duplex (GMII mode)\n");
240 PRINT("Link active, %s Mbit %s Duplex (MII mode)\n",
241 (phy
& PHY_STAT_100M
) ? "100" : (phy
& PHY_STAT_10M
) ? "10" : "unknown",
242 (phy
& PHY_STAT_FullDup
) ? "Full" : "Half");
244 PRINT("Link not active (MII mode)\n");
252 print_debug_info(void *cookie
)
254 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
256 // only print if interrupt count changed
257 if (device
->intTotalCount
== device
->intTotalCountOld
)
260 PRINT("Int %10d, %6d/s Rx: %10d, %6d/s Tx: %10d, %6d/s Tmr %10d, %6d/s\n",
261 device
->intTotalCount
,
262 device
->intCurrentCount
,
263 device
->intRxTotalCount
,
264 device
->intRxCurrentCount
,
265 device
->intTxTotalCount
,
266 device
->intTxCurrentCount
,
267 device
->intTimerTotalCount
,
268 device
->intTimerCurrentCount
);
270 device
->intTotalCountOld
= device
->intTotalCount
;
271 device
->intCurrentCount
= 0;
272 device
->intRxCurrentCount
= 0;
273 device
->intTxCurrentCount
= 0;
274 device
->intTimerCurrentCount
= 0;
280 init_buf_desc(rtl8169_device
*device
)
282 void *rx_buf_desc_virt
, *rx_buf_desc_phy
;
283 void *tx_buf_desc_virt
, *tx_buf_desc_phy
;
284 void *tx_buf_virt
, *tx_buf_phy
;
285 void *rx_buf_virt
, *rx_buf_phy
;
288 device
->txBufArea
= alloc_contiguous(&tx_buf_virt
, &tx_buf_phy
,
289 device
->txBufferCount
* FRAME_SIZE
, 0, "rtl8169 tx buf");
290 device
->rxBufArea
= alloc_contiguous(&rx_buf_virt
, &rx_buf_phy
,
291 device
->rxBufferCount
* FRAME_SIZE
, 0, "rtl8169 rx buf");
292 device
->txDescArea
= alloc_contiguous(&tx_buf_desc_virt
, &tx_buf_desc_phy
,
293 device
->txBufferCount
* sizeof(buf_desc
), 0, "rtl8169 tx desc");
294 device
->rxDescArea
= alloc_contiguous(&rx_buf_desc_virt
, &rx_buf_desc_phy
,
295 device
->rxBufferCount
* sizeof(buf_desc
), 0, "rtl8169 rx desc");
296 if (device
->txBufArea
< B_OK
|| device
->rxBufArea
< B_OK
297 || device
->txDescArea
< B_OK
|| device
->rxDescArea
< B_OK
)
300 device
->txDesc
= (buf_desc
*)tx_buf_desc_virt
;
301 device
->rxDesc
= (buf_desc
*)rx_buf_desc_virt
;
303 // setup transmit descriptors
304 for (i
= 0; i
< device
->txBufferCount
; i
++) {
305 device
->txBuf
[i
] = (char *)tx_buf_virt
+ (i
* FRAME_SIZE
);
306 device
->txDesc
[i
].stat_len
= TX_DESC_FS
| TX_DESC_LS
;
307 device
->txDesc
[i
].buf_low
308 = (uint32
)((char *)tx_buf_phy
+ (i
* FRAME_SIZE
));
309 device
->txDesc
[i
].buf_high
= 0;
311 device
->txDesc
[i
- 1].stat_len
|= TX_DESC_EOR
;
313 // setup receive descriptors
314 for (i
= 0; i
< device
->rxBufferCount
; i
++) {
315 device
->rxBuf
[i
] = (char *)rx_buf_virt
+ (i
* FRAME_SIZE
);
316 device
->rxDesc
[i
].stat_len
= RX_DESC_OWN
| FRAME_SIZE
;
317 device
->rxDesc
[i
].buf_low
318 = (uint32
)((char *)rx_buf_phy
+ (i
* FRAME_SIZE
));
319 device
->rxDesc
[i
].buf_high
= 0;
321 device
->rxDesc
[i
- 1].stat_len
|= RX_DESC_EOR
;
323 write32(REG_RDSAR_LOW
, (uint32
)rx_buf_desc_phy
);
324 write32(REG_RDSAR_HIGH
, 0);
325 write32(REG_TNPDS_LOW
, (uint32
)tx_buf_desc_phy
);
326 write32(REG_TNPDS_HIGH
, 0);
327 write32(REG_THPDS_LOW
, 0); // high priority tx is unused
328 write32(REG_THPDS_HIGH
, 0);
335 rtl8169_tx_int(rtl8169_device
*device
)
340 acquire_spinlock(&device
->txSpinlock
);
342 for (count
= 0, limit
= device
->txUsed
; limit
> 0; limit
--) {
343 if (device
->txDesc
[device
->txIntIndex
].stat_len
& TX_DESC_OWN
)
345 device
->txIntIndex
= (device
->txIntIndex
+ 1) % device
->txBufferCount
;
349 // dprintf("tx int, txUsed %d, count %d\n", device->txUsed, count);
351 device
->txUsed
-= count
;
353 release_spinlock(&device
->txSpinlock
);
356 release_sem_etc(device
->txFreeSem
, count
, B_DO_NOT_RESCHEDULE
);
361 rtl8169_rx_int(rtl8169_device
*device
)
366 acquire_spinlock(&device
->rxSpinlock
);
368 for (count
= 0, limit
= device
->rxFree
; limit
> 0; limit
--) {
369 if (device
->rxDesc
[device
->rxIntIndex
].stat_len
& RX_DESC_OWN
)
371 device
->rxIntIndex
= (device
->rxIntIndex
+ 1) % device
->rxBufferCount
;
375 // dprintf("rx int, rxFree %d, count %d\n", device->rxFree, count);
377 device
->rxFree
-= count
;
379 release_spinlock(&device
->rxSpinlock
);
382 release_sem_etc(device
->rxReadySem
, count
, B_DO_NOT_RESCHEDULE
);
387 rtl8169_get_link_state(rtl8169_device
*device
)
389 bool link_ok
= false;
390 bool full_duplex
= false;
392 bool linkStateChange
= false;
395 dump_phy_stat(device
);
396 print_link_status(device
);
398 phy
= read8(REG_PHY_STAT
);
399 if (phy
& PHY_STAT_EnTBI
) {
400 link_ok
= (read32(REG_TBICSR
) & TBICSR_TBILinkOk
);
406 if (phy
& PHY_STAT_LinkSts
) {
408 if (phy
& PHY_STAT_1000MF
) {
412 speed
= (phy
& PHY_STAT_100M
) ? 100000 : 10000;
413 full_duplex
= (phy
& PHY_STAT_FullDup
);
418 linkStateChange
= (link_ok
!= device
->link_ok
419 || full_duplex
!= device
->full_duplex
420 || speed
!= device
->speed
);
422 device
->link_ok
= link_ok
;
423 device
->full_duplex
= full_duplex
;
424 device
->speed
= speed
;
426 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
427 if (linkStateChange
&& device
->linkChangeSem
>= B_OK
)
428 release_sem_etc(device
->linkChangeSem
, 1, B_DO_NOT_RESCHEDULE
);
436 rtl8169_int(void *data
)
438 rtl8169_device
*device
= (rtl8169_device
*)data
;
442 stat
= read16(REG_INT_STAT
);
443 if (stat
== 0 || stat
== 0xffff)
444 return B_UNHANDLED_INTERRUPT
;
446 write16(REG_INT_STAT
, stat
);
447 ret
= B_HANDLED_INTERRUPT
;
449 PROFILING_ONLY(device
->intTotalCount
++);
450 PROFILING_ONLY(device
->intCurrentCount
++);
453 if (stat
& INT_TimeOut
) {
454 PROFILING_ONLY(device
->intTimerTotalCount
++);
455 PROFILING_ONLY(device
->intTimerCurrentCount
++);
458 if (stat
& INT_PUN
) {
459 rtl8169_get_link_state(device
);
462 if (stat
& (INT_TOK
| INT_TER
)) {
463 rtl8169_tx_int(device
);
464 PROFILING_ONLY(device
->intTxTotalCount
++);
465 PROFILING_ONLY(device
->intTxCurrentCount
++);
466 ret
= B_INVOKE_SCHEDULER
;
469 if (stat
& (INT_ROK
| INT_RER
| INT_FOVW
)) {
470 rtl8169_rx_int(device
);
471 PROFILING_ONLY(device
->intRxTotalCount
++);
472 PROFILING_ONLY(device
->intRxCurrentCount
++);
473 ret
= B_INVOKE_SCHEDULER
;
481 rtl8169_open(const char *name
, uint32 flags
, void** cookie
)
483 rtl8169_device
*device
;
491 TRACE("rtl8169_open()\n");
493 for (dev_id
= 0; (deviceName
= gDevNameList
[dev_id
]) != NULL
; dev_id
++) {
494 if (!strcmp(name
, deviceName
))
497 if (deviceName
== NULL
) {
498 ERROR("invalid device name\n");
502 // allow only one concurrent access
504 if (atomic_or(&gOpenMask
, mask
) & mask
)
507 *cookie
= device
= (rtl8169_device
*)malloc(sizeof(rtl8169_device
));
509 atomic_and(&gOpenMask
, ~(1 << dev_id
));
513 memset(device
, 0, sizeof(*device
));
515 device
->devId
= dev_id
;
516 device
->pciInfo
= gDevList
[dev_id
];
517 device
->nonblocking
= (flags
& O_NONBLOCK
) ? true : false;
518 device
->closed
= false;
521 device
->maxframesize
= 1514; // not FRAME_SIZE
522 device
->txBufferCount
= DEFAULT_TX_BUF_COUNT
;
523 device
->rxBufferCount
= DEFAULT_RX_BUF_COUNT
;
524 // get modifications from settings file
525 read_settings(device
);
527 device
->rxBuf
= (void **)malloc(sizeof(void *) * device
->rxBufferCount
);
528 B_INITIALIZE_SPINLOCK(&device
->rxSpinlock
);
529 device
->rxNextIndex
= 0;
530 device
->rxIntIndex
= 0;
531 device
->rxFree
= device
->rxBufferCount
;
532 device
->rxReadySem
= create_sem(0, "rtl8169 rx ready");
534 device
->txBuf
= (void **)malloc(sizeof(void *) * device
->txBufferCount
);
535 B_INITIALIZE_SPINLOCK(&device
->txSpinlock
);
536 device
->txNextIndex
= 0;
537 device
->txIntIndex
= 0;
539 device
->txFreeSem
= create_sem(device
->txBufferCount
, "rtl8169 tx free");
541 // enable busmaster and memory mapped access, disable io port access
542 val
= gPci
->read_pci_config(device
->pciInfo
->bus
, device
->pciInfo
->device
,
543 device
->pciInfo
->function
, PCI_command
, 2);
544 val
= PCI_PCICMD_BME
| PCI_PCICMD_MSE
| (val
& ~PCI_PCICMD_IOS
);
545 gPci
->write_pci_config(device
->pciInfo
->bus
, device
->pciInfo
->device
,
546 device
->pciInfo
->function
, PCI_command
, 2, val
);
548 // adjust PCI latency timer
549 TRACE("changing PCI latency to 0x40\n");
550 gPci
->write_pci_config(device
->pciInfo
->bus
, device
->pciInfo
->device
,
551 device
->pciInfo
->function
, PCI_latency
, 1, 0x40);
554 device
->irq
= device
->pciInfo
->u
.h0
.interrupt_line
;
555 if (device
->irq
== 0 || device
->irq
== 0xff) {
556 ERROR("no IRQ assigned\n");
560 TRACE("IRQ %d\n", device
->irq
);
562 // map registers into memory
564 if (device
->pciInfo
->device_id
== 0x8168)
569 TRACE("hardware register address [%i] %p\n", mmioIndex
,
570 (void *)device
->pciInfo
->u
.h0
.base_registers
[mmioIndex
]);
572 device
->regArea
= map_mem(&device
->regAddr
,
573 (void *)device
->pciInfo
->u
.h0
.base_registers
[mmioIndex
], 256, 0,
575 if (device
->regArea
< B_OK
) {
576 ERROR("can't map hardware registers\n");
580 TRACE("mapped registers to %p\n", device
->regAddr
);
582 // disable receiver & transmitter XXX might be removed
583 write8(REG_CR
, read8(REG_CR
) & ~(CR_RE
| CR_TE
));
586 write8(REG_CR
, read8(REG_CR
) | CR_RST
);
587 for (i
= 0; (read8(REG_CR
) & CR_RST
) && i
< 1000; i
++)
590 ERROR("hardware reset failed\n");
594 TRACE("reset done\n");
596 // get MAC hardware version
597 device
->mac_version
= ((read32(REG_TX_CONFIG
) & 0x7c000000) >> 25)
598 | ((read32(REG_TX_CONFIG
) & 0x00800000) >> 23);
599 TRACE("8169 Mac Version %d\n", device
->mac_version
);
600 if (device
->mac_version
> 0) { // this is a RTL8169s single chip
601 // get PHY hardware version
602 device
->phy_version
= read_phy_reg(device
, 0x03) & 0x000f;
603 TRACE("8169 Phy Version %d\n", device
->phy_version
);
605 // we should probably detect what kind of phy is used
606 device
->phy_version
= 0;
607 TRACE("8169 Phy Version unknown\n");
610 if (device
->mac_version
== 1) {
611 // as it's done by the BSD driver...
612 TRACE("Setting MAC Reg C+CR 0x82h = 0x01h\n");
613 write8(0x82, 0x01); // don't know what this does
614 TRACE("Setting PHY Reg 0x0bh = 0x00h\n");
615 write_phy_reg(device
, 0x0b, 0x0000);
616 // 0xb is a reserved (vendor specific register), don't know what
623 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
624 device
->linkChangeSem
= -1;
627 rtl8169_get_link_state(device
);
629 // initialize MAC address
630 for (i
= 0; i
< 6; i
++)
631 device
->macaddr
[i
] = read8(i
);
633 TRACE("MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
634 device
->macaddr
[0], device
->macaddr
[1], device
->macaddr
[2],
635 device
->macaddr
[3], device
->macaddr
[4], device
->macaddr
[5]);
637 // setup interrupt handler
638 if (install_io_interrupt_handler(device
->irq
, rtl8169_int
, device
, 0)
640 ERROR("can't install interrupt handler\n");
645 device
->intTotalCount
= 0;
646 device
->intTotalCountOld
= 0;
647 device
->intRxTotalCount
= 0;
648 device
->intTxTotalCount
= 0;
649 device
->intTimerTotalCount
= 0;
650 device
->intCurrentCount
= 0;
651 device
->intRxCurrentCount
= 0;
652 device
->intTxCurrentCount
= 0;
653 device
->intTimerCurrentCount
= 0;
654 device
->timer
= create_timer(print_debug_info
, device
, 1000000,
658 write16(0xe0, read16(0xe0)); // write CR+ command
660 write16(0xe0, read16(0xe0) | 0x0003);
661 // don't know what this does, BSD says "enable C+ Tx/Rx"
663 if (device
->mac_version
== 1) {
664 TRACE("Setting Reg C+CR bit 3 and bit 14 to 1\n");
665 // bit 3 is PCI multiple read/write enable (max Tx/Rx DMA burst size
666 // setting is no longer valid then)
667 // bit 14 ??? (need more docs)
668 write16(0xe0, read16(0xe0) | 0x4008);
671 // setup buffer descriptors and buffers
672 if (init_buf_desc(device
) != B_OK
) {
673 ERROR("setting up buffer descriptors failed\n");
677 // enable receiver & transmitter
678 write8(REG_CR
, read8(REG_CR
) | CR_RE
| CR_TE
);
680 write8(REG_9346CR
, 0xc0); // enable config access
681 write8(REG_CONFIG1
, read8(REG_CONFIG1
) & ~1); // disable power management
682 write8(REG_9346CR
, 0x00); // disable config access
684 write8(0xec, 0x3f); // disable early transmit treshold
685 write16(0xda, FRAME_SIZE
); // receive packet maximum size
687 write16(0x5c, read16(0x5c) & 0xf000); // disable early receive interrupts
689 write32(0x4c, 0); // RxMissed ???
691 // setup receive config, can only be done when receiver is enabled!
692 // 1024 byte FIFO treshold, 1024 DMA burst
693 write32(REG_RX_CONFIG
, (read32(REG_RX_CONFIG
) & RX_CONFIG_MASK
)
694 | (0x6 << RC_CONFIG_RXFTH_Shift
) | (0x6 << RC_CONFIG_MAXDMA_Shift
)
695 | RX_CONFIG_AcceptBroad
| RX_CONFIG_AcceptMulti
696 | RX_CONFIG_AcceptMyPhys
);
698 write32(0x8, 0); // multicast filter
699 write32(0xc, 0); // multicast filter
701 // setup transmit config, can only be done when transmitter is enabled!
702 // append CRC, 1024 DMA burst
703 write32(REG_TX_CONFIG
, (read32(REG_TX_CONFIG
) & ~(0x10000 | (1 << 8)))
706 // clear pending interrupt status
707 write16(REG_INT_STAT
, 0xffff);
709 // enable used interrupts
710 write16(REG_INT_MASK
, INT_FOVW
| INT_PUN
| INT_TER
| INT_TOK
| INT_RER
716 delete_sem(device
->rxReadySem
);
717 delete_sem(device
->txFreeSem
);
718 delete_area(device
->regArea
);
719 delete_area(device
->txBufArea
);
720 delete_area(device
->rxBufArea
);
721 delete_area(device
->txDescArea
);
722 delete_area(device
->rxDescArea
);
726 atomic_and(&gOpenMask
, ~(1 << dev_id
));
732 rtl8169_close(void* cookie
)
734 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
735 TRACE("rtl8169_close()\n");
737 device
->closed
= true;
738 release_sem(device
->rxReadySem
);
739 release_sem(device
->txFreeSem
);
746 rtl8169_free(void* cookie
)
748 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
749 TRACE("rtl8169_free()\n");
751 // disable receiver & transmitter
752 write8(REG_CR
, read8(REG_CR
) & ~(CR_RE
| CR_TE
));
754 // disable interrupts
755 write16(REG_INT_MASK
, 0);
757 PROFILING_ONLY(delete_timer(device
->timer
));
760 remove_io_interrupt_handler (device
->irq
, rtl8169_int
, device
);
762 delete_sem(device
->rxReadySem
);
763 delete_sem(device
->txFreeSem
);
764 delete_area(device
->regArea
);
765 delete_area(device
->txBufArea
);
766 delete_area(device
->rxBufArea
);
767 delete_area(device
->txDescArea
);
768 delete_area(device
->rxDescArea
);
772 atomic_and(&gOpenMask
, ~(1 << device
->devId
));
778 rtl8169_read(void* cookie
, off_t position
, void *buf
, size_t* numBytes
)
780 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
784 TRACE("rtl8169_read() enter\n");
786 if (device
->closed
) {
787 TRACE("rtl8169_read() interrupted 1\n");
788 return B_INTERRUPTED
;
791 stat
= acquire_sem_etc(device
->rxReadySem
, 1,
792 B_CAN_INTERRUPT
| (device
->nonblocking
? B_TIMEOUT
: 0), 0);
793 if (device
->closed
) {
794 // TRACE("rtl8169_read() interrupted 2\n");
795 // net_server will crash if we print this
796 // (race condition in net_server?)
797 return B_INTERRUPTED
;
799 if (stat
== B_WOULD_BLOCK
) {
800 TRACE("rtl8169_read() would block (OK 0 bytes)\n");
805 TRACE("rtl8169_read() error\n");
809 if (device
->rxDesc
[device
->rxNextIndex
].stat_len
& RX_DESC_OWN
) {
810 ERROR("rtl8169_read() buffer still in use\n");
814 len
= (device
->rxDesc
[device
->rxNextIndex
].stat_len
& RX_DESC_LEN_MASK
);
815 len
-= 4; // remove CRC that Realtek always appends
818 if (len
> (int)*numBytes
)
821 memcpy(buf
, device
->rxBuf
[device
->rxNextIndex
], len
);
824 cpu
= disable_interrupts();
825 acquire_spinlock(&device
->rxSpinlock
);
827 device
->rxDesc
[device
->rxNextIndex
].stat_len
= RX_DESC_OWN
| FRAME_SIZE
828 | (device
->rxDesc
[device
->rxNextIndex
].stat_len
& RX_DESC_EOR
);
831 release_spinlock(&device
->rxSpinlock
);
832 restore_interrupts(cpu
);
834 device
->rxNextIndex
= (device
->rxNextIndex
+ 1) % device
->rxBufferCount
;
836 TRACE("rtl8169_read() leave\n");
842 rtl8169_write(void* cookie
, off_t position
, const void* buffer
,
845 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
850 TRACE("rtl8169_write() enter\n");
853 if (len
> FRAME_SIZE
) {
854 TRACE("rtl8169_write() buffer too large\n");
858 if (device
->closed
) {
859 TRACE("rtl8169_write() interrupted 1\n");
860 return B_INTERRUPTED
;
863 stat
= acquire_sem_etc(device
->txFreeSem
, 1, B_CAN_INTERRUPT
| B_TIMEOUT
,
864 device
->nonblocking
? 0 : TX_TIMEOUT
);
865 if (device
->closed
) {
866 TRACE("rtl8169_write() interrupted 2\n");
867 return B_INTERRUPTED
;
869 if (stat
== B_WOULD_BLOCK
) {
870 TRACE("rtl8169_write() would block (OK 0 bytes)\n");
874 if (stat
== B_TIMED_OUT
) {
875 TRACE("rtl8169_write() timeout\n");
879 TRACE("rtl8169_write() error\n");
883 if (device
->txDesc
[device
->txNextIndex
].stat_len
& TX_DESC_OWN
) {
884 ERROR("rtl8169_write() buffer still in use\n");
888 memcpy(device
->txBuf
[device
->txNextIndex
], buffer
, len
);
890 cpu
= disable_interrupts();
891 acquire_spinlock(&device
->txSpinlock
);
894 device
->txDesc
[device
->txNextIndex
].stat_len
895 = (device
->txDesc
[device
->txNextIndex
].stat_len
& RX_DESC_EOR
)
896 | TX_DESC_OWN
| TX_DESC_FS
| TX_DESC_LS
| len
;
898 release_spinlock(&device
->txSpinlock
);
899 restore_interrupts(cpu
);
901 device
->txNextIndex
= (device
->txNextIndex
+ 1) % device
->txBufferCount
;
903 write8(REG_TPPOLL
, read8(REG_TPPOLL
) | TPPOLL_NPQ
); // set queue polling bit
905 TRACE("rtl8169_write() leave\n");
911 rtl8169_control(void *cookie
, uint32 op
, void *arg
, size_t len
)
913 rtl8169_device
*device
= (rtl8169_device
*)cookie
;
917 TRACE("rtl8169_control() ETHER_INIT\n");
921 TRACE("rtl8169_control() ETHER_GETADDR\n");
922 memcpy(arg
, &device
->macaddr
, sizeof(device
->macaddr
));
927 TRACE("non blocking mode on\n");
928 device
->nonblocking
= true;
929 /* could be used to unblock pending read and write calls,
930 * but this doesn't seem to be required
931 release_sem_etc(device->txFreeSem, 1, B_DO_NOT_RESCHEDULE);
932 release_sem_etc(device->rxReadySem, 1, B_DO_NOT_RESCHEDULE);
935 TRACE("non blocking mode off\n");
936 device
->nonblocking
= false;
941 TRACE("rtl8169_control() ETHER_ADDMULTI\n");
945 TRACE("rtl8169_control() ETHER_REMMULTI\n");
948 case ETHER_SETPROMISC
:
950 TRACE("promiscuous mode on\n");
951 write32(REG_RX_CONFIG
, read32(REG_RX_CONFIG
)
952 | RX_CONFIG_AcceptAllPhys
);
953 write32(0x8, 0xffffffff); // multicast filter
954 write32(0xc, 0xffffffff); // multicast filter
956 TRACE("promiscuous mode off\n");
957 write32(REG_RX_CONFIG
, read32(REG_RX_CONFIG
)
958 & ~RX_CONFIG_AcceptAllPhys
);
959 write32(0x8, 0); // multicast filter
960 write32(0xc, 0); // multicast filter
964 case ETHER_GETFRAMESIZE
:
965 TRACE("rtl8169_control() ETHER_GETFRAMESIZE, framesize = %d (MTU = %d)\n", device
->maxframesize
, device
->maxframesize
- 14);
966 *(uint32
*)arg
= device
->maxframesize
;
969 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
970 case ETHER_GET_LINK_STATE
:
972 ether_link_state_t state
;
974 state
.media
= IFM_ETHER
;
975 state
.media
|= (device
->link_ok
? IFM_ACTIVE
: 0);
976 state
.media
|= (device
->full_duplex
? IFM_FULL_DUPLEX
: IFM_HALF_DUPLEX
);
977 if (device
->speed
== 1000000000)
978 state
.media
|= IFM_1000_T
;
979 else if (device
->speed
== 100000000)
980 state
.media
|= IFM_100_TX
;
981 else if (device
->speed
== 10000000)
982 state
.media
|= IFM_10_T
;
984 state
.speed
= device
->speed
;
985 state
.quality
= 1000;
987 return user_memcpy(arg
, &state
, sizeof(ether_link_state_t
));
990 case ETHER_SET_LINK_STATE_SEM
:
992 if (user_memcpy(&device
->linkChangeSem
, arg
, sizeof(sem_id
)) < B_OK
) {
993 device
->linkChangeSem
= -1;
994 return B_BAD_ADDRESS
;
1001 TRACE("rtl8169_control() Invalid command\n");