vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / network / rtl8169 / device.c
blob6fb49f77193cdad752ba8b8212d3681541ad8b4e
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>
21 #include <Errors.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <driver_settings.h>
27 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
28 #include <net/if_media.h>
29 #endif
32 #include "debug.h"
33 #include "device.h"
34 #include "driver.h"
35 #include "hardware.h"
36 #include "util.h"
38 static int32 gOpenMask = 0;
41 static void
42 read_settings(rtl8169_device *device)
44 void *handle;
45 const char *param;
46 int mtu, count;
48 handle = load_driver_settings("rtl8169");
49 if (!handle)
50 return;
52 param = get_driver_parameter(handle, "mtu", "-1", "-1");
53 mtu = atoi(param);
54 if (mtu >= 50 && mtu <= 1500)
55 device->maxframesize = mtu + 14;
56 else if (mtu != -1)
57 dprintf("rtl8169: unsupported mtu setting '%s' ignored\n", param);
59 param = get_driver_parameter(handle, "rx_buffer_count", "-1", "-1");
60 count = atoi(param);
61 if (count >= 2 && count <= 1024)
62 device->rxBufferCount = count;
63 else if (count != -1)
64 dprintf("rtl8169: unsupported rx_buffer_count setting '%s' ignored\n", param);
66 param = get_driver_parameter(handle, "tx_buffer_count", "-1", "-1");
67 count = atoi(param);
68 if (count >= 2 && count <= 1024)
69 device->txBufferCount = count;
70 else if (count != -1)
71 dprintf("rtl8169: unsupported tx_buffer_count setting '%s' ignored\n", param);
73 unload_driver_settings(handle);
77 static void
78 write_phy_reg(rtl8169_device *device, int reg, uint16 value)
80 int i;
81 write32(REG_PHYAR, 0x80000000 | (reg & 0x1f) << 16 | value);
82 snooze(1000);
83 for (i = 0; i < 2000; i++) {
84 if ((read32(REG_PHYAR) & 0x80000000) == 0)
85 break;
86 snooze(100);
91 static uint16
92 read_phy_reg(rtl8169_device *device, int reg)
94 uint32 v;
95 int i;
96 write32(REG_PHYAR, (reg & 0x1f) << 16);
97 snooze(1000);
98 for (i = 0; i < 2000; i++) {
99 v = read32(REG_PHYAR);
100 if (v & 0x80000000)
101 return v & 0xffff;
102 snooze(100);
104 return 0xffff;
108 static inline void
109 write_phy_reg_bit(rtl8169_device *device, int reg, int bitnum, int bitval)
111 uint16 val = read_phy_reg(device, reg);
112 if (bitval == 1)
113 val |= (1 << bitnum);
114 else
115 val &= ~(1 << bitnum);
116 write_phy_reg(device, reg, val);
120 static void
121 phy_config(rtl8169_device *device)
123 TRACE("phy_config()\n");
125 if (device->phy_version == 0 || device->phy_version == 1) {
126 uint16 val;
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
187 static void
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");
206 } else {
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");
226 static void
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");
233 else
234 PRINT("Link not active (TBI mode)\n");
235 } else {
236 if (phy & PHY_STAT_LinkSts) {
237 if (phy & PHY_STAT_1000MF)
238 PRINT("Link active, 1000 Mbit Full Duplex (GMII mode)\n");
239 else
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");
243 } else {
244 PRINT("Link not active (MII mode)\n");
250 #ifdef PROFILING
251 static void
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)
258 return;
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;
276 #endif // PROFILING
279 static status_t
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;
286 int i;
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)
298 return B_NO_MEMORY;
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);
330 return B_OK;
334 static inline void
335 rtl8169_tx_int(rtl8169_device *device)
337 int32 limit;
338 int32 count;
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)
344 break;
345 device->txIntIndex = (device->txIntIndex + 1) % device->txBufferCount;
346 count++;
349 // dprintf("tx int, txUsed %d, count %d\n", device->txUsed, count);
351 device->txUsed -= count;
353 release_spinlock(&device->txSpinlock);
355 if (count)
356 release_sem_etc(device->txFreeSem, count, B_DO_NOT_RESCHEDULE);
360 static inline void
361 rtl8169_rx_int(rtl8169_device *device)
363 int32 limit;
364 int32 count;
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)
370 break;
371 device->rxIntIndex = (device->rxIntIndex + 1) % device->rxBufferCount;
372 count++;
375 // dprintf("rx int, rxFree %d, count %d\n", device->rxFree, count);
377 device->rxFree -= count;
379 release_spinlock(&device->rxSpinlock);
381 if (count)
382 release_sem_etc(device->rxReadySem, count, B_DO_NOT_RESCHEDULE);
386 static status_t
387 rtl8169_get_link_state(rtl8169_device *device)
389 bool link_ok = false;
390 bool full_duplex = false;
391 uint32 speed = 0;
392 bool linkStateChange = false;
393 uint32 phy;
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);
401 if (link_ok) {
402 speed = 1000000;
403 full_duplex = true;
405 } else {
406 if (phy & PHY_STAT_LinkSts) {
407 link_ok = true;
408 if (phy & PHY_STAT_1000MF) {
409 speed = 1000000;
410 full_duplex = true;
411 } else {
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);
429 #endif
431 return B_OK;
435 static int32
436 rtl8169_int(void *data)
438 rtl8169_device *device = (rtl8169_device *)data;
439 uint16 stat;
440 int32 ret;
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;
476 return ret;
480 status_t
481 rtl8169_open(const char *name, uint32 flags, void** cookie)
483 rtl8169_device *device;
484 char *deviceName;
485 int mmioIndex;
486 uint32 val;
487 int dev_id;
488 int mask;
489 int i;
491 TRACE("rtl8169_open()\n");
493 for (dev_id = 0; (deviceName = gDevNameList[dev_id]) != NULL; dev_id++) {
494 if (!strcmp(name, deviceName))
495 break;
497 if (deviceName == NULL) {
498 ERROR("invalid device name\n");
499 return B_ERROR;
502 // allow only one concurrent access
503 mask = 1 << dev_id;
504 if (atomic_or(&gOpenMask, mask) & mask)
505 return B_BUSY;
507 *cookie = device = (rtl8169_device *)malloc(sizeof(rtl8169_device));
508 if (!device) {
509 atomic_and(&gOpenMask, ~(1 << dev_id));
510 return B_NO_MEMORY;
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;
520 // setup defaults
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;
538 device->txUsed = 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);
553 // get IRQ
554 device->irq = device->pciInfo->u.h0.interrupt_line;
555 if (device->irq == 0 || device->irq == 0xff) {
556 ERROR("no IRQ assigned\n");
557 goto err;
560 TRACE("IRQ %d\n", device->irq);
562 // map registers into memory
564 if (device->pciInfo->device_id == 0x8168)
565 mmioIndex = 2;
566 else
567 mmioIndex = 1;
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,
574 "rtl8169 register");
575 if (device->regArea < B_OK) {
576 ERROR("can't map hardware registers\n");
577 goto err;
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));
585 // do a soft reset
586 write8(REG_CR, read8(REG_CR) | CR_RST);
587 for (i = 0; (read8(REG_CR) & CR_RST) && i < 1000; i++)
588 snooze(10);
589 if (i == 1000) {
590 ERROR("hardware reset failed\n");
591 goto err;
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);
604 } else {
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
617 // this does
620 // configure PHY
621 phy_config(device);
623 #ifdef HAIKU_TARGET_PLATFORM_HAIKU
624 device->linkChangeSem = -1;
625 #endif
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)
639 < B_OK) {
640 ERROR("can't install interrupt handler\n");
641 goto err;
644 #ifdef PROFILING
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,
655 B_PERIODIC_TIMER);
656 #endif // PROFILING
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");
674 goto err;
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)))
704 | (0x6 << 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
711 | INT_ROK);
713 return B_OK;
715 err:
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);
723 free(device->txBuf);
724 free(device->rxBuf);
725 free(device);
726 atomic_and(&gOpenMask, ~(1 << dev_id));
727 return B_ERROR;
731 status_t
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);
741 return B_OK;
745 status_t
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));
759 // well...
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);
769 free(device->txBuf);
770 free(device->rxBuf);
771 free(device);
772 atomic_and(&gOpenMask, ~(1 << device->devId));
773 return B_OK;
777 status_t
778 rtl8169_read(void* cookie, off_t position, void *buf, size_t* numBytes)
780 rtl8169_device *device = (rtl8169_device *)cookie;
781 cpu_status cpu;
782 status_t stat;
783 int len;
784 TRACE("rtl8169_read() enter\n");
786 if (device->closed) {
787 TRACE("rtl8169_read() interrupted 1\n");
788 return B_INTERRUPTED;
790 retry:
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");
801 *numBytes = 0;
802 return B_OK;
804 if (stat != B_OK) {
805 TRACE("rtl8169_read() error\n");
806 return B_ERROR;
809 if (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_OWN) {
810 ERROR("rtl8169_read() buffer still in use\n");
811 goto retry;
814 len = (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_LEN_MASK);
815 len -= 4; // remove CRC that Realtek always appends
816 if (len < 0)
817 len = 0;
818 if (len > (int)*numBytes)
819 len = *numBytes;
821 memcpy(buf, device->rxBuf[device->rxNextIndex], len);
822 *numBytes = 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);
829 device->rxFree++;
831 release_spinlock(&device->rxSpinlock);
832 restore_interrupts(cpu);
834 device->rxNextIndex = (device->rxNextIndex + 1) % device->rxBufferCount;
836 TRACE("rtl8169_read() leave\n");
837 return B_OK;
841 status_t
842 rtl8169_write(void* cookie, off_t position, const void* buffer,
843 size_t* numBytes)
845 rtl8169_device *device = (rtl8169_device *)cookie;
846 cpu_status cpu;
847 status_t stat;
848 int len;
850 TRACE("rtl8169_write() enter\n");
852 len = *numBytes;
853 if (len > FRAME_SIZE) {
854 TRACE("rtl8169_write() buffer too large\n");
855 return B_ERROR;
858 if (device->closed) {
859 TRACE("rtl8169_write() interrupted 1\n");
860 return B_INTERRUPTED;
862 retry:
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");
871 *numBytes = 0;
872 return B_OK;
874 if (stat == B_TIMED_OUT) {
875 TRACE("rtl8169_write() timeout\n");
876 return B_BUSY;
878 if (stat != B_OK) {
879 TRACE("rtl8169_write() error\n");
880 return B_ERROR;
883 if (device->txDesc[device->txNextIndex].stat_len & TX_DESC_OWN) {
884 ERROR("rtl8169_write() buffer still in use\n");
885 goto retry;
888 memcpy(device->txBuf[device->txNextIndex], buffer, len);
890 cpu = disable_interrupts();
891 acquire_spinlock(&device->txSpinlock);
893 device->txUsed++;
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");
906 return B_OK;
910 status_t
911 rtl8169_control(void *cookie, uint32 op, void *arg, size_t len)
913 rtl8169_device *device = (rtl8169_device *)cookie;
915 switch (op) {
916 case ETHER_INIT:
917 TRACE("rtl8169_control() ETHER_INIT\n");
918 return B_OK;
920 case ETHER_GETADDR:
921 TRACE("rtl8169_control() ETHER_GETADDR\n");
922 memcpy(arg, &device->macaddr, sizeof(device->macaddr));
923 return B_OK;
925 case ETHER_NONBLOCK:
926 if (*(int32 *)arg) {
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);
934 } else {
935 TRACE("non blocking mode off\n");
936 device->nonblocking = false;
938 return B_OK;
940 case ETHER_ADDMULTI:
941 TRACE("rtl8169_control() ETHER_ADDMULTI\n");
942 break;
944 case ETHER_REMMULTI:
945 TRACE("rtl8169_control() ETHER_REMMULTI\n");
946 return B_OK;
948 case ETHER_SETPROMISC:
949 if (*(int32 *)arg) {
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
955 } else {
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
962 return B_OK;
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;
967 return B_OK;
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;
996 return B_OK;
998 #endif
1000 default:
1001 TRACE("rtl8169_control() Invalid command\n");
1002 break;
1005 return B_ERROR;