1#include <compiler.h>
2#include <console/printf.h>
3#include <drivers/e1000.h>
4#include <drivers/mmio.h>
5#include <drivers/pci.h>
6#include <mem/alloc.h>
7#include <mem/alloc_or_die.h>
8#include <mem/page.h>
9#include <mem/pmm.h>
10#include <mem/vmm.h>
11#include <stdbool.h>
12#include <stdint.h>
13#include <string.h>
14#include <time/spin_sleep.h>
15
16LOG_HANDLE_DECLARE_DEFAULT(e1000);
17LOG_SITE_DECLARE_DEFAULT(e1000);
18
19#define E1000_MAX_TX_PACKET_SIZE 1518
20#define REG32(dev, offset) (&(dev->regs[(offset) / 4U]))
21
22static void e1000_reset(struct e1000_device *dev) {
23 mmio_write_32(REG32(dev, E1000_REG_CTRL), E1000_CTRL_RST);
24 sleep_spin_ms(msec: 1);
25}
26
27static void e1000_setup_tx_ring(struct e1000_device *dev) {
28 uint64_t space = sizeof(struct e1000_tx_desc) * E1000_NUM_TX_DESC;
29 dev->tx_descs_phys = pmm_alloc_page();
30 dev->tx_descs = mmio_map(phys: dev->tx_descs_phys, size: space);
31 memset(dev->tx_descs, 0, space);
32
33 for (int i = 0; i < E1000_NUM_TX_DESC; i++) {
34 dev->tx_buffers[i] = kmalloc_or_die(2048);
35
36 dev->tx_descs[i].addr =
37 vmm_get_phys((uintptr_t) dev->tx_buffers[i], VMM_FLAG_NONE);
38 dev->tx_descs[i].status = E1000_TXD_STAT_DD;
39 }
40
41 mmio_write_32(REG32(dev, E1000_REG_TDBAL),
42 value: (uint32_t) (dev->tx_descs_phys & 0xFFFFFFFF));
43 mmio_write_32(REG32(dev, E1000_REG_TDBAH),
44 value: (uint32_t) (dev->tx_descs_phys >> 32));
45 mmio_write_32(REG32(dev, E1000_REG_TDLEN),
46 E1000_NUM_TX_DESC * sizeof(struct e1000_tx_desc));
47 mmio_write_32(REG32(dev, E1000_REG_TDH), value: 0);
48 mmio_write_32(REG32(dev, E1000_REG_TDT), value: 0);
49 dev->tx_tail = 0;
50
51 mmio_write_32(REG32(dev, E1000_REG_TCTL),
52 E1000_TCTL_EN | E1000_TCTL_PSP |
53 (0x10 << E1000_TCTL_CT_SHIFT) |
54 (0x40 << E1000_TCTL_COLD_SHIFT));
55}
56
57static void e1000_setup_rx_ring(struct e1000_device *dev) {
58 uint64_t space = sizeof(struct e1000_rx_desc) * E1000_NUM_RX_DESC;
59 dev->rx_descs_phys = pmm_alloc_page();
60 dev->rx_descs = mmio_map(phys: dev->rx_descs_phys, size: space);
61 memset(dev->rx_descs, 0, space);
62
63 for (int i = 0; i < E1000_NUM_RX_DESC; i++) {
64 dev->rx_buffers[i] = kmalloc_or_die(E1000_RX_BUF_SIZE);
65
66 dev->rx_descs[i].addr =
67 vmm_get_phys((uintptr_t) dev->rx_buffers[i], VMM_FLAG_NONE);
68 dev->rx_descs[i].status = 0;
69 }
70
71 mmio_write_32(REG32(dev, E1000_REG_RDBAL),
72 value: (uint32_t) (dev->rx_descs_phys & 0xFFFFFFFF));
73 mmio_write_32(REG32(dev, E1000_REG_RDBAH),
74 value: (uint32_t) (dev->rx_descs_phys >> 32));
75 mmio_write_32(REG32(dev, E1000_REG_RDLEN),
76 E1000_NUM_RX_DESC * sizeof(struct e1000_rx_desc));
77 mmio_write_32(REG32(dev, E1000_REG_RDH), value: 0);
78 mmio_write_32(REG32(dev, E1000_REG_RDT), E1000_NUM_RX_DESC - 1);
79 dev->rx_tail = E1000_NUM_RX_DESC - 1;
80
81 mmio_write_32(REG32(dev, E1000_REG_RCTL),
82 E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SECRC);
83}
84
85int e1000_send_packet(struct e1000_device *dev, const void *data,
86 uint64_t len) {
87 if (len > E1000_MAX_TX_PACKET_SIZE) {
88 return -1;
89 }
90
91 uint32_t next = dev->tx_tail;
92 struct e1000_tx_desc *desc = &dev->tx_descs[next];
93
94 if (!(desc->status & E1000_TXD_STAT_DD)) {
95 return -1;
96 }
97
98 memcpy(dev->tx_buffers[next], data, len);
99
100 desc->length = (uint16_t) len;
101 desc->cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS | E1000_TXD_CMD_RS;
102 desc->status = 0;
103
104 dev->tx_tail = (next + 1) % E1000_NUM_TX_DESC;
105 mmio_write_32(REG32(dev, E1000_REG_TDT), value: dev->tx_tail);
106
107 return 0;
108}
109
110static inline uint16_t htons(uint16_t hostshort) {
111 return (hostshort << 8) | (hostshort >> 8);
112}
113
114static inline uint32_t htonl(uint32_t hostlong) {
115 return ((hostlong << 24) & 0xFF000000) | ((hostlong << 8) & 0x00FF0000) |
116 ((hostlong >> 8) & 0x0000FF00) | ((hostlong >> 24) & 0x000000FF);
117}
118
119static uint16_t checksum(void *data, int len) {
120 uint32_t sum = 0;
121 uint16_t *ptr = (uint16_t *) data;
122 while (len > 1) {
123 sum += *ptr++;
124 len -= 2;
125 }
126 if (len > 0)
127 sum += *((uint8_t *) ptr);
128 while (sum >> 16)
129 sum = (sum & 0xFFFF) + (sum >> 16);
130 return (uint16_t) (~sum);
131}
132
133void send_hardcoded_ping(struct e1000_device *dev) {
134 uint8_t packet[14 + 20 + 8 + 32];
135 memset(packet, 0, sizeof(packet));
136
137 struct eth_hdr *eth = (void *) packet;
138 struct ipv4_hdr *ip = (void *) (packet + 14);
139 struct icmp_hdr *icmp = (void *) (packet + 14 + 20);
140 uint8_t *payload = packet + 14 + 20 + 8;
141
142 uint8_t src_mac[6] = {0x52, 0x54, 0x00, 0x12, 0x34, 0x56};
143 uint8_t dest_mac[6] = {0x52, 0x54, 0x00, 0x8e, 0x61, 0xf4};
144 ip->dest_ip = htonl(hostlong: 0xC0A87A01); // 192.168.122.1
145 ip->src_ip = htonl(hostlong: 0xC0A87A64); // 192.168.122.100
146
147 memcpy(eth->dest, dest_mac, 6);
148 memcpy(eth->src, src_mac, 6);
149 eth->ethertype = htons(hostshort: 0x0800);
150
151 ip->version_ihl = (4 << 4) | 5;
152 ip->tos = 0;
153 ip->total_length = htons(hostshort: 20 + 8 + 32);
154 ip->id = htons(hostshort: 0x1234);
155 ip->flags_fragment = 0;
156 ip->ttl = 64;
157 ip->protocol = 1;
158 ip->checksum = 0;
159 ip->checksum = checksum(data: ip, len: 20);
160
161 icmp->type = 8; // Echo request
162 icmp->code = 0;
163 icmp->identifier = htons(hostshort: 0x1);
164 icmp->sequence = htons(hostshort: 0x1);
165 memset(payload, 0xAA, 32); // dummy payload
166
167 icmp->checksum = 0;
168 icmp->checksum = checksum(data: icmp, len: 8 + 32);
169
170 e1000_send_packet(dev, data: packet, len: sizeof(packet));
171}
172
173bool e1000_init(struct pci_device *pci, struct e1000_device *dev) {
174 memset(dev, 0, sizeof(*dev));
175
176 dev->bus = pci->bus;
177 dev->device = pci->dev;
178 dev->function = pci->function;
179
180 e1000_log(LOG_INFO, "Found device at %02x:%02x.%02x", pci->bus, pci->dev,
181 pci->function);
182
183 uint32_t bar = pci_read(bus: dev->bus, slot: dev->device, func: dev->function, PCI_BAR0);
184 if (bar & 0x1)
185 return false; // Not MMIO
186
187 uint32_t phys_addr = bar & ~0xF;
188
189 pci_write(bus: dev->bus, slot: dev->device, func: dev->function, PCI_BAR0, value: 0xFFFFFFFF);
190 uint32_t bar_mask =
191 pci_read(bus: dev->bus, slot: dev->device, func: dev->function, PCI_BAR0);
192 pci_write(bus: dev->bus, slot: dev->device, func: dev->function, PCI_BAR0, value: bar);
193
194 uint64_t mmio_size = ~(bar_mask & ~0xF) + 1;
195 if (mmio_size == 0 || mmio_size > (1 << 24))
196 return false;
197
198 dev->regs = mmio_map(phys: phys_addr, size: mmio_size);
199 if (!dev->regs)
200 return false;
201
202 e1000_reset(dev);
203
204 e1000_setup_tx_ring(dev);
205 e1000_setup_rx_ring(dev);
206 send_hardcoded_ping(dev);
207 e1000_log(LOG_INFO, "Device initialized successfully");
208 return true;
209}
210
211static enum errno e1000_pci_init(struct device *dev) {
212 struct pci_device *db = dev->driver_data;
213 uint8_t bus = db->bus, d = db->dev, func = db->function;
214 uint16_t did = db->device_id;
215 if (did == 0x1000 || did == 0x100E || did == 0x1010 || did == 0x1026 ||
216 did == 0x10D3 || did == 0x10F5) {
217 struct pci_device dev = {.bus = bus, .dev = d, .function = func};
218 struct e1000_device *device =
219 kmalloc_or_die(sizeof(struct e1000_device));
220
221 e1000_init(pci: &dev, dev: device);
222 }
223
224 return ERR_OK;
225}
226
227PCI_DEV_REGISTER(e1000, 2, 0, 0xff, 0x8086, e1000_pci_init);
228