12using namespace MaxOS::common;
13using namespace MaxOS::drivers;
14using namespace MaxOS::drivers::ethernet;
15using namespace MaxOS::hardwarecommunication;
16using namespace memory;
25#define buffer8192 ((2 << 16) | (1 << 25))
37 control_register = 0x0000;
38 status_register = 0x0008;
39 eprom_register = 0x0014;
40 control_ext_register = 0x0018;
41 interrupt_mask_register = 0x00D0;
43 receive_control_register = 0x0100;
44 receive_descriptor_low_register = 0x2800;
45 receive_descriptor_high_register = 0x2804;
46 receive_descriptor_length_register = 0x2808;
47 receive_descriptor_head_register = 0x2810;
48 receive_descriptor_tail_register = 0x2818;
50 send_control_register = 0x0400;
51 send_descriptor_low_register = 0x3800;
52 send_descriptor_high_register = 0x3804;
53 send_descriptor_length_register = 0x3808;
54 send_descriptor_head_register = 0x3810;
55 send_descriptor_tail_register = 0x3818;
66 eprom_present = detect_ee_prom();
69 if (read_mac_address()) {
71 mac_address[4], mac_address[5]);
74 ASSERT(
false,
"ERROR, INIT FAILED, MAC ADDRESS NOT FOUND");
77 for (
int i = 0; i < 0x80; i++)
78 write(0x5200 + i * 4, 0);
85IntelI217::~IntelI217() =
default;
102 command_port.write(address);
103 data_port.write(data);
123 command_port.write(address);
124 return data_port.read();
130bool IntelI217::detect_ee_prom() {
133 write(eprom_register, 0x1);
135 for (
int i = 0; i < 1000; i++)
151 write(eprom_register, (1) | ((
uint32_t) (addr) << 8));
152 while (!((
tmp = read(eprom_register)) & (1 << 4)));
154 write(eprom_register, (1) | ((
uint32_t) (addr) << 2));
155 while (!((
tmp = read(eprom_register)) & (1 << 1)));
161bool IntelI217::read_mac_address() {
168 mac_address[0] =
temp &
195 for (
int i = 0; i < 6; i++)
203void IntelI217::receive_init() {
211 for (
int i = 0; i < 32; i++) {
214 receive_dsrctrs[i]->status = 0;
222 write(receive_descriptor_low_register, (
uint64_t)
ptr);
223 write(receive_descriptor_high_register, 0);
226 write(receive_descriptor_length_register, 32 * 16);
229 write(receive_descriptor_head_register,
231 write(receive_descriptor_tail_register,
234 current_receive_buffer = 0;
236 write(receive_control_register, (1 << 1)
251void IntelI217::send_init() {
260 for (
int i = 0; i < 8; i++) {
262 send_dsrctrs[i]->buffer_address = 0;
263 send_dsrctrs[i]->cmd = 0;
264 send_dsrctrs[i]->status = (1 << 0);
273 write(send_descriptor_length_register, 8 * 16);
277 write(send_descriptor_head_register, 0);
278 write(send_descriptor_tail_register, 0);
280 current_send_buffer = 0;
282 write(send_control_register, (1 << 1)
302 write(interrupt_mask_register, 0x1F6DC);
303 write(interrupt_mask_register, 0xff & ~4);
318 write(interrupt_mask_register, 0x1);
327 if (
temp & 0x80) fetch_data_received();
330void IntelI217::fetch_data_received() {
335 while ((receive_dsrctrs[current_receive_buffer]->status & 0x1)) {
336 auto* buffer = (
uint8_t*) receive_dsrctrs[current_receive_buffer]->buffer_address;
337 uint16_t size = receive_dsrctrs[current_receive_buffer]->length;
346 receive_dsrctrs[current_receive_buffer]->status = 0;
348 old_cur = current_receive_buffer;
349 current_receive_buffer = (current_receive_buffer + 1) % 32;
351 write(receive_descriptor_tail_register,
old_cur);
361 send_dsrctrs[current_send_buffer]->buffer_address = (
uint64_t) buffer;
362 send_dsrctrs[current_send_buffer]->length = size;
365 send_dsrctrs[current_send_buffer]->cmd = (1 << 0)
370 send_dsrctrs[current_send_buffer]->status = 0;
373 current_send_buffer = (current_send_buffer + 1) % 8;
374 write(send_descriptor_tail_register, current_send_buffer);
377 while (!(send_dsrctrs[
old_cur]->status & 0xff));
382 while (own_mac == 0);
400 return "E1000 (i217)";
Stores the left, top, width and height of a rectangle.
virtual uint32_t reset()
Reset the driver.
virtual void deactivate()
Deactivate the driver.
static MediaAccessControlAddress create_media_access_control_address(uint8_t digit1, uint8_t digit2, uint8_t digit3, uint8_t digit4, uint8_t digit5, uint8_t digit6)
Create a Media Access Control Address.
void fire_data_received(uint8_t *buffer, uint32_t size)
Handle the recieved data.
void deactivate() final
Deactivate the driver.
void do_send(uint8_t *buffer, uint32_t size) final
(Device Side) send the data
uint64_t get_media_access_control_address() final
Get the MAC address.
void activate() final
Activate the driver.
uint32_t reset() final
Reset the driver.
string device_name() final
Get the device name of the driver.
string vendor_name() final
Get who created the device.
IntelI217(hardwarecommunication::PCIDeviceDescriptor *device_descriptor)
Constructs a new Intel I217 Ethernet driver. Gets the MAC address and clears the receive descriptor a...
void handle_interrupt() final
Handles an interrupt.
Handles a certain interrupt number.
Stores information about a PCI device.
Handles 32 bit memory IO.
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
Driver for the Intel I217 Ethernet Controller.
struct PACKED MaxOS::drivers::ethernet::SendDescriptor send_descriptor_t
Alias for SendDescriptor struct.
struct PACKED MaxOS::drivers::ethernet::ReceiveDescriptor receive_descriptor_t
Alias for ReceiveDescriptor struct.
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.