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,
24 #include <exec/types.h>
25 #include <exec/resident.h>
27 #include <exec/ports.h>
29 #include <aros/libcall.h>
30 #include <aros/macros.h>
35 #include <devices/timer.h>
36 #include <devices/sana2.h>
37 #include <devices/sana2specialstats.h>
39 #include <utility/utility.h>
40 #include <utility/tagitem.h>
41 #include <utility/hooks.h>
45 #include <proto/oop.h>
46 #include <proto/exec.h>
47 #include <proto/dos.h>
48 #include <proto/battclock.h>
50 #include <hardware/intbits.h>
55 #include LC_LIBDEFS_FILE
57 /* A bit fixed linux stuff here :) */
60 #define LIBBASE (unit->rtl8139u_device)
62 #if defined(__i386__) || defined(__x86_64__)
63 #define TIMER_RPROK 3599597124UL
65 static ULONG
usec2tick(ULONG usec
)
67 ULONG ret
, timer_rpr
= TIMER_RPROK
;
68 asm volatile("movl $0,%%eax; divl %2":"=a"(ret
):"d"(usec
),"m"(timer_rpr
));
72 void udelay(LONG usec
)
75 usec
= usec2tick(usec
);
78 oldtick
= BYTEIN(0x42);
79 oldtick
+= BYTEIN(0x42) << 8;
85 tick
+= BYTEIN(0x42) << 8;
87 usec
-= (oldtick
- tick
);
88 if (tick
> oldtick
) usec
-= 0x10000;
94 struct timerequest timerio
;
95 struct MsgPort
*timermp
;
97 void udelay(LONG usec
)
99 timerio
.tr_node
.io_Command
= TR_ADDREQUEST
;
100 timerio
.tr_time
.tv_secs
= usec
/ 1000000;
101 timerio
.tr_time
.tv_micro
= usec
% 1000000;
102 DoIO(&timerio
.tr_node
);
107 if ((timermp
= CreateMsgPort())) {
108 timerio
.tr_node
.io_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
109 timerio
.tr_node
.io_Message
.mn_ReplyPort
= timermp
;
110 timerio
.tr_node
.io_Message
.mn_Length
=sizeof(timerio
);
111 if (0 == OpenDevice("timer.device", UNIT_MICROHZ
, &timerio
.tr_node
, 0)) {
117 ADD2INIT(init_timer
, 10);
119 void exit_timer(void)
121 CloseDevice(&timerio
.tr_node
);
122 DeleteMsgPort(timermp
);
124 ADD2EXIT(exit_timer
, 10);
127 static inline struct fe_priv
*get_pcnpriv(struct net_device
*unit
)
129 return unit
->rtl8139u_fe_priv
;
132 static inline UBYTE
*get_hwbase(struct net_device
*unit
)
134 return (UBYTE
*)unit
->rtl8139u_BaseMem
;
137 static int read_eeprom(long base
, int location
, int addr_len
)
141 long rtlprom_addr
= base
+ RTLr_Cfg9346
;
142 int read_cmd
= location
| (EE_READ_CMD
<< addr_len
);
144 BYTEOUT(rtlprom_addr
, EE_ENB
& ~EE_CS
);
145 BYTEOUT(rtlprom_addr
, EE_ENB
);
147 // Shift the read command bits out
148 for (i
= 4 + addr_len
; i
>= 0; i
--)
150 int dataval
= (read_cmd
& (1 << i
)) ? EE_DATA_WRITE
: 0;
151 BYTEOUT(rtlprom_addr
, EE_ENB
| dataval
);
152 eeprom_delay(rtlprom_addr
);
153 BYTEOUT(rtlprom_addr
, EE_ENB
| dataval
| EE_SHIFT_CLK
);
154 eeprom_delay(rtlprom_addr
);
156 BYTEOUT(rtlprom_addr
, EE_ENB
);
157 eeprom_delay(rtlprom_addr
);
159 for (i
= 16; i
> 0; i
--)
161 BYTEOUT(rtlprom_addr
, EE_ENB
| EE_SHIFT_CLK
);
162 eeprom_delay(rtlprom_addr
);
163 retval
= (retval
<< 1) | ((BYTEIN(rtlprom_addr
) & EE_DATA_READ
) ? 1 : 0);
164 BYTEOUT(rtlprom_addr
, EE_ENB
);
165 eeprom_delay(rtlprom_addr
);
168 // Terminate EEPROM access
169 BYTEOUT(rtlprom_addr
, ~EE_CS
);
170 eeprom_delay(rtlprom_addr
);
174 // Syncronize the MII management interface by shifting 32 one bits out
175 static char mii_2_8139_map
[8] =
177 RTLr_MII_BMCR
, RTLr_MII_BMSR
, 0, 0, RTLr_NWayAdvert
, RTLr_NWayLPAR
, RTLr_NWayExpansion
, 0
180 static void mdio_sync(long base
)
184 for (i
= 32; i
>= 0; i
--)
186 BYTEOUT(base
, MDIO_WRITE1
);
188 BYTEOUT(base
, MDIO_WRITE1
| MDIO_CLK
);
193 static int mdio_read(struct net_device
*unit
, int phy_id
, int location
)
195 // struct fe_priv *np = get_pcnpriv(unit);
196 UBYTE
*base
= get_hwbase(unit
);
197 int mii_cmd
= (0xf6 << 10) | (phy_id
<< 5) | location
;
203 // Really a 8139. Use internal registers
204 return location
< 8 && mii_2_8139_map
[location
] ? WORDIN(base
+ mii_2_8139_map
[location
]) : 0;
207 mdio_sync((IPTR
)base
+ RTLr_MII_SMI
);
209 // Shift the read command bits out
210 for (i
= 15; i
>= 0; i
--)
212 int dataval
= (mii_cmd
& (1 << i
)) ? MDIO_DATA_OUT
: 0;
214 BYTEOUT(base
+ RTLr_MII_SMI
, MDIO_DIR
| dataval
);
215 mdio_delay(base
+ RTLr_MII_SMI
);
216 BYTEOUT(base
+ RTLr_MII_SMI
, MDIO_DIR
| dataval
| MDIO_CLK
);
217 mdio_delay(base
+ RTLr_MII_SMI
);
220 // Read the two transition, 16 data, and wire-idle bits
221 for (i
= 19; i
> 0; i
--)
223 BYTEOUT(base
+ RTLr_MII_SMI
, 0);
224 mdio_delay(base
+ RTLr_MII_SMI
);
225 retval
= (retval
<< 1) | ((BYTEIN(base
+ RTLr_MII_SMI
) & MDIO_DATA_IN
) ? 1 : 0);
226 BYTEOUT(base
+ RTLr_MII_SMI
, MDIO_CLK
);
227 mdio_delay(base
+ RTLr_MII_SMI
);
230 return (retval
>> 1) & 0xffff;
234 static void rtl8139nic_start_rx(struct net_device
*unit
)
236 // struct fe_priv *np = get_pcnpriv(unit);
237 // UBYTE *base = get_hwbase(unit);
239 RTLD(bug("[%s] rtl8139nic_start_rx\n", unit
->rtl8139u_name
))
240 // Already running? Stop it.
241 /* TODO: Handle starting/stopping Rx */
244 static void rtl8139nic_stop_rx(struct net_device
*unit
)
246 // UBYTE *base = get_hwbase(unit);
248 RTLD(bug("[%s] rtl8139nic_stop_rx\n", unit
->rtl8139u_name
))
249 /* TODO: Handle starting/stopping Rx */
252 static void rtl8139nic_start_tx(struct net_device
*unit
)
254 // UBYTE *base = get_hwbase(unit);
256 RTLD(bug("[%s] rtl8139nic_start_tx()\n", unit
->rtl8139u_name
))
257 /* TODO: Handle starting/stopping Tx */
260 static void rtl8139nic_stop_tx(struct net_device
*unit
)
262 // UBYTE *base = get_hwbase(unit);
264 RTLD(bug("[%s] rtl8139nic_stop_tx()\n", unit
->rtl8139u_name
))
265 /* TODO: Handle starting/stopping Tx */
268 static void rtl8139nic_txrx_reset(struct net_device
*unit
)
270 // struct fe_priv *np = get_pcnpriv(unit);
271 // UBYTE *base = get_hwbase(unit);
273 RTLD(bug("[%s] rtl8139nic_txrx_reset()\n", unit
->rtl8139u_name
))
278 * rtl8139nic_set_multicast: unit->set_multicast function
279 * Called with unit->xmit_lock held.
281 static void rtl8139nic_set_multicast(struct net_device
*unit
)
283 // struct fe_priv *np = get_pcnpriv(unit);
284 // UBYTE *base = get_hwbase(unit);
289 RTLD(bug("[%s] rtl8139nic_set_multicast()\n", unit
->rtl8139u_name
))
291 memset(addr
, 0, sizeof(addr
));
292 memset(mask
, 0, sizeof(mask
));
295 static void rtl8139nic_deinitialize(struct net_device
*unit
)
298 UBYTE
*base
= get_hwbase(unit
);
300 WORDOUT(base
+ RTLr_IntrMask
, 0);
301 BYTEOUT(base
+ RTLr_ChipCmd
, (BYTEIN(base
+ RTLr_ChipCmd
) & CmdClear
) | CmdReset
);
303 for (i
= 1000; i
> 0; i
--)
305 if ((BYTEIN(base
+ RTLr_ChipCmd
) & CmdReset
) == 0)
312 static void rtl8139nic_get_mac(struct net_device
*unit
, char * addr
, BOOL fromROM
)
314 UBYTE
*base
= get_hwbase(unit
);
317 RTLD(bug("[%s] rtl8139nic_get_mac()\n",unit
->rtl8139u_name
))
320 int addr_len
= read_eeprom((IPTR
)base
, 0, 8) == 0x8129 ? 8 : 6;
322 for (i
= 0; i
< 3; i
++)
324 UWORD mac_curr
= read_eeprom((IPTR
)base
, i
+ 7, addr_len
);
325 addr
[mac_add
++] = mac_curr
& 0xff;
326 addr
[mac_add
++] = (mac_curr
>> 8) & 0xff;
332 mac_cur
= LONGIN(base
+ RTLr_MAC0
+ 0);
333 addr
[0] = mac_cur
& 0xFF;
334 addr
[1] = (mac_cur
>> 8) & 0xFF;
335 addr
[2] = (mac_cur
>> 16) & 0xFF;
336 addr
[3] = (mac_cur
>> 24) & 0xFF;
337 mac_cur
= LONGIN(base
+ RTLr_MAC0
+ 4);
338 addr
[4] = mac_cur
& 0xFF;
339 addr
[5] = (mac_cur
>> 8) & 0xFF;
343 static void rtl8139nic_set_mac(struct net_device
*unit
)
345 UBYTE
*base
= get_hwbase(unit
);
348 RTLD(bug("[%s] rtl8139nic_set_mac()\n",unit
->rtl8139u_name
))
350 BYTEOUT(base
+ RTLr_Cfg9346
, 0xc0);
352 LONGOUT(base
+ RTLr_MAC0
+ 0,
353 unit
->rtl8139u_dev_addr
[0] |
354 (unit
->rtl8139u_dev_addr
[1] << 8) |
355 (unit
->rtl8139u_dev_addr
[2] << 16) |
356 (unit
->rtl8139u_dev_addr
[3] << 24));
357 LONGOUT(base
+ RTLr_MAC0
+ 4,
358 unit
->rtl8139u_dev_addr
[4] |
359 (unit
->rtl8139u_dev_addr
[5] << 8));
361 BYTEOUT(base
+ RTLr_Cfg9346
, 0x00);
364 /* Read it back to be certain! */
366 rtl8139nic_get_mac(unit
, newmac
, FALSE
);
368 bug("[%s] rtl8139nic_set_mac: New MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit
->rtl8139u_name
,
369 newmac
[0], newmac
[1], newmac
[2],
370 newmac
[3], newmac
[4], newmac
[5]))
373 static void rtl8139nic_initialize(struct net_device
*unit
)
375 struct fe_priv
*np
= unit
->rtl8139u_fe_priv
;
376 UBYTE
*base
= get_hwbase(unit
);
380 config1
= BYTEIN(base
+ RTLr_Config1
);
381 if (unit
->rtl8139u_rtl_chipcapabilities
& RTLc_HAS_MII_XCVR
)
384 BYTEOUT(base
+ RTLr_Config1
, config1
& ~0x03);
386 RTLD(bug("[%s] Chipset brought out of low power mode.\n", unit
->rtl8139u_name
))
388 rtl8139nic_get_mac(unit
, np
->orig_mac
, TRUE
);
390 int phy
, phy_idx
= 0;
391 if (unit
->rtl8139u_rtl_chipcapabilities
& RTLc_HAS_MII_XCVR
)
393 for (phy
= 0; phy
< 32 && phy_idx
< sizeof(np
->mii_phys
); phy
++)
395 int mii_status
= mdio_read(unit
, phy
, 1);
396 if (mii_status
!= 0xffff && mii_status
!= 0x0000)
398 np
->mii_phys
[phy_idx
++] = phy
;
399 np
->advertising
= mdio_read(unit
, phy
, 4);
400 RTLD(bug("[%s] MII transceiver %d status 0x%4.4x advertising %4.4x\n", unit
->rtl8139u_name
,
401 phy
, mii_status
, np
->advertising
))
408 RTLD(bug("[%s] No MII transceiver found, Assuming SYM transceiver\n", unit
->rtl8139u_name
))
409 np
->mii_phys
[0] = 32;
412 unit
->rtl8139u_dev_addr
[0] = unit
->rtl8139u_org_addr
[0] = np
->orig_mac
[0];
413 unit
->rtl8139u_dev_addr
[1] = unit
->rtl8139u_org_addr
[1] = np
->orig_mac
[1];
414 unit
->rtl8139u_dev_addr
[2] = unit
->rtl8139u_org_addr
[2] = np
->orig_mac
[2];
415 unit
->rtl8139u_dev_addr
[3] = unit
->rtl8139u_org_addr
[3] = np
->orig_mac
[3];
416 unit
->rtl8139u_dev_addr
[4] = unit
->rtl8139u_org_addr
[4] = np
->orig_mac
[4];
417 unit
->rtl8139u_dev_addr
[5] = unit
->rtl8139u_org_addr
[5] = np
->orig_mac
[5];
419 RTLD(bug("[%s] MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit
->rtl8139u_name
,
420 unit
->rtl8139u_dev_addr
[0], unit
->rtl8139u_dev_addr
[1], unit
->rtl8139u_dev_addr
[2],
421 unit
->rtl8139u_dev_addr
[3], unit
->rtl8139u_dev_addr
[4], unit
->rtl8139u_dev_addr
[5]))
423 BYTEOUT(base
+ RTLr_Cfg9346
, 0xc0);
424 if (unit
->rtl8139u_rtl_chipcapabilities
& RTLc_HAS_MII_XCVR
)
427 BYTEOUT(base
+ RTLr_Config1
, 0x03);
429 BYTEOUT(base
+ RTLr_HltClk
, 'H'); //Disable the chips clock ('R' enables)
430 RTLD(bug("[%s] Chipset put into low power mode.\n", unit
->rtl8139u_name
))
433 static void rtl8139nic_drain_tx(struct net_device
*unit
)
435 // struct fe_priv *np = get_pcnpriv(unit);
438 // for (i = 0; i < NUM_TX_DESC; i++)
440 /* TODO: rtl8139nic_drain_tx does nothing atm. */
444 static void rtl8139nic_drain_rx(struct net_device
*unit
)
446 // struct fe_priv *np = get_pcnpriv(unit);
449 // for (i = 0; i < RX_RING_SIZE; i++)
451 /* TODO: rtl8139nic_drain_rx does nothing atm. */
456 static void drain_ring(struct net_device
*unit
)
458 rtl8139nic_drain_tx(unit
);
459 rtl8139nic_drain_rx(unit
);
462 static int request_irq(struct net_device
*unit
)
464 RTLD(bug("[%s] request_irq()\n", unit
->rtl8139u_name
))
466 if (!unit
->rtl8139u_IntsAdded
)
468 AddIntServer(INTB_KERNEL
+ unit
->rtl8139u_IRQ
,
469 &unit
->rtl8139u_irqhandler
);
470 AddIntServer(INTB_VERTB
, &unit
->rtl8139u_touthandler
);
471 unit
->rtl8139u_IntsAdded
= TRUE
;
473 RTLD(bug("[%s] request_irq: IRQ Handlers configured\n", unit
->rtl8139u_name
))
478 static void free_irq(struct net_device
*unit
)
480 if (unit
->rtl8139u_IntsAdded
)
482 RemIntServer(INTB_KERNEL
+ unit
->rtl8139u_IRQ
,
483 &unit
->rtl8139u_irqhandler
);
484 RemIntServer(INTB_VERTB
, &unit
->rtl8139u_touthandler
);
485 unit
->rtl8139u_IntsAdded
= FALSE
;
489 int rtl8139nic_set_rxmode(struct net_device
*unit
)
491 struct fe_priv
*np
= get_pcnpriv(unit
);
492 UBYTE
*base
= get_hwbase(unit
);
493 ULONG mc_filter
[2]; //Multicast hash filter.
496 RTLD(bug("[%s] rtl8139nic_set_rxmode(flags %x)\n", unit
->rtl8139u_name
, unit
->rtl8139u_flags
))
498 /* TODO: Fix set_rxmode.. doesnt load multicast list atm .. */
499 if (unit
->rtl8139u_flags
& IFF_PROMISC
)
501 RTLD(bug("[%s] rtl8139nic_set_rxmode: Mode: PROMISC\n",unit
->rtl8139u_name
))
502 rx_mode
= AcceptBroadcast
| AcceptMulticast
| AcceptMyPhys
| AcceptAllPhys
;
503 mc_filter
[1] = mc_filter
[0] = 0xffffffff;
505 else if (unit
->rtl8139u_flags
& IFF_ALLMULTI
)
507 RTLD(bug("[%s] rtl8139nic_set_rxmode: Mode: ALLMULTI\n",unit
->rtl8139u_name
))
508 rx_mode
= AcceptBroadcast
| AcceptMulticast
| AcceptMyPhys
;
509 mc_filter
[1] = mc_filter
[0] = 0xffffffff;
513 // struct mclist *mclist;
515 RTLD(bug("[%s] rtl8139nic_set_rxmode: Mode: DEFAULT\n",unit
->rtl8139u_name
))
517 rx_mode
= AcceptBroadcast
| AcceptMulticast
| AcceptMyPhys
;
518 /*if (unit->mc_count < multicast_filter_limit)
520 mc_filter
[1] = mc_filter
[0] = 0;
521 /*for (i = 0, mclist = dev->netif->mclist; mclist && i < dev->netif->mccount; i++, mclist = mclist->next)
523 set_bit(mc_filter, ether_crc(6, (unsigned char *) &mclist->hwaddr) >> 26);
528 mc_filter[1] = mc_filter[0] = 0xffffffff;
532 LONGOUT(base
+ RTLr_RxConfig
, np
->rx_config
| rx_mode
);
533 LONGOUT(base
+ RTLr_MAR0
+ 0, mc_filter
[0]);
534 LONGOUT(base
+ RTLr_MAR0
+ 4, mc_filter
[1]);
539 static int rtl8139nic_open(struct net_device
*unit
)
541 struct fe_priv
*np
= get_pcnpriv(unit
);
542 UBYTE
*base
= get_hwbase(unit
);
543 int ret
, i
, rx_buf_len_idx
;
545 rx_buf_len_idx
= RX_BUF_LEN_IDX
;
547 ret
= request_irq(unit
);
553 np
->rx_buf_len
= 8192 << rx_buf_len_idx
;
555 np
->rx_buffer
= HIDD_PCIDriver_AllocPCIMem(
556 unit
->rtl8139u_PCIDriver
,
557 (np
->rx_buf_len
+ 16 + (TX_BUF_SIZE
* NUM_TX_DESC
))
560 if (np
->rx_buffer
!= NULL
)
562 np
->tx_buffer
= HIDD_PCIDriver_AllocPCIMem(
563 unit
->rtl8139u_PCIDriver
,
564 (np
->rx_buf_len
+ 16 + (TX_BUF_SIZE
* NUM_TX_DESC
))
568 if ((np
->rx_buffer
!= NULL
) && (np
->tx_buffer
!= NULL
))
570 RTLD(bug("[%s] rtl8139nic_open: Allocated IO Buffers [ %d x Tx @ %x] [ Rx @ %x, %d bytes]\n",
572 NUM_TX_DESC
, np
->tx_buffer
,
573 np
->rx_buffer
, np
->rx_buf_len
))
575 np
->tx_dirty
= np
->tx_current
= 0;
577 for (i
= 0; i
< NUM_TX_DESC
; i
++)
579 np
->tx_pbuf
[i
] = NULL
;
580 np
->tx_buf
[i
] = np
->tx_buffer
+ (i
* TX_BUF_SIZE
);
582 RTLD(bug("[%s] rtl8139nic_open: TX Buffers initialised\n",unit
->rtl8139u_name
))
584 // Early Tx threshold: 256 bytes
585 np
->tx_flag
= (TX_FIFO_THRESH
<< 11) & 0x003f0000;
586 np
->rx_config
= (RX_FIFO_THRESH
<< 13) | (rx_buf_len_idx
<< 11) | (RX_DMA_BURST
<< 8);
588 BYTEOUT(base
+ RTLr_ChipCmd
, (BYTEIN(base
+ RTLr_ChipCmd
) & CmdClear
) | CmdReset
);
590 for (i
= 1000; i
> 0; i
--)
592 if ((BYTEIN(base
+ RTLr_ChipCmd
) & CmdReset
) == 0)
597 RTLD(bug("[%s] rtl8139nic_open: NIC Reset\n",unit
->rtl8139u_name
))
599 rtl8139nic_set_mac(unit
);
600 RTLD(bug("[%s] rtl8139nic_open: copied MAC address\n",unit
->rtl8139u_name
))
605 BYTEOUT(base
+ RTLr_Cfg9346
, 0xc0);
607 //Enable Tx/Rx so we can set the config(s)
608 BYTEOUT(base
+ RTLr_ChipCmd
, (BYTEIN(base
+ RTLr_ChipCmd
) & CmdClear
) |
609 CmdRxEnb
| CmdTxEnb
);
610 LONGOUT(base
+ RTLr_RxConfig
, np
->rx_config
);
611 LONGOUT(base
+ RTLr_TxConfig
, TX_DMA_BURST
<< 8);
613 RTLD(bug("[%s] rtl8139nic_open: Enabled Tx/Rx\n",unit
->rtl8139u_name
))
616 if (np
->mii_phys
[0] >= 0 || (unit
->rtl8139u_rtl_chipcapabilities
& RTLc_HAS_MII_XCVR
))
618 UWORD mii_reg5
= mdio_read(unit
, np
->mii_phys
[0], 5);
619 if (mii_reg5
!= 0xffff)
621 if (((mii_reg5
& 0x0100) == 0x0100) || ((mii_reg5
& 0x00c0) == 0x0040))
627 if ((mii_reg5
== 0 ) || !(mii_reg5
& 0x0180))
629 unit
->rtl8139u_rtl_LinkSpeed
= 10000000;
633 unit
->rtl8139u_rtl_LinkSpeed
= 100000000;
636 RTLD(bug("[%s] rtl8139nic_open: Setting %s%s-duplex based on auto-neg partner ability %4.4x\n",unit
->rtl8139u_name
,
637 mii_reg5
== 0 ? "" : (mii_reg5
& 0x0180) ? "100mbps " : "10mbps ",
638 np
->full_duplex
? "full" : "half", mii_reg5
))
641 if (unit
->rtl8139u_rtl_chipcapabilities
& RTLc_HAS_MII_XCVR
)
644 BYTEOUT(base
+ RTLr_Config1
, np
->full_duplex
? 0x60 : 0x20);
647 BYTEOUT(base
+ RTLr_Cfg9346
, 0x00);
649 LONGOUT(base
+ RTLr_RxBuf
, (IPTR
)np
->rx_buffer
);
651 //Start the chips Tx/Rx processes
652 LONGOUT(base
+ RTLr_RxMissed
, 0);
654 rtl8139nic_set_rxmode(unit
);
656 WORDOUT(base
+ RTLr_MultiIntr
, WORDIN(RTLr_MultiIntr
) & MultiIntrClear
);
658 BYTEOUT(base
+ RTLr_ChipCmd
, (BYTEIN(base
+ RTLr_ChipCmd
) & CmdClear
) |
659 CmdRxEnb
| CmdTxEnb
);
661 // Enable all known interrupts by setting the interrupt mask ..
662 WORDOUT(base
+ RTLr_IntrMask
, PCIErr
|
672 unit
->rtl8139u_flags
|= IFF_UP
;
673 ReportEvents(LIBBASE
, unit
, S2EVENT_ONLINE
);
674 RTLD(bug("[%s] rtl8139nic_open: Device set as ONLINE\n",unit
->rtl8139u_name
))
683 static int rtl8139nic_close(struct net_device
*unit
)
685 struct fe_priv
*np
= get_pcnpriv(unit
);
687 unit
->rtl8139u_flags
&= ~IFF_UP
;
689 ObtainSemaphore(&np
->lock
);
691 ReleaseSemaphore(&np
->lock
);
693 unit
->rtl8139u_toutNEED
= FALSE
;
695 ObtainSemaphore(&np
->lock
);
697 rtl8139nic_deinitialize(unit
); // Stop the chipset and set it in 16bit-mode
699 ReleaseSemaphore(&np
->lock
);
705 HIDD_PCIDriver_FreePCIMem(unit
->rtl8139u_PCIDriver
, np
->rx_buffer
);
706 HIDD_PCIDriver_FreePCIMem(unit
->rtl8139u_PCIDriver
, np
->tx_buffer
);
708 ReportEvents(LIBBASE
, unit
, S2EVENT_OFFLINE
);
714 void rtl8139nic_get_functions(struct net_device
*Unit
)
716 Unit
->initialize
= rtl8139nic_initialize
;
717 Unit
->deinitialize
= rtl8139nic_deinitialize
;
718 Unit
->start
= rtl8139nic_open
;
719 Unit
->stop
= rtl8139nic_close
;
720 Unit
->set_mac_address
= rtl8139nic_set_mac
;
721 Unit
->set_multicast
= rtl8139nic_set_multicast
;