1 /*
2 * Copyright (c) 2013 Corey Tabaka
3 * Copyright (c) 2015 Travis Geiselbrecht
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 */
9
10 #include <lk/reg.h>
11 #include <lk/err.h>
12 #include <pcnet.h>
13 #include <lk/debug.h>
14 #include <lk/trace.h>
15 #include <assert.h>
16 #include <arch/x86.h>
17 #include <platform/pc.h>
18 #include <platform/pcnet.h>
19 #include <platform/interrupts.h>
20 #include <kernel/thread.h>
21 #include <kernel/mutex.h>
22 #include <kernel/event.h>
23 #include <dev/class/netif.h>
24 #include <dev/bus/pci.h>
25 #include <stdlib.h>
26 #include <malloc.h>
27 #include <string.h>
28 #include <lwip/pbuf.h>
29 #include <lk/init.h>
30
31 #define LOCAL_TRACE 0
32
33 #define PCNET_INIT_TIMEOUT 20000
34 #define MAX_PACKET_SIZE 1518
35
36 #define QEMU_IRQ_BUG_WORKAROUND 1
37
38 struct pcnet_state {
39 int irq;
40 addr_t base;
41
42 uint8_t padr[6];
43
44 struct init_block_32 *ib;
45
46 struct rd_style3 *rd;
47 struct td_style3 *td;
48
49 struct pbuf **rx_buffers;
50 struct pbuf **tx_buffers;
51
52 /* queue accounting */
53 int rd_head;
54 int td_head;
55 int td_tail;
56
57 int rd_count;
58 int td_count;
59
60 int tx_pending;
61
62 mutex_t tx_lock;
63
64 /* bottom half state */
65 event_t event;
66 event_t initialized;
67 bool done;
68
69 struct netstack_state *netstack_state;
70 };
71
72 static status_t pcnet_init(struct device *dev);
73 static status_t pcnet_read_pci_config(struct device *dev, pci_location_t loc);
74
75 static enum handler_return pcnet_irq_handler(void *arg);
76
77 static int pcnet_thread(void *arg);
78 static bool pcnet_service_tx(struct device *dev);
79 static bool pcnet_service_rx(struct device *dev);
80
81 static status_t pcnet_set_state(struct device *dev, struct netstack_state *state);
82 static ssize_t pcnet_get_hwaddr(struct device *dev, void *buf, size_t max_len);
83 static ssize_t pcnet_get_mtu(struct device *dev);
84
85 static status_t pcnet_output(struct device *dev, struct pbuf *p);
86
87 static struct netif_ops pcnet_ops = {
88 .std = {
89 .init = pcnet_init,
90 },
91
92 .set_state = pcnet_set_state,
93 .get_hwaddr = pcnet_get_hwaddr,
94 .get_mtu = pcnet_get_mtu,
95
96 .output = pcnet_output,
97 };
98
99 DRIVER_EXPORT(netif, &pcnet_ops.std);
100
pcnet_read_csr(struct device * dev,uint8_t rap)101 static inline uint32_t pcnet_read_csr(struct device *dev, uint8_t rap) {
102 struct pcnet_state *state = dev->state;
103
104 outpd(state->base + REG_RAP, rap);
105 return inpd(state->base + REG_RDP);
106 }
107
pcnet_write_csr(struct device * dev,uint8_t rap,uint16_t data)108 static inline void pcnet_write_csr(struct device *dev, uint8_t rap, uint16_t data) {
109 struct pcnet_state *state = dev->state;
110
111 outpd(state->base + REG_RAP, rap);
112 outpd(state->base + REG_RDP, data);
113 }
114
pcnet_read_bcr(struct device * dev,uint8_t rap)115 static inline uint32_t pcnet_read_bcr(struct device *dev, uint8_t rap) {
116 struct pcnet_state *state = dev->state;
117
118 outpd(state->base + REG_RAP, rap);
119 return inpd(state->base + REG_BDP);
120 }
121
pcnet_write_bcr(struct device * dev,uint8_t rap,uint16_t data)122 static inline void pcnet_write_bcr(struct device *dev, uint8_t rap, uint16_t data) {
123 struct pcnet_state *state = dev->state;
124
125 outpd(state->base + REG_RAP, rap);
126 outpd(state->base + REG_BDP, data);
127 }
128
pcnet_init(struct device * dev)129 static status_t pcnet_init(struct device *dev) {
130 status_t res = NO_ERROR;
131 pci_location_t loc;
132 int i;
133
134 const struct platform_pcnet_config *config = dev->config;
135
136 if (!config)
137 return ERR_NOT_CONFIGURED;
138
139 if (pci_bus_mgr_find_device(&loc, config->device_id, config->vendor_id, config->index) != _PCI_SUCCESSFUL) {
140 TRACEF("device not found\n");
141 return ERR_NOT_FOUND;
142 }
143
144 struct pcnet_state *state = calloc(1, sizeof(struct pcnet_state));
145 if (!state)
146 return ERR_NO_MEMORY;
147
148 dev->state = state;
149
150 res = pcnet_read_pci_config(dev, loc);
151 if (res)
152 goto error;
153
154 for (i=0; i < 6; i++)
155 state->padr[i] = inp(state->base + i);
156
157 LTRACEF("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", state->padr[0], state->padr[1], state->padr[2],
158 state->padr[3], state->padr[4], state->padr[5]);
159
160 /* put the controller into 32bit wide mode by performing a 32bit write to CSR0 */
161 outpd(state->base + 0, 0);
162
163 /* stop the controller for configuration */
164 pcnet_write_csr(dev, 0, CSR0_STOP);
165
166 /* setup 32bit (style 3) structures, burst, all CSR4 bits valid, TDM1[29] is ADD_FCS */
167 pcnet_write_csr(dev, 58, 3);
168
169 /* DMA plus enable */
170 pcnet_write_csr(dev, 4, pcnet_read_csr(dev, 4) | CSR4_DMAPLUS);
171
172 /* allocate 128 tx and 128 rx descriptor rings */
173 state->td_count = 128;
174 state->rd_count = 128;
175 state->td = memalign(16, state->td_count * DESC_SIZE);
176 state->rd = memalign(16, state->rd_count * DESC_SIZE);
177
178 state->rx_buffers = calloc(state->rd_count, sizeof(struct pbuf *));
179 state->tx_buffers = calloc(state->td_count, sizeof(struct pbuf *));
180
181 state->tx_pending = 0;
182
183 if (!state->td || !state->rd || !state->tx_buffers || !state->rx_buffers) {
184 res = ERR_NO_MEMORY;
185 goto error;
186 }
187
188 memset(state->td, 0, state->td_count * DESC_SIZE);
189 memset(state->rd, 0, state->rd_count * DESC_SIZE);
190
191 /* allocate temporary init block space */
192 state->ib = memalign(4, sizeof(struct init_block_32));
193 if (!state->ib) {
194 res = ERR_NO_MEMORY;
195 goto error;
196 }
197
198 LTRACEF("Init block addr: %p\n", state->ib);
199
200 /* setup init block */
201 state->ib->tlen = 7; // 128 descriptors
202 state->ib->rlen = 7; // 128 descriptors
203 state->ib->mode = 0;
204
205 state->ib->ladr = ~0;
206 state->ib->tdra = (uint32_t) state->td;
207 state->ib->rdra = (uint32_t) state->rd;
208
209 memcpy(state->ib->padr, state->padr, 6);
210
211 /* load the init block address */
212 pcnet_write_csr(dev, 1, (uint32_t) state->ib);
213 pcnet_write_csr(dev, 2, (uint32_t) state->ib >> 16);
214
215 /* setup receive descriptors */
216 for (i=0; i < state->rd_count; i++) {
217 //LTRACEF("Allocating pbuf %d\n", i);
218 struct pbuf *p = pbuf_alloc(PBUF_RAW, MAX_PACKET_SIZE, PBUF_RAM);
219
220 state->rd[i].rbadr = (uint32_t) p->payload;
221 state->rd[i].bcnt = -p->tot_len;
222 state->rd[i].ones = 0xf;
223 state->rd[i].own = 1;
224
225 state->rx_buffers[i] = p;
226 }
227
228 mutex_init(&state->tx_lock);
229
230 state->done = false;
231 event_init(&state->event, false, EVENT_FLAG_AUTOUNSIGNAL);
232 event_init(&state->initialized, false, 0);
233
234 /* start up a thread to process packet activity */
235 thread_resume(thread_create("[pcnet bh]", pcnet_thread, dev, DEFAULT_PRIORITY,
236 DEFAULT_STACK_SIZE));
237
238 register_int_handler(state->irq, pcnet_irq_handler, dev);
239 unmask_interrupt(state->irq);
240
241 #if QEMU_IRQ_BUG_WORKAROUND
242 register_int_handler(INT_BASE + 15, pcnet_irq_handler, dev);
243 unmask_interrupt(INT_BASE + 15);
244 #endif
245
246 /* wait for initialization to complete */
247 res = event_wait_timeout(&state->initialized, PCNET_INIT_TIMEOUT);
248 if (res) {
249 /* TODO: cancel bottom half thread and tear down device instance */
250 LTRACEF("Failed to wait for IDON: %d\n", res);
251 return res;
252 }
253
254 LTRACE_EXIT;
255 return res;
256
257 error:
258 LTRACEF("Error: %d\n", res);
259
260 if (state) {
261 free(state->td);
262 free(state->rd);
263 free(state->ib);
264 free(state->tx_buffers);
265 free(state->rx_buffers);
266 }
267
268 free(state);
269
270 return res;
271 }
272
pcnet_read_pci_config(struct device * dev,pci_location_t loc)273 static status_t pcnet_read_pci_config(struct device *dev, pci_location_t loc) {
274 status_t res = NO_ERROR;
275 pci_config_t config;
276 unsigned i;
277
278 DEBUG_ASSERT(dev->state);
279
280 struct pcnet_state *state = dev->state;
281
282 pci_read_config(loc, &config);
283
284 LTRACEF("Resources:\n");
285
286 for (i=0; i < countof(config.type0.base_addresses); i++) {
287 if (config.type0.base_addresses[i] & 0x1) {
288 LTRACEF(" BAR %d I/O REG: %04x\n", i, config.type0.base_addresses[i] & ~0x3);
289
290 state->base = config.type0.base_addresses[i] & ~0x3;
291 break;
292 }
293 }
294
295 if (!state->base) {
296 res = ERR_NOT_CONFIGURED;
297 goto error;
298 }
299
300 if (config.type0.interrupt_line != 0xff) {
301 LTRACEF(" IRQ %u\n", config.type0.interrupt_line);
302
303 state->irq = config.type0.interrupt_line + INT_BASE;
304 } else {
305 res = ERR_NOT_CONFIGURED;
306 goto error;
307 }
308
309 LTRACEF("Command: %04x\n", config.command);
310 LTRACEF("Status: %04x\n", config.status);
311
312 pci_write_config_half(loc, PCI_CONFIG_COMMAND,
313 (config.command | PCI_COMMAND_IO_EN | PCI_COMMAND_BUS_MASTER_EN) & ~PCI_COMMAND_MEM_EN);
314
315 error:
316 return res;
317 }
318
pcnet_irq_handler(void * arg)319 static enum handler_return pcnet_irq_handler(void *arg) {
320 struct device *dev = arg;
321 struct pcnet_state *state = dev->state;
322
323 mask_interrupt(state->irq);
324
325 #if QEMU_IRQ_BUG_WORKAROUND
326 mask_interrupt(INT_BASE + 15);
327 #endif
328
329 event_signal(&state->event, false);
330
331 return INT_RESCHEDULE;
332 }
333
pcnet_thread(void * arg)334 static int pcnet_thread(void *arg) {
335 DEBUG_ASSERT(arg);
336
337 struct device *dev = arg;
338 struct pcnet_state *state = dev->state;
339
340 /* kick off init, enable ints, and start operation */
341 pcnet_write_csr(dev, 0, CSR0_INIT | CSR0_IENA | CSR0_STRT);
342
343 while (!state->done) {
344 LTRACEF("Waiting for event.\n");
345 //event_wait_timeout(&state->event, 5000);
346 event_wait(&state->event);
347
348 int csr0 = pcnet_read_csr(dev, 0);
349
350 /* disable interrupts at the controller */
351 pcnet_write_csr(dev, 0, csr0 & ~CSR0_IENA);
352
353 LTRACEF("CSR0 = %04x\n", csr0);
354
355 #if LOCAL_TRACE
356 if (csr0 & CSR0_RINT) TRACEF("RINT\n");
357 if (csr0 & CSR0_TINT) TRACEF("TINT\n");
358 #endif
359
360 if (csr0 & CSR0_IDON) {
361 LTRACEF("IDON\n");
362
363 /* free the init block that we no longer need */
364 free(state->ib);
365 state->ib = NULL;
366
367 event_signal(&state->initialized, true);
368 }
369
370 if (csr0 & CSR0_ERR) {
371 LTRACEF("ERR\n");
372
373 /* TODO: handle errors, though not many need it */
374
375 /* clear flags, preserve necessary enables */
376 pcnet_write_csr(dev, 0, csr0 & (CSR0_TXON | CSR0_RXON | CSR0_IENA));
377 }
378
379 bool again = !!(csr0 & (CSR0_RINT | CSR0_TINT));
380 while (again) {
381 again = pcnet_service_tx(dev) | pcnet_service_rx(dev);
382 }
383
384 /* enable interrupts at the controller */
385 pcnet_write_csr(dev, 0, CSR0_IENA);
386 unmask_interrupt(state->irq);
387
388 #if QEMU_IRQ_BUG_WORKAROUND
389 unmask_interrupt(INT_BASE + 15);
390 #endif
391 }
392
393 return 0;
394 }
395
pcnet_service_tx(struct device * dev)396 static bool pcnet_service_tx(struct device *dev) {
397 LTRACE_ENTRY;
398
399 struct pcnet_state *state = dev->state;
400
401 mutex_acquire(&state->tx_lock);
402
403 struct td_style3 *td = &state->td[state->td_tail];
404
405 if (state->tx_pending && td->own == 0) {
406 struct pbuf *p = state->tx_buffers[state->td_tail];
407 DEBUG_ASSERT(p);
408
409 state->tx_buffers[state->td_tail] = NULL;
410
411 LTRACEF("Retiring packet: td_tail=%d p=%p tot_len=%u\n", state->td_tail, p, p->tot_len);
412
413 state->tx_pending--;
414 state->td_tail = (state->td_tail + 1) % state->td_count;
415
416 if (td->err) {
417 LTRACEF("Descriptor error status encountered\n");
418 hexdump8(td, sizeof(*td));
419 }
420
421 mutex_release(&state->tx_lock);
422
423 pbuf_free(p);
424
425 LTRACE_EXIT;
426 return true;
427 } else {
428 mutex_release(&state->tx_lock);
429
430 #if 0
431 LTRACEF("Nothing to do for TX.\n");
432 for (int i=0; i < state->td_count; i++)
433 printf("%d ", state->td[i].own);
434 printf("\n");
435 #endif
436
437 LTRACE_EXIT;
438 return false;
439 }
440 }
441
pcnet_service_rx(struct device * dev)442 static bool pcnet_service_rx(struct device *dev) {
443 LTRACE_ENTRY;
444
445 struct pcnet_state *state = dev->state;
446
447 struct rd_style3 *rd = &state->rd[state->rd_head];
448
449 if (rd->own == 0) {
450 struct pbuf *p = state->rx_buffers[state->rd_head];
451 DEBUG_ASSERT(p);
452
453 LTRACEF("Processing RX descriptor %d\n", state->rd_head);
454
455 if (rd->err) {
456 LTRACEF("Descriptor error status encountered\n");
457 hexdump8(rd, sizeof(*rd));
458 } else {
459 if (rd->mcnt <= p->tot_len) {
460
461 pbuf_realloc(p, rd->mcnt);
462
463 #if LOCAL_TRACE
464 LTRACEF("payload=%p len=%u\n", p->payload, p->tot_len);
465 hexdump8(p->payload, p->tot_len);
466 #endif
467
468 class_netstack_input(dev, state->netstack_state, p);
469
470 p = state->rx_buffers[state->rd_head] = pbuf_alloc(PBUF_RAW, MAX_PACKET_SIZE, PBUF_RAM);
471 } else {
472 LTRACEF("RX packet size error: mcnt = %u, buf len = %u\n", rd->mcnt, p->tot_len);
473 }
474 }
475
476 memset(rd, 0, sizeof(*rd));
477 memset(p->payload, 0, p->tot_len);
478
479 rd->rbadr = (uint32_t) p->payload;
480 rd->bcnt = -p->tot_len;
481 rd->ones = 0xf;
482 rd->own = 1;
483
484 state->rd_head = (state->rd_head + 1) % state->rd_count;
485
486 LTRACE_EXIT;
487 return true;
488 } else {
489 #if 0
490 LTRACEF("Nothing to do for RX: rd_head=%d.\n", state->rd_head);
491 for (int i=0; i < state->rd_count; i++)
492 printf("%d ", state->rd[i].own);
493 printf("\n");
494 #endif
495 }
496
497 LTRACE_EXIT;
498 return false;
499 }
500
pcnet_set_state(struct device * dev,struct netstack_state * netstack_state)501 static status_t pcnet_set_state(struct device *dev, struct netstack_state *netstack_state) {
502 if (!dev)
503 return ERR_INVALID_ARGS;
504
505 if (!dev->state)
506 return ERR_NOT_CONFIGURED;
507
508 struct pcnet_state *state = dev->state;
509
510 state->netstack_state = netstack_state;
511
512 return NO_ERROR;
513 }
514
pcnet_get_hwaddr(struct device * dev,void * buf,size_t max_len)515 static ssize_t pcnet_get_hwaddr(struct device *dev, void *buf, size_t max_len) {
516 if (!dev || !buf)
517 return ERR_INVALID_ARGS;
518
519 if (!dev->state)
520 return ERR_NOT_CONFIGURED;
521
522 struct pcnet_state *state = dev->state;
523
524 memcpy(buf, state->padr, MIN(sizeof(state->padr), max_len));
525
526 return sizeof(state->padr);
527 }
528
pcnet_get_mtu(struct device * dev)529 static ssize_t pcnet_get_mtu(struct device *dev) {
530 if (!dev)
531 return ERR_INVALID_ARGS;
532
533 return 1500;
534 }
535
pcnet_output(struct device * dev,struct pbuf * p)536 static status_t pcnet_output(struct device *dev, struct pbuf *p) {
537 LTRACE_ENTRY;
538
539 if (!dev || !p)
540 return ERR_INVALID_ARGS;
541
542 if (!dev->state)
543 return ERR_NOT_CONFIGURED;
544
545 status_t res = NO_ERROR;
546 struct pcnet_state *state = dev->state;
547
548 mutex_acquire(&state->tx_lock);
549
550 struct td_style3 *td = &state->td[state->td_head];
551
552 if (td->own) {
553 LTRACEF("TX descriptor ring full\n");
554 res = ERR_NOT_READY; // maybe this should be ERR_NOT_ENOUGH_BUFFER?
555 goto done;
556 }
557
558 pbuf_ref(p);
559 p = pbuf_coalesce(p, PBUF_RAW);
560
561 #if LOCAL_TRACE
562 LTRACEF("Queuing packet: td_head=%d p=%p tot_len=%u\n", state->td_head, p, p->tot_len);
563 hexdump8(p->payload, p->tot_len);
564 #endif
565
566 /* clear flags */
567 memset(td, 0, sizeof(*td));
568
569 td->tbadr = (uint32_t) p->payload;
570 td->bcnt = -p->tot_len;
571 td->stp = 1;
572 td->enp = 1;
573 td->add_no_fcs = 1;
574 td->ones = 0xf;
575
576 state->tx_buffers[state->td_head] = p;
577 state->tx_pending++;
578
579 state->td_head = (state->td_head + 1) % state->td_count;
580
581 td->own = 1;
582
583 /* trigger tx */
584 pcnet_write_csr(dev, 0, CSR0_TDMD);
585
586 done:
587 mutex_release(&state->tx_lock);
588 LTRACE_EXIT;
589 return res;
590 }
591
592 static const struct platform_pcnet_config pcnet0_config = {
593 .vendor_id = 0x1022,
594 .device_id = 0x2000,
595 .index = 0,
596 };
597
598 DEVICE_INSTANCE(netif, pcnet0, &pcnet0_config, 0);
599
pcnet_init_hook(uint level)600 static void pcnet_init_hook(uint level) {
601 status_t err = device_init(device_get_by_name(netif, pcnet0));
602 if (err < 0)
603 return;
604
605 class_netif_add(device_get_by_name(netif, pcnet0));
606 }
607
608 LK_INIT_HOOK(pcnet, &pcnet_init_hook, LK_INIT_LEVEL_PLATFORM);
609
610