1/* Realtek RTL8169 Family Driver
2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved.
3 *
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.
8 *
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.
11 *
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.
18 */
19
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
30
31
32#include "debug.h"
33#include "device.h"
34#include "driver.h"
35#include "hardware.h"
36#include "util.h"
37
38static int32 gOpenMask = 0;
39
40
41static void
42read_settings(rtl8169_device *device)
43{
44	void *handle;
45	const char *param;
46	int mtu, count;
47
48	handle = load_driver_settings("rtl8169");
49	if (!handle)
50		return;
51
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);
58
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);
65
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);
72
73	unload_driver_settings(handle);
74}
75
76
77static void
78write_phy_reg(rtl8169_device *device, int reg, uint16 value)
79{
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);
87	}
88}
89
90
91static uint16
92read_phy_reg(rtl8169_device *device, int reg)
93{
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);
103	}
104	return 0xffff;
105}
106
107
108static inline void
109write_phy_reg_bit(rtl8169_device *device, int reg, int bitnum, int bitval)
110{
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);
117}
118
119
120static void
121phy_config(rtl8169_device *device)
122{
123	TRACE("phy_config()\n");
124
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?)
179	}
180
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
184}
185
186
187static void
188dump_phy_stat(rtl8169_device *device)
189{
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");
214	}
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");
223}
224
225
226static void
227print_link_status(rtl8169_device *device)
228{
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");
245		}
246	}
247}
248
249
250#ifdef PROFILING
251static void
252print_debug_info(void *cookie)
253{
254	rtl8169_device *device = (rtl8169_device *)cookie;
255
256	// only print if interrupt count changed
257	if (device->intTotalCount == device->intTotalCountOld)
258		return;
259
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);
269
270	device->intTotalCountOld = device->intTotalCount;
271	device->intCurrentCount = 0;
272	device->intRxCurrentCount = 0;
273	device->intTxCurrentCount = 0;
274	device->intTimerCurrentCount = 0;
275}
276#endif // PROFILING
277
278
279static status_t
280init_buf_desc(rtl8169_device *device)
281{
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;
287
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;
299
300	device->txDesc = (buf_desc *)tx_buf_desc_virt;
301	device->rxDesc = (buf_desc *)rx_buf_desc_virt;
302
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;
310	}
311	device->txDesc[i - 1].stat_len |= TX_DESC_EOR;
312
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;
320	}
321	device->rxDesc[i - 1].stat_len |= RX_DESC_EOR;
322
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);
329
330	return B_OK;
331}
332
333
334static inline void
335rtl8169_tx_int(rtl8169_device *device)
336{
337	int32 limit;
338	int32 count;
339
340	acquire_spinlock(&device->txSpinlock);
341
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++;
347	}
348
349//	dprintf("tx int, txUsed %d, count %d\n", device->txUsed, count);
350
351	device->txUsed -= count;
352
353	release_spinlock(&device->txSpinlock);
354
355	if (count)
356		release_sem_etc(device->txFreeSem, count, B_DO_NOT_RESCHEDULE);
357}
358
359
360static inline void
361rtl8169_rx_int(rtl8169_device *device)
362{
363	int32 limit;
364	int32 count;
365
366	acquire_spinlock(&device->rxSpinlock);
367
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++;
373	}
374
375//	dprintf("rx int, rxFree %d, count %d\n", device->rxFree, count);
376
377	device->rxFree -= count;
378
379	release_spinlock(&device->rxSpinlock);
380
381	if (count)
382		release_sem_etc(device->rxReadySem, count, B_DO_NOT_RESCHEDULE);
383}
384
385
386static status_t
387rtl8169_get_link_state(rtl8169_device *device)
388{
389	bool link_ok = false;
390	bool full_duplex = false;
391	uint32 speed = 0;
392	bool linkStateChange = false;
393	uint32 phy;
394
395	dump_phy_stat(device);
396	print_link_status(device);
397
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;
404		}
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);
414			}
415		}
416	}
417
418	linkStateChange = (link_ok != device->link_ok
419		|| full_duplex != device->full_duplex
420		|| speed != device->speed);
421
422	device->link_ok = link_ok;
423	device->full_duplex = full_duplex;
424	device->speed = speed;
425
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
430
431	return B_OK;
432}
433
434
435static int32
436rtl8169_int(void *data)
437{
438	rtl8169_device *device = (rtl8169_device *)data;
439	uint16 stat;
440	int32 ret;
441
442	stat = read16(REG_INT_STAT);
443	if (stat == 0 || stat == 0xffff)
444		return B_UNHANDLED_INTERRUPT;
445
446	write16(REG_INT_STAT, stat);
447	ret = B_HANDLED_INTERRUPT;
448
449	PROFILING_ONLY(device->intTotalCount++);
450	PROFILING_ONLY(device->intCurrentCount++);
451
452
453	if (stat & INT_TimeOut) {
454		PROFILING_ONLY(device->intTimerTotalCount++);
455		PROFILING_ONLY(device->intTimerCurrentCount++);
456	}
457
458	if (stat & INT_PUN) {
459		rtl8169_get_link_state(device);
460	}
461
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;
467	}
468
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;
474	}
475
476  	return ret;
477}
478
479
480status_t
481rtl8169_open(const char *name, uint32 flags, void** cookie)
482{
483	rtl8169_device *device;
484	char *deviceName;
485	int mmioIndex;
486	uint32 val;
487	int dev_id;
488	int mask;
489	int i;
490
491	TRACE("rtl8169_open()\n");
492
493	for (dev_id = 0; (deviceName = gDevNameList[dev_id]) != NULL; dev_id++) {
494		if (!strcmp(name, deviceName))
495			break;
496	}
497	if (deviceName == NULL) {
498		ERROR("invalid device name\n");
499		return B_ERROR;
500	}
501
502	// allow only one concurrent access
503	mask = 1 << dev_id;
504	if (atomic_or(&gOpenMask, mask) & mask)
505		return B_BUSY;
506
507	*cookie = device = (rtl8169_device *)malloc(sizeof(rtl8169_device));
508	if (!device) {
509		atomic_and(&gOpenMask, ~(1 << dev_id));
510		return B_NO_MEMORY;
511	}
512
513	memset(device, 0, sizeof(*device));
514
515	device->devId = dev_id;
516	device->pciInfo = gDevList[dev_id];
517	device->nonblocking = (flags & O_NONBLOCK) ? true : false;
518	device->closed = false;
519
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);
526
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");
533
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");
540
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);
547
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);
552
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;
558	}
559
560	TRACE("IRQ %d\n", device->irq);
561
562	// map registers into memory
563
564	if (device->pciInfo->device_id == 0x8168)
565		mmioIndex = 2;
566	else
567		mmioIndex = 1;
568
569	TRACE("hardware register address [%i] %p\n", mmioIndex,
570		(void *)device->pciInfo->u.h0.base_registers[mmioIndex]);
571
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;
578	}
579
580	TRACE("mapped registers to %p\n", device->regAddr);
581
582	// disable receiver & transmitter XXX might be removed
583	write8(REG_CR, read8(REG_CR) & ~(CR_RE | CR_TE));
584
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;
592	}
593
594	TRACE("reset done\n");
595
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");
608	}
609
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
618	}
619
620	// configure PHY
621	phy_config(device);
622
623#ifdef HAIKU_TARGET_PLATFORM_HAIKU
624	device->linkChangeSem = -1;
625#endif
626
627	rtl8169_get_link_state(device);
628
629	// initialize MAC address
630	for (i = 0; i < 6; i++)
631		device->macaddr[i] = read8(i);
632
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]);
636
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;
642	}
643
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
657
658	write16(0xe0, read16(0xe0)); // write CR+ command
659
660	write16(0xe0, read16(0xe0) | 0x0003);
661		// don't know what this does, BSD says "enable C+ Tx/Rx"
662
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);
669	}
670
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;
675	}
676
677	// enable receiver & transmitter
678	write8(REG_CR, read8(REG_CR) | CR_RE | CR_TE);
679
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
683
684	write8(0xec, 0x3f); 		// disable early transmit treshold
685	write16(0xda, FRAME_SIZE);	// receive packet maximum size
686
687	write16(0x5c, read16(0x5c) & 0xf000); // disable early receive interrupts
688
689	write32(0x4c, 0); // RxMissed ???
690
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);
697
698	write32(0x8, 0); // multicast filter
699	write32(0xc, 0); // multicast filter
700
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));
705
706  	// clear pending interrupt status
707  	write16(REG_INT_STAT, 0xffff);
708
709  	// enable used interrupts
710 	write16(REG_INT_MASK, INT_FOVW | INT_PUN | INT_TER | INT_TOK | INT_RER
711 		| INT_ROK);
712
713	return B_OK;
714
715err:
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;
728}
729
730
731status_t
732rtl8169_close(void* cookie)
733{
734	rtl8169_device *device = (rtl8169_device *)cookie;
735	TRACE("rtl8169_close()\n");
736
737	device->closed = true;
738	release_sem(device->rxReadySem);
739	release_sem(device->txFreeSem);
740
741	return B_OK;
742}
743
744
745status_t
746rtl8169_free(void* cookie)
747{
748	rtl8169_device *device = (rtl8169_device *)cookie;
749	TRACE("rtl8169_free()\n");
750
751	// disable receiver & transmitter
752	write8(REG_CR, read8(REG_CR) & ~(CR_RE | CR_TE));
753
754	// disable interrupts
755  	write16(REG_INT_MASK, 0);
756
757	PROFILING_ONLY(delete_timer(device->timer));
758
759  	// well...
760  	remove_io_interrupt_handler (device->irq, rtl8169_int, device);
761
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;
774}
775
776
777status_t
778rtl8169_read(void* cookie, off_t position, void *buf, size_t* numBytes)
779{
780	rtl8169_device *device = (rtl8169_device *)cookie;
781	cpu_status cpu;
782	status_t stat;
783	int len;
784	TRACE("rtl8169_read() enter\n");
785
786	if (device->closed) {
787		TRACE("rtl8169_read() interrupted 1\n");
788		return B_INTERRUPTED;
789	}
790retry:
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;
798	}
799	if (stat == B_WOULD_BLOCK) {
800		TRACE("rtl8169_read() would block (OK 0 bytes)\n");
801		*numBytes = 0;
802		return B_OK;
803	}
804	if (stat != B_OK) {
805		TRACE("rtl8169_read() error\n");
806		return B_ERROR;
807	}
808
809	if (device->rxDesc[device->rxNextIndex].stat_len & RX_DESC_OWN) {
810		ERROR("rtl8169_read() buffer still in use\n");
811		goto retry;
812	}
813
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;
820
821	memcpy(buf, device->rxBuf[device->rxNextIndex], len);
822	*numBytes = len;
823
824	cpu = disable_interrupts();
825	acquire_spinlock(&device->rxSpinlock);
826
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++;
830
831	release_spinlock(&device->rxSpinlock);
832	restore_interrupts(cpu);
833
834	device->rxNextIndex = (device->rxNextIndex + 1) % device->rxBufferCount;
835
836	TRACE("rtl8169_read() leave\n");
837	return B_OK;
838}
839
840
841status_t
842rtl8169_write(void* cookie, off_t position, const void* buffer,
843	size_t* numBytes)
844{
845	rtl8169_device *device = (rtl8169_device *)cookie;
846	cpu_status cpu;
847	status_t stat;
848	int len;
849
850	TRACE("rtl8169_write() enter\n");
851
852	len = *numBytes;
853	if (len > FRAME_SIZE) {
854		TRACE("rtl8169_write() buffer too large\n");
855		return B_ERROR;
856	}
857
858	if (device->closed) {
859		TRACE("rtl8169_write() interrupted 1\n");
860		return B_INTERRUPTED;
861	}
862retry:
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;
868	}
869	if (stat == B_WOULD_BLOCK) {
870		TRACE("rtl8169_write() would block (OK 0 bytes)\n");
871		*numBytes = 0;
872		return B_OK;
873	}
874	if (stat == B_TIMED_OUT) {
875		TRACE("rtl8169_write() timeout\n");
876		return B_BUSY;
877	}
878	if (stat != B_OK) {
879		TRACE("rtl8169_write() error\n");
880		return B_ERROR;
881	}
882
883	if (device->txDesc[device->txNextIndex].stat_len & TX_DESC_OWN) {
884		ERROR("rtl8169_write() buffer still in use\n");
885		goto retry;
886	}
887
888	memcpy(device->txBuf[device->txNextIndex], buffer, len);
889
890	cpu = disable_interrupts();
891	acquire_spinlock(&device->txSpinlock);
892
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;
897
898	release_spinlock(&device->txSpinlock);
899	restore_interrupts(cpu);
900
901	device->txNextIndex = (device->txNextIndex + 1) % device->txBufferCount;
902
903	write8(REG_TPPOLL, read8(REG_TPPOLL) | TPPOLL_NPQ); // set queue polling bit
904
905	TRACE("rtl8169_write() leave\n");
906	return B_OK;
907}
908
909
910status_t
911rtl8169_control(void *cookie, uint32 op, void *arg, size_t len)
912{
913	rtl8169_device *device = (rtl8169_device *)cookie;
914
915	switch (op) {
916		case ETHER_INIT:
917			TRACE("rtl8169_control() ETHER_INIT\n");
918			return B_OK;
919
920		case ETHER_GETADDR:
921			TRACE("rtl8169_control() ETHER_GETADDR\n");
922			memcpy(arg, &device->macaddr, sizeof(device->macaddr));
923			return B_OK;
924
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);
933				*/
934			} else {
935				TRACE("non blocking mode off\n");
936				device->nonblocking = false;
937			}
938			return B_OK;
939
940		case ETHER_ADDMULTI:
941			TRACE("rtl8169_control() ETHER_ADDMULTI\n");
942			break;
943
944		case ETHER_REMMULTI:
945			TRACE("rtl8169_control() ETHER_REMMULTI\n");
946			return B_OK;
947
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
961			}
962			return B_OK;
963
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;
968
969#ifdef HAIKU_TARGET_PLATFORM_HAIKU
970		case ETHER_GET_LINK_STATE:
971		{
972			ether_link_state_t state;
973
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;
983
984			state.speed = device->speed;
985			state.quality = 1000;
986
987			return user_memcpy(arg, &state, sizeof(ether_link_state_t));
988		}
989
990		case ETHER_SET_LINK_STATE_SEM:
991		{
992			if (user_memcpy(&device->linkChangeSem, arg, sizeof(sem_id)) < B_OK) {
993				device->linkChangeSem = -1;
994				return B_BAD_ADDRESS;
995			}
996			return B_OK;
997		}
998#endif
999
1000		default:
1001			TRACE("rtl8169_control() Invalid command\n");
1002			break;
1003	}
1004
1005	return B_ERROR;
1006}
1007
1008