Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / devs / networks / rtl8168 / rtl8168.c
blob737f9f36fef9a85ffd44fa8aeb8a9bc42e078036
1 /*
2 * $Id: rtl8168.c 29318 2008-08-29 20:52:01Z NicJA $
3 */
5 /*
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 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 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, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA.
22 #include "rtl8168.h"
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/io.h>
27 #include <exec/ports.h>
29 #include <aros/libcall.h>
30 #include <aros/macros.h>
31 #include <aros/io.h>
33 #include <oop/oop.h>
35 #include <devices/sana2.h>
36 #include <devices/sana2specialstats.h>
38 #include <utility/utility.h>
39 #include <utility/tagitem.h>
40 #include <utility/hooks.h>
42 #include <hidd/pci.h>
43 #include <hidd/irq.h>
45 #include <proto/oop.h>
46 #include <proto/exec.h>
47 #include <proto/dos.h>
48 #include <proto/battclock.h>
50 #include <stdlib.h>
52 #include "unit.h"
53 #include LC_LIBDEFS_FILE
55 #undef LIBBASE
56 #define LIBBASE (unit->rtl8168u_device)
58 #define _R(NAME,MAC,RCR,MASK, JumFrameSz) \
59 { .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz }
61 static const struct {
62 const char *name;
63 UBYTE mcfg;
64 ULONG RCR_Cfg;
65 ULONG RxConfigMask; /* Clears the bits supported by this chip */
66 ULONG jumbo_frame_sz;
67 } rtl_chip_info[] = {
68 _R("RTL8168B/8111B",
69 CFG_METHOD_1,
70 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
71 0xff7e1880,
72 Jumbo_Frame_4k),
74 _R("RTL8168B/8111B",
75 CFG_METHOD_2,
76 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
77 0xff7e1880,
78 Jumbo_Frame_4k),
80 _R("RTL8168B/8111B",
81 CFG_METHOD_3,
82 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
83 0xff7e1880,
84 Jumbo_Frame_4k),
86 _R("RTL8168C/8111C",
87 CFG_METHOD_4, RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
88 0xff7e1880,
89 Jumbo_Frame_6k),
91 _R("RTL8168C/8111C",
92 CFG_METHOD_5,
93 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
94 0xff7e1880,
95 Jumbo_Frame_6k),
97 _R("RTL8168C/8111C",
98 CFG_METHOD_6,
99 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
100 0xff7e1880,
101 Jumbo_Frame_6k),
103 _R("RTL8168CP/8111CP",
104 CFG_METHOD_7,
105 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
106 0xff7e1880,
107 Jumbo_Frame_6k),
109 _R("RTL8168CP/8111CP",
110 CFG_METHOD_8,
111 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
112 0xff7e1880,
113 Jumbo_Frame_6k),
115 _R("RTL8168D/8111D",
116 CFG_METHOD_9,
117 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
118 0xff7e1880,
119 Jumbo_Frame_9k),
121 _R("RTL8168D/8111D",
122 CFG_METHOD_10,
123 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
124 0xff7e1880,
125 Jumbo_Frame_9k),
127 _R("RTL8168D/8111D",
128 CFG_METHOD_11,
129 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
130 0xff7e1880,
131 Jumbo_Frame_9k),
133 #undef _R
135 void rtl8168nic_USecDelay(struct net_device *unit, ULONG usec)
137 if (unit != NULL)
139 unit->rtl8168u_DelayPort.mp_SigTask = FindTask(NULL);
140 unit->rtl8168u_DelayReq.tr_node.io_Command = TR_ADDREQUEST;
141 unit->rtl8168u_DelayReq.tr_time.tv_micro = usec % 1000000;
142 unit->rtl8168u_DelayReq.tr_time.tv_secs = usec / 1000000;
144 DoIO((struct IORequest *)&unit->rtl8168u_DelayReq);
148 static inline struct rtl8168_priv *get_pcnpriv(struct net_device *unit)
150 return unit->rtl8168u_priv;
153 static inline UBYTE *get_hwbase(struct net_device *unit)
155 return (UBYTE *)unit->rtl8168u_BaseMem;
158 void MMIO_W8(APTR addr, UBYTE val8)
160 UBYTE tmp;
162 *((volatile UBYTE *)(addr)) = (val8);
164 tmp = RTL_R8(addr);
167 void MMIO_W16(APTR addr, UWORD val16)
169 UWORD tmp;
171 *((volatile UWORD *)(addr)) = (val16);
173 tmp = RTL_R16(addr);
177 void MMIO_W32(APTR addr, ULONG val32)
179 ULONG tmp;
181 *((volatile ULONG *)(addr)) = (val32);
183 tmp = RTL_R32(addr);
186 static void mdio_write(struct net_device *unit, int RegAddr, UWORD value)
188 APTR base = get_hwbase(unit);
189 int i;
191 RTL_W32(base + (PHYAR), PHYAR_Write |
192 (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift |
193 (value & PHYAR_Data_Mask));
195 for (i = 0; i < 10; i++) {
196 /* Check if the RTL8168 has completed writing to the specified MII register */
197 if (!(RTL_R32(base + (PHYAR)) & PHYAR_Flag))
198 break;
200 udelay(100);
204 static ULONG mdio_read(struct net_device *unit, int RegAddr)
206 APTR base = get_hwbase(unit);
207 UWORD value = 0xffff;
208 int i;
210 RTL_W32(base + (PHYAR), PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift);
212 for (i = 0; i < 10; i++) {
213 /* Check if the RTL8168 has completed retrieving data from the specified MII register */
214 if (RTL_R32(base + (PHYAR)) & PHYAR_Flag) {
215 value = (UWORD)(RTL_R32(base + (PHYAR)) & PHYAR_Data_Mask);
216 break;
218 udelay(100);
220 return value;
223 static void rtl8168nic_EPHYWrite(struct net_device *unit, int RegAddr, UWORD value)
225 APTR base = get_hwbase(unit);
226 int i;
228 RTL_W32(base + (EPHYAR),
229 EPHYAR_Write |
230 (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift |
231 (value & EPHYAR_Data_Mask));
233 for (i = 0; i < 10; i++) {
234 udelay(100);
236 /* Check if the RTL8168 has completed EPHY write */
237 if (!(RTL_R32(base + (EPHYAR)) & EPHYAR_Flag))
238 break;
241 udelay(20);
244 static UWORD rtl8168nic_EPHYRead(struct net_device *unit, int RegAddr)
246 APTR base = get_hwbase(unit);
247 UWORD value = 0xffff;
248 int i;
250 RTL_W32(base + (EPHYAR),
251 EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift);
253 for (i = 0; i < 10; i++) {
254 udelay(100);
256 /* Check if the RTL8168 has completed EPHY read */
257 if (RTL_R32(base + (EPHYAR)) & EPHYAR_Flag) {
258 value = (UWORD)(RTL_R32(base + (EPHYAR)) & EPHYAR_Data_Mask);
259 break;
263 udelay(20);
265 return value;
268 static void rtl8168nic_CSIWrite(struct net_device *unit, int addr, ULONG value)
270 APTR base = get_hwbase(unit);
271 int i;
273 RTL_W32(base + (CSIDR), value);
274 RTL_W32(base + (CSIAR),
275 CSIAR_Write |
276 CSIAR_ByteEn << CSIAR_ByteEn_shift |
277 (addr & CSIAR_Addr_Mask));
279 for (i = 0; i < 10; i++) {
280 udelay(100);
282 /* Check if the RTL8168 has completed CSI write */
283 if (!(RTL_R32(base + (CSIAR)) & CSIAR_Flag))
284 break;
287 udelay(20);
290 static ULONG rtl8168nic_CSIRead(struct net_device *unit, int addr)
292 APTR base = get_hwbase(unit);
293 ULONG value = 0xffffffff;
294 int i;
296 RTL_W32(base + (CSIAR),
297 CSIAR_Read |
298 CSIAR_ByteEn << CSIAR_ByteEn_shift |
299 (addr & CSIAR_Addr_Mask));
301 for (i = 0; i < 10; i++) {
302 udelay(100);
304 /* Check if the RTL8168 has completed CSI read */
305 if (RTL_R32(base + (CSIAR)) & CSIAR_Flag) {
306 value = RTL_R32(base + (CSIDR));
307 break;
311 udelay(20);
313 return value;
316 static void rtl8168nic_PHYPowerUP(struct net_device *unit)
318 APTR base = get_hwbase(unit);
320 RTLD(bug("[%s] rtl8168nic_PHYPowerUP()\n", unit->rtl8168u_name))
322 mdio_write(unit, 0x1F, 0x0000);
323 mdio_write(unit, 0x0E, 0x0000);
326 static void rtl8168nic_GetMACVersion(struct net_device *unit)
328 struct rtl8168_priv *np = get_pcnpriv(unit);
329 APTR base = get_hwbase(unit);
330 ULONG reg, val32;
331 ULONG ICVerID;
333 RTLD(bug("[%s] rtl8168nic_GetMACVersion()\n", unit->rtl8168u_name))
335 val32 = RTL_R32(base + (TxConfig));
336 reg = val32 & 0x7c800000;
337 ICVerID = val32 & 0x00700000;
339 switch(reg)
341 case 0x30000000:
342 np->mcfg = CFG_METHOD_1;
343 break;
344 case 0x38000000:
345 if(ICVerID == 0x00000000) {
346 np->mcfg = CFG_METHOD_2;
347 } else if(ICVerID == 0x00500000) {
348 np->mcfg = CFG_METHOD_3;
349 } else {
350 np->mcfg = CFG_METHOD_3;
352 break;
353 case 0x3C000000:
354 if(ICVerID == 0x00000000) {
355 np->mcfg = CFG_METHOD_4;
356 } else if(ICVerID == 0x00200000) {
357 np->mcfg = CFG_METHOD_5;
358 } else if(ICVerID == 0x00400000) {
359 np->mcfg = CFG_METHOD_6;
360 } else {
361 np->mcfg = CFG_METHOD_6;
363 break;
364 case 0x3C800000:
365 if (ICVerID == 0x00100000){
366 np->mcfg = CFG_METHOD_7;
367 } else if (ICVerID == 0x00300000){
368 np->mcfg = CFG_METHOD_8;
369 } else {
370 np->mcfg = CFG_METHOD_8;
372 break;
373 case 0x28000000:
374 if(ICVerID == 0x00100000) {
375 np->mcfg = CFG_METHOD_9;
376 } else if(ICVerID == 0x00200000) {
377 np->mcfg = CFG_METHOD_10;
378 } else if(ICVerID == 0x00300000) {
379 np->mcfg = CFG_METHOD_11;
380 } else {
381 np->mcfg = CFG_METHOD_11;
383 break;
384 default:
385 np->mcfg = 0xFFFFFFFF;
386 RTLD(bug("[%s] rtl8168nic_GetMACVersion: unknown chip version (%x)\n", unit->rtl8168u_name, reg))
387 break;
391 static void rtl8168nic_PrintMACVersion(struct net_device *unit)
393 struct rtl8168_priv *np = get_pcnpriv(unit);
394 int i;
396 RTLD(bug("[%s] rtl8168nic_PrintMACVersion()\n", unit->rtl8168u_name))
398 for (i = (sizeof(rtl_chip_info) / sizeof(rtl_chip_info[0])) - 1; i >= 0; i--)
400 if (np->mcfg == rtl_chip_info[i].mcfg)
402 RTLD(bug("[%s] rtl8168nic_PrintMACVersion: mcfg == %s (%04d)\n", unit->rtl8168u_name,
403 rtl_chip_info[i].name,
404 rtl_chip_info[i].mcfg))
405 return;
409 RTLD(bug("[%s] rtl8168nic_PrintMACVersion: mac_version == Unknown\n", unit->rtl8168u_name))
412 static void rtl8168nic_HWPHYConfig(struct net_device *unit)
414 struct rtl8168_priv *np = get_pcnpriv(unit);
415 APTR base = get_hwbase(unit);
416 int data;
418 RTLD(bug("[%s] rtl8168nic_HWPHYConfig()\n", unit->rtl8168u_name))
420 if (np->mcfg == CFG_METHOD_1)
422 mdio_write(unit, 0x1F, 0x0001);
423 mdio_write(unit, 0x0B, 0x94B0);
425 mdio_write(unit, 0x1F, 0x0003);
426 mdio_write(unit, 0x12, 0x6096);
427 mdio_write(unit, 0x1F, 0x0000);
429 mdio_write(unit, 0x0D, 0xF8A0);
430 } else if (np->mcfg == CFG_METHOD_2) {
431 mdio_write(unit, 0x1F, 0x0001);
432 mdio_write(unit, 0x0B, 0x94B0);
434 mdio_write(unit, 0x1F, 0x0003);
435 mdio_write(unit, 0x12, 0x6096);
437 mdio_write(unit, 0x1F, 0x0000);
438 } else if (np->mcfg == CFG_METHOD_3) {
439 mdio_write(unit, 0x1F, 0x0001);
440 mdio_write(unit, 0x0B, 0x94B0);
442 mdio_write(unit, 0x1F, 0x0003);
443 mdio_write(unit, 0x12, 0x6096);
445 mdio_write(unit, 0x1F, 0x0000);
446 } else if (np->mcfg == CFG_METHOD_4) {
447 mdio_write(unit, 0x1F, 0x0001);
448 mdio_write(unit, 0x12, 0x2300);
449 mdio_write(unit, 0x1F, 0x0000);
450 mdio_write(unit, 0x1F, 0x0003);
451 mdio_write(unit, 0x16, 0x000A);
452 mdio_write(unit, 0x1F, 0x0000);
454 mdio_write(unit, 0x1F, 0x0003);
455 mdio_write(unit, 0x12, 0xC096);
456 mdio_write(unit, 0x1F, 0x0000);
458 mdio_write(unit, 0x1F, 0x0002);
459 mdio_write(unit, 0x00, 0x88DE);
460 mdio_write(unit, 0x01, 0x82B1);
461 mdio_write(unit, 0x1F, 0x0000);
463 mdio_write(unit, 0x1F, 0x0002);
464 mdio_write(unit, 0x08, 0x9E30);
465 mdio_write(unit, 0x09, 0x01F0);
466 mdio_write(unit, 0x1F, 0x0000);
468 mdio_write(unit, 0x1F, 0x0002);
469 mdio_write(unit, 0x0A, 0x5500);
470 mdio_write(unit, 0x1F, 0x0000);
472 mdio_write(unit, 0x1F, 0x0002);
473 mdio_write(unit, 0x03, 0x7002);
474 mdio_write(unit, 0x1F, 0x0000);
476 mdio_write(unit, 0x1F, 0x0002);
477 mdio_write(unit, 0x0C, 0x00C8);
478 mdio_write(unit, 0x1F, 0x0000);
480 mdio_write(unit, 0x1F, 0x0000);
481 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
482 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
483 } else if (np->mcfg == CFG_METHOD_5) {
484 mdio_write(unit, 0x1F, 0x0001);
485 mdio_write(unit, 0x12, 0x2300);
486 mdio_write(unit, 0x1F, 0x0003);
487 mdio_write(unit, 0x16, 0x0F0A);
488 mdio_write(unit, 0x1F, 0x0000);
490 mdio_write(unit, 0x1F, 0x0002);
491 mdio_write(unit, 0x00, 0x88DE);
492 mdio_write(unit, 0x01, 0x82B1);
493 mdio_write(unit, 0x1F, 0x0000);
495 mdio_write(unit, 0x1F, 0x0002);
496 mdio_write(unit, 0x0C, 0x7EB8);
497 mdio_write(unit, 0x1F, 0x0000);
499 mdio_write(unit, 0x1F, 0x0002);
500 mdio_write(unit, 0x06, 0x0761);
501 mdio_write(unit, 0x1F, 0x0000);
503 mdio_write(unit, 0x1F, 0x0001);
504 mdio_write(unit, 0x03, 0x802F);
505 mdio_write(unit, 0x02, 0x4F02);
506 mdio_write(unit, 0x01, 0x0409);
507 mdio_write(unit, 0x00, 0xF099);
508 mdio_write(unit, 0x04, 0x9800);
509 mdio_write(unit, 0x04, 0x9000);
510 mdio_write(unit, 0x1F, 0x0000);
512 mdio_write(unit, 0x1F, 0x0000);
513 mdio_write(unit, 0x16, mdio_read(unit, 0x16) | (1 << 0));
515 mdio_write(unit, 0x1F, 0x0000);
516 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
517 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
519 mdio_write(unit, 0x1F, 0x0001);
520 mdio_write(unit, 0x1D, 0x3D98);
521 mdio_write(unit, 0x1F, 0x0000);
523 mdio_write(unit, 0x1F, 0x0001);
524 mdio_write(unit, 0x17, 0x0CC0);
525 mdio_write(unit, 0x1F, 0x0000);
526 } else if (np->mcfg == CFG_METHOD_6) {
527 mdio_write(unit, 0x1F, 0x0001);
528 mdio_write(unit, 0x12, 0x2300);
529 mdio_write(unit, 0x1F, 0x0003);
530 mdio_write(unit, 0x16, 0x0F0A);
531 mdio_write(unit, 0x1F, 0x0000);
533 mdio_write(unit, 0x1F, 0x0002);
534 mdio_write(unit, 0x00, 0x88DE);
535 mdio_write(unit, 0x01, 0x82B1);
536 mdio_write(unit, 0x1F, 0x0000);
538 mdio_write(unit, 0x1F, 0x0002);
539 mdio_write(unit, 0x0C, 0x7EB8);
540 mdio_write(unit, 0x1F, 0x0000);
542 mdio_write(unit, 0x1F, 0x0002);
543 mdio_write(unit, 0x06, 0x0761);
544 mdio_write(unit, 0x1F, 0x0000);
546 mdio_write(unit, 0x1F, 0x0000);
547 mdio_write(unit, 0x16, mdio_read(unit, 0x16) | (1 << 0));
549 mdio_write(unit, 0x1F, 0x0000);
550 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
551 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
553 mdio_write(unit, 0x1F, 0x0001);
554 mdio_write(unit, 0x1D, 0x3D98);
555 mdio_write(unit, 0x1F, 0x0000);
557 mdio_write(unit, 0x1f, 0x0001);
558 mdio_write(unit, 0x17, 0x0CC0);
559 mdio_write(unit, 0x1F, 0x0000);
560 } else if (np->mcfg == CFG_METHOD_7) {
561 mdio_write(unit, 0x1F, 0x0000);
562 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
563 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
565 mdio_write(unit, 0x1F, 0x0001);
566 mdio_write(unit, 0x1D, 0x3D98);
568 mdio_write(unit, 0x1F, 0x0001);
569 mdio_write(unit, 0x14, 0xCAA3);
570 mdio_write(unit, 0x1C, 0x000A);
571 mdio_write(unit, 0x18, 0x65D0);
573 mdio_write(unit, 0x1F, 0x0003);
574 mdio_write(unit, 0x17, 0xB580);
575 mdio_write(unit, 0x18, 0xFF54);
576 mdio_write(unit, 0x19, 0x3954);
578 mdio_write(unit, 0x1F, 0x0002);
579 mdio_write(unit, 0x0D, 0x310C);
580 mdio_write(unit, 0x0E, 0x310C);
581 mdio_write(unit, 0x0F, 0x311C);
582 mdio_write(unit, 0x06, 0x0761);
584 mdio_write(unit, 0x1F, 0x0003);
585 mdio_write(unit, 0x18, 0xFF55);
586 mdio_write(unit, 0x19, 0x3955);
587 mdio_write(unit, 0x18, 0xFF54);
588 mdio_write(unit, 0x19, 0x3954);
590 mdio_write(unit, 0x1f, 0x0001);
591 mdio_write(unit, 0x17, 0x0CC0);
593 mdio_write(unit, 0x1F, 0x0000);
594 } else if (np->mcfg == CFG_METHOD_8) {
595 mdio_write(unit, 0x1F, 0x0000);
596 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
598 mdio_write(unit, 0x1F, 0x0001);
599 mdio_write(unit, 0x14, 0xCAA3);
600 mdio_write(unit, 0x1C, 0x000A);
601 mdio_write(unit, 0x18, 0x65D0);
603 mdio_write(unit, 0x1F, 0x0003);
604 mdio_write(unit, 0x17, 0xB580);
605 mdio_write(unit, 0x18, 0xFF54);
606 mdio_write(unit, 0x19, 0x3954);
608 mdio_write(unit, 0x1F, 0x0002);
609 mdio_write(unit, 0x0D, 0x310C);
610 mdio_write(unit, 0x0E, 0x310C);
611 mdio_write(unit, 0x0F, 0x311C);
612 mdio_write(unit, 0x06, 0x0761);
614 mdio_write(unit, 0x1F, 0x0003);
615 mdio_write(unit, 0x18, 0xFF55);
616 mdio_write(unit, 0x19, 0x3955);
617 mdio_write(unit, 0x18, 0xFF54);
618 mdio_write(unit, 0x19, 0x3954);
620 mdio_write(unit, 0x1f, 0x0001);
621 mdio_write(unit, 0x17, 0x0CC0);
623 mdio_write(unit, 0x1F, 0x0000);
624 } else if (np->mcfg == CFG_METHOD_9) {
625 mdio_write(unit, 0x1F, 0x0001);
626 mdio_write(unit, 0x06, 0x4064);
627 mdio_write(unit, 0x07, 0x2863);
628 mdio_write(unit, 0x08, 0x059C);
629 mdio_write(unit, 0x09, 0x26B4);
630 mdio_write(unit, 0x0A, 0x6A19);
631 mdio_write(unit, 0x0B, 0xACC0);
632 mdio_write(unit, 0x10, 0xF06D);
633 mdio_write(unit, 0x14, 0x7F68);
634 mdio_write(unit, 0x18, 0x7FD9);
635 mdio_write(unit, 0x1C, 0xF0FF);
636 mdio_write(unit, 0x1D, 0x3D9C);
637 mdio_write(unit, 0x1F, 0x0003);
638 mdio_write(unit, 0x12, 0xF49F);
639 mdio_write(unit, 0x13, 0x070B);
640 mdio_write(unit, 0x1A, 0x05AD);
641 mdio_write(unit, 0x14, 0x94C0);
643 mdio_write(unit, 0x1F, 0x0002);
644 mdio_write(unit, 0x0B, 0x0B10);
645 mdio_write(unit, 0x0C, 0xA2F7);
647 mdio_write(unit, 0x1F, 0x0002);
648 mdio_write(unit, 0x06, 0x5571);
650 mdio_write(unit, 0x1F, 0x0002);
651 mdio_write(unit, 0x02, 0xC107);
652 mdio_write(unit, 0x03, 0x1002);
654 mdio_write(unit, 0x1F, 0x0001);
655 mdio_write(unit, 0x17, 0x0CC0);
657 mdio_write(unit, 0x1F, 0x0005);
658 mdio_write(unit, 0x05, 0x8200);
659 mdio_write(unit, 0x06, 0xF8F9);
660 mdio_write(unit, 0x06, 0xFAEF);
661 mdio_write(unit, 0x06, 0x59EE);
662 mdio_write(unit, 0x06, 0xF8EA);
663 mdio_write(unit, 0x06, 0x00EE);
664 mdio_write(unit, 0x06, 0xF8EB);
665 mdio_write(unit, 0x06, 0x00E0);
666 mdio_write(unit, 0x06, 0xF87C);
667 mdio_write(unit, 0x06, 0xE1F8);
668 mdio_write(unit, 0x06, 0x7D59);
669 mdio_write(unit, 0x06, 0x0FEF);
670 mdio_write(unit, 0x06, 0x0139);
671 mdio_write(unit, 0x06, 0x029E);
672 mdio_write(unit, 0x06, 0x06EF);
673 mdio_write(unit, 0x06, 0x1039);
674 mdio_write(unit, 0x06, 0x089F);
675 mdio_write(unit, 0x06, 0x2AEE);
676 mdio_write(unit, 0x06, 0xF8EA);
677 mdio_write(unit, 0x06, 0x00EE);
678 mdio_write(unit, 0x06, 0xF8EB);
679 mdio_write(unit, 0x06, 0x01E0);
680 mdio_write(unit, 0x06, 0xF87C);
681 mdio_write(unit, 0x06, 0xE1F8);
682 mdio_write(unit, 0x06, 0x7D58);
683 mdio_write(unit, 0x06, 0x409E);
684 mdio_write(unit, 0x06, 0x0F39);
685 mdio_write(unit, 0x06, 0x46AA);
686 mdio_write(unit, 0x06, 0x0BBF);
687 mdio_write(unit, 0x06, 0x8251);
688 mdio_write(unit, 0x06, 0xD682);
689 mdio_write(unit, 0x06, 0x5902);
690 mdio_write(unit, 0x06, 0x014F);
691 mdio_write(unit, 0x06, 0xAE09);
692 mdio_write(unit, 0x06, 0xBF82);
693 mdio_write(unit, 0x06, 0x59D6);
694 mdio_write(unit, 0x06, 0x8261);
695 mdio_write(unit, 0x06, 0x0201);
696 mdio_write(unit, 0x06, 0x4FEF);
697 mdio_write(unit, 0x06, 0x95FE);
698 mdio_write(unit, 0x06, 0xFDFC);
699 mdio_write(unit, 0x06, 0x054D);
700 mdio_write(unit, 0x06, 0x2000);
701 mdio_write(unit, 0x06, 0x024E);
702 mdio_write(unit, 0x06, 0x2200);
703 mdio_write(unit, 0x06, 0x024D);
704 mdio_write(unit, 0x06, 0xDFFF);
705 mdio_write(unit, 0x06, 0x014E);
706 mdio_write(unit, 0x06, 0xDDFF);
707 mdio_write(unit, 0x06, 0x0100);
708 mdio_write(unit, 0x06, 0x6010);
709 mdio_write(unit, 0x05, 0xFFF6);
710 mdio_write(unit, 0x06, 0x00EC);
711 mdio_write(unit, 0x05, 0x83D4);
712 mdio_write(unit, 0x06, 0x8200);
713 mdio_write(unit, 0x1F, 0x0000);
714 } else if (np->mcfg == CFG_METHOD_10) {
715 mdio_write(unit, 0x1F, 0x0001);
716 mdio_write(unit, 0x06, 0x4064);
717 mdio_write(unit, 0x07, 0x2863);
718 mdio_write(unit, 0x08, 0x059C);
719 mdio_write(unit, 0x09, 0x26B4);
720 mdio_write(unit, 0x0A, 0x6A19);
721 mdio_write(unit, 0x0B, 0xACC0);
722 mdio_write(unit, 0x10, 0xF06D);
723 mdio_write(unit, 0x14, 0x7F68);
724 mdio_write(unit, 0x18, 0x7FD9);
725 mdio_write(unit, 0x1C, 0xF0FF);
726 mdio_write(unit, 0x1D, 0x3D9C);
727 mdio_write(unit, 0x1F, 0x0003);
728 mdio_write(unit, 0x12, 0xF49F);
729 mdio_write(unit, 0x13, 0x070B);
730 mdio_write(unit, 0x1A, 0x05AD);
731 mdio_write(unit, 0x14, 0x94C0);
733 mdio_write(unit, 0x1F, 0x0002);
734 mdio_write(unit, 0x06, 0x5571);
736 mdio_write(unit, 0x1F, 0x0002);
737 mdio_write(unit, 0x05, 0x2642);
739 mdio_write(unit, 0x1F, 0x0002);
740 mdio_write(unit, 0x02, 0xC107);
741 mdio_write(unit, 0x03, 0x1002);
743 mdio_write(unit, 0x1F, 0x0001);
744 mdio_write(unit, 0x17, 0x0CC0);
746 mdio_write(unit, 0x1F, 0x0002);
747 mdio_write(unit, 0x0F, 0x0017);
749 mdio_write(unit, 0x1F, 0x0005);
750 mdio_write(unit, 0x05, 0x8200);
751 mdio_write(unit, 0x06, 0xF8F9);
752 mdio_write(unit, 0x06, 0xFAEF);
753 mdio_write(unit, 0x06, 0x59EE);
754 mdio_write(unit, 0x06, 0xF8EA);
755 mdio_write(unit, 0x06, 0x00EE);
756 mdio_write(unit, 0x06, 0xF8EB);
757 mdio_write(unit, 0x06, 0x00E0);
758 mdio_write(unit, 0x06, 0xF87C);
759 mdio_write(unit, 0x06, 0xE1F8);
760 mdio_write(unit, 0x06, 0x7D59);
761 mdio_write(unit, 0x06, 0x0FEF);
762 mdio_write(unit, 0x06, 0x0139);
763 mdio_write(unit, 0x06, 0x029E);
764 mdio_write(unit, 0x06, 0x06EF);
765 mdio_write(unit, 0x06, 0x1039);
766 mdio_write(unit, 0x06, 0x089F);
767 mdio_write(unit, 0x06, 0x2AEE);
768 mdio_write(unit, 0x06, 0xF8EA);
769 mdio_write(unit, 0x06, 0x00EE);
770 mdio_write(unit, 0x06, 0xF8EB);
771 mdio_write(unit, 0x06, 0x01E0);
772 mdio_write(unit, 0x06, 0xF87C);
773 mdio_write(unit, 0x06, 0xE1F8);
774 mdio_write(unit, 0x06, 0x7D58);
775 mdio_write(unit, 0x06, 0x409E);
776 mdio_write(unit, 0x06, 0x0F39);
777 mdio_write(unit, 0x06, 0x46AA);
778 mdio_write(unit, 0x06, 0x0BBF);
779 mdio_write(unit, 0x06, 0x8251);
780 mdio_write(unit, 0x06, 0xD682);
781 mdio_write(unit, 0x06, 0x5902);
782 mdio_write(unit, 0x06, 0x014F);
783 mdio_write(unit, 0x06, 0xAE09);
784 mdio_write(unit, 0x06, 0xBF82);
785 mdio_write(unit, 0x06, 0x59D6);
786 mdio_write(unit, 0x06, 0x8261);
787 mdio_write(unit, 0x06, 0x0201);
788 mdio_write(unit, 0x06, 0x4FEF);
789 mdio_write(unit, 0x06, 0x95FE);
790 mdio_write(unit, 0x06, 0xFDFC);
791 mdio_write(unit, 0x06, 0x054D);
792 mdio_write(unit, 0x06, 0x2000);
793 mdio_write(unit, 0x06, 0x024E);
794 mdio_write(unit, 0x06, 0x2200);
795 mdio_write(unit, 0x06, 0x024D);
796 mdio_write(unit, 0x06, 0xDFFF);
797 mdio_write(unit, 0x06, 0x014E);
798 mdio_write(unit, 0x06, 0xDDFF);
799 mdio_write(unit, 0x06, 0x0100);
800 mdio_write(unit, 0x02, 0x6010);
801 mdio_write(unit, 0x05, 0xFFF6);
802 mdio_write(unit, 0x06, 0x00EC);
803 mdio_write(unit, 0x05, 0x83D4);
804 mdio_write(unit, 0x06, 0x8200);
805 mdio_write(unit, 0x1F, 0x0000);
806 } else if (np->mcfg == CFG_METHOD_11) {
807 mdio_write(unit, 0x1F, 0x0001);
808 mdio_write(unit, 0x06, 0x4064);
809 mdio_write(unit, 0x07, 0x2863);
810 mdio_write(unit, 0x08, 0x059C);
811 mdio_write(unit, 0x09, 0x26B4);
812 mdio_write(unit, 0x0A, 0x6A19);
813 mdio_write(unit, 0x0B, 0xACC0);
814 mdio_write(unit, 0x10, 0xF06D);
815 mdio_write(unit, 0x14, 0x7F68);
816 mdio_write(unit, 0x18, 0x7FD9);
817 mdio_write(unit, 0x1C, 0xF0FF);
818 mdio_write(unit, 0x1D, 0x3D9C);
819 mdio_write(unit, 0x1F, 0x0003);
820 mdio_write(unit, 0x12, 0xF49F);
821 mdio_write(unit, 0x13, 0x070B);
822 mdio_write(unit, 0x1A, 0x05AD);
823 mdio_write(unit, 0x14, 0x94C0);
825 mdio_write(unit, 0x1F, 0x0002);
826 mdio_write(unit, 0x06, 0x5571);
828 mdio_write(unit, 0x1F, 0x0002);
829 mdio_write(unit, 0x05, 0x2642);
831 mdio_write(unit, 0x1F, 0x0002);
832 mdio_write(unit, 0x02, 0xC107);
833 mdio_write(unit, 0x03, 0x1002);
835 mdio_write(unit, 0x1F, 0x0001);
836 mdio_write(unit, 0x17, 0x0CC0);
838 mdio_write(unit, 0x1F, 0x0002);
839 mdio_write(unit, 0x0F, 0x0017);
843 static void rtl8168nic_DSM(struct net_device *unit, int dev_state)
845 struct rtl8168_priv *np = get_pcnpriv(unit);
846 APTR base = get_hwbase(unit);
848 switch (dev_state) {
849 case DSM_MAC_INIT:
850 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6)) {
851 if (RTL_R8(base + (MACDBG)) & 0x80) {
852 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
853 } else {
854 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
858 break;
859 case DSM_NIC_GOTO_D3:
860 case DSM_IF_DOWN:
861 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
862 if (RTL_R8(base + (MACDBG)) & 0x80)
863 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
865 break;
866 case DSM_NIC_RESUME_D3:
867 case DSM_IF_UP:
868 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
869 if (RTL_R8(base + (MACDBG)) & 0x80)
870 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
872 break;
876 static int rtl8168nic_SetSpeedXMII(struct net_device *unit,
877 UBYTE autoneg,
878 UWORD speed,
879 UBYTE duplex)
881 struct rtl8168_priv *np = get_pcnpriv(unit);
882 APTR base = get_hwbase(unit);
883 int auto_nego = 0;
884 int giga_ctrl = 0;
885 int bmcr_true_force = 0;
886 unsigned long flags;
888 RTLD(bug("[%s] rtl8168nic_SetSpeedXMII()\n", unit->rtl8168u_name))
890 if ((speed != SPEED_1000) &&
891 (speed != SPEED_100) &&
892 (speed != SPEED_10)) {
893 speed = SPEED_1000;
894 duplex = DUPLEX_FULL;
897 if ((autoneg == AUTONEG_ENABLE) || (speed == SPEED_1000)) {
898 /*n-way force*/
899 if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) {
900 auto_nego |= ADVERTISE_10HALF;
901 } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) {
902 auto_nego |= ADVERTISE_10HALF |
903 ADVERTISE_10FULL;
904 } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) {
905 auto_nego |= ADVERTISE_100HALF |
906 ADVERTISE_10HALF |
907 ADVERTISE_10FULL;
908 } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) {
909 auto_nego |= ADVERTISE_100HALF |
910 ADVERTISE_100FULL |
911 ADVERTISE_10HALF |
912 ADVERTISE_10FULL;
913 } else if (speed == SPEED_1000) {
914 giga_ctrl |= ADVERTISE_1000HALF |
915 ADVERTISE_1000FULL;
917 auto_nego |= ADVERTISE_100HALF |
918 ADVERTISE_100FULL |
919 ADVERTISE_10HALF |
920 ADVERTISE_10FULL;
923 //disable flow contorol
924 auto_nego &= ~ADVERTISE_PAUSE_CAP;
925 auto_nego &= ~ADVERTISE_PAUSE_ASYM;
927 np->phy_auto_nego_reg = auto_nego;
928 np->phy_1000_ctrl_reg = giga_ctrl;
930 np->autoneg = autoneg;
931 np->speed = speed;
932 np->duplex = duplex;
934 rtl8168nic_PHYPowerUP(unit);
936 mdio_write(unit, 0x1f, 0x0000);
937 mdio_write(unit, MII_ADVERTISE, auto_nego);
938 mdio_write(unit, MII_CTRL1000, giga_ctrl);
939 mdio_write(unit, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
940 } else {
941 /*true force*/
942 #ifndef BMCR_SPEED100
943 #define BMCR_SPEED100 0x0040
944 #endif
946 #ifndef BMCR_SPEED10
947 #define BMCR_SPEED10 0x0000
948 #endif
949 if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) {
950 bmcr_true_force = BMCR_SPEED10;
951 } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) {
952 bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX;
953 } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) {
954 bmcr_true_force = BMCR_SPEED100;
955 } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) {
956 bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX;
959 mdio_write(unit, 0x1f, 0x0000);
960 mdio_write(unit, MII_BMCR, bmcr_true_force);
963 return 0;
967 static void rtl8168nic_start_rx(struct net_device *unit)
969 struct rtl8168_priv *np = get_pcnpriv(unit);
970 APTR base = get_hwbase(unit);
972 RTLD(bug("[%s] rtl8168nic_start_rx\n", unit->rtl8168u_name))
973 // Already running? Stop it.
974 #warning "TODO: Handle starting/stopping Rx"
977 static void rtl8168nic_stop_rx(struct net_device *unit)
979 APTR base = get_hwbase(unit);
981 RTLD(bug("[%s] rtl8168nic_stop_rx\n", unit->rtl8168u_name))
982 #warning "TODO: Handle starting/stopping Rx"
985 static void rtl8168nic_start_tx(struct net_device *unit)
987 APTR base = get_hwbase(unit);
989 RTLD(bug("[%s] rtl8168nic_start_tx()\n", unit->rtl8168u_name))
990 #warning "TODO: Handle starting/stopping Tx"
993 static void rtl8168nic_stop_tx(struct net_device *unit)
995 APTR base = get_hwbase(unit);
997 RTLD(bug("[%s] rtl8168nic_stop_tx()\n", unit->rtl8168u_name))
998 #warning "TODO: Handle starting/stopping Tx"
1001 static void rtl8168nic_txrx_reset(struct net_device *unit)
1003 struct rtl8168_priv *np = get_pcnpriv(unit);
1004 APTR base = get_hwbase(unit);
1006 RTLD(bug("[%s] rtl8168nic_txrx_reset()\n", unit->rtl8168u_name))
1010 * rtl8168nic_SetMulticast: unit->set_multicast function
1011 * Called with unit->xmit_lock held.
1013 static void rtl8168nic_SetMulticast(struct net_device *unit)
1015 struct rtl8168_priv *np = get_pcnpriv(unit);
1016 APTR base = get_hwbase(unit);
1017 ULONG addr[2];
1018 ULONG mask[2];
1019 ULONG pff;
1021 RTLD(bug("[%s] rtl8168nic_SetMulticast()\n", unit->rtl8168u_name))
1023 memset(addr, 0, sizeof(addr));
1024 memset(mask, 0, sizeof(mask));
1027 static void rtl8168nic_DeInit(struct net_device *unit)
1029 #warning "TODO: Clean up / DeInit hardware"
1032 static void rtl8168nic_GetMACAddr(struct net_device *unit, char *addr, BOOL fromROM)
1034 APTR base = get_hwbase(unit);
1035 int i;
1037 RTLD(bug("[%s] rtl8168nic_GetMACAddr()\n",unit->rtl8168u_name))
1038 /* Get MAC address. FIXME: read EEPROM */
1039 for (i = 0; i < MAC_ADDR_LEN; i++)
1040 addr[i] = RTL_R8(base + MAC0 + i);
1043 static void rtl8168nic_SetMACAddr(struct net_device *unit)
1045 APTR base = get_hwbase(unit);
1046 int i,j;
1048 RTLD(bug("[%s] rtl8168nic_SetMACAddr()\n",unit->rtl8168u_name))
1050 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1052 RTL_W32(base + (MAC0),
1053 unit->rtl8168u_dev_addr[0] |
1054 (unit->rtl8168u_dev_addr[1] << 8) |
1055 (unit->rtl8168u_dev_addr[2] << 16) |
1056 (unit->rtl8168u_dev_addr[3] << 24));
1057 RTL_W32(base + (MAC4),
1058 unit->rtl8168u_dev_addr[4] |
1059 (unit->rtl8168u_dev_addr[5] << 8));
1061 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
1063 RTLD(
1064 /* Read it back to be certain! */
1065 TEXT newmac[6];
1066 rtl8168nic_GetMACAddr(unit, newmac, FALSE);
1068 bug("[%s] rtl8168nic_SetMACAddr: New MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8168u_name,
1069 newmac[0], newmac[1], newmac[2],
1070 newmac[3], newmac[4], newmac[5])
1074 static void rtl8168nic_LinkOption(struct net_device *unit, UBYTE *aut, UWORD *spd, UBYTE *dup)
1076 unsigned char opt_speed;
1077 unsigned char opt_duplex;
1078 unsigned char opt_autoneg;
1080 opt_speed = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->speed[unit->rtl8168u_UnitNum] : 0xff;
1081 opt_duplex = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->duplex[unit->rtl8168u_UnitNum] : 0xff;
1082 opt_autoneg = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->autoneg[unit->rtl8168u_UnitNum] : 0xff;
1084 if ((opt_speed == 0xff) |
1085 (opt_duplex == 0xff) |
1086 (opt_autoneg == 0xff)) {
1087 *spd = SPEED_1000;
1088 *dup = DUPLEX_FULL;
1089 *aut = AUTONEG_ENABLE;
1090 } else {
1091 *spd = unit->rtl8168u_device->speed[unit->rtl8168u_UnitNum];
1092 *dup = unit->rtl8168u_device->duplex[unit->rtl8168u_UnitNum];
1093 *aut = unit->rtl8168u_device->autoneg[unit->rtl8168u_UnitNum];
1097 static void rtl8168nic_Init(struct net_device *unit)
1099 struct pHidd_PCIDevice_WriteConfigByte pcibyte;
1101 struct rtl8168_priv *np = get_pcnpriv(unit);
1102 APTR base = get_hwbase(unit);
1103 UBYTE autoneg, duplex;
1104 UWORD speed;
1105 int i, config1;
1107 RTLD(bug("[%s] rtl8168nic_Init(unit @ %p)\n", unit->rtl8168u_name, unit))
1109 /* Identify chip attached to board */
1110 rtl8168nic_GetMACVersion(unit);
1111 rtl8168nic_PrintMACVersion(unit);
1113 for (i = (sizeof(rtl_chip_info) / sizeof(rtl_chip_info[0])) - 1; i >= 0; i--) {
1114 if (np->mcfg == rtl_chip_info[i].mcfg)
1115 break;
1118 if (i < 0) {
1119 /* Unknown chip: assume array element #0, original RTL-8168 */
1120 RTLD(bug("[%s] rtl8168nic_Init: Unknown Realtek chip version, assuming %s\n", unit->rtl8168u_name, rtl_chip_info[0].name))
1121 i++;
1124 np->chipset = i;
1125 unit->rtl8168u_rtl_chipname = rtl_chip_info[np->chipset].name;
1127 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1128 RTL_W8(base + (Config1), RTL_R8(base + Config1) | PMEnable);
1129 RTL_W8(base + (Config5), RTL_R8(base + Config5) & PMEStatus);
1130 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
1132 RTLD(bug("[%s] rtl8168nic_Init: Power Management enabled\n", unit->rtl8168u_name))
1135 /* RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1136 np->features |= rtl8168_try_msi(pdev, base);
1137 RTL_W8(base + (Cfg9346), Cfg9346_Lock); /*
1139 /***/
1141 rtl8168nic_GetMACAddr(unit, &np->orig_mac[0], TRUE);
1143 unit->rtl8168u_dev_addr[0] = unit->rtl8168u_org_addr[0] = np->orig_mac[0];
1144 unit->rtl8168u_dev_addr[1] = unit->rtl8168u_org_addr[1] = np->orig_mac[1];
1145 unit->rtl8168u_dev_addr[2] = unit->rtl8168u_org_addr[2] = np->orig_mac[2];
1146 unit->rtl8168u_dev_addr[3] = unit->rtl8168u_org_addr[3] = np->orig_mac[3];
1147 unit->rtl8168u_dev_addr[4] = unit->rtl8168u_org_addr[4] = np->orig_mac[4];
1148 unit->rtl8168u_dev_addr[5] = unit->rtl8168u_org_addr[5] = np->orig_mac[5];
1150 RTLD(bug("[%s] rtl8168nic_Init: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8168u_name,
1151 unit->rtl8168u_dev_addr[0], unit->rtl8168u_dev_addr[1], unit->rtl8168u_dev_addr[2],
1152 unit->rtl8168u_dev_addr[3], unit->rtl8168u_dev_addr[4], unit->rtl8168u_dev_addr[5]))
1154 bug("[%s] rtl8168nic_Init: This product is covered by one or more of the following patents:\n", unit->rtl8168u_name);
1155 bug("[%s] rtl8168nic_Init: US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625.\n", unit->rtl8168u_name);
1158 unit->features |= NETIF_F_IP_CSUM;
1160 np->cp_cmd |= RxChkSum;
1161 np->cp_cmd |= RTL_R16(base + (CPlusCmd));
1163 np->intr_mask = unit->rtl8168u_intr_mask;
1165 rtl8168nic_HWPHYConfig(unit);
1167 RTLD(bug("[%s] rtl8168nic_Init: PHY Configured\n", unit->rtl8168u_name))
1169 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1170 pcibyte.reg = PCI_LATENCY_TIMER;
1171 pcibyte.val = 0x40;
1172 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1174 rtl8168nic_LinkOption(unit, &autoneg, &speed, &duplex);
1176 rtl8168nic_SetSpeedXMII(unit, autoneg, speed, duplex);
1178 RTLD(bug("[%s] rtl8168nic_Init: Link Speed %dbps %s duplex %s\n", unit->rtl8168u_name, speed, (duplex == DUPLEX_HALF) ? "half" :"full", (autoneg == AUTONEG_ENABLE) ? "(autoneg)" :""))
1181 static void rtl8168nic_drain_tx(struct net_device *unit)
1183 struct rtl8168_priv *np = get_pcnpriv(unit);
1184 int i;
1185 // for (i = 0; i < NUM_TX_DESC; i++) {
1186 #warning "TODO: rtl8168nic_drain_tx does nothing atm."
1187 // }
1190 static void rtl8168nic_drain_rx(struct net_device *unit)
1192 struct rtl8168_priv *np = get_pcnpriv(unit);
1193 int i;
1194 // for (i = 0; i < RX_RING_SIZE; i++) {
1195 #warning "TODO: rtl8168nic_drain_rx does nothing atm."
1196 // }
1200 static void drain_ring(struct net_device *unit)
1202 rtl8168nic_drain_tx(unit);
1203 rtl8168nic_drain_rx(unit);
1206 static int request_irq(struct net_device *unit)
1208 OOP_Object *irq = OOP_NewObject(NULL, CLID_Hidd_IRQ, NULL);
1209 BOOL ret;
1211 RTLD(bug("[%s] request_irq()\n", unit->rtl8168u_name))
1213 if (irq)
1215 ret = HIDD_IRQ_AddHandler(irq, unit->rtl8168u_irqhandler, unit->rtl8168u_IRQ);
1216 HIDD_IRQ_AddHandler(irq, unit->rtl8168u_touthandler, vHidd_IRQ_Timer);
1218 RTLD(bug("[%s] request_irq: IRQ Handlers configured\n", unit->rtl8168u_name))
1220 OOP_DisposeObject(irq);
1222 if (ret)
1224 return 0;
1227 return 1;
1230 static void free_irq(struct net_device *unit)
1232 OOP_Object *irq = OOP_NewObject(NULL, CLID_Hidd_IRQ, NULL);
1233 if (irq)
1235 HIDD_IRQ_RemHandler(irq, unit->rtl8168u_irqhandler);
1236 HIDD_IRQ_RemHandler(irq, unit->rtl8168u_touthandler);
1237 OOP_DisposeObject(irq);
1241 static void rtl8168nic_SetRXBufSize(struct net_device *unit)
1243 struct rtl8168_priv *np = get_pcnpriv(unit);
1244 APTR base = get_hwbase(unit);
1245 unsigned int mtu = unit->rtl8168u_mtu;
1247 RTLD(bug("[%s] rtl8168nic_SetRXBufSize()\n", unit->rtl8168u_name))
1249 np->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
1251 RTL_W16(base + (RxMaxSize), np->rx_buf_sz + 1);
1254 static void rtl8168nic_NICReset(struct net_device *unit)
1256 struct rtl8168_priv *np = get_pcnpriv(unit);
1257 APTR base = get_hwbase(unit);
1258 int i;
1260 RTLD(bug("[%s] rtl8168nic_NICReset()\n", unit->rtl8168u_name))
1262 if ((np->mcfg != CFG_METHOD_1) &&
1263 (np->mcfg != CFG_METHOD_2) &&
1264 (np->mcfg != CFG_METHOD_3)) {
1265 RTL_W8(base + (ChipCmd), StopReq | CmdRxEnb | CmdTxEnb);
1266 udelay(100);
1269 /* Soft reset the chip. */
1270 RTL_W8(base + (ChipCmd), CmdReset);
1272 /* Check that the chip has finished the reset. */
1273 for (i = 1000; i > 0; i--) {
1274 if ((RTL_R8(base + (ChipCmd)) & CmdReset) == 0)
1275 break;
1276 udelay(100);
1280 static void rtl8168nic_SetRxMode(struct net_device *unit)
1282 struct rtl8168_priv *np = get_pcnpriv(unit);
1283 APTR base = get_hwbase(unit);
1284 unsigned long flags;
1285 ULONG mc_filter[2]; /* Multicast hash filter */
1286 int i, j, k, rx_mode;
1287 ULONG tmp = 0;
1289 RTLD(bug("[%s] rtl8168nic_SetRxMode()\n", unit->rtl8168u_name))
1291 if (unit->rtl8168u_flags & IFF_PROMISC) {
1292 /* Unconditionally log net taps. */
1293 RTLD(bug("[%s] rtl8168nic_SetRxMode: Promiscuous mode enabled\n", unit->rtl8168u_name))
1294 rx_mode =
1295 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
1296 AcceptAllPhys;
1297 mc_filter[1] = mc_filter[0] = 0xffffffff;
1298 } else if ((unit->rtl8168u_mc_count > unit->rtl8168u_device->rtl8168b_MulticastFilterLimit)
1299 || (unit->rtl8168u_flags & IFF_ALLMULTI)) {
1300 /* Too many to filter perfectly -- accept all multicasts. */
1301 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
1302 mc_filter[1] = mc_filter[0] = 0xffffffff;
1303 } else {
1304 struct dev_mc_list *mclist;
1305 rx_mode = AcceptBroadcast | AcceptMyPhys;
1306 mc_filter[1] = mc_filter[0] = 0;
1307 for (i = 0, mclist = unit->rtl8168u_mc_list; mclist && i < unit->rtl8168u_mc_count;
1308 i++, mclist = mclist->next) {
1309 // int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1310 // mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1311 rx_mode |= AcceptMulticast;
1315 np->rtl8168_rx_config = rtl_chip_info[np->chipset].RCR_Cfg;
1316 tmp = np->rtl8168_rx_config | rx_mode | (RTL_R32(base + (RxConfig)) & rtl_chip_info[np->chipset].RxConfigMask);
1318 for (j = 0; j < 2; j++) {
1319 ULONG mask = 0x000000ff;
1320 ULONG tmp1 = 0;
1321 ULONG tmp2 = 0;
1322 int x = 0;
1323 int y = 0;
1325 for (k = 0; k < 4; k++) {
1326 tmp1 = mc_filter[j] & mask;
1327 x = 32 - (8 + 16 * k);
1328 y = x - 2 * x;
1330 if (x > 0)
1331 tmp2 = tmp2 | (tmp1 << x);
1332 else
1333 tmp2 = tmp2 | (tmp1 >> y);
1335 mask = mask << 8;
1337 mc_filter[j] = tmp2;
1340 RTL_W32(base + (RxConfig), tmp);
1341 RTL_W32(base + (MAR0 + 0), mc_filter[1]);
1342 RTL_W32(base + (MAR0 + 4), mc_filter[0]);
1345 static void rtl8168nic_HWStart(struct net_device *unit)
1347 struct rtl8168_priv *np = get_pcnpriv(unit);
1348 APTR base = get_hwbase(unit);
1350 struct pHidd_PCIDevice_WriteConfigByte pcibyte;
1352 UBYTE device_control;
1353 UWORD ephy_data;
1354 ULONG csi_tmp;
1356 RTLD(bug("[%s] rtl8168nic_HWStart()\n", unit->rtl8168u_name))
1358 rtl8168nic_NICReset(unit);
1360 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1362 RTL_W8(base + (Reserved1), Reserved1_data);
1364 np->cp_cmd |= PktCntrDisable | INTT_1;
1365 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1367 RTL_W16(base + (IntrMitigate), 0x5151);
1369 //Work around for RxFIFO overflow
1370 if (np->mcfg == CFG_METHOD_1) {
1371 unit->rtl8168u_intr_mask |= RxFIFOOver | PCSTimeout;
1372 unit->rtl8168u_intr_mask &= ~RxDescUnavail;
1375 RTL_W32(base + (TxDescStartAddrLow), ((UQUAD) np->TxPhyAddr & DMA_32BIT_MASK));
1376 RTL_W32(base + (TxDescStartAddrHigh), ((UQUAD) np->TxPhyAddr >> 32));
1377 RTL_W32(base + (RxDescAddrLow), ((UQUAD) np->RxPhyAddr & DMA_32BIT_MASK));
1378 RTL_W32(base + (RxDescAddrHigh), ((UQUAD) np->RxPhyAddr >> 32));
1380 /* Set Rx Config register */
1381 rtl8168nic_SetRxMode(unit);
1383 /* Set DMA burst size and Interframe Gap Time */
1384 if (np->mcfg == CFG_METHOD_1) {
1385 RTL_W32(base + (TxConfig), (TX_DMA_BURST_512 << TxDMAShift) |
1386 (InterFrameGap << TxInterFrameGapShift));
1387 } else {
1388 RTL_W32(base + (TxConfig), (TX_DMA_BURST_unlimited << TxDMAShift) |
1389 (InterFrameGap << TxInterFrameGapShift));
1392 /* Clear the interrupt status register. */
1393 RTL_W16(base + (IntrStatus), 0xFFFF);
1395 if (np->rx_fifo_overflow == 0) {
1396 /* Enable all known interrupts by setting the interrupt mask. */
1397 RTL_W16(base + (IntrMask), unit->rtl8168u_intr_mask);
1398 netif_start_queue(unit);
1401 if (np->mcfg == CFG_METHOD_4) {
1402 /*set PCI configuration space offset 0x70F to 0x27*/
1403 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1404 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1405 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1407 RTL_W8(base + (DBG_reg), (0x0E << 4) | Fix_Nak_1 | Fix_Nak_2);
1409 /*Set EPHY registers begin*/
1410 /*Set EPHY register offset 0x02 bit 11 to 0 and bit 12 to 1*/
1411 ephy_data = rtl8168nic_EPHYRead(unit, 0x02);
1412 ephy_data &= ~(1 << 11);
1413 ephy_data |= (1 << 12);
1414 rtl8168nic_EPHYWrite(unit, 0x02, ephy_data);
1416 /*Set EPHY register offset 0x03 bit 1 to 1*/
1417 ephy_data = rtl8168nic_EPHYRead(unit, 0x03);
1418 ephy_data |= (1 << 1);
1419 rtl8168nic_EPHYWrite(unit, 0x03, ephy_data);
1421 /*Set EPHY register offset 0x06 bit 7 to 0*/
1422 ephy_data = rtl8168nic_EPHYRead(unit, 0x06);
1423 ephy_data &= ~(1 << 7);
1424 rtl8168nic_EPHYWrite(unit, 0x06, ephy_data);
1425 /*Set EPHY registers end*/
1427 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1429 //disable clock request.
1430 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1431 pcibyte.reg = 0x81;
1432 pcibyte.val = 0x00;
1433 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1435 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1436 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1437 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1439 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1440 RTL_W8(base + (Reserved1), Reserved1_data);
1441 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1442 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1444 //Set PCI configuration space offset 0x79 to 0x20
1445 /*Increase the Tx performance*/
1446 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1447 pcibyte.reg = 0x79;
1448 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1449 device_control &= ~0x70;
1450 device_control |= 0x20;
1451 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1452 pcibyte.reg = 0x79;
1453 pcibyte.val = device_control;
1454 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1456 //tx checksum offload disable
1457 // unit->features &= ~NETIF_F_IP_CSUM;
1459 //rx checksum offload disable
1460 np->cp_cmd &= ~RxChkSum;
1461 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1462 } else {
1463 RTL_W8(base + (Reserved1), Reserved1_data);
1464 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1465 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1467 //Set PCI configuration space offset 0x79 to 0x50
1468 /*Increase the Tx performance*/
1469 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1470 pcibyte.reg = 0x79;
1471 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1472 device_control &= ~0x70;
1473 device_control |= 0x50;
1474 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1475 pcibyte.reg = 0x79;
1476 pcibyte.val = device_control;
1477 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1479 //tx checksum offload enable
1480 // unit->features |= NETIF_F_IP_CSUM;
1482 //rx checksum offload enable
1483 np->cp_cmd |= RxChkSum;
1484 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1486 } else if (np->mcfg == CFG_METHOD_5) {
1487 /*set PCI configuration space offset 0x70F to 0x27*/
1488 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1489 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1490 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1492 /******set EPHY registers for RTL8168CP begin******/
1493 //Set EPHY register offset 0x01 bit 0 to 1.
1494 ephy_data = rtl8168nic_EPHYRead(unit, 0x01);
1495 ephy_data |= (1 << 0);
1496 rtl8168nic_EPHYWrite(unit, 0x01, ephy_data);
1498 //Set EPHY register offset 0x03 bit 10 to 0, bit 9 to 1 and bit 5 to 1.
1499 ephy_data = rtl8168nic_EPHYRead(unit, 0x03);
1500 ephy_data &= ~(1 << 10);
1501 ephy_data |= (1 << 9);
1502 ephy_data |= (1 << 5);
1503 rtl8168nic_EPHYWrite(unit, 0x03, ephy_data);
1504 /******set EPHY registers for RTL8168CP end******/
1506 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1508 //disable clock request.
1509 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1510 pcibyte.reg = 0x81;
1511 pcibyte.val = 0x00;
1512 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1514 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1515 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1516 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1518 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1519 RTL_W8(base + (Reserved1), Reserved1_data);
1520 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1521 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1523 //Set PCI configuration space offset 0x79 to 0x20
1524 /*Increase the Tx performance*/
1525 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1526 pcibyte.reg = 0x79;
1527 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1528 device_control &= ~0x70;
1529 device_control |= 0x20;
1530 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1531 pcibyte.reg = 0x79;
1532 pcibyte.val = device_control;
1533 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1535 //tx checksum offload disable
1536 // unit->features &= ~NETIF_F_IP_CSUM;
1538 //rx checksum offload disable
1539 np->cp_cmd &= ~RxChkSum;
1540 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1541 } else {
1542 RTL_W8(base + (Reserved1), Reserved1_data);
1543 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1544 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1546 //Set PCI configuration space offset 0x79 to 0x50
1547 /*Increase the Tx performance*/
1548 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1549 pcibyte.reg = 0x79;
1550 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1551 device_control &= ~0x70;
1552 device_control |= 0x50;
1553 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1554 pcibyte.reg = 0x79;
1555 pcibyte.val = device_control;
1556 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1558 //tx checksum offload enable
1559 // unit->features |= NETIF_F_IP_CSUM;
1561 //rx checksum offload enable
1562 np->cp_cmd |= RxChkSum;
1563 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1565 } else if (np->mcfg == CFG_METHOD_6) {
1566 /*set PCI configuration space offset 0x70F to 0x27*/
1567 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1568 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1569 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1571 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1573 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1574 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1575 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1577 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1578 RTL_W8(base + (Reserved1), Reserved1_data);
1579 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1580 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1582 //Set PCI configuration space offset 0x79 to 0x20
1583 /*Increase the Tx performance*/
1584 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1585 pcibyte.reg = 0x79;
1586 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1587 device_control &= ~0x70;
1588 device_control |= 0x20;
1589 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1590 pcibyte.reg = 0x79;
1591 pcibyte.val = device_control;
1592 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1594 //tx checksum offload disable
1595 // unit->features &= ~NETIF_F_IP_CSUM;
1597 //rx checksum offload disable
1598 np->cp_cmd &= ~RxChkSum;
1599 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1600 } else {
1601 RTL_W8(base + (Reserved1), Reserved1_data);
1602 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1603 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1605 //Set PCI configuration space offset 0x79 to 0x50
1606 /*Increase the Tx performance*/
1607 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1608 pcibyte.reg = 0x79;
1609 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1610 device_control &= ~0x70;
1611 device_control |= 0x50;
1612 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1613 pcibyte.reg = 0x79;
1614 pcibyte.val = device_control;
1615 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1617 //tx checksum offload enable
1618 // unit->features |= NETIF_F_IP_CSUM;
1620 //rx checksum offload enable
1621 np->cp_cmd |= RxChkSum;
1622 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1624 } else if (np->mcfg == CFG_METHOD_7) {
1625 /*set PCI configuration space offset 0x70F to 0x27*/
1626 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1627 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1628 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1630 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1631 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1632 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1634 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1636 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1637 RTL_W8(base + (Reserved1), Reserved1_data);
1638 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1639 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1641 //Set PCI configuration space offset 0x79 to 0x20
1642 /*Increase the Tx performance*/
1643 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1644 pcibyte.reg = 0x79;
1645 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1646 device_control &= ~0x70;
1647 device_control |= 0x20;
1648 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1649 pcibyte.reg = 0x79;
1650 pcibyte.val = device_control;
1651 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1653 //tx checksum offload disable
1654 // unit->features &= ~NETIF_F_IP_CSUM;
1656 //rx checksum offload disable
1657 np->cp_cmd &= ~RxChkSum;
1658 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1659 } else {
1660 RTL_W8(base + (Reserved1), Reserved1_data);
1661 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1662 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1664 //Set PCI configuration space offset 0x79 to 0x50
1665 /*Increase the Tx performance*/
1666 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1667 pcibyte.reg = 0x79;
1668 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1669 device_control &= ~0x70;
1670 device_control |= 0x50;
1671 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1672 pcibyte.reg = 0x79;
1673 pcibyte.val = device_control;
1674 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1676 //tx checksum offload enable
1677 // unit->features |= NETIF_F_IP_CSUM;
1679 //rx checksum offload enable
1680 np->cp_cmd |= RxChkSum;
1681 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1683 } else if (np->mcfg == CFG_METHOD_8) {
1684 /*set PCI configuration space offset 0x70F to 0x27*/
1685 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1686 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1687 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1689 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1690 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1691 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1693 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1695 RTL_W8(base + (0xD1), 0x20);
1697 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1698 RTL_W8(base + (Reserved1), Reserved1_data);
1699 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1700 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1702 //Set PCI configuration space offset 0x79 to 0x20
1703 /*Increase the Tx performance*/
1704 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1705 pcibyte.reg = 0x79;
1706 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1707 device_control &= ~0x70;
1708 device_control |= 0x20;
1709 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1710 pcibyte.reg = 0x79;
1711 pcibyte.val = device_control;
1712 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1714 //tx checksum offload disable
1715 // unit->features &= ~NETIF_F_IP_CSUM;
1717 //rx checksum offload disable
1718 np->cp_cmd &= ~RxChkSum;
1719 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1720 } else {
1721 RTL_W8(base + (Reserved1), Reserved1_data);
1722 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1723 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1725 //Set PCI configuration space offset 0x79 to 0x50
1726 /*Increase the Tx performance*/
1727 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1728 pcibyte.reg = 0x79;
1729 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1730 device_control &= ~0x70;
1731 device_control |= 0x50;
1732 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1733 pcibyte.reg = 0x79;
1734 pcibyte.val = device_control;
1735 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1737 //tx checksum offload enable
1738 // unit->features |= NETIF_F_IP_CSUM;
1740 //rx checksum offload enable
1741 np->cp_cmd |= RxChkSum;
1742 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1745 } else if (np->mcfg == CFG_METHOD_9) {
1746 /*set PCI configuration space offset 0x70F to 0x27*/
1747 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1748 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1749 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1751 //disable clock request.
1752 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1753 pcibyte.reg = 0x81;
1754 pcibyte.val = 0x00;
1755 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1757 RTL_W8(base + (Config1), 0xCF);
1758 RTL_W8(base + (Config2), 0x9C);
1759 RTL_W8(base + (Config3), 0x62);
1761 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1762 RTL_W8(base + (Reserved1), Reserved1_data);
1763 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1764 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1766 //Set PCI configuration space offset 0x79 to 0x20
1767 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1768 pcibyte.reg = 0x79;
1769 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1770 device_control &= ~0x70;
1771 device_control |= 0x20;
1772 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1773 pcibyte.reg = 0x79;
1774 pcibyte.val = device_control;
1775 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1777 //tx checksum offload disable
1778 // unit->features &= ~NETIF_F_IP_CSUM;
1780 //rx checksum offload disable
1781 np->cp_cmd &= ~RxChkSum;
1782 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1783 } else {
1784 RTL_W8(base + (Reserved1), Reserved1_data);
1785 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1786 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1788 //Set PCI configuration space offset 0x79 to 0x50
1789 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1790 pcibyte.reg = 0x79;
1791 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1792 device_control &= ~0x70;
1793 device_control |= 0x50;
1794 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1795 pcibyte.reg = 0x79;
1796 pcibyte.val = device_control;
1797 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1799 //tx checksum offload enable
1800 // unit->features |= NETIF_F_IP_CSUM;
1802 //rx checksum offload enable
1803 np->cp_cmd |= RxChkSum;
1804 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1807 /******set EPHY registers begin******/
1808 rtl8168nic_EPHYWrite(unit, 0x01, 0x7C7D);
1809 rtl8168nic_EPHYWrite(unit, 0x02, 0x091F);
1810 rtl8168nic_EPHYWrite(unit, 0x06, 0xB271);
1811 rtl8168nic_EPHYWrite(unit, 0x07, 0xCE00);
1812 /******set EPHY registers end******/
1814 } else if (np->mcfg == CFG_METHOD_10) {
1815 /*set PCI configuration space offset 0x70F to 0x27*/
1816 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1817 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1818 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1820 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1821 RTL_W8(base + (Reserved1), Reserved1_data);
1822 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1823 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1825 //Set PCI configuration space offset 0x79 to 0x20
1826 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1827 pcibyte.reg = 0x79;
1828 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1829 device_control &= ~0x70;
1830 device_control |= 0x20;
1831 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1832 pcibyte.reg = 0x79;
1833 pcibyte.val = device_control;
1834 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1836 //tx checksum offload disable
1837 // unit->features &= ~NETIF_F_IP_CSUM;
1839 //rx checksum offload disable
1840 np->cp_cmd &= ~RxChkSum;
1841 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1842 } else {
1843 RTL_W8(base + (Reserved1), Reserved1_data);
1844 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1845 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1847 //Set PCI configuration space offset 0x79 to 0x50
1848 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1849 pcibyte.reg = 0x79;
1850 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1851 device_control &= ~0x70;
1852 device_control |= 0x50;
1853 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1854 pcibyte.reg = 0x79;
1855 pcibyte.val = device_control;
1856 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1858 //tx checksum offload enable
1859 // unit->features |= NETIF_F_IP_CSUM;
1861 //rx checksum offload enable
1862 np->cp_cmd |= RxChkSum;
1863 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1866 RTL_W8(base + (Config1), 0xDF);
1868 /******set EPHY registers begin******/
1869 rtl8168nic_EPHYWrite(unit, 0x01, 0x7C7D);
1870 rtl8168nic_EPHYWrite(unit, 0x02, 0x091F);
1871 rtl8168nic_EPHYWrite(unit, 0x03, 0xC5BA);
1872 rtl8168nic_EPHYWrite(unit, 0x06, 0xB279);
1873 rtl8168nic_EPHYWrite(unit, 0x07, 0xAF00);
1874 rtl8168nic_EPHYWrite(unit, 0x1E, 0xB8EB);
1875 /******set EPHY registers end******/
1877 //disable clock request.
1878 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1879 pcibyte.reg = 0x81;
1880 pcibyte.val = 0x00;
1881 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1883 } else if (np->mcfg == CFG_METHOD_11) {
1884 /*set PCI configuration space offset 0x70F to 0x27*/
1885 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1886 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1887 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1889 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1890 RTL_W8(base + (Reserved1), Reserved1_data);
1891 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1892 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1894 //Set PCI configuration space offset 0x79 to 0x20
1895 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1896 pcibyte.reg = 0x79;
1897 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1898 device_control &= ~0x70;
1899 device_control |= 0x20;
1900 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1901 pcibyte.reg = 0x79;
1902 pcibyte.val = device_control;
1903 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1905 //tx checksum offload disable
1906 // unit->features &= ~NETIF_F_IP_CSUM;
1908 //rx checksum offload disable
1909 np->cp_cmd &= ~RxChkSum;
1910 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1911 } else {
1912 RTL_W8(base + (Reserved1), Reserved1_data);
1913 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1914 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1916 //Set PCI configuration space offset 0x79 to 0x50
1917 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1918 pcibyte.reg = 0x79;
1919 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1920 device_control &= ~0x70;
1921 device_control |= 0x50;
1922 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1923 pcibyte.reg = 0x79;
1924 pcibyte.val = device_control;
1925 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1927 //tx checksum offload enable
1928 // unit->features |= NETIF_F_IP_CSUM;
1930 //rx checksum offload enable
1931 np->cp_cmd |= RxChkSum;
1932 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1935 RTL_W8(base + (Config1), 0xDF);
1937 /******set EPHY registers begin******/
1938 rtl8168nic_EPHYWrite(unit, 0x01, 0x6C7F);
1939 rtl8168nic_EPHYWrite(unit, 0x02, 0x011F);
1940 rtl8168nic_EPHYWrite(unit, 0x03, 0xC1B2);
1941 rtl8168nic_EPHYWrite(unit, 0x1A, 0x0546);
1942 rtl8168nic_EPHYWrite(unit, 0x1C, 0x80C4);
1943 rtl8168nic_EPHYWrite(unit, 0x1D, 0x78E4);
1944 /******set EPHY registers end******/
1946 //disable clock request.
1947 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1948 pcibyte.reg = 0x81;
1949 pcibyte.val = 0x00;
1950 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1952 RTL_W8(base + (0xF3), RTL_R8(base + (0xF3)) | (1 << 2));
1954 } else if (np->mcfg == CFG_METHOD_1) {
1955 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1957 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1958 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1959 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1961 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1962 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1963 pcibyte.reg = 0x69;
1964 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1965 device_control &= ~0x70;
1966 device_control |= 0x28;
1967 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1968 pcibyte.reg = 0x69;
1969 pcibyte.val = device_control;
1970 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1971 } else {
1972 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1973 pcibyte.reg = 0x69;
1974 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1975 device_control &= ~0x70;
1976 device_control |= 0x58;
1977 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1978 pcibyte.reg = 0x69;
1979 pcibyte.val = device_control;
1980 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1982 } else if (np->mcfg == CFG_METHOD_2) {
1983 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1985 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1986 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1987 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1989 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1990 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1991 pcibyte.reg = 0x69;
1992 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1993 device_control &= ~0x70;
1994 device_control |= 0x28;
1995 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1996 pcibyte.reg = 0x69;
1997 pcibyte.val = device_control;
1998 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2000 RTL_W8(base + (Reserved1), Reserved1_data);
2001 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | (1 << 0));
2002 } else {
2003 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2004 pcibyte.reg = 0x69;
2005 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2006 device_control &= ~0x70;
2007 device_control |= 0x58;
2008 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
2009 pcibyte.reg = 0x69;
2010 pcibyte.val = device_control;
2011 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2013 RTL_W8(base + (Reserved1), Reserved1_data);
2014 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~(1 << 0));
2016 } else if (np->mcfg == CFG_METHOD_3) {
2017 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
2019 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
2020 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
2021 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
2023 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
2024 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2025 pcibyte.reg = 0x69;
2026 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2027 device_control &= ~0x70;
2028 device_control |= 0x28;
2029 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
2030 pcibyte.reg = 0x69;
2031 pcibyte.val = device_control;
2032 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2034 RTL_W8(base + (Reserved1), Reserved1_data);
2035 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | (1 << 0));
2036 } else {
2037 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2038 pcibyte.reg = 0x69;
2039 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2040 device_control &= ~0x70;
2041 device_control |= 0x58;
2042 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
2043 pcibyte.reg = 0x69;
2044 pcibyte.val = device_control;
2045 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2047 RTL_W8(base + (Reserved1), Reserved1_data);
2048 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~(1 << 0));
2052 if ((np->mcfg == CFG_METHOD_1) || (np->mcfg == CFG_METHOD_2) || (np->mcfg == CFG_METHOD_3)) {
2053 /* csum offload command for RTL8168B/8111B */
2054 np->tx_tcp_csum_cmd = TxIPCS | TxTCPCS;
2055 np->tx_udp_csum_cmd = TxIPCS | TxUDPCS;
2056 np->tx_ip_csum_cmd = TxIPCS;
2057 } else {
2058 /* csum offload command for RTL8168C/8111C and RTL8168CP/8111CP */
2059 np->tx_tcp_csum_cmd = TxIPCS_C | TxTCPCS_C;
2060 np->tx_udp_csum_cmd = TxIPCS_C | TxUDPCS_C;
2061 np->tx_ip_csum_cmd = TxIPCS_C;
2064 RTL_W8(base + (ChipCmd), CmdTxEnb | CmdRxEnb);
2066 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
2068 if (!np->pci_cfg_is_read) {
2069 struct pHidd_PCIDevice_ReadConfigWord readpciword;
2071 pcibyte.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2072 pcibyte.reg = PCI_COMMAND;
2073 np->pci_cfg_space.cmd = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2075 pcibyte.reg = PCI_CACHE_LINE_SIZE;
2076 np->pci_cfg_space.cls = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2078 readpciword.mID = OOP_GetMethodID(CLID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
2079 readpciword.reg = PCI_BASE_ADDRESS_0;
2080 np->pci_cfg_space.io_base_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2081 readpciword.reg = PCI_BASE_ADDRESS_0 + 2;
2082 np->pci_cfg_space.io_base_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2083 readpciword.reg = PCI_BASE_ADDRESS_2;
2084 np->pci_cfg_space.mem_base_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2085 readpciword.reg = PCI_BASE_ADDRESS_2 + 2;
2086 np->pci_cfg_space.mem_base_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2088 pcibyte.reg = PCI_INTERRUPT_LINE;
2089 np->pci_cfg_space.ilr = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2091 readpciword.reg = PCI_BASE_ADDRESS_4;
2092 np->pci_cfg_space.resv_0x20_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2093 readpciword.reg = PCI_BASE_ADDRESS_4 + 2;
2094 np->pci_cfg_space.resv_0x20_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2095 readpciword.reg = PCI_BASE_ADDRESS_5;
2096 np->pci_cfg_space.resv_0x24_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2097 readpciword.reg = PCI_BASE_ADDRESS_5 + 2;
2098 np->pci_cfg_space.resv_0x24_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2100 np->pci_cfg_is_read = 1;
2103 rtl8168nic_DSM(unit, DSM_MAC_INIT);
2105 udelay(10);
2108 static unsigned int rtl8168nic_XMIILinkOK(struct net_device *unit)
2110 struct rtl8168_priv *np = get_pcnpriv(unit);
2111 APTR base = get_hwbase(unit);
2113 mdio_write(unit, 0x1f, 0x0000);
2115 return RTL_R8(base + (PHYstatus)) & LinkStatus;
2118 void rtl8168_CheckLinkStatus(struct net_device *unit)
2120 struct rtl8168_priv *np = get_pcnpriv(unit);
2121 APTR base = get_hwbase(unit);
2122 unsigned long flags;
2124 if (rtl8168nic_XMIILinkOK(unit)) {
2125 netif_carrier_on(unit);
2126 RTLD(bug("[%s] rtl8168_CheckLinkStatus: Link Up\n", unit->rtl8168u_name))
2127 } else {
2128 RTLD(bug("[%s] rtl8168_CheckLinkStatus: Link Down\n", unit->rtl8168u_name))
2129 netif_carrier_off(unit);
2133 static void rtl8168nic_InitRingIndexes(struct rtl8168_priv *np)
2135 np->dirty_tx = 0;
2136 np->dirty_rx = 0;
2137 np->cur_tx = 0;
2138 np->cur_rx = 0;
2141 static void rtl8168nic_TxDescInit(struct rtl8168_priv *np)
2143 int i = 0;
2145 // memset(np->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
2147 for (i = 0; i < NUM_TX_DESC; i++)
2148 if(i == (NUM_TX_DESC - 1))
2149 np->TxDescArray[i].opts1 = AROS_LONG2LE(RingEnd);
2152 static void rtl8168nic_RxDescInit(struct rtl8168_priv *np)
2154 int i = 0;
2156 // memset(np->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
2158 for (i = 0; i < NUM_RX_DESC; i++) {
2159 if(i == (NUM_RX_DESC - 1))
2160 np->RxDescArray[i].opts1 = AROS_LONG2LE((DescOwn | RingEnd | (ULONG)np->rx_buf_sz));
2161 else
2162 np->RxDescArray[i].opts1 = AROS_LONG2LE(DescOwn | (ULONG)np->rx_buf_sz);
2166 static ULONG rtl8168nic_RxFill(struct net_device *unit, ULONG start, ULONG end)
2168 struct rtl8168_priv *np = get_pcnpriv(unit);
2169 ULONG cur;
2171 for (cur = start; end - cur > 0; cur++) {
2172 int ret, i = cur % NUM_RX_DESC;
2174 if (np->RxDescArray[i].addr)
2175 continue;
2177 if ((np->RxDescArray[i].addr = HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, np->rx_buf_sz)) == NULL)
2178 break;
2180 // RTLD(bug("[%s] rtl8168nic_RxFill: Rx Buffer %d Allocated @ %p\n", unit->rtl8168u_name, i, np->RxDescArray[i].addr))
2182 return cur - start;
2185 static inline void rtl8168nic_MarkAsLastDescriptor(struct RxDesc *desc)
2187 desc->opts1 |= AROS_LONG2LE(RingEnd);
2190 static int rtl8168nic_InitRings(struct net_device *unit)
2192 struct rtl8168_priv *np = get_pcnpriv(unit);
2194 RTLD(bug("[%s] rtl8168nic_InitRings(unit @ %p)\n", unit->rtl8168u_name, unit))
2196 rtl8168nic_InitRingIndexes(np);
2198 rtl8168nic_TxDescInit(np);
2199 rtl8168nic_RxDescInit(np);
2201 if (rtl8168nic_RxFill(unit, 0, NUM_RX_DESC) != NUM_RX_DESC)
2202 goto err_out;
2204 rtl8168nic_MarkAsLastDescriptor(np->RxDescArray + NUM_RX_DESC - 1);
2206 return 0;
2208 err_out:
2209 // rtl8168_rx_clear(np);
2210 return -1;
2213 static int rtl8168nic_Open(struct net_device *unit)
2215 struct rtl8168_priv *np = get_pcnpriv(unit);
2216 APTR base = get_hwbase(unit);
2217 int ret;
2219 RTLD(bug("[%s] rtl8168nic_Open(unit @ %p)\n", unit->rtl8168u_name, unit))
2221 rtl8168nic_SetRXBufSize(unit);
2223 ret = request_irq(unit);
2224 if (ret)
2225 goto out_drain;
2227 np->TxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, R8168_TX_RING_BYTES);
2228 np->TxPhyAddr = np->TxDescArray;
2230 np->RxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, R8168_RX_RING_BYTES);
2231 np->RxPhyAddr = np->RxDescArray;
2233 if ((np->TxDescArray) && (np->RxDescArray))
2235 RTLD(bug("[%s] rtl8168nic_Open: Allocated Descriptor Arrays - Tx @ %p (%d bytes), Rx @ %p (%d bytes)\n", unit->rtl8168u_name,
2236 np->TxDescArray, R8168_TX_RING_BYTES,
2237 np->RxDescArray, R8168_RX_RING_BYTES))
2238 if (rtl8168nic_InitRings(unit) == 0)
2240 rtl8168nic_HWStart(unit);
2242 // if (np->esd_flag == 0) {
2243 // rtl8168_request_esd_timer(unit);
2244 // }
2246 // rtl8168_request_link_timer(unit);
2248 rtl8168nic_DSM(unit, DSM_IF_UP);
2250 rtl8168_CheckLinkStatus(unit);
2252 else
2254 RTLD(bug("[%s] rtl8168nic_Open: Failed to initialise Descriptor Arrays!\n",unit->rtl8168u_name))
2257 else
2259 RTLD(bug("[%s] rtl8168nic_Open: Failed to Allocate Descriptor Arrays!\n",unit->rtl8168u_name))
2261 return 0;
2263 out_drain:
2264 drain_ring(unit);
2265 return ret;
2268 static int rtl8168nic_Close(struct net_device *unit)
2270 struct rtl8168_priv *np = get_pcnpriv(unit);
2271 UBYTE *base;
2273 RTLD(bug("[%s] rtl8168nic_Close()\n", unit->rtl8168u_name))
2275 unit->rtl8168u_flags &= ~IFF_UP;
2277 ObtainSemaphore(&np->lock);
2278 // np->in_shutdown = 1;
2279 ReleaseSemaphore(&np->lock);
2281 unit->rtl8168u_toutNEED = FALSE;
2283 netif_stop_queue(unit);
2284 ObtainSemaphore(&np->lock);
2286 rtl8168nic_DeInit(unit);
2288 base = get_hwbase(unit);
2290 ReleaseSemaphore(&np->lock);
2292 free_irq(unit);
2294 drain_ring(unit);
2296 // HIDD_PCIDriver_FreePCIMem(unit->rtl8168u_PCIDriver, np->rx_buffer);
2297 // HIDD_PCIDriver_FreePCIMem(unit->rtl8168u_PCIDriver, np->tx_buffer);
2299 ReportEvents(LIBBASE, unit, S2EVENT_OFFLINE);
2301 return 0;
2305 void rtl8168nic_get_functions(struct net_device *Unit)
2307 Unit->initialize = rtl8168nic_Init;
2308 Unit->deinitialize = rtl8168nic_DeInit;
2309 Unit->start = rtl8168nic_Open;
2310 Unit->stop = rtl8168nic_Close;
2311 Unit->set_mac_address = rtl8168nic_SetMACAddr;
2312 Unit->set_multicast = rtl8168nic_SetMulticast;