revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / rtl8169 / rtl8169.c
blob20270700293d041de21c193a7aaa668aae58a668
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 "rtl8169.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 #include "rtl8169_hw.h"
57 #include "rtl8168_hw.h"
58 #include "rtl8101_hw.h"
60 #undef LIBBASE
61 #define LIBBASE (unit->rtl8169u_device)
63 #define _R(NAME, MAC, MASK) \
64 { .name = NAME, .mcfg = MAC, .RxConfigMask = MASK }
66 static const struct
68 const char *name;
69 UBYTE mcfg;
70 ULONG RxConfigMask; /* Clears the bits supported by this chip */
71 } rtl_chip_info[] =
73 _R("RTL8169",
74 RTL_GIGA_MAC_VER_01,
75 0xff7e1880),
77 _R("RTL8169s",
78 RTL_GIGA_MAC_VER_02,
79 0xff7e1880),
81 _R("RTL8110s",
82 RTL_GIGA_MAC_VER_03,
83 0xff7e1880),
85 _R("RTL8169sb/8110sb",
86 RTL_GIGA_MAC_VER_04,
87 0xff7e1880),
89 _R("RTL8169sc/8110sc",
90 RTL_GIGA_MAC_VER_05,
91 0xff7e1880),
93 _R("RTL8169sc/8110sc",
94 RTL_GIGA_MAC_VER_06,
95 0xff7e1880),
97 _R("RTL8168b/8111b",
98 RTL_GIGA_MAC_VER_11,
99 0xff7e1880),
101 _R("RTL8168b/8111b",
102 RTL_GIGA_MAC_VER_12,
103 0xff7e1880),
105 _R("RTL8101e",
106 RTL_GIGA_MAC_VER_13,
107 0xff7e1880),
109 _R("RTL8100e",
110 RTL_GIGA_MAC_VER_14,
111 0xff7e1880),
113 _R("RTL8100e",
114 RTL_GIGA_MAC_VER_15,
115 0xff7e1880),
117 _R("RTL8168b/8111b",
118 RTL_GIGA_MAC_VER_17,
119 0xff7e1880),
121 _R("RTL8101e",
122 RTL_GIGA_MAC_VER_16,
123 0xff7e1880),
125 _R("RTL8168cp/8111cp",
126 RTL_GIGA_MAC_VER_18,
127 0xff7e1880),
129 _R("RTL8168c/8111c",
130 RTL_GIGA_MAC_VER_19,
131 0xff7e1880),
133 _R("RTL8168c/8111c",
134 RTL_GIGA_MAC_VER_20,
135 0xff7e1880),
138 _R("RTL8168B/8111B",
139 CFG_METHOD_1,
140 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
141 0xff7e1880,
142 Jumbo_Frame_4k),
144 _R("RTL8168B/8111B",
145 CFG_METHOD_2,
146 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
147 0xff7e1880,
148 Jumbo_Frame_4k),
150 _R("RTL8168B/8111B",
151 CFG_METHOD_3,
152 (Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
153 0xff7e1880,
154 Jumbo_Frame_4k),
156 _R("RTL8168C/8111C",
157 CFG_METHOD_4,
158 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
159 0xff7e1880,
160 Jumbo_Frame_6k),
162 _R("RTL8168C/8111C",
163 CFG_METHOD_5,
164 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
165 0xff7e1880,
166 Jumbo_Frame_6k),
168 _R("RTL8168C/8111C",
169 CFG_METHOD_6,
170 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
171 0xff7e1880,
172 Jumbo_Frame_6k),
174 _R("RTL8168CP/8111CP",
175 CFG_METHOD_7,
176 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
177 0xff7e1880,
178 Jumbo_Frame_6k),
180 _R("RTL8168CP/8111CP",
181 CFG_METHOD_8,
182 RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
183 0xff7e1880,
184 Jumbo_Frame_6k),
186 _R("RTL8168D/8111D",
187 CFG_METHOD_9,
188 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
189 0xff7e1880,
190 Jumbo_Frame_9k),
192 _R("RTL8168D/8111D",
193 CFG_METHOD_10,
194 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
195 0xff7e1880,
196 Jumbo_Frame_9k),
198 _R("RTL8168D/8111D",
199 CFG_METHOD_11,
200 RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
201 0xff7e1880,
202 Jumbo_Frame_9k),*/
204 #undef _R
206 static const unsigned int rtl8169_rx_config =
207 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
209 void rtl8169_USecDelay(struct net_device *unit, ULONG usec)
211 if (unit != NULL)
213 unit->rtl8169u_DelayPort.mp_SigTask = FindTask(NULL);
214 unit->rtl8169u_DelayReq.tr_node.io_Command = TR_ADDREQUEST;
215 unit->rtl8169u_DelayReq.tr_time.tv_micro = usec % 1000000;
216 unit->rtl8169u_DelayReq.tr_time.tv_secs = usec / 1000000;
218 DoIO((struct IORequest *) &unit->rtl8169u_DelayReq);
222 struct rtl8169_priv *get_pcnpriv(struct net_device *unit)
224 return unit->rtl8169u_priv;
227 UBYTE *get_hwbase(struct net_device *unit)
229 return (UBYTE *) unit->rtl8169u_BaseMem;
232 void MMIO_W8(APTR addr, UBYTE val8)
234 *((volatile UBYTE *)(addr)) = (val8);
235 RTL_R8(addr);
238 void MMIO_W16(APTR addr, UWORD val16)
240 *((volatile UWORD *)(addr)) = (val16);
241 RTL_R16(addr);
244 void MMIO_W32(APTR addr, ULONG val32)
246 *((volatile ULONG *)(addr)) = (val32);
247 RTL_R32(addr);
250 void mdio_write(struct net_device *unit, int RegAddr, UWORD value)
252 APTR base = get_hwbase(unit);
253 int i;
255 RTL_W32(base + (PHYAR), PHYAR_Write |
256 (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift |
257 (value & PHYAR_Data_Mask));
259 for (i = 20; i > 0; i--)
261 /* Check if the RTL8169 has completed writing to the specified MDIO register */
262 if (!(RTL_R32(base + (PHYAR)) & PHYAR_Flag))
264 break;
266 udelay(25);
270 ULONG mdio_read(struct net_device *unit, int RegAddr)
272 APTR base = get_hwbase(unit);
273 UWORD value = 0xffff;
274 int i;
276 RTL_W32(base + (PHYAR), PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift);
278 for (i = 20; i > 0; i--)
280 /* Check if the RTL8169 has completed retrieving data from the specified MDIO register */
281 if (RTL_R32(base + (PHYAR)) & PHYAR_Flag)
283 value = (UWORD)(RTL_R32(base + (PHYAR)) & PHYAR_Data_Mask);
284 break;
286 udelay(25);
288 return value;
291 void rtl_phy_write(struct net_device *unit, struct phy_reg *regs, int len)
293 while (len-- > 0)
295 mdio_write(unit, regs->reg, regs->val);
296 regs++;
300 #if 0
301 static void rtl8169_PHYPowerUP(struct net_device *unit)
303 RTLD(bug("[%s] rtl8169_PHYPowerUP()\n", unit->rtl8169u_name))
305 mdio_write(unit, 0x1F, 0x0000);
306 mdio_write(unit, 0x0E, 0x0000);
308 #endif
310 void rtl8169_write_gmii_reg_bit(struct net_device *unit, int reg,
311 int bitnum, int bitval)
313 int val;
315 val = mdio_read(unit, reg);
316 val = (bitval == 1) ? val | (bitval << bitnum) : val & ~(0x0001 << bitnum);
317 mdio_write(unit, reg, val & 0xffff);
320 static void rtl8169_GetMACVersion(struct net_device *unit)
322 struct rtl8169_priv *np = get_pcnpriv(unit);
323 APTR base = get_hwbase(unit);
326 * The driver currently handles the 8168Bf and the 8168Be identically
327 * but they can be identified more specifically through the test below
328 * if needed:
330 * (RTL_R32(TxConfig) & 0x700000) == 0x500000 ? 8168Bf : 8168Be
332 * Same thing for the 8101Eb and the 8101Ec:
334 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
336 const struct
338 ULONG mask;
339 ULONG val;
340 int mac_version;
341 } mac_info[] =
343 /* 8168B family. */
344 { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_18 },
345 { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 },
346 { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 },
347 { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_20 },
349 /* 8168B family. */
350 { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 },
351 { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 },
352 { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 },
353 { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
355 /* 8101 family. */
356 { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
357 { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
358 { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
359 /* FIXME: where did these entries come from ? -- FR */
360 { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
361 { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 },
363 /* 8110 family. */
364 { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 },
365 { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 },
366 { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 },
367 { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 },
368 { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 },
369 { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 },
371 { 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */
372 }, *p = mac_info;
373 ULONG reg;
375 reg = RTL_R32(base + (TxConfig));
376 while ((reg & p->mask) != p->val)
378 p++;
380 np->mcfg = p->mac_version;
382 if (p->mask == 0x00000000)
384 RTLD(bug("[%s] unknown MAC (%08x)\n", unit->rtl8169u_name, reg))
388 static void rtl8169_PrintMACVersion(struct net_device *unit)
390 struct rtl8169_priv *np = get_pcnpriv(unit);
391 int i;
393 RTLD(bug("[%s] rtl8169_PrintMACVersion()\n", unit->rtl8169u_name))
395 for (i = (sizeof(rtl_chip_info) / sizeof(rtl_chip_info[0])) - 1; i >= 0; i--)
397 if (np->mcfg == rtl_chip_info[i].mcfg)
399 RTLD(bug("[%s] rtl8169_PrintMACVersion: mcfg == %s (%04d)\n", unit->rtl8169u_name,
400 rtl_chip_info[i].name,
401 rtl_chip_info[i].mcfg))
402 return;
406 RTLD(bug("[%s] rtl8169_PrintMACVersion: mac_version == Unknown\n", unit->rtl8169u_name))
409 static void rtl_hw_phy_config(struct net_device *unit)
411 struct rtl8169_priv *np = get_pcnpriv(unit);
413 rtl8169_PrintMACVersion(unit);
415 switch (np->mcfg)
417 case RTL_GIGA_MAC_VER_01:
418 break;
419 case RTL_GIGA_MAC_VER_02:
420 case RTL_GIGA_MAC_VER_03:
421 rtl8169s_hw_phy_config(unit);
422 break;
423 case RTL_GIGA_MAC_VER_04:
424 rtl8169sb_hw_phy_config(unit);
425 break;
426 case RTL_GIGA_MAC_VER_18:
427 rtl8168cp_hw_phy_config(unit);
428 break;
429 case RTL_GIGA_MAC_VER_19:
430 rtl8168c_hw_phy_config(unit);
431 break;
432 case RTL_GIGA_MAC_VER_20:
433 rtl8168cx_hw_phy_config(unit);
434 break;
435 default:
436 break;
440 /*static void rtl8169_DSM(struct net_device *unit, int dev_state)
442 struct rtl8169_priv *np = get_pcnpriv(unit);
443 APTR base = get_hwbase(unit);
445 switch (dev_state)
447 case DSM_MAC_INIT:
448 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
450 if (RTL_R8(base + (MACDBG)) & 0x80)
452 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
454 else
456 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
459 break;
461 case DSM_NIC_GOTO_D3:
462 case DSM_IF_DOWN:
463 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
465 if (RTL_R8(base + (MACDBG)) & 0x80)
467 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) & ~GPIO_en);
470 break;
472 case DSM_NIC_RESUME_D3:
473 case DSM_IF_UP:
474 if ((np->mcfg == CFG_METHOD_5) || (np->mcfg == CFG_METHOD_6))
476 if (RTL_R8(base + (MACDBG)) & 0x80)
478 RTL_W8(base + (GPIO), RTL_R8(base + (GPIO)) | GPIO_en);
481 break;
486 static int rtl8169_set_speed_tbi(struct net_device *unit,
487 UBYTE autoneg, UWORD speed, UBYTE duplex)
489 // struct rtl8169_priv *np = get_pcnpriv(unit);
490 APTR base = get_hwbase(unit);
491 ULONG reg;
493 reg = RTL_R32(base + TBICSR);
494 if ((autoneg == AUTONEG_DISABLE) && (speed == SPEED_1000) &&
495 (duplex == DUPLEX_FULL))
497 RTL_W32(base + TBICSR, reg & ~(TBINwEnable | TBINwRestart));
499 else if (autoneg == AUTONEG_ENABLE)
501 RTL_W32(base + TBICSR, reg | TBINwEnable | TBINwRestart);
503 else
505 RTLD(bug("[%s] incorrect speed setting refused in TBI mode\n", unit->rtl8169u_name))
508 return 0;
511 static int rtl8169_set_speed_xmii(struct net_device *unit,
512 UBYTE autoneg, UWORD speed, UBYTE duplex)
514 struct rtl8169_priv *np = get_pcnpriv(unit);
515 // APTR base = get_hwbase(unit);
516 int auto_nego = 0;
517 int giga_ctrl = 0;
518 // int bmcr_true_force = 0;
519 // unsigned long flags;
521 auto_nego = mdio_read(unit, MII_ADVERTISE);
522 auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
523 ADVERTISE_100HALF | ADVERTISE_100FULL);
524 giga_ctrl = mdio_read(unit, MII_CTRL1000);
525 giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
527 if (autoneg == AUTONEG_ENABLE)
529 auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
530 ADVERTISE_100HALF | ADVERTISE_100FULL);
531 giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
533 else
535 if (speed == SPEED_10)
537 auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
539 else if (speed == SPEED_100)
541 auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
543 else if (speed == SPEED_1000)
545 giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
547 if (duplex == DUPLEX_HALF)
549 auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
551 if (duplex == DUPLEX_FULL)
553 auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
556 /* This tweak comes straight from Realtek's driver. */
557 if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
558 ((np->mcfg == RTL_GIGA_MAC_VER_13) ||
559 (np->mcfg == RTL_GIGA_MAC_VER_16)))
561 auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
565 /* The 8100e/8101e do Fast Ethernet only. */
566 if ((np->mcfg == RTL_GIGA_MAC_VER_13) ||
567 (np->mcfg == RTL_GIGA_MAC_VER_14) ||
568 (np->mcfg == RTL_GIGA_MAC_VER_15) ||
569 (np->mcfg == RTL_GIGA_MAC_VER_16))
571 if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)))
573 RTLD(bug("[%s] PHY does not support 1000Mbps.\n", unit->rtl8169u_name))
575 giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
578 auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
580 if ((np->mcfg == RTL_GIGA_MAC_VER_12) ||
581 (np->mcfg == RTL_GIGA_MAC_VER_17))
583 /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
584 mdio_write(unit, 0x1f, 0x0000);
585 mdio_write(unit, 0x0e, 0x0000);
588 np->phy_auto_nego_reg = auto_nego;
589 np->phy_1000_ctrl_reg = giga_ctrl;
591 mdio_write(unit, MII_ADVERTISE, auto_nego);
592 mdio_write(unit, MII_CTRL1000, giga_ctrl);
593 mdio_write(unit, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
594 return 0;
597 #if 0
598 static void rtl8169_start_rx(struct net_device *unit)
600 RTLD(bug("[%s] rtl8169_start_rx\n", unit->rtl8169u_name))
601 // Already running? Stop it.
602 /* TODO: Handle starting/stopping Rx */
605 static void rtl8169_stop_rx(struct net_device *unit)
607 RTLD(bug("[%s] rtl8169_stop_rx\n", unit->rtl8169u_name))
608 /* TODO: Handle starting/stopping Rx */
611 static void rtl8169_start_tx(struct net_device *unit)
613 RTLD(bug("[%s] rtl8169_start_tx()\n", unit->rtl8169u_name))
614 /* TODO: Handle starting/stopping Tx */
617 static void rtl8169_stop_tx(struct net_device *unit)
619 RTLD(bug("[%s] rtl8169_stop_tx()\n", unit->rtl8169u_name))
620 /* TODO: Handle starting/stopping Tx */
623 static void rtl8169_txrx_reset(struct net_device *unit)
625 RTLD(bug("[%s] rtl8169_txrx_reset()\n", unit->rtl8169u_name))
627 #endif
630 * rtl8169_SetMulticast: unit->set_multicast function
631 * Called with unit->xmit_lock held.
633 static void rtl8169_SetMulticast(struct net_device *unit)
635 ULONG addr[2];
636 ULONG mask[2];
638 RTLD(bug("[%s] rtl8169_SetMulticast()\n", unit->rtl8169u_name))
640 memset(addr, 0, sizeof(addr));
641 memset(mask, 0, sizeof(mask));
644 static void rtl8169_irq_mask_and_ack(struct net_device *unit)
646 APTR base = get_hwbase(unit);
647 RTL_W16(base + IntrMask, 0x0000);
648 RTL_W16(base + IntrStatus, 0xffff);
651 static void rtl8169_asic_down(struct net_device *unit)
653 APTR base = get_hwbase(unit);
654 RTL_W8(base + ChipCmd, 0x00);
655 rtl8169_irq_mask_and_ack(unit);
656 RTL_R16(base + CPlusCmd);
659 static void rtl8169_DeInit(struct net_device *unit)
661 APTR base = get_hwbase(unit);
662 rtl8169_asic_down(unit);
664 /* Update the error counts. */
665 RTL_W32(base + RxMissed, 0);
668 static void rtl8169_GetMACAddr(struct net_device *unit, char *addr, BOOL fromROM)
670 APTR base = get_hwbase(unit);
671 int i;
673 RTLD(bug("[%s] rtl8169_GetMACAddr()\n",unit->rtl8169u_name))
674 /* Get MAC address. FIXME: read EEPROM */
675 for (i = 0; i < MAC_ADDR_LEN; i++)
677 addr[i] = RTL_R8(base + MAC0 + i);
681 static void rtl8169_SetMACAddr(struct net_device *unit)
683 APTR base = get_hwbase(unit);
685 RTLD(bug("[%s] rtl8169_SetMACAddr()\n", unit->rtl8169u_name))
687 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
689 RTL_W32(base + (MAC0),
690 unit->rtl8169u_dev_addr[0] |
691 (unit->rtl8169u_dev_addr[1] << 8) |
692 (unit->rtl8169u_dev_addr[2] << 16) |
693 (unit->rtl8169u_dev_addr[3] << 24));
694 RTL_W32(base + (MAC4),
695 unit->rtl8169u_dev_addr[4] |
696 (unit->rtl8169u_dev_addr[5] << 8));
698 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
700 RTLD(
701 /* Read it back to be certain! */
702 TEXT newmac[6];
703 rtl8169_GetMACAddr(unit, newmac, FALSE);
705 bug("[%s] rtl8169_SetMACAddr: New MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8169u_name,
706 newmac[0], newmac[1], newmac[2],
707 newmac[3], newmac[4], newmac[5])
711 static void rtl8169_LinkOption(struct net_device *unit, UBYTE *aut, UWORD *spd, UBYTE *dup)
713 unsigned char opt_speed;
714 unsigned char opt_duplex;
715 unsigned char opt_autoneg;
717 opt_speed = ((unit->rtl8169u_UnitNum < MAX_UNITS) && (unit->rtl8169u_UnitNum >= 0)) ? unit->rtl8169u_device->speed[unit->rtl8169u_UnitNum] : 0xff;
718 opt_duplex = ((unit->rtl8169u_UnitNum < MAX_UNITS) && (unit->rtl8169u_UnitNum >= 0)) ? unit->rtl8169u_device->duplex[unit->rtl8169u_UnitNum] : 0xff;
719 opt_autoneg = ((unit->rtl8169u_UnitNum < MAX_UNITS) && (unit->rtl8169u_UnitNum >= 0)) ? unit->rtl8169u_device->autoneg[unit->rtl8169u_UnitNum] : 0xff;
721 if ((opt_speed == 0xff) |
722 (opt_duplex == 0xff) |
723 (opt_autoneg == 0xff))
725 *spd = SPEED_1000;
726 *dup = DUPLEX_FULL;
727 *aut = AUTONEG_ENABLE;
729 else
731 *spd = unit->rtl8169u_device->speed[unit->rtl8169u_UnitNum];
732 *dup = unit->rtl8169u_device->duplex[unit->rtl8169u_UnitNum];
733 *aut = unit->rtl8169u_device->autoneg[unit->rtl8169u_UnitNum];
737 static void rtl8169_phy_reset(struct net_device *unit)
739 struct rtl8169_priv *np = get_pcnpriv(unit);
740 APTR base = get_hwbase(unit);
741 unsigned int i;
743 if ((np->mcfg <= RTL_GIGA_MAC_VER_06) &&
744 (RTL_R8(base + PHYstatus) & TBI_Enable))
746 rtl8169_tbi_reset_enable(unit);
748 else
750 rtl8169_xmii_reset_enable(unit);
753 if ((np->mcfg <= RTL_GIGA_MAC_VER_06) &&
754 (RTL_R8(base + PHYstatus) & TBI_Enable))
756 for (i = 0; i < 100; i++)
758 if (!rtl8169_tbi_reset_pending(unit))
760 return;
762 rtl8169_USecDelay(unit, 100);
765 else
767 for (i = 0; i < 100; i++)
769 if (!rtl8169_xmii_reset_pending(unit))
771 return;
773 rtl8169_USecDelay(unit, 100);
778 static void rtl8169_Init(struct net_device *unit)
780 struct rtl8169_priv *np = get_pcnpriv(unit);
781 APTR base = get_hwbase(unit);
782 UBYTE autoneg, duplex;
783 UWORD speed;
784 int i;
785 // int config1;
787 RTLD(bug("[%s] rtl8169_Init(unit @ %p)\n", unit->rtl8169u_name, unit))
789 np->intr_mask = 0xffff;
790 np->intr_event = unit->rtl8169u_intr_event;
791 np->napi_event = unit->rtl8169u_napi_event;
793 /* Unneeded ? Don't mess with Mrs. Murphy. */
794 rtl8169_irq_mask_and_ack(unit);
796 /* Soft reset the chip. */
797 RTL_W8(base + ChipCmd, CmdReset);
799 /* Check that the chip has finished the reset. */
800 for (i = 0; i < 100; i++)
802 if ((RTL_R8(base + ChipCmd) & CmdReset) == 0)
804 break;
806 rtl8169_USecDelay(unit, 100);
809 /* Identify chip attached to board */
810 rtl8169_GetMACVersion(unit);
811 rtl8169_PrintMACVersion(unit);
813 for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++)
815 if (np->mcfg == rtl_chip_info[i].mcfg)
817 break;
821 if (i == ARRAY_SIZE(rtl_chip_info))
823 i = 0;
825 np->chipset = i;
827 unit->rtl8169u_rtl_chipname = rtl_chip_info[np->chipset].name;
829 RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
830 RTL_W8(base + (Config1), RTL_R8(base + Config1) | PMEnable);
831 RTL_W8(base + (Config5), RTL_R8(base + Config5) & PMEStatus);
833 RTLD(bug("[%s] rtl8169_Init: Power Management enabled\n", unit->rtl8169u_name))
835 /* RTL_W8(base + (Cfg9346), Cfg9346_Unlock);
836 np->features |= rtl8169_try_msi(pdev, base);
837 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
840 RTL_W8(base + (Cfg9346), Cfg9346_Lock);
842 rtl8169_GetMACAddr(unit, &np->orig_mac[0], TRUE);
844 unit->rtl8169u_dev_addr[0] = unit->rtl8169u_org_addr[0] = np->orig_mac[0];
845 unit->rtl8169u_dev_addr[1] = unit->rtl8169u_org_addr[1] = np->orig_mac[1];
846 unit->rtl8169u_dev_addr[2] = unit->rtl8169u_org_addr[2] = np->orig_mac[2];
847 unit->rtl8169u_dev_addr[3] = unit->rtl8169u_org_addr[3] = np->orig_mac[3];
848 unit->rtl8169u_dev_addr[4] = unit->rtl8169u_org_addr[4] = np->orig_mac[4];
849 unit->rtl8169u_dev_addr[5] = unit->rtl8169u_org_addr[5] = np->orig_mac[5];
851 RTLD(bug("[%s] rtl8169_Init: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit->rtl8169u_name,
852 unit->rtl8169u_dev_addr[0], unit->rtl8169u_dev_addr[1], unit->rtl8169u_dev_addr[2],
853 unit->rtl8169u_dev_addr[3], unit->rtl8169u_dev_addr[4], unit->rtl8169u_dev_addr[5]))
855 bug("[%s] rtl8169_Init: This product is covered by one or more of the following patents:\n", unit->rtl8169u_name);
856 bug("[%s] rtl8169_Init: US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625.\n", unit->rtl8169u_name);
859 unit->features |= NETIF_F_IP_CSUM;
861 np->cp_cmd |= RxChkSum;
862 np->cp_cmd |= RTL_R16(base + (CPlusCmd));
864 //np->intr_mask = unit->rtl8169u_intr_mask;
866 // rtl8169_init_phy
867 rtl_hw_phy_config(unit);
869 if (np->mcfg <= RTL_GIGA_MAC_VER_06)
871 RTL_W8(base + 0x82, 0x01);
874 RTLD(bug("[%s] rtl8169_Init: PHY Configured\n", unit->rtl8169u_name))
876 HIDD_PCIDevice_WriteConfigByte(unit->rtl8169u_PCIDevice, PCI_LATENCY_TIMER, 0x40);
878 if (np->mcfg <= RTL_GIGA_MAC_VER_06)
880 HIDD_PCIDevice_WriteConfigByte(unit->rtl8169u_PCIDevice, PCI_CACHE_LINE_SIZE, 0x08);
883 if (np->mcfg == RTL_GIGA_MAC_VER_02)
885 RTL_W8(base + 0x82, 0x01);
886 mdio_write(unit, 0x0b, 0x0000); //w 0x0b 15 0 0
889 rtl8169_phy_reset(unit);
891 rtl8169_LinkOption(unit, &autoneg, &speed, &duplex);
893 if ((np->mcfg <= RTL_GIGA_MAC_VER_06) &&
894 (RTL_R8(base + PHYstatus) & TBI_Enable))
896 rtl8169_set_speed_tbi(unit, autoneg, speed, duplex);
898 else
900 rtl8169_set_speed_xmii(unit, autoneg, speed, duplex);
903 RTLD(bug("[%s] rtl8169_Init: Link Speed %dbps %s duplex %s\n", unit->rtl8169u_name, speed, (duplex == DUPLEX_HALF) ? "half" :"full", (autoneg == AUTONEG_ENABLE) ? "(autoneg)" :""))
906 static void rtl8169_drain_tx(struct net_device *unit)
908 // struct rtl8169_priv *np = get_pcnpriv(unit);
909 // int i;
910 // for (i = 0; i < NUM_TX_DESC; i++) {
911 /* TODO: rtl8169_drain_tx does nothing atm. */
912 // }
915 static void rtl8169_drain_rx(struct net_device *unit)
917 // struct rtl8169_priv *np = get_pcnpriv(unit);
918 // int i;
919 // for (i = 0; i < RX_RING_SIZE; i++) {
920 /* TODO: rtl8169_drain_rx does nothing atm. */
921 // }
924 static void drain_ring(struct net_device *unit)
926 rtl8169_drain_tx(unit);
927 rtl8169_drain_rx(unit);
930 static int request_irq(struct net_device *unit)
932 RTLD(bug("[%s] request_irq()\n", unit->rtl8169u_name))
934 if (!unit->rtl8169u_IntsAdded)
936 if (!HIDD_PCIDevice_AddInterrupt(unit->rtl8169u_PCIDevice, &unit->rtl8169u_irqhandler))
937 return 1;
938 AddIntServer(INTB_VERTB, &unit->rtl8169u_touthandler);
939 unit->rtl8169u_IntsAdded = TRUE;
942 return 0;
945 static void free_irq(struct net_device *unit)
947 if (unit->rtl8169u_IntsAdded)
949 HIDD_PCIDevice_RemoveInterrupt(unit->rtl8169u_PCIDevice, &unit->rtl8169u_irqhandler);
950 RemIntServer(INTB_VERTB, &unit->rtl8169u_touthandler);
951 unit->rtl8169u_IntsAdded = FALSE;
955 void rtl_set_rx_max_size(struct net_device *unit)
957 struct rtl8169_priv *np = get_pcnpriv(unit);
958 APTR base = get_hwbase(unit);
959 unsigned int mtu = unit->rtl8169u_mtu;
961 RTLD(bug("[%s] rtl_set_rx_max_size()\n", unit->rtl8169u_name))
963 np->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
965 RTLD(bug("[%s] %d\n", unit->rtl8169u_name, np->rx_buf_sz + 1))
967 RTL_W16(base + (RxMaxSize), np->rx_buf_sz + 1);
970 /*void rtl_set_tx_max_size(struct net_device *unit)
972 struct rtl8169_priv *np = get_pcnpriv(unit);
973 APTR base = get_hwbase(unit);
974 unsigned int mtu = unit->rtl8169u_mtu;
976 RTLD(bug("[%s] rtl_set_tx_max_size()\n", unit->rtl8169u_name))
978 np->tx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : TX_BUF_SIZE;
980 RTL_W16(base + (TxMaxSize), np->tx_buf_sz + 1);
984 /*static void rtl8169_NICReset(struct net_device *unit)
986 struct rtl8169_priv *np = get_pcnpriv(unit);
987 APTR base = get_hwbase(unit);
988 int i;
990 RTLD(bug("[%s] rtl8169_NICReset()\n", unit->rtl8169u_name))
992 if ((np->mcfg != CFG_METHOD_1) &&
993 (np->mcfg != CFG_METHOD_2) &&
994 (np->mcfg != CFG_METHOD_3))
996 RTL_W8(base + (ChipCmd), StopReq | CmdRxEnb | CmdTxEnb);
997 udelay(100);
1000 // Soft reset the chip.
1001 RTL_W8(base + (ChipCmd), CmdReset);
1003 // Check that the chip has finished the reset.
1004 for (i = 1000; i > 0; i--)
1006 if ((RTL_R8(base + (ChipCmd)) & CmdReset) == 0)
1008 break;
1010 udelay(100);
1014 UWORD rtl_rw_cpluscmd(struct net_device *unit)
1016 APTR base = get_hwbase(unit);
1017 UWORD cmd;
1019 cmd = RTL_R16(base + CPlusCmd);
1020 RTL_W16(base + CPlusCmd, cmd);
1021 return cmd;
1024 void rtl_set_rx_tx_desc_registers(struct net_device *unit)
1026 struct rtl8169_priv *np = get_pcnpriv(unit);
1027 APTR base = get_hwbase(unit);
1029 * Magic spell: some iop3xx ARM board needs the TxDescAddrHigh
1030 * register to be written before TxDescAddrLow to work.
1031 * Switching from MMIO to I/O access fixes the issue as well.
1033 RTL_W32(base + (TxDescStartAddrHigh), ((UQUAD) (IPTR)np->TxPhyAddr >> 32));
1034 RTL_W32(base + (TxDescStartAddrLow), ((UQUAD) (IPTR)np->TxPhyAddr & DMA_32BIT_MASK));
1035 RTL_W32(base + (RxDescAddrHigh), ((UQUAD) (IPTR)np->RxPhyAddr >> 32));
1036 RTL_W32(base + (RxDescAddrLow), ((UQUAD) (IPTR)np->RxPhyAddr & DMA_32BIT_MASK));
1039 void rtl_set_rx_tx_config_registers(struct net_device *unit)
1041 struct rtl8169_priv *np = get_pcnpriv(unit);
1042 APTR base = get_hwbase(unit);
1044 ULONG cfg = rtl8169_rx_config;
1046 cfg |= (RTL_R32(base + RxConfig) & rtl_chip_info[np->chipset].RxConfigMask);
1047 RTL_W32(base + RxConfig, cfg);
1049 /* Set DMA burst size and Interframe Gap Time */
1050 RTL_W32(base + TxConfig, (TX_DMA_BURST << TxDMAShift) |
1051 (InterFrameGap << TxInterFrameGapShift));
1054 void rtl_set_rx_mode(struct net_device *unit)
1056 struct rtl8169_priv *np = get_pcnpriv(unit);
1057 APTR base = get_hwbase(unit);
1059 // unsigned long flags;
1060 ULONG mc_filter[2]; /* Multicast hash filter */
1061 int rx_mode;
1062 ULONG tmp = 0;
1064 if (unit->rtl8169u_flags & IFF_PROMISC)
1066 /* Unconditionally log net taps. */
1067 RTLD(bug("[%s] rtl8169_SetRxMode: Promiscuous mode enabled\n", unit->rtl8169u_name))
1068 rx_mode = AcceptBroadcast |
1069 AcceptMulticast |
1070 AcceptMyPhys |
1071 AcceptAllPhys;
1072 mc_filter[1] = mc_filter[0] = 0xffffffff;
1074 else if ((unit->rtl8169u_mc_count > unit->rtl8169u_device->rtl8169b_MulticastFilterLimit) ||
1075 (unit->rtl8169u_flags))
1077 /* Too many to filter perfectly -- accept all multicasts. */
1078 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
1079 mc_filter[1] = mc_filter[0] = 0xffffffff;
1081 else
1083 struct dev_mc_list *mclist;
1084 unsigned int i;
1086 rx_mode = AcceptBroadcast | AcceptMyPhys;
1087 mc_filter[1] = mc_filter[0] = 0;
1088 for (i = 0, mclist = unit->rtl8169u_mc_list; mclist && i < unit->rtl8169u_mc_count;
1089 i++, mclist = mclist->next)
1091 // int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1092 // mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1093 rx_mode |= AcceptMulticast;
1097 tmp = rtl8169_rx_config | rx_mode |
1098 (RTL_R32(base + RxConfig) & rtl_chip_info[np->chipset].RxConfigMask);
1100 if (np->mcfg > RTL_GIGA_MAC_VER_06)
1102 ULONG data = mc_filter[0];
1104 mc_filter[0] = swab32(mc_filter[1]);
1105 mc_filter[1] = swab32(data);
1108 RTL_W32(base + MAR0 + 0, mc_filter[0]);
1109 RTL_W32(base + MAR0 + 4, mc_filter[1]);
1111 RTL_W32(base + RxConfig, tmp);
1114 #if 0
1115 static unsigned int rtl8169_XMIILinkOK(struct net_device *unit)
1117 // struct rtl8169_priv *np = get_pcnpriv(unit);
1118 APTR base = get_hwbase(unit);
1120 mdio_write(unit, 0x1f, 0x0000);
1122 return RTL_R8(base + (PHYstatus)) & LinkStatus;
1124 #endif
1126 void rtl8169_CheckLinkStatus(struct net_device *unit)
1128 struct rtl8169_priv *np = get_pcnpriv(unit);
1129 APTR base = get_hwbase(unit);
1130 // unsigned long flags;
1131 int result;
1133 if ((np->mcfg <= RTL_GIGA_MAC_VER_06) &&
1134 (RTL_R8(base + PHYstatus) & TBI_Enable))
1136 result = rtl8169_tbi_link_ok(unit);
1138 else
1140 result = rtl8169_xmii_link_ok(unit);
1143 if (result)
1145 netif_carrier_on(unit);
1146 RTLD(bug("[%s] rtl8169_CheckLinkStatus: Link Up\n", unit->rtl8169u_name))
1148 else
1150 RTLD(bug("[%s] rtl8169_CheckLinkStatus: Link Down\n", unit->rtl8169u_name))
1151 netif_carrier_off(unit);
1155 static void rtl8169_InitRingIndexes(struct rtl8169_priv *np)
1157 np->dirty_tx = 0;
1158 np->dirty_rx = 0;
1159 np->cur_tx = 0;
1160 np->cur_rx = 0;
1163 static void rtl8169_TxDescInit(struct rtl8169_priv *np)
1165 int i = 0;
1167 memset(np->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
1169 for (i = 0; i < NUM_TX_DESC; i++)
1171 if(i == (NUM_TX_DESC - 1))
1173 np->TxDescArray[i].opts1 = AROS_LONG2LE(RingEnd);
1178 static ULONG rtl8169_TxFill(struct net_device *unit, ULONG start, ULONG end)
1180 struct rtl8169_priv *np = get_pcnpriv(unit);
1181 ULONG cur;
1183 for (cur = start; end - cur > 0; cur++)
1185 int i = cur % NUM_TX_DESC;
1187 if (np->TxDescArray[i].addr)
1189 continue;
1192 if ((np->TxDescArray[i].addr = (IPTR)HIDD_PCIDriver_AllocPCIMem(unit->rtl8169u_PCIDriver, TX_BUF_SIZE)) == 0)
1194 break;
1197 return cur - start;
1200 static void rtl8169_RxDescInit(struct rtl8169_priv *np)
1202 int i = 0;
1204 memset(np->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
1206 for (i = 0; i < NUM_RX_DESC; i++)
1208 if(i == (NUM_RX_DESC - 1))
1210 np->RxDescArray[i].opts1 = AROS_LONG2LE((DescOwn | RingEnd | (ULONG) np->rx_buf_sz));
1212 else
1214 np->RxDescArray[i].opts1 = AROS_LONG2LE(DescOwn | (ULONG) np->rx_buf_sz);
1219 static ULONG rtl8169_RxFill(struct net_device *unit, ULONG start, ULONG end)
1221 struct rtl8169_priv *np = get_pcnpriv(unit);
1222 ULONG cur;
1224 for (cur = start; end - cur > 0; cur++)
1226 int i = cur % NUM_RX_DESC;
1228 if (np->RxDescArray[i].addr)
1230 continue;
1233 if ((np->RxDescArray[i].addr = (IPTR)HIDD_PCIDriver_AllocPCIMem(unit->rtl8169u_PCIDriver, np->rx_buf_sz)) == 0)
1235 break;
1238 return cur - start;
1241 static inline void rtl8169_MarkAsLastDescriptor(struct RxDesc *desc)
1243 desc->opts1 |= AROS_LONG2LE(RingEnd);
1246 static int rtl8169_InitRings(struct net_device *unit)
1248 struct rtl8169_priv *np = get_pcnpriv(unit);
1250 RTLD(bug("[%s] rtl8169_InitRings(unit @ %p)\n", unit->rtl8169u_name, unit))
1252 rtl8169_InitRingIndexes(np);
1254 rtl8169_TxDescInit(np);
1255 rtl8169_RxDescInit(np);
1257 if (rtl8169_RxFill(unit, 0, NUM_RX_DESC) != NUM_RX_DESC)
1259 goto err_out;
1262 if (rtl8169_TxFill(unit, 0, NUM_TX_DESC) != NUM_TX_DESC)
1264 goto err_out;
1267 // rtl8169_MarkAsLastDescriptor(np->RxDescArray + (NUM_RX_DESC - 1));
1269 return 0;
1271 err_out:
1272 // rtl8169_rx_clear(np);
1273 return -1;
1276 static void rtl8169_HWStart(struct net_device *unit)
1278 int i;
1279 APTR base = get_hwbase(unit);
1281 /* Soft reset the chip. */
1282 RTL_W8(base + ChipCmd, CmdReset);
1284 /* Check that the chip has finished the reset. */
1285 for (i = 0; i < 100; i++)
1287 if ((RTL_R8(base + ChipCmd) & CmdReset) == 0)
1289 break;
1291 udelay(100);
1294 switch(unit->rtl8169u_config)
1296 case RTL_CFG_0:
1297 rtl_hw_start_8169(unit);
1298 break;
1299 case RTL_CFG_1:
1300 case UNKNOWN_CFG:
1301 rtl_hw_start_8168(unit);
1302 break;
1303 case RTL_CFG_2:
1304 rtl_hw_start_8101(unit);
1305 break;
1308 netif_start_queue(unit);
1311 static int rtl8169_Open(struct net_device *unit)
1313 struct rtl8169_priv *np = get_pcnpriv(unit);
1314 // APTR base = get_hwbase(unit);
1315 int ret;
1317 RTLD(bug("[%s] rtl8169_Open(unit @ %p)\n", unit->rtl8169u_name, unit))
1319 rtl_set_rx_max_size(unit);
1321 ret = request_irq(unit);
1322 if (ret)
1324 goto out_drain;
1327 np->TxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8169u_PCIDriver, R8169_TX_RING_BYTES);
1328 np->TxPhyAddr = np->TxDescArray;
1330 np->RxDescArray = HIDD_PCIDriver_AllocPCIMem(unit->rtl8169u_PCIDriver, R8169_RX_RING_BYTES);
1331 np->RxPhyAddr = np->RxDescArray;
1333 if ((np->TxDescArray) && (np->RxDescArray))
1335 RTLD(bug("[%s] rtl8169_Open: Allocated Descriptor Arrays - Tx @ %p (%d bytes), Rx @ %p (%d bytes)\n", unit->rtl8169u_name,
1336 np->TxDescArray, R8169_TX_RING_BYTES,
1337 np->RxDescArray, R8169_RX_RING_BYTES))
1338 if (rtl8169_InitRings(unit) == 0)
1340 rtl8169_HWStart(unit);
1342 // if (np->esd_flag == 0)
1343 // {
1344 // rtl8169_request_esd_timer(unit);
1345 // }
1347 // rtl8169_request_link_timer(unit);
1349 //rtl8169_DSM(unit, DSM_IF_UP);
1351 rtl8169_CheckLinkStatus(unit);
1353 else
1355 RTLD(bug("[%s] rtl8169_Open: Failed to initialise Descriptor Arrays!\n",unit->rtl8169u_name))
1358 else
1360 RTLD(bug("[%s] rtl8169_Open: Failed to Allocate Descriptor Arrays!\n",unit->rtl8169u_name))
1363 unit->rtl8169u_flags |= IFF_UP;
1364 return 0;
1366 out_drain:
1367 drain_ring(unit);
1368 return ret;
1371 static int rtl8169_Close(struct net_device *unit)
1373 struct rtl8169_priv *np = get_pcnpriv(unit);
1374 // UBYTE *base;
1376 RTLD(bug("[%s] rtl8169_Close()\n", unit->rtl8169u_name))
1378 unit->rtl8169u_flags &= ~IFF_UP;
1380 ObtainSemaphore(&np->lock);
1381 // np->in_shutdown = 1;
1382 ReleaseSemaphore(&np->lock);
1384 unit->rtl8169u_toutNEED = FALSE;
1386 netif_stop_queue(unit);
1387 ObtainSemaphore(&np->lock);
1389 rtl8169_DeInit(unit);
1391 ReleaseSemaphore(&np->lock);
1393 free_irq(unit);
1395 drain_ring(unit);
1397 // HIDD_PCIDriver_FreePCIMem(unit->rtl8169u_PCIDriver, np->rx_buffer);
1398 // HIDD_PCIDriver_FreePCIMem(unit->rtl8169u_PCIDriver, np->tx_buffer);
1400 ReportEvents(LIBBASE, unit, S2EVENT_OFFLINE);
1402 return 0;
1405 void rtl8169_get_functions(struct net_device *Unit)
1407 Unit->initialize = rtl8169_Init;
1408 Unit->deinitialize = rtl8169_DeInit;
1409 Unit->start = rtl8169_Open;
1410 Unit->stop = rtl8169_Close;
1411 Unit->set_mac_address = rtl8169_SetMACAddr;
1412 Unit->set_multicast = rtl8169_SetMulticast;