grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / networks / rtl8168 / rtl8168.c
blob36dad1d6b4eba649643555d610c1796166739f13
1 /*
2 * $Id$
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>
44 #include <proto/oop.h>
45 #include <proto/exec.h>
46 #include <proto/dos.h>
47 #include <proto/battclock.h>
49 #include <hardware/intbits.h>
51 #include <stdlib.h>
53 #include "unit.h"
54 #include LC_LIBDEFS_FILE
56 #undef LIBBASE
57 #define LIBBASE (unit->rtl8168u_device)
59 #define _R(NAME,MAC,RCR,MASK, JumFrameSz) \
60 { .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz }
62 static const struct {
63 const char *name;
64 UBYTE mcfg;
65 ULONG RCR_Cfg;
66 ULONG RxConfigMask; /* Clears the bits supported by this chip */
67 ULONG jumbo_frame_sz;
68 } rtl_chip_info[] = {
69 _R("RTL8168B/8111B",
70 CFG_METHOD_1,
71 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
72 0xff7e1880,
73 Jumbo_Frame_4k),
75 _R("RTL8168B/8111B",
76 CFG_METHOD_2,
77 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
78 0xff7e1880,
79 Jumbo_Frame_4k),
81 _R("RTL8168B/8111B",
82 CFG_METHOD_3,
83 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
84 0xff7e1880,
85 Jumbo_Frame_4k),
87 _R("RTL8168C/8111C",
88 CFG_METHOD_4, RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
89 0xff7e1880,
90 Jumbo_Frame_6k),
92 _R("RTL8168C/8111C",
93 CFG_METHOD_5,
94 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
95 0xff7e1880,
96 Jumbo_Frame_6k),
98 _R("RTL8168C/8111C",
99 CFG_METHOD_6,
100 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
101 0xff7e1880,
102 Jumbo_Frame_6k),
104 _R("RTL8168CP/8111CP",
105 CFG_METHOD_7,
106 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
107 0xff7e1880,
108 Jumbo_Frame_6k),
110 _R("RTL8168CP/8111CP",
111 CFG_METHOD_8,
112 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
113 0xff7e1880,
114 Jumbo_Frame_6k),
116 _R("RTL8168D/8111D",
117 CFG_METHOD_9,
118 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
119 0xff7e1880,
120 Jumbo_Frame_9k),
122 _R("RTL8168D/8111D",
123 CFG_METHOD_10,
124 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
125 0xff7e1880,
126 Jumbo_Frame_9k),
128 _R("RTL8168D/8111D",
129 CFG_METHOD_11,
130 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
131 0xff7e1880,
132 Jumbo_Frame_9k),
134 #undef _R
136 void rtl8168nic_USecDelay(struct net_device *unit, ULONG usec)
138 if (unit != NULL)
140 unit->rtl8168u_DelayPort.mp_SigTask = FindTask(NULL);
141 unit->rtl8168u_DelayReq.tr_node.io_Command = TR_ADDREQUEST;
142 unit->rtl8168u_DelayReq.tr_time.tv_micro = usec % 1000000;
143 unit->rtl8168u_DelayReq.tr_time.tv_secs = usec / 1000000;
145 DoIO((struct IORequest *)&unit->rtl8168u_DelayReq);
149 static inline struct rtl8168_priv *get_pcnpriv(struct net_device *unit)
151 return unit->rtl8168u_priv;
154 static inline UBYTE *get_hwbase(struct net_device *unit)
156 return (UBYTE *)unit->rtl8168u_BaseMem;
159 void MMIO_W8(APTR addr, UBYTE val8)
161 *((volatile UBYTE *)(addr)) = (val8);
163 RTL_R8(addr);
166 void MMIO_W16(APTR addr, UWORD val16)
168 *((volatile UWORD *)(addr)) = (val16);
170 RTL_R16(addr);
173 void MMIO_W32(APTR addr, ULONG val32)
175 *((volatile ULONG *)(addr)) = (val32);
177 RTL_R32(addr);
180 static void mdio_write(struct net_device *unit, int RegAddr, UWORD value)
182 APTR base = get_hwbase(unit);
183 int i;
185 RTL_W32(base + (PHYAR), PHYAR_Write |
186 (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift |
187 (value & PHYAR_Data_Mask));
189 for (i = 0; i < 10; i++) {
190 /* Check if the RTL8168 has completed writing to the specified MII register */
191 if (!(RTL_R32(base + (PHYAR)) & PHYAR_Flag))
192 break;
194 udelay(100);
198 static ULONG mdio_read(struct net_device *unit, int RegAddr)
200 APTR base = get_hwbase(unit);
201 UWORD value = 0xffff;
202 int i;
204 RTL_W32(base + (PHYAR), PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift);
206 for (i = 0; i < 10; i++) {
207 /* Check if the RTL8168 has completed retrieving data from the specified MII register */
208 if (RTL_R32(base + (PHYAR)) & PHYAR_Flag) {
209 value = (UWORD)(RTL_R32(base + (PHYAR)) & PHYAR_Data_Mask);
210 break;
212 udelay(100);
214 return value;
217 static void rtl8168nic_EPHYWrite(struct net_device *unit, int RegAddr, UWORD value)
219 APTR base = get_hwbase(unit);
220 int i;
222 RTL_W32(base + (EPHYAR),
223 EPHYAR_Write |
224 (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift |
225 (value & EPHYAR_Data_Mask));
227 for (i = 0; i < 10; i++) {
228 udelay(100);
230 /* Check if the RTL8168 has completed EPHY write */
231 if (!(RTL_R32(base + (EPHYAR)) & EPHYAR_Flag))
232 break;
235 udelay(20);
238 static UWORD rtl8168nic_EPHYRead(struct net_device *unit, int RegAddr)
240 APTR base = get_hwbase(unit);
241 UWORD value = 0xffff;
242 int i;
244 RTL_W32(base + (EPHYAR),
245 EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift);
247 for (i = 0; i < 10; i++) {
248 udelay(100);
250 /* Check if the RTL8168 has completed EPHY read */
251 if (RTL_R32(base + (EPHYAR)) & EPHYAR_Flag) {
252 value = (UWORD)(RTL_R32(base + (EPHYAR)) & EPHYAR_Data_Mask);
253 break;
257 udelay(20);
259 return value;
262 static void rtl8168nic_CSIWrite(struct net_device *unit, int addr, ULONG value)
264 APTR base = get_hwbase(unit);
265 int i;
267 RTL_W32(base + (CSIDR), value);
268 RTL_W32(base + (CSIAR),
269 CSIAR_Write |
270 CSIAR_ByteEn << CSIAR_ByteEn_shift |
271 (addr & CSIAR_Addr_Mask));
273 for (i = 0; i < 10; i++) {
274 udelay(100);
276 /* Check if the RTL8168 has completed CSI write */
277 if (!(RTL_R32(base + (CSIAR)) & CSIAR_Flag))
278 break;
281 udelay(20);
284 static ULONG rtl8168nic_CSIRead(struct net_device *unit, int addr)
286 APTR base = get_hwbase(unit);
287 ULONG value = 0xffffffff;
288 int i;
290 RTL_W32(base + (CSIAR),
291 CSIAR_Read |
292 CSIAR_ByteEn << CSIAR_ByteEn_shift |
293 (addr & CSIAR_Addr_Mask));
295 for (i = 0; i < 10; i++) {
296 udelay(100);
298 /* Check if the RTL8168 has completed CSI read */
299 if (RTL_R32(base + (CSIAR)) & CSIAR_Flag) {
300 value = RTL_R32(base + (CSIDR));
301 break;
305 udelay(20);
307 return value;
310 static void rtl8168nic_PHYPowerUP(struct net_device *unit)
312 // APTR base = get_hwbase(unit);
314 RTLD(bug("[%s] rtl8168nic_PHYPowerUP()\n", unit->rtl8168u_name))
316 mdio_write(unit, 0x1F, 0x0000);
317 mdio_write(unit, 0x0E, 0x0000);
320 static void rtl8168nic_GetMACVersion(struct net_device *unit)
322 struct rtl8168_priv *np = get_pcnpriv(unit);
323 APTR base = get_hwbase(unit);
324 ULONG reg, val32;
325 ULONG ICVerID;
327 RTLD(bug("[%s] rtl8168nic_GetMACVersion()\n", unit->rtl8168u_name))
329 val32 = RTL_R32(base + (TxConfig));
330 reg = val32 & 0x7c800000;
331 ICVerID = val32 & 0x00700000;
333 switch(reg)
335 case 0x30000000:
336 np->mcfg = CFG_METHOD_1;
337 break;
338 case 0x38000000:
339 if(ICVerID == 0x00000000) {
340 np->mcfg = CFG_METHOD_2;
341 } else if(ICVerID == 0x00500000) {
342 np->mcfg = CFG_METHOD_3;
343 } else {
344 np->mcfg = CFG_METHOD_3;
346 break;
347 case 0x3C000000:
348 if(ICVerID == 0x00000000) {
349 np->mcfg = CFG_METHOD_4;
350 } else if(ICVerID == 0x00200000) {
351 np->mcfg = CFG_METHOD_5;
352 } else if(ICVerID == 0x00400000) {
353 np->mcfg = CFG_METHOD_6;
354 } else {
355 np->mcfg = CFG_METHOD_6;
357 break;
358 case 0x3C800000:
359 if (ICVerID == 0x00100000){
360 np->mcfg = CFG_METHOD_7;
361 } else if (ICVerID == 0x00300000){
362 np->mcfg = CFG_METHOD_8;
363 } else {
364 np->mcfg = CFG_METHOD_8;
366 break;
367 case 0x28000000:
368 if(ICVerID == 0x00100000) {
369 np->mcfg = CFG_METHOD_9;
370 } else if(ICVerID == 0x00200000) {
371 np->mcfg = CFG_METHOD_10;
372 } else if(ICVerID == 0x00300000) {
373 np->mcfg = CFG_METHOD_11;
374 } else {
375 np->mcfg = CFG_METHOD_11;
377 break;
378 default:
379 np->mcfg = 0xFFFFFFFF;
380 RTLD(bug("[%s] rtl8168nic_GetMACVersion: unknown chip version (%x)\n", unit->rtl8168u_name, reg))
381 break;
385 static void rtl8168nic_PrintMACVersion(struct net_device *unit)
387 struct rtl8168_priv *np = get_pcnpriv(unit);
388 int i;
390 RTLD(bug("[%s] rtl8168nic_PrintMACVersion()\n", unit->rtl8168u_name))
392 for (i = (sizeof(rtl_chip_info) / sizeof(rtl_chip_info[0])) - 1; i >= 0; i--)
394 if (np->mcfg == rtl_chip_info[i].mcfg)
396 RTLD(bug("[%s] rtl8168nic_PrintMACVersion: mcfg == %s (%04d)\n", unit->rtl8168u_name,
397 rtl_chip_info[i].name,
398 rtl_chip_info[i].mcfg))
399 return;
403 RTLD(bug("[%s] rtl8168nic_PrintMACVersion: mac_version == Unknown\n", unit->rtl8168u_name))
406 static void rtl8168nic_HWPHYConfig(struct net_device *unit)
408 struct rtl8168_priv *np = get_pcnpriv(unit);
409 // APTR base = get_hwbase(unit);
410 // int data;
412 RTLD(bug("[%s] rtl8168nic_HWPHYConfig()\n", unit->rtl8168u_name))
414 if (np->mcfg == CFG_METHOD_1)
416 mdio_write(unit, 0x1F, 0x0001);
417 mdio_write(unit, 0x0B, 0x94B0);
419 mdio_write(unit, 0x1F, 0x0003);
420 mdio_write(unit, 0x12, 0x6096);
421 mdio_write(unit, 0x1F, 0x0000);
423 mdio_write(unit, 0x0D, 0xF8A0);
424 } else if (np->mcfg == CFG_METHOD_2) {
425 mdio_write(unit, 0x1F, 0x0001);
426 mdio_write(unit, 0x0B, 0x94B0);
428 mdio_write(unit, 0x1F, 0x0003);
429 mdio_write(unit, 0x12, 0x6096);
431 mdio_write(unit, 0x1F, 0x0000);
432 } else if (np->mcfg == CFG_METHOD_3) {
433 mdio_write(unit, 0x1F, 0x0001);
434 mdio_write(unit, 0x0B, 0x94B0);
436 mdio_write(unit, 0x1F, 0x0003);
437 mdio_write(unit, 0x12, 0x6096);
439 mdio_write(unit, 0x1F, 0x0000);
440 } else if (np->mcfg == CFG_METHOD_4) {
441 mdio_write(unit, 0x1F, 0x0001);
442 mdio_write(unit, 0x12, 0x2300);
443 mdio_write(unit, 0x1F, 0x0000);
444 mdio_write(unit, 0x1F, 0x0003);
445 mdio_write(unit, 0x16, 0x000A);
446 mdio_write(unit, 0x1F, 0x0000);
448 mdio_write(unit, 0x1F, 0x0003);
449 mdio_write(unit, 0x12, 0xC096);
450 mdio_write(unit, 0x1F, 0x0000);
452 mdio_write(unit, 0x1F, 0x0002);
453 mdio_write(unit, 0x00, 0x88DE);
454 mdio_write(unit, 0x01, 0x82B1);
455 mdio_write(unit, 0x1F, 0x0000);
457 mdio_write(unit, 0x1F, 0x0002);
458 mdio_write(unit, 0x08, 0x9E30);
459 mdio_write(unit, 0x09, 0x01F0);
460 mdio_write(unit, 0x1F, 0x0000);
462 mdio_write(unit, 0x1F, 0x0002);
463 mdio_write(unit, 0x0A, 0x5500);
464 mdio_write(unit, 0x1F, 0x0000);
466 mdio_write(unit, 0x1F, 0x0002);
467 mdio_write(unit, 0x03, 0x7002);
468 mdio_write(unit, 0x1F, 0x0000);
470 mdio_write(unit, 0x1F, 0x0002);
471 mdio_write(unit, 0x0C, 0x00C8);
472 mdio_write(unit, 0x1F, 0x0000);
474 mdio_write(unit, 0x1F, 0x0000);
475 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
476 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
477 } else if (np->mcfg == CFG_METHOD_5) {
478 mdio_write(unit, 0x1F, 0x0001);
479 mdio_write(unit, 0x12, 0x2300);
480 mdio_write(unit, 0x1F, 0x0003);
481 mdio_write(unit, 0x16, 0x0F0A);
482 mdio_write(unit, 0x1F, 0x0000);
484 mdio_write(unit, 0x1F, 0x0002);
485 mdio_write(unit, 0x00, 0x88DE);
486 mdio_write(unit, 0x01, 0x82B1);
487 mdio_write(unit, 0x1F, 0x0000);
489 mdio_write(unit, 0x1F, 0x0002);
490 mdio_write(unit, 0x0C, 0x7EB8);
491 mdio_write(unit, 0x1F, 0x0000);
493 mdio_write(unit, 0x1F, 0x0002);
494 mdio_write(unit, 0x06, 0x0761);
495 mdio_write(unit, 0x1F, 0x0000);
497 mdio_write(unit, 0x1F, 0x0001);
498 mdio_write(unit, 0x03, 0x802F);
499 mdio_write(unit, 0x02, 0x4F02);
500 mdio_write(unit, 0x01, 0x0409);
501 mdio_write(unit, 0x00, 0xF099);
502 mdio_write(unit, 0x04, 0x9800);
503 mdio_write(unit, 0x04, 0x9000);
504 mdio_write(unit, 0x1F, 0x0000);
506 mdio_write(unit, 0x1F, 0x0000);
507 mdio_write(unit, 0x16, mdio_read(unit, 0x16) | (1 << 0));
509 mdio_write(unit, 0x1F, 0x0000);
510 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
511 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
513 mdio_write(unit, 0x1F, 0x0001);
514 mdio_write(unit, 0x1D, 0x3D98);
515 mdio_write(unit, 0x1F, 0x0000);
517 mdio_write(unit, 0x1F, 0x0001);
518 mdio_write(unit, 0x17, 0x0CC0);
519 mdio_write(unit, 0x1F, 0x0000);
520 } else if (np->mcfg == CFG_METHOD_6) {
521 mdio_write(unit, 0x1F, 0x0001);
522 mdio_write(unit, 0x12, 0x2300);
523 mdio_write(unit, 0x1F, 0x0003);
524 mdio_write(unit, 0x16, 0x0F0A);
525 mdio_write(unit, 0x1F, 0x0000);
527 mdio_write(unit, 0x1F, 0x0002);
528 mdio_write(unit, 0x00, 0x88DE);
529 mdio_write(unit, 0x01, 0x82B1);
530 mdio_write(unit, 0x1F, 0x0000);
532 mdio_write(unit, 0x1F, 0x0002);
533 mdio_write(unit, 0x0C, 0x7EB8);
534 mdio_write(unit, 0x1F, 0x0000);
536 mdio_write(unit, 0x1F, 0x0002);
537 mdio_write(unit, 0x06, 0x0761);
538 mdio_write(unit, 0x1F, 0x0000);
540 mdio_write(unit, 0x1F, 0x0000);
541 mdio_write(unit, 0x16, mdio_read(unit, 0x16) | (1 << 0));
543 mdio_write(unit, 0x1F, 0x0000);
544 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
545 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
547 mdio_write(unit, 0x1F, 0x0001);
548 mdio_write(unit, 0x1D, 0x3D98);
549 mdio_write(unit, 0x1F, 0x0000);
551 mdio_write(unit, 0x1f, 0x0001);
552 mdio_write(unit, 0x17, 0x0CC0);
553 mdio_write(unit, 0x1F, 0x0000);
554 } else if (np->mcfg == CFG_METHOD_7) {
555 mdio_write(unit, 0x1F, 0x0000);
556 mdio_write(unit, 0x14, mdio_read(unit, 0x14) | (1 << 5));
557 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
559 mdio_write(unit, 0x1F, 0x0001);
560 mdio_write(unit, 0x1D, 0x3D98);
562 mdio_write(unit, 0x1F, 0x0001);
563 mdio_write(unit, 0x14, 0xCAA3);
564 mdio_write(unit, 0x1C, 0x000A);
565 mdio_write(unit, 0x18, 0x65D0);
567 mdio_write(unit, 0x1F, 0x0003);
568 mdio_write(unit, 0x17, 0xB580);
569 mdio_write(unit, 0x18, 0xFF54);
570 mdio_write(unit, 0x19, 0x3954);
572 mdio_write(unit, 0x1F, 0x0002);
573 mdio_write(unit, 0x0D, 0x310C);
574 mdio_write(unit, 0x0E, 0x310C);
575 mdio_write(unit, 0x0F, 0x311C);
576 mdio_write(unit, 0x06, 0x0761);
578 mdio_write(unit, 0x1F, 0x0003);
579 mdio_write(unit, 0x18, 0xFF55);
580 mdio_write(unit, 0x19, 0x3955);
581 mdio_write(unit, 0x18, 0xFF54);
582 mdio_write(unit, 0x19, 0x3954);
584 mdio_write(unit, 0x1f, 0x0001);
585 mdio_write(unit, 0x17, 0x0CC0);
587 mdio_write(unit, 0x1F, 0x0000);
588 } else if (np->mcfg == CFG_METHOD_8) {
589 mdio_write(unit, 0x1F, 0x0000);
590 mdio_write(unit, 0x0D, mdio_read(unit, 0x0D) | (1 << 5));
592 mdio_write(unit, 0x1F, 0x0001);
593 mdio_write(unit, 0x14, 0xCAA3);
594 mdio_write(unit, 0x1C, 0x000A);
595 mdio_write(unit, 0x18, 0x65D0);
597 mdio_write(unit, 0x1F, 0x0003);
598 mdio_write(unit, 0x17, 0xB580);
599 mdio_write(unit, 0x18, 0xFF54);
600 mdio_write(unit, 0x19, 0x3954);
602 mdio_write(unit, 0x1F, 0x0002);
603 mdio_write(unit, 0x0D, 0x310C);
604 mdio_write(unit, 0x0E, 0x310C);
605 mdio_write(unit, 0x0F, 0x311C);
606 mdio_write(unit, 0x06, 0x0761);
608 mdio_write(unit, 0x1F, 0x0003);
609 mdio_write(unit, 0x18, 0xFF55);
610 mdio_write(unit, 0x19, 0x3955);
611 mdio_write(unit, 0x18, 0xFF54);
612 mdio_write(unit, 0x19, 0x3954);
614 mdio_write(unit, 0x1f, 0x0001);
615 mdio_write(unit, 0x17, 0x0CC0);
617 mdio_write(unit, 0x1F, 0x0000);
618 } else if (np->mcfg == CFG_METHOD_9) {
619 mdio_write(unit, 0x1F, 0x0001);
620 mdio_write(unit, 0x06, 0x4064);
621 mdio_write(unit, 0x07, 0x2863);
622 mdio_write(unit, 0x08, 0x059C);
623 mdio_write(unit, 0x09, 0x26B4);
624 mdio_write(unit, 0x0A, 0x6A19);
625 mdio_write(unit, 0x0B, 0xACC0);
626 mdio_write(unit, 0x10, 0xF06D);
627 mdio_write(unit, 0x14, 0x7F68);
628 mdio_write(unit, 0x18, 0x7FD9);
629 mdio_write(unit, 0x1C, 0xF0FF);
630 mdio_write(unit, 0x1D, 0x3D9C);
631 mdio_write(unit, 0x1F, 0x0003);
632 mdio_write(unit, 0x12, 0xF49F);
633 mdio_write(unit, 0x13, 0x070B);
634 mdio_write(unit, 0x1A, 0x05AD);
635 mdio_write(unit, 0x14, 0x94C0);
637 mdio_write(unit, 0x1F, 0x0002);
638 mdio_write(unit, 0x0B, 0x0B10);
639 mdio_write(unit, 0x0C, 0xA2F7);
641 mdio_write(unit, 0x1F, 0x0002);
642 mdio_write(unit, 0x06, 0x5571);
644 mdio_write(unit, 0x1F, 0x0002);
645 mdio_write(unit, 0x02, 0xC107);
646 mdio_write(unit, 0x03, 0x1002);
648 mdio_write(unit, 0x1F, 0x0001);
649 mdio_write(unit, 0x17, 0x0CC0);
651 mdio_write(unit, 0x1F, 0x0005);
652 mdio_write(unit, 0x05, 0x8200);
653 mdio_write(unit, 0x06, 0xF8F9);
654 mdio_write(unit, 0x06, 0xFAEF);
655 mdio_write(unit, 0x06, 0x59EE);
656 mdio_write(unit, 0x06, 0xF8EA);
657 mdio_write(unit, 0x06, 0x00EE);
658 mdio_write(unit, 0x06, 0xF8EB);
659 mdio_write(unit, 0x06, 0x00E0);
660 mdio_write(unit, 0x06, 0xF87C);
661 mdio_write(unit, 0x06, 0xE1F8);
662 mdio_write(unit, 0x06, 0x7D59);
663 mdio_write(unit, 0x06, 0x0FEF);
664 mdio_write(unit, 0x06, 0x0139);
665 mdio_write(unit, 0x06, 0x029E);
666 mdio_write(unit, 0x06, 0x06EF);
667 mdio_write(unit, 0x06, 0x1039);
668 mdio_write(unit, 0x06, 0x089F);
669 mdio_write(unit, 0x06, 0x2AEE);
670 mdio_write(unit, 0x06, 0xF8EA);
671 mdio_write(unit, 0x06, 0x00EE);
672 mdio_write(unit, 0x06, 0xF8EB);
673 mdio_write(unit, 0x06, 0x01E0);
674 mdio_write(unit, 0x06, 0xF87C);
675 mdio_write(unit, 0x06, 0xE1F8);
676 mdio_write(unit, 0x06, 0x7D58);
677 mdio_write(unit, 0x06, 0x409E);
678 mdio_write(unit, 0x06, 0x0F39);
679 mdio_write(unit, 0x06, 0x46AA);
680 mdio_write(unit, 0x06, 0x0BBF);
681 mdio_write(unit, 0x06, 0x8251);
682 mdio_write(unit, 0x06, 0xD682);
683 mdio_write(unit, 0x06, 0x5902);
684 mdio_write(unit, 0x06, 0x014F);
685 mdio_write(unit, 0x06, 0xAE09);
686 mdio_write(unit, 0x06, 0xBF82);
687 mdio_write(unit, 0x06, 0x59D6);
688 mdio_write(unit, 0x06, 0x8261);
689 mdio_write(unit, 0x06, 0x0201);
690 mdio_write(unit, 0x06, 0x4FEF);
691 mdio_write(unit, 0x06, 0x95FE);
692 mdio_write(unit, 0x06, 0xFDFC);
693 mdio_write(unit, 0x06, 0x054D);
694 mdio_write(unit, 0x06, 0x2000);
695 mdio_write(unit, 0x06, 0x024E);
696 mdio_write(unit, 0x06, 0x2200);
697 mdio_write(unit, 0x06, 0x024D);
698 mdio_write(unit, 0x06, 0xDFFF);
699 mdio_write(unit, 0x06, 0x014E);
700 mdio_write(unit, 0x06, 0xDDFF);
701 mdio_write(unit, 0x06, 0x0100);
702 mdio_write(unit, 0x06, 0x6010);
703 mdio_write(unit, 0x05, 0xFFF6);
704 mdio_write(unit, 0x06, 0x00EC);
705 mdio_write(unit, 0x05, 0x83D4);
706 mdio_write(unit, 0x06, 0x8200);
707 mdio_write(unit, 0x1F, 0x0000);
708 } else if (np->mcfg == CFG_METHOD_10) {
709 mdio_write(unit, 0x1F, 0x0001);
710 mdio_write(unit, 0x06, 0x4064);
711 mdio_write(unit, 0x07, 0x2863);
712 mdio_write(unit, 0x08, 0x059C);
713 mdio_write(unit, 0x09, 0x26B4);
714 mdio_write(unit, 0x0A, 0x6A19);
715 mdio_write(unit, 0x0B, 0xACC0);
716 mdio_write(unit, 0x10, 0xF06D);
717 mdio_write(unit, 0x14, 0x7F68);
718 mdio_write(unit, 0x18, 0x7FD9);
719 mdio_write(unit, 0x1C, 0xF0FF);
720 mdio_write(unit, 0x1D, 0x3D9C);
721 mdio_write(unit, 0x1F, 0x0003);
722 mdio_write(unit, 0x12, 0xF49F);
723 mdio_write(unit, 0x13, 0x070B);
724 mdio_write(unit, 0x1A, 0x05AD);
725 mdio_write(unit, 0x14, 0x94C0);
727 mdio_write(unit, 0x1F, 0x0002);
728 mdio_write(unit, 0x06, 0x5571);
730 mdio_write(unit, 0x1F, 0x0002);
731 mdio_write(unit, 0x05, 0x2642);
733 mdio_write(unit, 0x1F, 0x0002);
734 mdio_write(unit, 0x02, 0xC107);
735 mdio_write(unit, 0x03, 0x1002);
737 mdio_write(unit, 0x1F, 0x0001);
738 mdio_write(unit, 0x17, 0x0CC0);
740 mdio_write(unit, 0x1F, 0x0002);
741 mdio_write(unit, 0x0F, 0x0017);
743 mdio_write(unit, 0x1F, 0x0005);
744 mdio_write(unit, 0x05, 0x8200);
745 mdio_write(unit, 0x06, 0xF8F9);
746 mdio_write(unit, 0x06, 0xFAEF);
747 mdio_write(unit, 0x06, 0x59EE);
748 mdio_write(unit, 0x06, 0xF8EA);
749 mdio_write(unit, 0x06, 0x00EE);
750 mdio_write(unit, 0x06, 0xF8EB);
751 mdio_write(unit, 0x06, 0x00E0);
752 mdio_write(unit, 0x06, 0xF87C);
753 mdio_write(unit, 0x06, 0xE1F8);
754 mdio_write(unit, 0x06, 0x7D59);
755 mdio_write(unit, 0x06, 0x0FEF);
756 mdio_write(unit, 0x06, 0x0139);
757 mdio_write(unit, 0x06, 0x029E);
758 mdio_write(unit, 0x06, 0x06EF);
759 mdio_write(unit, 0x06, 0x1039);
760 mdio_write(unit, 0x06, 0x089F);
761 mdio_write(unit, 0x06, 0x2AEE);
762 mdio_write(unit, 0x06, 0xF8EA);
763 mdio_write(unit, 0x06, 0x00EE);
764 mdio_write(unit, 0x06, 0xF8EB);
765 mdio_write(unit, 0x06, 0x01E0);
766 mdio_write(unit, 0x06, 0xF87C);
767 mdio_write(unit, 0x06, 0xE1F8);
768 mdio_write(unit, 0x06, 0x7D58);
769 mdio_write(unit, 0x06, 0x409E);
770 mdio_write(unit, 0x06, 0x0F39);
771 mdio_write(unit, 0x06, 0x46AA);
772 mdio_write(unit, 0x06, 0x0BBF);
773 mdio_write(unit, 0x06, 0x8251);
774 mdio_write(unit, 0x06, 0xD682);
775 mdio_write(unit, 0x06, 0x5902);
776 mdio_write(unit, 0x06, 0x014F);
777 mdio_write(unit, 0x06, 0xAE09);
778 mdio_write(unit, 0x06, 0xBF82);
779 mdio_write(unit, 0x06, 0x59D6);
780 mdio_write(unit, 0x06, 0x8261);
781 mdio_write(unit, 0x06, 0x0201);
782 mdio_write(unit, 0x06, 0x4FEF);
783 mdio_write(unit, 0x06, 0x95FE);
784 mdio_write(unit, 0x06, 0xFDFC);
785 mdio_write(unit, 0x06, 0x054D);
786 mdio_write(unit, 0x06, 0x2000);
787 mdio_write(unit, 0x06, 0x024E);
788 mdio_write(unit, 0x06, 0x2200);
789 mdio_write(unit, 0x06, 0x024D);
790 mdio_write(unit, 0x06, 0xDFFF);
791 mdio_write(unit, 0x06, 0x014E);
792 mdio_write(unit, 0x06, 0xDDFF);
793 mdio_write(unit, 0x06, 0x0100);
794 mdio_write(unit, 0x02, 0x6010);
795 mdio_write(unit, 0x05, 0xFFF6);
796 mdio_write(unit, 0x06, 0x00EC);
797 mdio_write(unit, 0x05, 0x83D4);
798 mdio_write(unit, 0x06, 0x8200);
799 mdio_write(unit, 0x1F, 0x0000);
800 } else if (np->mcfg == CFG_METHOD_11) {
801 mdio_write(unit, 0x1F, 0x0001);
802 mdio_write(unit, 0x06, 0x4064);
803 mdio_write(unit, 0x07, 0x2863);
804 mdio_write(unit, 0x08, 0x059C);
805 mdio_write(unit, 0x09, 0x26B4);
806 mdio_write(unit, 0x0A, 0x6A19);
807 mdio_write(unit, 0x0B, 0xACC0);
808 mdio_write(unit, 0x10, 0xF06D);
809 mdio_write(unit, 0x14, 0x7F68);
810 mdio_write(unit, 0x18, 0x7FD9);
811 mdio_write(unit, 0x1C, 0xF0FF);
812 mdio_write(unit, 0x1D, 0x3D9C);
813 mdio_write(unit, 0x1F, 0x0003);
814 mdio_write(unit, 0x12, 0xF49F);
815 mdio_write(unit, 0x13, 0x070B);
816 mdio_write(unit, 0x1A, 0x05AD);
817 mdio_write(unit, 0x14, 0x94C0);
819 mdio_write(unit, 0x1F, 0x0002);
820 mdio_write(unit, 0x06, 0x5571);
822 mdio_write(unit, 0x1F, 0x0002);
823 mdio_write(unit, 0x05, 0x2642);
825 mdio_write(unit, 0x1F, 0x0002);
826 mdio_write(unit, 0x02, 0xC107);
827 mdio_write(unit, 0x03, 0x1002);
829 mdio_write(unit, 0x1F, 0x0001);
830 mdio_write(unit, 0x17, 0x0CC0);
832 mdio_write(unit, 0x1F, 0x0002);
833 mdio_write(unit, 0x0F, 0x0017);
837 static void rtl8168nic_DSM(struct net_device *unit, int dev_state)
839 struct rtl8168_priv *np = get_pcnpriv(unit);
840 APTR base = get_hwbase(unit);
842 switch (dev_state) {
843 case DSM_MAC_INIT:
844 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6)) {
845 if (RTL_R8(base + (MACDBG)) & 0x80) {
846 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
847 } else {
848 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
852 break;
853 case DSM_NIC_GOTO_D3:
854 case DSM_IF_DOWN:
855 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
856 if (RTL_R8(base + (MACDBG)) & 0x80)
857 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
859 break;
860 case DSM_NIC_RESUME_D3:
861 case DSM_IF_UP:
862 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
863 if (RTL_R8(base + (MACDBG)) & 0x80)
864 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
866 break;
870 static int rtl8168nic_SetSpeedXMII(struct net_device *unit,
871 UBYTE autoneg,
872 UWORD speed,
873 UBYTE duplex)
875 struct rtl8168_priv *np = get_pcnpriv(unit);
876 // APTR base = get_hwbase(unit);
877 int auto_nego = 0;
878 int giga_ctrl = 0;
879 int bmcr_true_force = 0;
880 // unsigned long flags;
882 RTLD(bug("[%s] rtl8168nic_SetSpeedXMII()\n", unit->rtl8168u_name))
884 if ((speed != SPEED_1000) &&
885 (speed != SPEED_100) &&
886 (speed != SPEED_10)) {
887 speed = SPEED_1000;
888 duplex = DUPLEX_FULL;
891 if ((autoneg == AUTONEG_ENABLE) || (speed == SPEED_1000)) {
892 /*n-way force*/
893 if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) {
894 auto_nego |= ADVERTISE_10HALF;
895 } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) {
896 auto_nego |= ADVERTISE_10HALF |
897 ADVERTISE_10FULL;
898 } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) {
899 auto_nego |= ADVERTISE_100HALF |
900 ADVERTISE_10HALF |
901 ADVERTISE_10FULL;
902 } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) {
903 auto_nego |= ADVERTISE_100HALF |
904 ADVERTISE_100FULL |
905 ADVERTISE_10HALF |
906 ADVERTISE_10FULL;
907 } else if (speed == SPEED_1000) {
908 giga_ctrl |= ADVERTISE_1000HALF |
909 ADVERTISE_1000FULL;
911 auto_nego |= ADVERTISE_100HALF |
912 ADVERTISE_100FULL |
913 ADVERTISE_10HALF |
914 ADVERTISE_10FULL;
917 //disable flow contorol
918 auto_nego &= ~ADVERTISE_PAUSE_CAP;
919 auto_nego &= ~ADVERTISE_PAUSE_ASYM;
921 np->phy_auto_nego_reg = auto_nego;
922 np->phy_1000_ctrl_reg = giga_ctrl;
924 np->autoneg = autoneg;
925 np->speed = speed;
926 np->duplex = duplex;
928 rtl8168nic_PHYPowerUP(unit);
930 mdio_write(unit, 0x1f, 0x0000);
931 mdio_write(unit, MII_ADVERTISE, auto_nego);
932 mdio_write(unit, MII_CTRL1000, giga_ctrl);
933 mdio_write(unit, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
934 } else {
935 /*true force*/
936 #ifndef BMCR_SPEED100
937 #define BMCR_SPEED100 0x0040
938 #endif
940 #ifndef BMCR_SPEED10
941 #define BMCR_SPEED10 0x0000
942 #endif
943 if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) {
944 bmcr_true_force = BMCR_SPEED10;
945 } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) {
946 bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX;
947 } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) {
948 bmcr_true_force = BMCR_SPEED100;
949 } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) {
950 bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX;
953 mdio_write(unit, 0x1f, 0x0000);
954 mdio_write(unit, MII_BMCR, bmcr_true_force);
957 return 0;
960 #if 0
961 static void rtl8168nic_start_rx(struct net_device *unit)
963 // struct rtl8168_priv *np = get_pcnpriv(unit);
964 // APTR base = get_hwbase(unit);
966 RTLD(bug("[%s] rtl8168nic_start_rx\n", unit->rtl8168u_name))
967 // Already running? Stop it.
968 /* TODO: Handle starting/stopping Rx */
971 static void rtl8168nic_stop_rx(struct net_device *unit)
973 // APTR base = get_hwbase(unit);
975 RTLD(bug("[%s] rtl8168nic_stop_rx\n", unit->rtl8168u_name))
976 /* TODO: Handle starting/stopping Rx */
979 static void rtl8168nic_start_tx(struct net_device *unit)
981 // APTR base = get_hwbase(unit);
983 RTLD(bug("[%s] rtl8168nic_start_tx()\n", unit->rtl8168u_name))
984 /* TODO: Handle starting/stopping Tx */
987 static void rtl8168nic_stop_tx(struct net_device *unit)
989 // APTR base = get_hwbase(unit);
991 RTLD(bug("[%s] rtl8168nic_stop_tx()\n", unit->rtl8168u_name))
992 /* TODO: Handle starting/stopping Tx */
995 static void rtl8168nic_txrx_reset(struct net_device *unit)
997 // struct rtl8168_priv *np = get_pcnpriv(unit);
998 // APTR base = get_hwbase(unit);
1000 RTLD(bug("[%s] rtl8168nic_txrx_reset()\n", unit->rtl8168u_name))
1002 #endif
1005 * rtl8168nic_SetMulticast: unit->set_multicast function
1006 * Called with unit->xmit_lock held.
1008 static void rtl8168nic_SetMulticast(struct net_device *unit)
1010 // struct rtl8168_priv *np = get_pcnpriv(unit);
1011 // APTR base = get_hwbase(unit);
1012 ULONG addr[2];
1013 ULONG mask[2];
1014 // ULONG pff;
1016 RTLD(bug("[%s] rtl8168nic_SetMulticast()\n", unit->rtl8168u_name))
1018 memset(addr, 0, sizeof(addr));
1019 memset(mask, 0, sizeof(mask));
1022 static void rtl8168nic_DeInit(struct net_device *unit)
1024 /* TODO: Clean up / DeInit hardware */
1027 static void rtl8168nic_GetMACAddr(struct net_device *unit, char *addr, BOOL fromROM)
1029 APTR base = get_hwbase(unit);
1030 int i;
1032 RTLD(bug("[%s] rtl8168nic_GetMACAddr()\n",unit->rtl8168u_name))
1033 /* Get MAC address. FIXME: read EEPROM */
1034 for (i = 0; i < MAC_ADDR_LEN; i++)
1035 addr[i] = RTL_R8(base + MAC0 + i);
1038 static void rtl8168nic_SetMACAddr(struct net_device *unit)
1040 APTR base = get_hwbase(unit);
1041 // int i,j;
1043 RTLD(bug("[%s] rtl8168nic_SetMACAddr()\n",unit->rtl8168u_name))
1045 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1047 RTL_W32(base + (MAC0),
1048 unit->rtl8168u_dev_addr[0] |
1049 (unit->rtl8168u_dev_addr[1] << 8) |
1050 (unit->rtl8168u_dev_addr[2] << 16) |
1051 (unit->rtl8168u_dev_addr[3] << 24));
1052 RTL_W32(base + (MAC4),
1053 unit->rtl8168u_dev_addr[4] |
1054 (unit->rtl8168u_dev_addr[5] << 8));
1056 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
1058 RTLD(
1059 /* Read it back to be certain! */
1060 TEXT newmac[6];
1061 rtl8168nic_GetMACAddr(unit, newmac, FALSE);
1063 bug("[%s] rtl8168nic_SetMACAddr: New MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8168u_name,
1064 newmac[0], newmac[1], newmac[2],
1065 newmac[3], newmac[4], newmac[5])
1069 static void rtl8168nic_LinkOption(struct net_device *unit, UBYTE *aut, UWORD *spd, UBYTE *dup)
1071 unsigned char opt_speed;
1072 unsigned char opt_duplex;
1073 unsigned char opt_autoneg;
1075 opt_speed = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->speed[unit->rtl8168u_UnitNum] : 0xff;
1076 opt_duplex = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->duplex[unit->rtl8168u_UnitNum] : 0xff;
1077 opt_autoneg = ((unit->rtl8168u_UnitNum < MAX_UNITS) && (unit->rtl8168u_UnitNum >= 0)) ? unit->rtl8168u_device->autoneg[unit->rtl8168u_UnitNum] : 0xff;
1079 if ((opt_speed == 0xff) |
1080 (opt_duplex == 0xff) |
1081 (opt_autoneg == 0xff)) {
1082 *spd = SPEED_1000;
1083 *dup = DUPLEX_FULL;
1084 *aut = AUTONEG_ENABLE;
1085 } else {
1086 *spd = unit->rtl8168u_device->speed[unit->rtl8168u_UnitNum];
1087 *dup = unit->rtl8168u_device->duplex[unit->rtl8168u_UnitNum];
1088 *aut = unit->rtl8168u_device->autoneg[unit->rtl8168u_UnitNum];
1092 static void rtl8168nic_Init(struct net_device *unit)
1094 struct pHidd_PCIDevice_WriteConfigByte pcibyte;
1096 struct rtl8168_priv *np = get_pcnpriv(unit);
1097 APTR base = get_hwbase(unit);
1098 UBYTE autoneg, duplex;
1099 UWORD speed;
1100 int i;
1101 // int config1;
1103 RTLD(bug("[%s] rtl8168nic_Init(unit @ %p)\n", unit->rtl8168u_name, unit))
1105 /* Identify chip attached to board */
1106 rtl8168nic_GetMACVersion(unit);
1107 rtl8168nic_PrintMACVersion(unit);
1109 for (i = (sizeof(rtl_chip_info) / sizeof(rtl_chip_info[0])) - 1; i >= 0; i--) {
1110 if (np->mcfg == rtl_chip_info[i].mcfg)
1111 break;
1114 if (i < 0) {
1115 /* Unknown chip: assume array element #0, original RTL-8168 */
1116 RTLD(bug("[%s] rtl8168nic_Init: Unknown Realtek chip version, assuming %s\n", unit->rtl8168u_name, rtl_chip_info[0].name))
1117 i++;
1120 np->chipset = i;
1121 unit->rtl8168u_rtl_chipname = rtl_chip_info[np->chipset].name;
1123 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1124 RTL_W8(base + (Config1), RTL_R8(base + Config1) | PMEnable);
1125 RTL_W8(base + (Config5), RTL_R8(base + Config5) & PMEStatus);
1126 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
1128 RTLD(bug("[%s] rtl8168nic_Init: Power Management enabled\n", unit->rtl8168u_name))
1131 /* RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1132 np->features |= rtl8168_try_msi(pdev, base);
1133 RTL_W8(base + (Cfg9346), Cfg9346_Lock); */
1136 rtl8168nic_GetMACAddr(unit, &np->orig_mac[0], TRUE);
1138 unit->rtl8168u_dev_addr[0] = unit->rtl8168u_org_addr[0] = np->orig_mac[0];
1139 unit->rtl8168u_dev_addr[1] = unit->rtl8168u_org_addr[1] = np->orig_mac[1];
1140 unit->rtl8168u_dev_addr[2] = unit->rtl8168u_org_addr[2] = np->orig_mac[2];
1141 unit->rtl8168u_dev_addr[3] = unit->rtl8168u_org_addr[3] = np->orig_mac[3];
1142 unit->rtl8168u_dev_addr[4] = unit->rtl8168u_org_addr[4] = np->orig_mac[4];
1143 unit->rtl8168u_dev_addr[5] = unit->rtl8168u_org_addr[5] = np->orig_mac[5];
1145 RTLD(bug("[%s] rtl8168nic_Init: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8168u_name,
1146 unit->rtl8168u_dev_addr[0], unit->rtl8168u_dev_addr[1], unit->rtl8168u_dev_addr[2],
1147 unit->rtl8168u_dev_addr[3], unit->rtl8168u_dev_addr[4], unit->rtl8168u_dev_addr[5]))
1149 bug("[%s] rtl8168nic_Init: This product is covered by one or more of the following patents:\n", unit->rtl8168u_name);
1150 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);
1153 unit->features |= NETIF_F_IP_CSUM;
1155 np->cp_cmd |= RxChkSum;
1156 np->cp_cmd |= RTL_R16(base + (CPlusCmd));
1158 np->intr_mask = unit->rtl8168u_intr_mask;
1160 rtl8168nic_HWPHYConfig(unit);
1162 RTLD(bug("[%s] rtl8168nic_Init: PHY Configured\n", unit->rtl8168u_name))
1164 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1165 pcibyte.reg = PCI_LATENCY_TIMER;
1166 pcibyte.val = 0x40;
1167 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1169 rtl8168nic_LinkOption(unit, &autoneg, &speed, &duplex);
1171 rtl8168nic_SetSpeedXMII(unit, autoneg, speed, duplex);
1173 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)" :""))
1176 static void rtl8168nic_drain_tx(struct net_device *unit)
1178 // struct rtl8168_priv *np = get_pcnpriv(unit);
1179 // int i;
1180 // for (i = 0; i < NUM_TX_DESC; i++) {
1181 /* TODO: rtl8168nic_drain_tx does nothing atm. */
1182 // }
1185 static void rtl8168nic_drain_rx(struct net_device *unit)
1187 // struct rtl8168_priv *np = get_pcnpriv(unit);
1188 // int i;
1189 // for (i = 0; i < RX_RING_SIZE; i++) {
1190 /* TODO: rtl8168nic_drain_rx does nothing atm. */
1191 // }
1195 static void drain_ring(struct net_device *unit)
1197 rtl8168nic_drain_tx(unit);
1198 rtl8168nic_drain_rx(unit);
1201 static int request_irq(struct net_device *unit)
1204 RTLD(bug("[%s] request_irq()\n", unit->rtl8168u_name))
1206 if (!unit->rtl8168u_IntsAdded)
1208 AddIntServer(INTB_KERNEL + unit->rtl8168u_IRQ,
1209 &unit->rtl8168u_irqhandler);
1210 AddIntServer(INTB_VERTB, &unit->rtl8168u_touthandler);
1211 unit->rtl8168u_IntsAdded = TRUE;
1214 RTLD(bug("[%s] request_irq: IRQ Handlers configured\n", unit->rtl8168u_name))
1215 return 0;
1218 static void free_irq(struct net_device *unit)
1220 if (unit->rtl8168u_IntsAdded)
1222 RemIntServer(INTB_KERNEL + unit->rtl8168u_IRQ,
1223 &unit->rtl8168u_irqhandler);
1224 RemIntServer(INTB_VERTB, &unit->rtl8168u_touthandler);
1225 unit->rtl8168u_IntsAdded = FALSE;
1229 static void rtl8168nic_SetRXBufSize(struct net_device *unit)
1231 struct rtl8168_priv *np = get_pcnpriv(unit);
1232 APTR base = get_hwbase(unit);
1233 unsigned int mtu = unit->rtl8168u_mtu;
1235 RTLD(bug("[%s] rtl8168nic_SetRXBufSize()\n", unit->rtl8168u_name))
1237 np->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
1239 RTL_W16(base + (RxMaxSize), np->rx_buf_sz + 1);
1242 static void rtl8168nic_NICReset(struct net_device *unit)
1244 struct rtl8168_priv *np = get_pcnpriv(unit);
1245 APTR base = get_hwbase(unit);
1246 int i;
1248 RTLD(bug("[%s] rtl8168nic_NICReset()\n", unit->rtl8168u_name))
1250 if ((np->mcfg != CFG_METHOD_1) &&
1251 (np->mcfg != CFG_METHOD_2) &&
1252 (np->mcfg != CFG_METHOD_3)) {
1253 RTL_W8(base + (ChipCmd), StopReq | CmdRxEnb | CmdTxEnb);
1254 udelay(100);
1257 /* Soft reset the chip. */
1258 RTL_W8(base + (ChipCmd), CmdReset);
1260 /* Check that the chip has finished the reset. */
1261 for (i = 1000; i > 0; i--) {
1262 if ((RTL_R8(base + (ChipCmd)) & CmdReset) == 0)
1263 break;
1264 udelay(100);
1268 static void rtl8168nic_SetRxMode(struct net_device *unit)
1270 struct rtl8168_priv *np = get_pcnpriv(unit);
1271 APTR base = get_hwbase(unit);
1272 // unsigned long flags;
1273 ULONG mc_filter[2]; /* Multicast hash filter */
1274 int i, j, k, rx_mode;
1275 ULONG tmp = 0;
1277 RTLD(bug("[%s] rtl8168nic_SetRxMode()\n", unit->rtl8168u_name))
1279 if (unit->rtl8168u_flags & IFF_PROMISC) {
1280 /* Unconditionally log net taps. */
1281 RTLD(bug("[%s] rtl8168nic_SetRxMode: Promiscuous mode enabled\n", unit->rtl8168u_name))
1282 rx_mode =
1283 AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
1284 AcceptAllPhys;
1285 mc_filter[1] = mc_filter[0] = 0xffffffff;
1286 } else if ((unit->rtl8168u_mc_count > unit->rtl8168u_device->rtl8168b_MulticastFilterLimit)
1287 || (unit->rtl8168u_flags & IFF_ALLMULTI)) {
1288 /* Too many to filter perfectly -- accept all multicasts. */
1289 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
1290 mc_filter[1] = mc_filter[0] = 0xffffffff;
1291 } else {
1292 struct dev_mc_list *mclist;
1293 rx_mode = AcceptBroadcast | AcceptMyPhys;
1294 mc_filter[1] = mc_filter[0] = 0;
1295 for (i = 0, mclist = unit->rtl8168u_mc_list; mclist && i < unit->rtl8168u_mc_count;
1296 i++, mclist = mclist->next) {
1297 // int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1298 // mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1299 rx_mode |= AcceptMulticast;
1303 np->rtl8168_rx_config = rtl_chip_info[np->chipset].RCR_Cfg;
1304 tmp = np->rtl8168_rx_config | rx_mode | (RTL_R32(base + (RxConfig)) & rtl_chip_info[np->chipset].RxConfigMask);
1306 for (j = 0; j < 2; j++) {
1307 ULONG mask = 0x000000ff;
1308 ULONG tmp1 = 0;
1309 ULONG tmp2 = 0;
1310 int x = 0;
1311 int y = 0;
1313 for (k = 0; k < 4; k++) {
1314 tmp1 = mc_filter[j] & mask;
1315 x = 32 - (8 + 16 * k);
1316 y = x - 2 * x;
1318 if (x > 0)
1319 tmp2 = tmp2 | (tmp1 << x);
1320 else
1321 tmp2 = tmp2 | (tmp1 >> y);
1323 mask = mask << 8;
1325 mc_filter[j] = tmp2;
1328 RTL_W32(base + (RxConfig), tmp);
1329 RTL_W32(base + (MAR0 + 0), mc_filter[1]);
1330 RTL_W32(base + (MAR0 + 4), mc_filter[0]);
1333 static void rtl8168nic_HWStart(struct net_device *unit)
1335 struct rtl8168_priv *np = get_pcnpriv(unit);
1336 APTR base = get_hwbase(unit);
1338 struct pHidd_PCIDevice_WriteConfigByte pcibyte;
1340 UBYTE device_control;
1341 UWORD ephy_data;
1342 ULONG csi_tmp;
1344 RTLD(bug("[%s] rtl8168nic_HWStart()\n", unit->rtl8168u_name))
1346 rtl8168nic_NICReset(unit);
1348 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
1350 RTL_W8(base + (Reserved1), Reserved1_data);
1352 np->cp_cmd |= PktCntrDisable | INTT_1;
1353 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1355 RTL_W16(base + (IntrMitigate), 0x5151);
1357 //Work around for RxFIFO overflow
1358 if (np->mcfg == CFG_METHOD_1) {
1359 unit->rtl8168u_intr_mask |= RxFIFOOver | PCSTimeout;
1360 unit->rtl8168u_intr_mask &= ~RxDescUnavail;
1363 RTL_W32(base + (TxDescStartAddrLow), ((UQUAD) (IPTR)np->TxPhyAddr & DMA_32BIT_MASK));
1364 RTL_W32(base + (TxDescStartAddrHigh), ((UQUAD) (IPTR)np->TxPhyAddr >> 32));
1365 RTL_W32(base + (RxDescAddrLow), ((UQUAD) (IPTR)np->RxPhyAddr & DMA_32BIT_MASK));
1366 RTL_W32(base + (RxDescAddrHigh), ((UQUAD) (IPTR)np->RxPhyAddr >> 32));
1368 /* Set Rx Config register */
1369 rtl8168nic_SetRxMode(unit);
1371 /* Set DMA burst size and Interframe Gap Time */
1372 if (np->mcfg == CFG_METHOD_1) {
1373 RTL_W32(base + (TxConfig), (TX_DMA_BURST_512 << TxDMAShift) |
1374 (InterFrameGap << TxInterFrameGapShift));
1375 } else {
1376 RTL_W32(base + (TxConfig), (TX_DMA_BURST_unlimited << TxDMAShift) |
1377 (InterFrameGap << TxInterFrameGapShift));
1380 /* Clear the interrupt status register. */
1381 RTL_W16(base + (IntrStatus), 0xFFFF);
1383 if (np->rx_fifo_overflow == 0) {
1384 /* Enable all known interrupts by setting the interrupt mask. */
1385 RTL_W16(base + (IntrMask), unit->rtl8168u_intr_mask);
1386 netif_start_queue(unit);
1389 if (np->mcfg == CFG_METHOD_4) {
1390 /*set PCI configuration space offset 0x70F to 0x27*/
1391 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1392 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1393 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1395 RTL_W8(base + (DBG_reg), (0x0E << 4) | Fix_Nak_1 | Fix_Nak_2);
1397 /*Set EPHY registers begin*/
1398 /*Set EPHY register offset 0x02 bit 11 to 0 and bit 12 to 1*/
1399 ephy_data = rtl8168nic_EPHYRead(unit, 0x02);
1400 ephy_data &= ~(1 << 11);
1401 ephy_data |= (1 << 12);
1402 rtl8168nic_EPHYWrite(unit, 0x02, ephy_data);
1404 /*Set EPHY register offset 0x03 bit 1 to 1*/
1405 ephy_data = rtl8168nic_EPHYRead(unit, 0x03);
1406 ephy_data |= (1 << 1);
1407 rtl8168nic_EPHYWrite(unit, 0x03, ephy_data);
1409 /*Set EPHY register offset 0x06 bit 7 to 0*/
1410 ephy_data = rtl8168nic_EPHYRead(unit, 0x06);
1411 ephy_data &= ~(1 << 7);
1412 rtl8168nic_EPHYWrite(unit, 0x06, ephy_data);
1413 /*Set EPHY registers end*/
1415 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1417 //disable clock request.
1418 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1419 pcibyte.reg = 0x81;
1420 pcibyte.val = 0x00;
1421 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1423 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1424 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1425 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1427 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1428 RTL_W8(base + (Reserved1), Reserved1_data);
1429 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1430 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1432 //Set PCI configuration space offset 0x79 to 0x20
1433 /*Increase the Tx performance*/
1434 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1435 pcibyte.reg = 0x79;
1436 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1437 device_control &= ~0x70;
1438 device_control |= 0x20;
1439 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1440 pcibyte.reg = 0x79;
1441 pcibyte.val = device_control;
1442 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1444 //tx checksum offload disable
1445 // unit->features &= ~NETIF_F_IP_CSUM;
1447 //rx checksum offload disable
1448 np->cp_cmd &= ~RxChkSum;
1449 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1450 } else {
1451 RTL_W8(base + (Reserved1), Reserved1_data);
1452 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1453 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1455 //Set PCI configuration space offset 0x79 to 0x50
1456 /*Increase the Tx performance*/
1457 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1458 pcibyte.reg = 0x79;
1459 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1460 device_control &= ~0x70;
1461 device_control |= 0x50;
1462 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1463 pcibyte.reg = 0x79;
1464 pcibyte.val = device_control;
1465 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1467 //tx checksum offload enable
1468 // unit->features |= NETIF_F_IP_CSUM;
1470 //rx checksum offload enable
1471 np->cp_cmd |= RxChkSum;
1472 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1474 } else if (np->mcfg == CFG_METHOD_5) {
1475 /*set PCI configuration space offset 0x70F to 0x27*/
1476 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1477 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1478 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1480 /******set EPHY registers for RTL8168CP begin******/
1481 //Set EPHY register offset 0x01 bit 0 to 1.
1482 ephy_data = rtl8168nic_EPHYRead(unit, 0x01);
1483 ephy_data |= (1 << 0);
1484 rtl8168nic_EPHYWrite(unit, 0x01, ephy_data);
1486 //Set EPHY register offset 0x03 bit 10 to 0, bit 9 to 1 and bit 5 to 1.
1487 ephy_data = rtl8168nic_EPHYRead(unit, 0x03);
1488 ephy_data &= ~(1 << 10);
1489 ephy_data |= (1 << 9);
1490 ephy_data |= (1 << 5);
1491 rtl8168nic_EPHYWrite(unit, 0x03, ephy_data);
1492 /******set EPHY registers for RTL8168CP end******/
1494 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1496 //disable clock request.
1497 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1498 pcibyte.reg = 0x81;
1499 pcibyte.val = 0x00;
1500 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1502 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1503 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1504 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1506 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1507 RTL_W8(base + (Reserved1), Reserved1_data);
1508 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1509 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1511 //Set PCI configuration space offset 0x79 to 0x20
1512 /*Increase the Tx performance*/
1513 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1514 pcibyte.reg = 0x79;
1515 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1516 device_control &= ~0x70;
1517 device_control |= 0x20;
1518 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1519 pcibyte.reg = 0x79;
1520 pcibyte.val = device_control;
1521 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1523 //tx checksum offload disable
1524 // unit->features &= ~NETIF_F_IP_CSUM;
1526 //rx checksum offload disable
1527 np->cp_cmd &= ~RxChkSum;
1528 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1529 } else {
1530 RTL_W8(base + (Reserved1), Reserved1_data);
1531 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1532 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1534 //Set PCI configuration space offset 0x79 to 0x50
1535 /*Increase the Tx performance*/
1536 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1537 pcibyte.reg = 0x79;
1538 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1539 device_control &= ~0x70;
1540 device_control |= 0x50;
1541 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1542 pcibyte.reg = 0x79;
1543 pcibyte.val = device_control;
1544 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1546 //tx checksum offload enable
1547 // unit->features |= NETIF_F_IP_CSUM;
1549 //rx checksum offload enable
1550 np->cp_cmd |= RxChkSum;
1551 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1553 } else if (np->mcfg == CFG_METHOD_6) {
1554 /*set PCI configuration space offset 0x70F to 0x27*/
1555 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1556 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1557 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1559 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1561 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1562 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1563 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1565 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1566 RTL_W8(base + (Reserved1), Reserved1_data);
1567 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1568 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1570 //Set PCI configuration space offset 0x79 to 0x20
1571 /*Increase the Tx performance*/
1572 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1573 pcibyte.reg = 0x79;
1574 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1575 device_control &= ~0x70;
1576 device_control |= 0x20;
1577 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1578 pcibyte.reg = 0x79;
1579 pcibyte.val = device_control;
1580 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1582 //tx checksum offload disable
1583 // unit->features &= ~NETIF_F_IP_CSUM;
1585 //rx checksum offload disable
1586 np->cp_cmd &= ~RxChkSum;
1587 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1588 } else {
1589 RTL_W8(base + (Reserved1), Reserved1_data);
1590 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1591 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1593 //Set PCI configuration space offset 0x79 to 0x50
1594 /*Increase the Tx performance*/
1595 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1596 pcibyte.reg = 0x79;
1597 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1598 device_control &= ~0x70;
1599 device_control |= 0x50;
1600 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1601 pcibyte.reg = 0x79;
1602 pcibyte.val = device_control;
1603 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1605 //tx checksum offload enable
1606 // unit->features |= NETIF_F_IP_CSUM;
1608 //rx checksum offload enable
1609 np->cp_cmd |= RxChkSum;
1610 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1612 } else if (np->mcfg == CFG_METHOD_7) {
1613 /*set PCI configuration space offset 0x70F to 0x27*/
1614 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1615 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1616 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1618 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1619 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1620 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1622 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1624 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1625 RTL_W8(base + (Reserved1), Reserved1_data);
1626 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1627 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1629 //Set PCI configuration space offset 0x79 to 0x20
1630 /*Increase the Tx performance*/
1631 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1632 pcibyte.reg = 0x79;
1633 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1634 device_control &= ~0x70;
1635 device_control |= 0x20;
1636 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1637 pcibyte.reg = 0x79;
1638 pcibyte.val = device_control;
1639 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1641 //tx checksum offload disable
1642 // unit->features &= ~NETIF_F_IP_CSUM;
1644 //rx checksum offload disable
1645 np->cp_cmd &= ~RxChkSum;
1646 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1647 } else {
1648 RTL_W8(base + (Reserved1), Reserved1_data);
1649 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1650 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1652 //Set PCI configuration space offset 0x79 to 0x50
1653 /*Increase the Tx performance*/
1654 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1655 pcibyte.reg = 0x79;
1656 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1657 device_control &= ~0x70;
1658 device_control |= 0x50;
1659 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1660 pcibyte.reg = 0x79;
1661 pcibyte.val = device_control;
1662 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1664 //tx checksum offload enable
1665 // unit->features |= NETIF_F_IP_CSUM;
1667 //rx checksum offload enable
1668 np->cp_cmd |= RxChkSum;
1669 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1671 } else if (np->mcfg == CFG_METHOD_8) {
1672 /*set PCI configuration space offset 0x70F to 0x27*/
1673 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1674 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1675 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1677 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1678 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1679 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1681 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1683 RTL_W8(base + (0xD1), 0x20);
1685 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1686 RTL_W8(base + (Reserved1), Reserved1_data);
1687 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1688 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1690 //Set PCI configuration space offset 0x79 to 0x20
1691 /*Increase the Tx performance*/
1692 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1693 pcibyte.reg = 0x79;
1694 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1695 device_control &= ~0x70;
1696 device_control |= 0x20;
1697 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1698 pcibyte.reg = 0x79;
1699 pcibyte.val = device_control;
1700 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1702 //tx checksum offload disable
1703 // unit->features &= ~NETIF_F_IP_CSUM;
1705 //rx checksum offload disable
1706 np->cp_cmd &= ~RxChkSum;
1707 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1708 } else {
1709 RTL_W8(base + (Reserved1), Reserved1_data);
1710 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1711 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1713 //Set PCI configuration space offset 0x79 to 0x50
1714 /*Increase the Tx performance*/
1715 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1716 pcibyte.reg = 0x79;
1717 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1718 device_control &= ~0x70;
1719 device_control |= 0x50;
1720 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1721 pcibyte.reg = 0x79;
1722 pcibyte.val = device_control;
1723 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1725 //tx checksum offload enable
1726 // unit->features |= NETIF_F_IP_CSUM;
1728 //rx checksum offload enable
1729 np->cp_cmd |= RxChkSum;
1730 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1733 } else if (np->mcfg == CFG_METHOD_9) {
1734 /*set PCI configuration space offset 0x70F to 0x27*/
1735 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1736 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1737 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1739 //disable clock request.
1740 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1741 pcibyte.reg = 0x81;
1742 pcibyte.val = 0x00;
1743 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1745 RTL_W8(base + (Config1), 0xCF);
1746 RTL_W8(base + (Config2), 0x9C);
1747 RTL_W8(base + (Config3), 0x62);
1749 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1750 RTL_W8(base + (Reserved1), Reserved1_data);
1751 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1752 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1754 //Set PCI configuration space offset 0x79 to 0x20
1755 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1756 pcibyte.reg = 0x79;
1757 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1758 device_control &= ~0x70;
1759 device_control |= 0x20;
1760 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1761 pcibyte.reg = 0x79;
1762 pcibyte.val = device_control;
1763 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1765 //tx checksum offload disable
1766 // unit->features &= ~NETIF_F_IP_CSUM;
1768 //rx checksum offload disable
1769 np->cp_cmd &= ~RxChkSum;
1770 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1771 } else {
1772 RTL_W8(base + (Reserved1), Reserved1_data);
1773 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1774 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1776 //Set PCI configuration space offset 0x79 to 0x50
1777 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1778 pcibyte.reg = 0x79;
1779 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1780 device_control &= ~0x70;
1781 device_control |= 0x50;
1782 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1783 pcibyte.reg = 0x79;
1784 pcibyte.val = device_control;
1785 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1787 //tx checksum offload enable
1788 // unit->features |= NETIF_F_IP_CSUM;
1790 //rx checksum offload enable
1791 np->cp_cmd |= RxChkSum;
1792 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1795 /******set EPHY registers begin******/
1796 rtl8168nic_EPHYWrite(unit, 0x01, 0x7C7D);
1797 rtl8168nic_EPHYWrite(unit, 0x02, 0x091F);
1798 rtl8168nic_EPHYWrite(unit, 0x06, 0xB271);
1799 rtl8168nic_EPHYWrite(unit, 0x07, 0xCE00);
1800 /******set EPHY registers end******/
1802 } else if (np->mcfg == CFG_METHOD_10) {
1803 /*set PCI configuration space offset 0x70F to 0x27*/
1804 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1805 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1806 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1808 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1809 RTL_W8(base + (Reserved1), Reserved1_data);
1810 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1811 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1813 //Set PCI configuration space offset 0x79 to 0x20
1814 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1815 pcibyte.reg = 0x79;
1816 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1817 device_control &= ~0x70;
1818 device_control |= 0x20;
1819 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1820 pcibyte.reg = 0x79;
1821 pcibyte.val = device_control;
1822 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1824 //tx checksum offload disable
1825 // unit->features &= ~NETIF_F_IP_CSUM;
1827 //rx checksum offload disable
1828 np->cp_cmd &= ~RxChkSum;
1829 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1830 } else {
1831 RTL_W8(base + (Reserved1), Reserved1_data);
1832 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1833 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1835 //Set PCI configuration space offset 0x79 to 0x50
1836 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1837 pcibyte.reg = 0x79;
1838 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1839 device_control &= ~0x70;
1840 device_control |= 0x50;
1841 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1842 pcibyte.reg = 0x79;
1843 pcibyte.val = device_control;
1844 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1846 //tx checksum offload enable
1847 // unit->features |= NETIF_F_IP_CSUM;
1849 //rx checksum offload enable
1850 np->cp_cmd |= RxChkSum;
1851 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1854 RTL_W8(base + (Config1), 0xDF);
1856 /******set EPHY registers begin******/
1857 rtl8168nic_EPHYWrite(unit, 0x01, 0x7C7D);
1858 rtl8168nic_EPHYWrite(unit, 0x02, 0x091F);
1859 rtl8168nic_EPHYWrite(unit, 0x03, 0xC5BA);
1860 rtl8168nic_EPHYWrite(unit, 0x06, 0xB279);
1861 rtl8168nic_EPHYWrite(unit, 0x07, 0xAF00);
1862 rtl8168nic_EPHYWrite(unit, 0x1E, 0xB8EB);
1863 /******set EPHY registers end******/
1865 //disable clock request.
1866 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1867 pcibyte.reg = 0x81;
1868 pcibyte.val = 0x00;
1869 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1871 } else if (np->mcfg == CFG_METHOD_11) {
1872 /*set PCI configuration space offset 0x70F to 0x27*/
1873 /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/
1874 csi_tmp = rtl8168nic_CSIRead(unit, 0x70c) & 0x00ffffff;
1875 rtl8168nic_CSIWrite(unit, 0x70c, csi_tmp | 0x27000000);
1877 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1878 RTL_W8(base + (Reserved1), Reserved1_data);
1879 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) | Jumbo_En0);
1880 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | Jumbo_En1);
1882 //Set PCI configuration space offset 0x79 to 0x20
1883 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1884 pcibyte.reg = 0x79;
1885 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1886 device_control &= ~0x70;
1887 device_control |= 0x20;
1888 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1889 pcibyte.reg = 0x79;
1890 pcibyte.val = device_control;
1891 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1893 //tx checksum offload disable
1894 // unit->features &= ~NETIF_F_IP_CSUM;
1896 //rx checksum offload disable
1897 np->cp_cmd &= ~RxChkSum;
1898 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1899 } else {
1900 RTL_W8(base + (Reserved1), Reserved1_data);
1901 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Jumbo_En0);
1902 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~Jumbo_En1);
1904 //Set PCI configuration space offset 0x79 to 0x50
1905 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1906 pcibyte.reg = 0x79;
1907 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1908 device_control &= ~0x70;
1909 device_control |= 0x50;
1910 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1911 pcibyte.reg = 0x79;
1912 pcibyte.val = device_control;
1913 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1915 //tx checksum offload enable
1916 // unit->features |= NETIF_F_IP_CSUM;
1918 //rx checksum offload enable
1919 np->cp_cmd |= RxChkSum;
1920 RTL_W16(base + (CPlusCmd), np->cp_cmd);
1923 RTL_W8(base + (Config1), 0xDF);
1925 /******set EPHY registers begin******/
1926 rtl8168nic_EPHYWrite(unit, 0x01, 0x6C7F);
1927 rtl8168nic_EPHYWrite(unit, 0x02, 0x011F);
1928 rtl8168nic_EPHYWrite(unit, 0x03, 0xC1B2);
1929 rtl8168nic_EPHYWrite(unit, 0x1A, 0x0546);
1930 rtl8168nic_EPHYWrite(unit, 0x1C, 0x80C4);
1931 rtl8168nic_EPHYWrite(unit, 0x1D, 0x78E4);
1932 /******set EPHY registers end******/
1934 //disable clock request.
1935 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1936 pcibyte.reg = 0x81;
1937 pcibyte.val = 0x00;
1938 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1940 RTL_W8(base + (0xF3), RTL_R8(base + (0xF3)) | (1 << 2));
1942 } else if (np->mcfg == CFG_METHOD_1) {
1943 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1945 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1946 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1947 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1949 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1950 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1951 pcibyte.reg = 0x69;
1952 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1953 device_control &= ~0x70;
1954 device_control |= 0x28;
1955 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1956 pcibyte.reg = 0x69;
1957 pcibyte.val = device_control;
1958 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1959 } else {
1960 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1961 pcibyte.reg = 0x69;
1962 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1963 device_control &= ~0x70;
1964 device_control |= 0x58;
1965 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1966 pcibyte.reg = 0x69;
1967 pcibyte.val = device_control;
1968 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1970 } else if (np->mcfg == CFG_METHOD_2) {
1971 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
1973 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
1974 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
1975 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
1977 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
1978 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1979 pcibyte.reg = 0x69;
1980 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1981 device_control &= ~0x70;
1982 device_control |= 0x28;
1983 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1984 pcibyte.reg = 0x69;
1985 pcibyte.val = device_control;
1986 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1988 RTL_W8(base + (Reserved1), Reserved1_data);
1989 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | (1 << 0));
1990 } else {
1991 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
1992 pcibyte.reg = 0x69;
1993 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
1994 device_control &= ~0x70;
1995 device_control |= 0x58;
1996 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
1997 pcibyte.reg = 0x69;
1998 pcibyte.val = device_control;
1999 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2001 RTL_W8(base + (Reserved1), Reserved1_data);
2002 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~(1 << 0));
2004 } else if (np->mcfg == CFG_METHOD_3) {
2005 RTL_W8(base + (Config3), RTL_R8(base + (Config3)) & ~Beacon_en);
2007 RTL_W16(base + (CPlusCmd), RTL_R16(base + (CPlusCmd)) &
2008 ~(EnableBist | Macdbgo_oe | Force_halfdup | Force_rxflow_en | Force_txflow_en |
2009 Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel));
2011 if (unit->rtl8168u_mtu > ETH_DATA_LEN) {
2012 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2013 pcibyte.reg = 0x69;
2014 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2015 device_control &= ~0x70;
2016 device_control |= 0x28;
2017 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
2018 pcibyte.reg = 0x69;
2019 pcibyte.val = device_control;
2020 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2022 RTL_W8(base + (Reserved1), Reserved1_data);
2023 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) | (1 << 0));
2024 } else {
2025 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2026 pcibyte.reg = 0x69;
2027 device_control = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2028 device_control &= ~0x70;
2029 device_control |= 0x58;
2030 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_WriteConfigByte);
2031 pcibyte.reg = 0x69;
2032 pcibyte.val = device_control;
2033 OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2035 RTL_W8(base + (Reserved1), Reserved1_data);
2036 RTL_W8(base + (Config4), RTL_R8(base + (Config4)) & ~(1 << 0));
2040 if ((np->mcfg == CFG_METHOD_1) || (np->mcfg == CFG_METHOD_2) || (np->mcfg == CFG_METHOD_3)) {
2041 /* csum offload command for RTL8168B/8111B */
2042 np->tx_tcp_csum_cmd = TxIPCS | TxTCPCS;
2043 np->tx_udp_csum_cmd = TxIPCS | TxUDPCS;
2044 np->tx_ip_csum_cmd = TxIPCS;
2045 } else {
2046 /* csum offload command for RTL8168C/8111C and RTL8168CP/8111CP */
2047 np->tx_tcp_csum_cmd = TxIPCS_C | TxTCPCS_C;
2048 np->tx_udp_csum_cmd = TxIPCS_C | TxUDPCS_C;
2049 np->tx_ip_csum_cmd = TxIPCS_C;
2052 RTL_W8(base + (ChipCmd), CmdTxEnb | CmdRxEnb);
2054 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
2056 if (!np->pci_cfg_is_read) {
2057 struct pHidd_PCIDevice_ReadConfigWord readpciword;
2059 pcibyte.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigByte);
2060 pcibyte.reg = PCI_COMMAND;
2061 np->pci_cfg_space.cmd = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2063 pcibyte.reg = PCI_CACHE_LINE_SIZE;
2064 np->pci_cfg_space.cls = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2066 readpciword.mID = OOP_GetMethodID(IID_Hidd_PCIDevice, moHidd_PCIDevice_ReadConfigWord);
2067 readpciword.reg = PCI_BASE_ADDRESS_0;
2068 np->pci_cfg_space.io_base_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2069 readpciword.reg = PCI_BASE_ADDRESS_0 + 2;
2070 np->pci_cfg_space.io_base_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2071 readpciword.reg = PCI_BASE_ADDRESS_2;
2072 np->pci_cfg_space.mem_base_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2073 readpciword.reg = PCI_BASE_ADDRESS_2 + 2;
2074 np->pci_cfg_space.mem_base_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2076 pcibyte.reg = PCI_INTERRUPT_LINE;
2077 np->pci_cfg_space.ilr = (UBYTE)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&pcibyte);
2079 readpciword.reg = PCI_BASE_ADDRESS_4;
2080 np->pci_cfg_space.resv_0x20_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2081 readpciword.reg = PCI_BASE_ADDRESS_4 + 2;
2082 np->pci_cfg_space.resv_0x20_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2083 readpciword.reg = PCI_BASE_ADDRESS_5;
2084 np->pci_cfg_space.resv_0x24_l = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2085 readpciword.reg = PCI_BASE_ADDRESS_5 + 2;
2086 np->pci_cfg_space.resv_0x24_h = (UWORD)OOP_DoMethod(unit->rtl8168u_PCIDevice, (OOP_Msg)&readpciword);
2088 np->pci_cfg_is_read = 1;
2091 rtl8168nic_DSM(unit, DSM_MAC_INIT);
2093 udelay(10);
2096 static unsigned int rtl8168nic_XMIILinkOK(struct net_device *unit)
2098 // struct rtl8168_priv *np = get_pcnpriv(unit);
2099 APTR base = get_hwbase(unit);
2101 mdio_write(unit, 0x1f, 0x0000);
2103 return RTL_R8(base + (PHYstatus)) & LinkStatus;
2106 void rtl8168_CheckLinkStatus(struct net_device *unit)
2108 // struct rtl8168_priv *np = get_pcnpriv(unit);
2109 // APTR base = get_hwbase(unit);
2110 // unsigned long flags;
2112 if (rtl8168nic_XMIILinkOK(unit)) {
2113 netif_carrier_on(unit);
2114 RTLD(bug("[%s] rtl8168_CheckLinkStatus: Link Up\n", unit->rtl8168u_name))
2115 } else {
2116 RTLD(bug("[%s] rtl8168_CheckLinkStatus: Link Down\n", unit->rtl8168u_name))
2117 netif_carrier_off(unit);
2121 static void rtl8168nic_InitRingIndexes(struct rtl8168_priv *np)
2123 np->dirty_tx = 0;
2124 np->dirty_rx = 0;
2125 np->cur_tx = 0;
2126 np->cur_rx = 0;
2129 static void rtl8168nic_TxDescInit(struct rtl8168_priv *np)
2131 int i = 0;
2133 // memset(np->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
2135 for (i = 0; i < NUM_TX_DESC; i++)
2136 if(i == (NUM_TX_DESC - 1))
2137 np->TxDescArray[i].opts1 = AROS_LONG2LE(RingEnd);
2140 static void rtl8168nic_RxDescInit(struct rtl8168_priv *np)
2142 int i = 0;
2144 // memset(np->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
2146 for (i = 0; i < NUM_RX_DESC; i++) {
2147 if(i == (NUM_RX_DESC - 1))
2148 np->RxDescArray[i].opts1 = AROS_LONG2LE((DescOwn | RingEnd | (ULONG)np->rx_buf_sz));
2149 else
2150 np->RxDescArray[i].opts1 = AROS_LONG2LE(DescOwn | (ULONG)np->rx_buf_sz);
2154 static ULONG rtl8168nic_RxFill(struct net_device *unit, ULONG start, ULONG end)
2156 struct rtl8168_priv *np = get_pcnpriv(unit);
2157 ULONG cur;
2159 for (cur = start; end - cur > 0; cur++) {
2160 int i = cur % NUM_RX_DESC;
2162 if (np->RxDescArray[i].addr)
2163 continue;
2165 if ((np->RxDescArray[i].addr = (IPTR)HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, np->rx_buf_sz)) == 0)
2166 break;
2168 // RTLD(bug("[%s] rtl8168nic_RxFill: Rx Buffer %d Allocated @ %p\n", unit->rtl8168u_name, i, np->RxDescArray[i].addr))
2170 return cur - start;
2173 static inline void rtl8168nic_MarkAsLastDescriptor(struct RxDesc *desc)
2175 desc->opts1 |= AROS_LONG2LE(RingEnd);
2178 static int rtl8168nic_InitRings(struct net_device *unit)
2180 struct rtl8168_priv *np = get_pcnpriv(unit);
2182 RTLD(bug("[%s] rtl8168nic_InitRings(unit @ %p)\n", unit->rtl8168u_name, unit))
2184 rtl8168nic_InitRingIndexes(np);
2186 rtl8168nic_TxDescInit(np);
2187 rtl8168nic_RxDescInit(np);
2189 if (rtl8168nic_RxFill(unit, 0, NUM_RX_DESC) != NUM_RX_DESC)
2190 goto err_out;
2192 rtl8168nic_MarkAsLastDescriptor(np->RxDescArray + NUM_RX_DESC - 1);
2194 return 0;
2196 err_out:
2197 // rtl8168_rx_clear(np);
2198 return -1;
2201 static int rtl8168nic_Open(struct net_device *unit)
2203 struct rtl8168_priv *np = get_pcnpriv(unit);
2204 // APTR base = get_hwbase(unit);
2205 int ret;
2207 RTLD(bug("[%s] rtl8168nic_Open(unit @ %p)\n", unit->rtl8168u_name, unit))
2209 rtl8168nic_SetRXBufSize(unit);
2211 ret = request_irq(unit);
2212 if (ret)
2213 goto out_drain;
2215 np->TxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, R8168_TX_RING_BYTES);
2216 np->TxPhyAddr = np->TxDescArray;
2218 np->RxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8168u_PCIDriver, R8168_RX_RING_BYTES);
2219 np->RxPhyAddr = np->RxDescArray;
2221 if ((np->TxDescArray) && (np->RxDescArray))
2223 RTLD(bug("[%s] rtl8168nic_Open: Allocated Descriptor Arrays - Tx @ %p (%d bytes), Rx @ %p (%d bytes)\n", unit->rtl8168u_name,
2224 np->TxDescArray, R8168_TX_RING_BYTES,
2225 np->RxDescArray, R8168_RX_RING_BYTES))
2226 if (rtl8168nic_InitRings(unit) == 0)
2228 rtl8168nic_HWStart(unit);
2230 // if (np->esd_flag == 0) {
2231 // rtl8168_request_esd_timer(unit);
2232 // }
2234 // rtl8168_request_link_timer(unit);
2236 rtl8168nic_DSM(unit, DSM_IF_UP);
2238 rtl8168_CheckLinkStatus(unit);
2240 else
2242 RTLD(bug("[%s] rtl8168nic_Open: Failed to initialise Descriptor Arrays!\n",unit->rtl8168u_name))
2245 else
2247 RTLD(bug("[%s] rtl8168nic_Open: Failed to Allocate Descriptor Arrays!\n",unit->rtl8168u_name))
2249 return 0;
2251 out_drain:
2252 drain_ring(unit);
2253 return ret;
2256 static int rtl8168nic_Close(struct net_device *unit)
2258 struct rtl8168_priv *np = get_pcnpriv(unit);
2260 RTLD(bug("[%s] rtl8168nic_Close()\n", unit->rtl8168u_name))
2262 unit->rtl8168u_flags &= ~IFF_UP;
2264 ObtainSemaphore(&np->lock);
2265 // np->in_shutdown = 1;
2266 ReleaseSemaphore(&np->lock);
2268 unit->rtl8168u_toutNEED = FALSE;
2270 netif_stop_queue(unit);
2271 ObtainSemaphore(&np->lock);
2273 rtl8168nic_DeInit(unit);
2275 ReleaseSemaphore(&np->lock);
2277 free_irq(unit);
2279 drain_ring(unit);
2281 // HIDD_PCIDriver_FreePCIMem(unit->rtl8168u_PCIDriver, np->rx_buffer);
2282 // HIDD_PCIDriver_FreePCIMem(unit->rtl8168u_PCIDriver, np->tx_buffer);
2284 ReportEvents(LIBBASE, unit, S2EVENT_OFFLINE);
2286 return 0;
2290 void rtl8168nic_get_functions(struct net_device *Unit)
2292 Unit->initialize = rtl8168nic_Init;
2293 Unit->deinitialize = rtl8168nic_DeInit;
2294 Unit->start = rtl8168nic_Open;
2295 Unit->stop = rtl8168nic_Close;
2296 Unit->set_mac_address = rtl8168nic_SetMACAddr;
2297 Unit->set_multicast = rtl8168nic_SetMulticast;