1/* @title: e1000 */
2#include <compiler/core.h>
3#include <drivers/pci.h>
4#include <log.h>
5#include <math/bit.h>
6#include <stdbool.h>
7#include <stdint.h>
8#pragma once
9// Register offsets
10#define E1000_REG_CTRL 0x0000
11#define E1000_REG_STATUS 0x0008
12#define E1000_REG_TCTL 0x0400
13#define E1000_REG_TDBAL 0x03800
14#define E1000_REG_TDBAH 0x03804
15#define E1000_REG_TDLEN 0x03808
16#define E1000_REG_TDH 0x03810
17#define E1000_REG_TDT 0x03818
18
19#define E1000_REG_RCTL 0x0100
20#define E1000_REG_RDBAL 0x02800
21#define E1000_REG_RDBAH 0x02804
22#define E1000_REG_RDLEN 0x02808
23#define E1000_REG_RDH 0x02810
24#define E1000_REG_RDT 0x02818
25
26#define E1000_REG_IMS 0x00D0
27#define E1000_REG_ICR 0x00C0
28
29// Transmit Control Register
30#define E1000_TCTL_EN BIT(1)
31#define E1000_TCTL_PSP BIT(3)
32#define E1000_TCTL_CT_SHIFT 4
33#define E1000_TCTL_COLD_SHIFT 12
34
35// Receive Control Register
36#define E1000_RCTL_EN BIT(1)
37#define E1000_RCTL_BAM BIT(15)
38#define E1000_RCTL_SECRC BIT(26)
39
40#define E1000_NUM_RX_DESC 64
41#define E1000_NUM_TX_DESC 64
42
43struct e1000_device {
44 uint32_t cc_mem_io *regs; // MMIO virtual base
45
46 // TX
47 struct e1000_tx_desc *tx_descs;
48 uintptr_t tx_descs_phys;
49 uint32_t tx_tail;
50 void *tx_buffers[E1000_NUM_TX_DESC]; // one per desc
51
52 // RX
53 struct e1000_rx_desc *rx_descs;
54 uintptr_t rx_descs_phys;
55 uint32_t rx_tail;
56 void *rx_buffers[E1000_NUM_RX_DESC];
57
58 // PCI location
59 uint8_t bus, device, function;
60};
61
62/* NOTE: offsets and sizes asserted in kernel/drivers/e1000_layout.c */
63struct e1000_tx_desc {
64 uint64_t addr;
65 uint16_t length;
66 uint8_t cso;
67 union {
68 uint8_t cmd;
69 struct {
70 uint8_t eop : 1;
71 uint8_t ifcs : 1;
72 uint8_t ic : 1;
73 uint8_t rs : 1;
74 uint8_t rsvd : 1;
75 uint8_t dext : 1;
76 uint8_t vlei : 1;
77 uint8_t ide : 1;
78 };
79 };
80 union {
81 uint8_t status;
82 struct {
83 uint8_t dd : 1;
84 uint8_t ec : 1;
85 uint8_t lc : 1;
86 uint8_t rsvd0 : 5;
87 };
88 };
89 uint8_t css;
90 uint16_t special;
91} cc_packed;
92
93struct e1000_rx_desc {
94 uint64_t addr;
95 uint16_t length;
96 uint16_t checksum;
97 union {
98 uint8_t status;
99 struct {
100 uint8_t dd : 1;
101 uint8_t eop : 1;
102 uint8_t ixsm : 1;
103 uint8_t vp : 1;
104 uint8_t rsvd : 4;
105 };
106 };
107 uint8_t errors;
108 uint16_t special;
109} cc_packed;
110
111// Ethernet header (14 bytes)
112struct eth_hdr {
113 uint8_t dest[6];
114 uint8_t src[6];
115 uint16_t ethertype;
116} cc_packed;
117
118// IPv4 header (20 bytes)
119struct ipv4_hdr {
120 uint8_t version_ihl;
121 uint8_t tos;
122 uint16_t total_length;
123 uint16_t id;
124 uint16_t flags_fragment;
125 uint8_t ttl;
126 uint8_t protocol;
127 uint16_t checksum;
128 uint32_t src_ip;
129 uint32_t dest_ip;
130} cc_packed;
131
132struct icmp_hdr {
133 uint8_t type;
134 uint8_t code;
135 uint16_t checksum;
136 uint16_t identifier;
137 uint16_t sequence;
138} cc_packed;
139
140#define E1000_TXD_CMD_EOP BIT(0)
141#define E1000_TXD_CMD_IFCS BIT(1)
142#define E1000_TXD_CMD_RS BIT(3)
143#define E1000_TXD_STAT_DD BIT(0)
144
145#define E1000_RXD_STAT_DD BIT(0)
146#define E1000_RXD_STAT_EOP BIT(1)
147#define E1000_CTRL_RST BIT(26) // Software reset
148
149#define E1000_BAR_INDEX 0
150#define PCI_BAR0 0x10
151
152#define E1000_RX_BUF_SIZE 2048
153
154bool e1000_init(struct pci_device *dev, struct e1000_device *out);
155#define E1000_MAX_TX_PACKET_SIZE 1518 // Standard Ethernet frame
156
157LOG_SITE_EXTERN(e1000);
158LOG_HANDLE_EXTERN(e1000);
159#define e1000_log(log_level, fmt, ...) \
160 log(LOG_SITE(e1000), LOG_HANDLE(e1000), log_level, fmt, ##__VA_ARGS__)
161