3 * Realtek 8139 ethernet card
5 * Copyright (C) 2009 Pawel Dziepak
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "manes/manec.h"
27 #include "services/interrupt_manager.h"
29 #include "arch/low/lowlevel.h"
30 #include "arch/low/hlt.h"
32 using namespace resources
;
34 extern p
<net::nic
> faar
;
36 bool rtl8139::init_device(p
<did
> id
) {
38 this->id
= *id
.cast
<pci_did
>();
45 bool rtl8139::check_device(p
<did
> id
) {
46 p
<pci_did
> pid
= id
.cast
<pci_did
>();
51 /* It must be an ethernet card */
52 unsigned int devclass
= pid
->get_devclass() >> 8;
53 if (devclass
!= 0x0200)
56 unsigned int devid
= pid
->get_devid();
57 /* It must be a *compatible* ethernet card */
58 if (devid
!= 0x813910ec)
64 void rtl8139::send_data(const buffer
&x
) {
69 net::mac_addr
rtl8139::get_haddr() const {
72 return net::mac_addr::from_be(*(u32
*)addr
, ((u16
*)addr
)[2]);
76 void rtl8139::irq_handler() {
77 u16 status
= id
.inw(isr
);
85 //rec.method(this, &rtl8139::receive_packet);
86 //manes::manec::get()->get<services::asynch_tasks>("/asnych_tasks")->add_task(rec);
92 arch::unlock_irqs(id
.irq
);
96 void rtl8139::init() {
98 manes::manec::get()->get
<services::interrupt_manager
>("/interrupt_manager")->register_interrupt(id
.irq
+ 0x20, delegate
<void>::method(this, &rtl8139::irq_handler
));
105 while (id
.inb(cmd
) & 0x10);
107 /* Prepare receive buffer */
108 rec_buffer
= new char[8192 + 16];
109 id
.outl(rbstart
, (u32
)rec_buffer
);
112 /* IRQ on Transmit OK and Receive OK */
114 id
.outw(isr
, 0xffff);
116 /* Configure receiver */
117 id
.outl(rec_conf
, 0xf | (1 << 7));
119 /* Enable receiver and transmitter */
123 void rtl8139::send_packet(const buffer
&x
) {
124 assert("rtl8139: packet is too big", x
.get_size() >= 0x700);
126 id
.outl(tsad0
+ send_index
* 4, (u32
)x
.get_address());
129 id
.outl(tsd0
+ send_index
* 4, x
.get_size());
133 void rtl8139::receive_packet() {
136 packet
*pkg
= (packet
*)((u32
)rec_buffer
+ id
.inl(capr
));
137 u32 size
= pkg
->size
;
138 u8
* buf
= new u8
[size
+ 4];
139 memcpy(buf
, pkg
, size
+ 4);
142 id
.outl(capr
, pkg
->size
);
147 receiver(buffer((void*)&pkg
[1], pkg
->size
));
152 void rtl8139::get_mac_addr(u8
*addr
) const {
153 for (int i
= 0; i
< 6; i
++)
158 void rtl8139::register_type() {
159 manes::manec::get()->register_driver
<rtl8139
>("rtl8139", "nic", delegate
<bool, p
<did
> >::function(&rtl8139::check_device
));