/[dynamips]/trunk/dev_dec21140.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/dev_dec21140.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (11 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 28941 byte(s)
make working copy

1 /*
2 * Cisco router simlation platform.
3 * Copyright (C) 2005,2006 Christophe Fillot. All rights reserved.
4 *
5 * DEC21140 FastEthernet chip emulation.
6 *
7 * It allows to emulate a C7200-IO-FE card with 1 port and PA-FE-TX cards.
8 *
9 * Many many thanks to mtve (aka "Mtv Europe") for his great work on
10 * this stuff.
11 *
12 * Manuals:
13 *
14 * DECchip 21140 PCI fast Ethernet LAN controller Hardware reference manual
15 * http://ftp.nluug.nl/NetBSD/misc/dec-docs/ec-qc0cb-te.ps.gz
16 *
17 * National DP83840 PHY
18 * http://www.rezrov.net/docs/DP83840A.pdf
19 *
20 * Remark: only Big-endian mode is supported.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <errno.h>
30 #include <assert.h>
31
32 #include "crc.h"
33 #include "utils.h"
34 #include "cpu.h"
35 #include "vm.h"
36 #include "dynamips.h"
37 #include "memory.h"
38 #include "device.h"
39 #include "net.h"
40 #include "net_io.h"
41 #include "ptask.h"
42 #include "dev_dec21140.h"
43
44 /* Debugging flags */
45 #define DEBUG_MII_REGS 0
46 #define DEBUG_CSR_REGS 0
47 #define DEBUG_PCI_REGS 0
48 #define DEBUG_TRANSMIT 0
49 #define DEBUG_RECEIVE 0
50
51 /* DEC21140 PCI vendor/product codes */
52 #define DEC21140_PCI_VENDOR_ID 0x1011
53 #define DEC21140_PCI_PRODUCT_ID 0x0009
54
55 /* DEC21140 PCI registers */
56 #define DEC21140_PCI_CFID_REG_OFFSET 0x00
57 #define DEC21140_PCI_CFCS_REG_OFFSET 0x04
58 #define DEC21140_PCI_CFRV_REG_OFFSET 0x08
59 #define DEC21140_PCI_CFLT_REG_OFFSET 0x0C
60 #define DEC21140_PCI_CBIO_REG_OFFSET 0x10
61 #define DEC21140_PCI_CBMA_REG_OFFSET 0x14
62 #define DEC21140_PCI_CFIT_REG_OFFSET 0x3C
63 #define DEC21140_PCI_CFDA_REG_OFFSET 0x40
64
65 /* Number of CSR registers */
66 #define DEC21140_CSR_NR 16
67
68 /* CSR5: Status Register */
69 #define DEC21140_CSR5_TI 0x00000001 /* TX Interrupt */
70 #define DEC21140_CSR5_TPS 0x00000002 /* TX Process Stopped */
71 #define DEC21140_CSR5_TU 0x00000004 /* TX Buffer Unavailable */
72 #define DEC21140_CSR5_TJT 0x00000008 /* TX Jabber Timeout */
73 #define DEC21140_CSR5_UNF 0x00000020 /* TX Underflow */
74 #define DEC21140_CSR5_RI 0x00000040 /* RX Interrupt */
75 #define DEC21140_CSR5_RU 0x00000080 /* RX Buffer Unavailable */
76 #define DEC21140_CSR5_RPS 0x00000100 /* RX Process Stopped */
77 #define DEC21140_CSR5_RWT 0x00000200 /* RX Watchdog Timeout */
78 #define DEC21140_CSR5_GTE 0x00000800 /* Gen Purpose Timer Expired */
79 #define DEC21140_CSR5_FBE 0x00002000 /* Fatal Bus Error */
80 #define DEC21140_CSR5_AIS 0x00008000 /* Abnormal Interrupt Summary */
81 #define DEC21140_CSR5_NIS 0x00010000 /* Normal Interrupt Summary */
82
83 #define DEC21140_NIS_BITS \
84 (DEC21140_CSR5_TI|DEC21140_CSR5_RI|DEC21140_CSR5_TU)
85
86 #define DEC21140_AIS_BITS \
87 (DEC21140_CSR5_TPS|DEC21140_CSR5_TJT|DEC21140_CSR5_UNF| \
88 DEC21140_CSR5_RU|DEC21140_CSR5_RPS|DEC21140_CSR5_RWT| \
89 DEC21140_CSR5_GTE|DEC21140_CSR5_FBE)
90
91 #define DEC21140_CSR5_RS_SHIFT 17
92 #define DEC21140_CSR5_TS_SHIFT 20
93
94 /* CSR6: Operating Mode Register */
95 #define DEC21140_CSR6_START_RX 0x00000002
96 #define DEC21140_CSR6_START_TX 0x00002000
97 #define DEC21140_CSR6_PROMISC 0x00000040
98
99 /* CSR9: Serial EEPROM and MII */
100 #define DEC21140_CSR9_RX_BIT 0x00080000
101 #define DEC21140_CSR9_MII_READ 0x00040000
102 #define DEC21140_CSR9_TX_BIT 0x00020000
103 #define DEC21140_CSR9_MDC_CLOCK 0x00010000
104 #define DEC21140_CSR9_READ 0x00004000
105 #define DEC21140_CSR9_WRITE 0x00002000
106
107 /* Maximum packet size */
108 #define DEC21140_MAX_PKT_SIZE 2048
109
110 /* Send up to 32 packets in a TX ring scan pass */
111 #define DEC21140_TXRING_PASS_COUNT 32
112
113 /* Setup frame size */
114 #define DEC21140_SETUP_FRAME_SIZE 192
115
116 /* RX descriptors */
117 #define DEC21140_RXDESC_OWN 0x80000000 /* Ownership */
118 #define DEC21140_RXDESC_LS 0x00000100 /* Last Segment */
119 #define DEC21140_RXDESC_FS 0x00000200 /* First Segment */
120 #define DEC21140_RXDESC_MF 0x00000400 /* Multicast Frame */
121 #define DEC21140_RXDESC_DE 0x00004000 /* Descriptor Error */
122 #define DEC21140_RXDESC_RCH 0x01000000 /* Sec. Addr. Chained */
123 #define DEC21140_RXDESC_RER 0x02000000 /* Receive End of Ring */
124 #define DEC21140_RXDESC_FL_SHIFT 16
125 #define DEC21140_RXDESC_LEN_MASK 0x7ff
126
127 /* TX descriptors */
128 #define DEC21140_TXDESC_OWN 0x80000000 /* Ownership */
129 #define DEC21140_TXDESC_TCH 0x01000000 /* Sec. Addr. Chained */
130 #define DEC21140_TXDESC_TER 0x02000000 /* Transmit End of Ring */
131 #define DEC21140_TXDESC_SET 0x08000000 /* Setup frame */
132 #define DEC21140_TXDESC_FS 0x20000000 /* First Segment */
133 #define DEC21140_TXDESC_LS 0x40000000 /* Last Segment */
134 #define DEC21140_TXDESC_IC 0x80000000 /* IRQ on completion */
135
136 #define DEC21140_TXDESC_LEN_MASK 0x7ff
137
138 /* RX Descriptor */
139 struct rx_desc {
140 m_uint32_t rdes[4];
141 };
142
143 /* TX Descriptor */
144 struct tx_desc {
145 m_uint32_t tdes[4];
146 };
147
148 /* DEC21140 Data */
149 struct dec21140_data {
150 char *name;
151
152 /* Physical addresses of current RX and TX descriptors */
153 m_uint32_t rx_current;
154 m_uint32_t tx_current;
155
156 /* CSR registers */
157 m_uint32_t csr[DEC21140_CSR_NR];
158
159 /* MII registers */
160 m_uint32_t mii_state;
161 m_uint32_t mii_phy;
162 m_uint32_t mii_reg;
163 m_uint32_t mii_data;
164 m_uint32_t mii_outbits;
165 m_uint16_t mii_regs[32][32];
166
167 /* Ethernet unicast addresses */
168 n_eth_addr_t mac_addr[16];
169 u_int mac_addr_count;
170
171 /* Device information */
172 struct vdevice *dev;
173
174 /* PCI device information */
175 struct pci_device *pci_dev;
176
177 /* Virtual machine */
178 vm_instance_t *vm;
179
180 /* NetIO descriptor */
181 netio_desc_t *nio;
182
183 /* TX ring scanner task id */
184 ptask_id_t tx_tid;
185 };
186
187 /* Log a dec21140 message */
188 #define DEC21140_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
189
190 /* Check if a packet must be delivered to the emulated chip */
191 static inline int dec21140_handle_mac_addr(struct dec21140_data *d,
192 m_uint8_t *pkt)
193 {
194 n_eth_hdr_t *hdr = (n_eth_hdr_t *)pkt;
195 int i;
196
197 /* Accept systematically frames if we are running is promiscuous mode */
198 if (d->csr[6] & DEC21140_CSR6_PROMISC)
199 return(TRUE);
200
201 /* Accept systematically all multicast frames */
202 if (eth_addr_is_mcast(&hdr->daddr))
203 return(TRUE);
204
205 /* Accept frames directly for us, discard others */
206 for(i=0;i<d->mac_addr_count;i++)
207 if (!memcmp(&d->mac_addr[i],&hdr->daddr,N_ETH_ALEN))
208 return(TRUE);
209
210 return(FALSE);
211 }
212
213 /* Update MAC addresses */
214 static void dec21140_update_mac_addr(struct dec21140_data *d,
215 u_char *setup_frame)
216 {
217 n_eth_addr_t addr;
218 int i,nb_addr,addr_size;
219
220 d->mac_addr_count = 0;
221
222 addr_size = N_ETH_ALEN * 2;
223 nb_addr = DEC21140_SETUP_FRAME_SIZE / addr_size;
224
225 for(i=0;i<nb_addr;i++) {
226 addr.eth_addr_byte[0] = setup_frame[(i * addr_size) + 0];
227 addr.eth_addr_byte[1] = setup_frame[(i * addr_size) + 1];
228 addr.eth_addr_byte[2] = setup_frame[(i * addr_size) + 4];
229 addr.eth_addr_byte[3] = setup_frame[(i * addr_size) + 5];
230 addr.eth_addr_byte[4] = setup_frame[(i * addr_size) + 8];
231 addr.eth_addr_byte[5] = setup_frame[(i * addr_size) + 9];
232
233 if (!eth_addr_is_mcast(&addr)) {
234 memcpy(&d->mac_addr[d->mac_addr_count],&addr,N_ETH_ALEN);
235 DEC21140_LOG(d,"unicast MAC address: "
236 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
237 addr.eth_addr_byte[0],addr.eth_addr_byte[1],
238 addr.eth_addr_byte[2],addr.eth_addr_byte[3],
239 addr.eth_addr_byte[4],addr.eth_addr_byte[5]);
240 d->mac_addr_count++;
241 }
242 }
243 }
244
245 /* Get a PCI register name */
246 static char *pci_cfgreg_name(int reg)
247 {
248 static char *name[] = {
249 "FID", "FCS", "FRV", "FLT", "BIO", "BMA", "?", "?",
250 "?", "?", "?", "?", "?", "?", "?", "FIT", "FDA"
251 };
252
253 return((reg>=0) && (reg<=DEC21140_CSR_NR*4) && ((reg&3)==0) ?
254 name[reg>>2] : "?");
255 }
256
257 /*
258 * read from register of DP83840A PHY
259 */
260 static m_uint16_t mii_reg_read(struct dec21140_data *d)
261 {
262 #if DEBUG_MII_REGS
263 DEC21140_LOG(d,"MII PHY read %d reg %d\n",d->mii_phy,d->mii_reg);
264 #endif
265
266 /*
267 * if it's BASIC MODE STATUS REGISTER (BMSR) at address 0x1
268 * then tell them that "Link Status" is up and no troubles.
269 */
270 if (d->mii_reg == 1) {
271 if (d->nio != NULL)
272 return(0x04);
273 else
274 return(0x00);
275 }
276
277 return(d->mii_regs[d->mii_phy][d->mii_reg]);
278 }
279
280 /*
281 * write to register of DP83840A PHY
282 */
283 static void mii_reg_write(struct dec21140_data *d)
284 {
285 #if DEBUG_MII_REGS
286 DEC21140_LOG(d,"MII PHY write %d reg %d value %04x\n",
287 d->mii_phy,d->mii_reg,d->mii_data);
288 #endif
289 assert(d->mii_phy < 32);
290 assert(d->mii_reg < 32);
291 d->mii_regs[d->mii_phy][d->mii_reg] = d->mii_data;
292 }
293
294 /*
295 * process new bit sent by IOS to PHY.
296 */
297 static void mii_newbit(struct dec21140_data *d,int newbit)
298 {
299 #if DEBUG_MII_REGS
300 DEC21140_LOG(d,"MII state was %d\n",d->mii_state);
301 #endif
302
303 switch (d->mii_state) {
304 case 0: /* init */
305 d->mii_state = newbit ? 0 : 1;
306 d->mii_phy = 0;
307 d->mii_reg = 0;
308 d->mii_data = 0;
309 break;
310
311 case 1: /* already got 0 */
312 d->mii_state = newbit ? 2 : 0;
313 break;
314
315 case 2: /* already got attention */
316 d->mii_state = newbit ? 3 : 4;
317 break;
318
319 case 3: /* probably it's read */
320 d->mii_state = newbit ? 0 : 10;
321 break;
322
323 case 4: /* probably it's write */
324 d->mii_state = newbit ? 20 : 0;
325 break;
326
327 case 10: case 11: case 12: case 13: case 14:
328 case 20: case 21: case 22: case 23: case 24:
329 /* read or write state, read 5 bits of phy */
330 d->mii_phy <<= 1;
331 d->mii_phy |= newbit;
332 d->mii_state++;
333 break;
334
335 case 15: case 16: case 17: case 18: case 19:
336 case 25: case 26: case 27: case 28: case 29:
337 /* read or write state, read 5 bits of reg */
338 d->mii_reg <<= 1;
339 d->mii_reg |= newbit;
340 d->mii_state++;
341
342 if (d->mii_state == 20) {
343 /* read state, got everything */
344 d->mii_outbits = mii_reg_read (d) << 15; /* first bit will
345 * be thrown away!
346 */
347 d->mii_state = 0;
348 }
349
350 break;
351
352 case 30: /* write state, read first waiting bit */
353 d->mii_state = newbit ? 31 : 0;
354 break;
355
356 case 31: /* write state, read second waiting bit */
357 d->mii_state = newbit ? 0 : 32;
358 break;
359
360 case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39:
361 case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47:
362 /* write state, read 16 bits of data */
363 d->mii_data <<= 1;
364 d->mii_data |= newbit;
365 d->mii_state++;
366
367 if (d->mii_state == 48) {
368 /* write state, got everything */
369 mii_reg_write (d);
370 d->mii_state = 0;
371 }
372
373 break;
374 default:
375 DEC21140_LOG(d,"MII impossible state\n");
376 }
377
378 #if DEBUG_MII_REGS
379 DEC21140_LOG(d,"MII state now %d\n",d->mii_state);
380 #endif
381 }
382
383 /* Update the interrupt status */
384 static inline void dev_dec21140_update_irq_status(struct dec21140_data *d)
385 {
386 int trigger = FALSE;
387 m_uint32_t csr5;
388
389 /* Work on a temporary copy of csr5 */
390 csr5 = d->csr[5];
391
392 /* Compute Interrupt Summary */
393 csr5 &= ~(DEC21140_CSR5_AIS|DEC21140_CSR5_NIS);
394
395 if (csr5 & DEC21140_NIS_BITS) {
396 csr5 |= DEC21140_CSR5_NIS;
397 trigger = TRUE;
398 }
399
400 if (csr5 & DEC21140_AIS_BITS) {
401 csr5 |= DEC21140_CSR5_AIS;
402 trigger = TRUE;
403 }
404
405 d->csr[5] = csr5;
406
407 if (trigger)
408 pci_dev_trigger_irq(d->vm,d->pci_dev);
409 else
410 pci_dev_clear_irq(d->vm,d->pci_dev);
411 }
412
413 /*
414 * dev_dec21140_access()
415 */
416 void *dev_dec21140_access(cpu_gen_t *cpu,struct vdevice *dev,
417 m_uint32_t offset,u_int op_size,u_int op_type,
418 m_uint64_t *data)
419 {
420 struct dec21140_data *d = dev->priv_data;
421 u_int reg;
422
423 /* which CSR register ? */
424 reg = offset / 8;
425
426 if ((reg >= DEC21140_CSR_NR) || (offset % 8) != 0) {
427 cpu_log(cpu,d->name,"invalid access to offset 0x%x\n",offset);
428 return NULL;
429 }
430
431 if (op_type == MTS_READ) {
432 #if DEBUG_CSR_REGS
433 cpu_log(cpu,d->name,"read CSR%u value 0x%x\n",reg,d->csr[reg]);
434 #endif
435 switch(reg) {
436 case 5:
437 /* Dynamically construct CSR5 */
438 *data = 0;
439
440 if (d->csr[6] & DEC21140_CSR6_START_RX)
441 *data |= 0x03 << DEC21140_CSR5_RS_SHIFT;
442
443 if (d->csr[6] & DEC21140_CSR6_START_TX)
444 *data |= 0x03 << DEC21140_CSR5_TS_SHIFT;
445
446 *data |= d->csr[5];
447 break;
448
449 case 8:
450 /* CSR8 is cleared when read (missed frame counter) */
451 d->csr[reg] = 0;
452 *data = 0;
453 break;
454
455 default:
456 *data = d->csr[reg];
457 }
458 } else {
459 #if DEBUG_CSR_REGS
460 cpu_log(cpu,d->name,"write CSR%u value 0x%x\n",reg,(m_uint32_t)*data);
461 #endif
462 switch(reg) {
463 case 3:
464 d->csr[reg] = *data;
465 d->rx_current = d->csr[reg];
466 break;
467 case 4:
468 d->csr[reg] = *data;
469 d->tx_current = d->csr[reg];
470 break;
471 case 5:
472 d->csr[reg] &= ~(*data);
473 dev_dec21140_update_irq_status(d);
474 break;
475 case 9:
476 /*
477 * CSR9, probably they want to mess with MII PHY
478 * The protocol to PHY is like serial over one bit.
479 * We will ignore clock 0 of read or write.
480 *
481 * This whole code is needed only to tell IOS that "Link Status"
482 * bit in BMSR register of DP83840A PHY is set.
483 *
484 * Also it makes "sh contr f0/0" happy.
485 */
486 d->csr[reg] = *data;
487
488 if ((*data & ~DEC21140_CSR9_TX_BIT) == (DEC21140_CSR9_MII_READ|
489 DEC21140_CSR9_READ|DEC21140_CSR9_MDC_CLOCK)) {
490 /*
491 * read, pop one bit from mii_outbits
492 */
493 if (d->mii_outbits & (1<<31))
494 d->csr[9] |= DEC21140_CSR9_RX_BIT;
495 else
496 d->csr[9] &= ~DEC21140_CSR9_RX_BIT;
497 d->mii_outbits <<= 1;
498 } else if((*data&~DEC21140_CSR9_TX_BIT) ==
499 (DEC21140_CSR9_WRITE|DEC21140_CSR9_MDC_CLOCK)) {
500 /*
501 * write, we've got input, do state machine
502 */
503 mii_newbit(d,(*data&DEC21140_CSR9_TX_BIT) ? 1 : 0);
504 }
505 break;
506
507 default:
508 d->csr[reg] = *data;
509 }
510 }
511
512 return NULL;
513 }
514
515 /*
516 * Get the address of the next RX descriptor.
517 */
518 static m_uint32_t rxdesc_get_next(struct dec21140_data *d,m_uint32_t rxd_addr,
519 struct rx_desc *rxd)
520 {
521 m_uint32_t nrxd_addr;
522
523 /* go to the next descriptor */
524 if (rxd->rdes[1] & DEC21140_RXDESC_RER)
525 nrxd_addr = d->csr[3];
526 else {
527 if (rxd->rdes[1] & DEC21140_RXDESC_RCH)
528 nrxd_addr = rxd->rdes[3];
529 else
530 nrxd_addr = rxd_addr + sizeof(struct rx_desc);
531 }
532
533 return(nrxd_addr);
534 }
535
536 /* Read a RX descriptor */
537 static void rxdesc_read(struct dec21140_data *d,m_uint32_t rxd_addr,
538 struct rx_desc *rxd)
539 {
540 /* get the next descriptor from VM physical RAM */
541 physmem_copy_from_vm(d->vm,rxd,rxd_addr,sizeof(struct rx_desc));
542
543 /* byte-swapping */
544 rxd->rdes[0] = vmtoh32(rxd->rdes[0]);
545 rxd->rdes[1] = vmtoh32(rxd->rdes[1]);
546 rxd->rdes[2] = vmtoh32(rxd->rdes[2]);
547 rxd->rdes[3] = vmtoh32(rxd->rdes[3]);
548 }
549
550 /*
551 * Try to acquire the specified RX descriptor. Returns TRUE if we have it.
552 * It assumes that the byte-swapping is done.
553 */
554 static inline int rxdesc_acquire(m_uint32_t rdes0)
555 {
556 return(rdes0 & DEC21140_RXDESC_OWN);
557 }
558
559 /* Put a packet in buffer(s) of a descriptor */
560 static void rxdesc_put_pkt(struct dec21140_data *d,struct rx_desc *rxd,
561 u_char **pkt,ssize_t *pkt_len)
562 {
563 ssize_t len1,len2,cp_len;
564
565 /* get rbs1 and rbs2 */
566 len1 = rxd->rdes[1] & DEC21140_RXDESC_LEN_MASK;
567 len2 = (rxd->rdes[1] >> 10) & DEC21140_RXDESC_LEN_MASK;
568
569 /* try with buffer #1 */
570 if (len1 != 0)
571 {
572 /* compute the data length to copy */
573 cp_len = m_min(len1,*pkt_len);
574
575 /* copy packet data to the VM physical RAM */
576 physmem_copy_to_vm(d->vm,*pkt,rxd->rdes[2],cp_len);
577
578 *pkt += cp_len;
579 *pkt_len -= cp_len;
580 }
581
582 /* try with buffer #2 */
583 if ((len2 != 0) && !(rxd->rdes[1] & DEC21140_RXDESC_RCH))
584 {
585 /* compute the data length to copy */
586 cp_len = m_min(len2,*pkt_len);
587
588 /* copy packet data to the VM physical RAM */
589 physmem_copy_to_vm(d->vm,*pkt,rxd->rdes[3],cp_len);
590
591 *pkt += cp_len;
592 *pkt_len -= cp_len;
593 }
594 }
595
596 /*
597 * Put a packet in the RX ring of the DEC21140.
598 */
599 static int dev_dec21140_receive_pkt(struct dec21140_data *d,
600 u_char *pkt,ssize_t pkt_len)
601 {
602 m_uint32_t rx_start,rxdn_addr,rxdn_rdes0;
603 struct rx_desc rxd0,rxdn,*rxdc;
604 ssize_t tot_len = pkt_len;
605 u_char *pkt_ptr = pkt;
606 n_eth_hdr_t *hdr;
607 int i;
608
609 /* Truncate the packet if it is too big */
610 pkt_len = m_min(pkt_len,DEC21140_MAX_PKT_SIZE);
611
612 /* Copy the current rxring descriptor */
613 rxdesc_read(d,d->rx_current,&rxd0);
614
615 /* We must have the first descriptor... */
616 if (!rxdesc_acquire(rxd0.rdes[0]))
617 return(FALSE);
618
619 /* Remember the first RX descriptor address */
620 rx_start = d->rx_current;
621
622 for(i=0,rxdc=&rxd0;tot_len>0;i++)
623 {
624 /* Put data into the descriptor buffers */
625 rxdesc_put_pkt(d,rxdc,&pkt_ptr,&tot_len);
626
627 /* Get address of the next descriptor */
628 rxdn_addr = rxdesc_get_next(d,d->rx_current,rxdc);
629
630 /* We have finished if the complete packet has been stored */
631 if (tot_len == 0) {
632 rxdc->rdes[0] = DEC21140_RXDESC_LS;
633 rxdc->rdes[0] |= (pkt_len + 4) << DEC21140_RXDESC_FL_SHIFT;
634
635 /* if this is a multicast frame, set the appropriate bit */
636 hdr = (n_eth_hdr_t *)pkt;
637 if (eth_addr_is_mcast(&hdr->daddr))
638 rxdc->rdes[0] |= DEC21140_RXDESC_MF;
639
640 if (i != 0)
641 physmem_copy_u32_to_vm(d->vm,d->rx_current,rxdc->rdes[0]);
642
643 d->rx_current = rxdn_addr;
644 break;
645 }
646
647 /* Get status of the next descriptor to see if we can acquire it */
648 rxdn_rdes0 = physmem_copy_u32_from_vm(d->vm,rxdn_addr);
649
650 if (!rxdesc_acquire(rxdn_rdes0))
651 rxdc->rdes[0] = DEC21140_RXDESC_LS | DEC21140_RXDESC_DE;
652 else
653 rxdc->rdes[0] = 0; /* ok, no special flag */
654
655 /* Update the new status (only if we are not on the first desc) */
656 if (i != 0)
657 physmem_copy_u32_to_vm(d->vm,d->rx_current,rxdc->rdes[0]);
658
659 /* Update the RX pointer */
660 d->rx_current = rxdn_addr;
661
662 if (rxdc->rdes[0] != 0)
663 break;
664
665 /* Read the next descriptor from VM physical RAM */
666 rxdesc_read(d,rxdn_addr,&rxdn);
667 rxdc = &rxdn;
668 }
669
670 /* Update the first RX descriptor */
671 rxd0.rdes[0] |= DEC21140_RXDESC_FS;
672 physmem_copy_u32_to_vm(d->vm,rx_start,rxd0.rdes[0]);
673
674 /* Indicate that we have a frame ready */
675 d->csr[5] |= DEC21140_CSR5_RI;
676 dev_dec21140_update_irq_status(d);
677 return(TRUE);
678 }
679
680 /* Handle the DEC21140 RX ring */
681 static int dev_dec21140_handle_rxring(netio_desc_t *nio,
682 u_char *pkt,ssize_t pkt_len,
683 struct dec21140_data *d)
684 {
685 /*
686 * Don't start receive if the RX ring address has not been set
687 * and if the SR bit in CSR6 is not set yet.
688 */
689 if ((d->csr[3] == 0) || !(d->csr[6] & DEC21140_CSR6_START_RX))
690 return(FALSE);
691
692 #if DEBUG_RECEIVE
693 DEC21140_LOG(d,"receiving a packet of %d bytes\n",pkt_len);
694 mem_dump(log_file,pkt,pkt_len);
695 #endif
696
697 /*
698 * Receive only multicast/broadcast trafic + unicast traffic
699 * for this virtual machine.
700 */
701 if (dec21140_handle_mac_addr(d,pkt))
702 return(dev_dec21140_receive_pkt(d,pkt,pkt_len));
703
704 return(FALSE);
705 }
706
707 /* Read a TX descriptor */
708 static void txdesc_read(struct dec21140_data *d,m_uint32_t txd_addr,
709 struct tx_desc *txd)
710 {
711 /* get the descriptor from VM physical RAM */
712 physmem_copy_from_vm(d->vm,txd,txd_addr,sizeof(struct tx_desc));
713
714 /* byte-swapping */
715 txd->tdes[0] = vmtoh32(txd->tdes[0]);
716 txd->tdes[1] = vmtoh32(txd->tdes[1]);
717 txd->tdes[2] = vmtoh32(txd->tdes[2]);
718 txd->tdes[3] = vmtoh32(txd->tdes[3]);
719 }
720
721 /* Set the address of the next TX descriptor */
722 static void txdesc_set_next(struct dec21140_data *d,struct tx_desc *txd)
723 {
724 if (txd->tdes[1] & DEC21140_TXDESC_TER)
725 d->tx_current = d->csr[4];
726 else {
727 if (txd->tdes[1] & DEC21140_TXDESC_TCH)
728 d->tx_current = txd->tdes[3];
729 else
730 d->tx_current += sizeof(struct tx_desc);
731 }
732 }
733
734 /* Handle the TX ring (single packet) */
735 static int dev_dec21140_handle_txring_single(struct dec21140_data *d)
736 {
737 u_char pkt[DEC21140_MAX_PKT_SIZE],*pkt_ptr;
738 u_char setup_frame[DEC21140_SETUP_FRAME_SIZE];
739 m_uint32_t tx_start,len1,len2,clen,tot_len;
740 struct tx_desc txd0,ctxd,*ptxd;
741 int done = FALSE;
742
743 /*
744 * Don't start transmit if the txring address has not been set
745 * and if the ST bit in CSR6 is not set yet.
746 */
747 if ((d->csr[4] == 0) || (!(d->csr[6] & DEC21140_CSR6_START_TX)))
748 return(FALSE);
749
750 /* Copy the current txring descriptor */
751 tx_start = d->tx_current;
752 ptxd = &txd0;
753 txdesc_read(d,tx_start,ptxd);
754
755 /* If we don't own the first descriptor, we cannot transmit */
756 if (!(txd0.tdes[0] & DEC21140_TXDESC_OWN))
757 return(FALSE);
758
759 /*
760 * Ignore setup frames (clear the own bit and skip).
761 * We extract unicast MAC addresses to allow only appropriate traffic
762 * to pass.
763 */
764 if (!(txd0.tdes[1] & (DEC21140_TXDESC_FS|DEC21140_TXDESC_LS)))
765 {
766 len1 = ptxd->tdes[1] & DEC21140_TXDESC_LEN_MASK;
767 len2 = (ptxd->tdes[1] >> 11) & DEC21140_TXDESC_LEN_MASK;
768
769 if (txd0.tdes[1] & DEC21140_TXDESC_SET) {
770 physmem_copy_from_vm(d->vm,setup_frame,ptxd->tdes[2],
771 sizeof(setup_frame));
772 dec21140_update_mac_addr(d,setup_frame);
773 }
774
775 txdesc_set_next(d,ptxd);
776 goto clear_txd0_own_bit;
777 }
778
779 #if DEBUG_TRANSMIT
780 DEC21140_LOG(d,"dec21140_handle_txring: 1st desc: "
781 "tdes[0]=0x%x, tdes[1]=0x%x, tdes[2]=0x%x, tdes[3]=0x%x\n",
782 ptxd->tdes[0],ptxd->tdes[1],ptxd->tdes[2],ptxd->tdes[3]);
783 #endif
784
785 /* Empty packet for now */
786 pkt_ptr = pkt;
787 tot_len = 0;
788
789 do {
790 #if DEBUG_TRANSMIT
791 DEC21140_LOG(d,"dec21140_handle_txring: loop: "
792 "tdes[0]=0x%x, tdes[1]=0x%x, tdes[2]=0x%x, tdes[3]=0x%x\n",
793 ptxd->tdes[0],ptxd->tdes[1],ptxd->tdes[2],ptxd->tdes[3]);
794 #endif
795
796 if (!(ptxd->tdes[0] & DEC21140_TXDESC_OWN)) {
797 DEC21140_LOG(d,"dec21140_handle_txring: descriptor not owned!\n");
798 return(FALSE);
799 }
800
801 len1 = ptxd->tdes[1] & DEC21140_TXDESC_LEN_MASK;
802 len2 = (ptxd->tdes[1] >> 11) & DEC21140_TXDESC_LEN_MASK;
803 clen = len1 + len2;
804
805 /* Be sure that we have either len1 or len2 not null */
806 if (clen != 0)
807 {
808 if (len1 != 0)
809 physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->tdes[2],len1);
810
811 if ((len2 != 0) && !(ptxd->tdes[1] & DEC21140_TXDESC_TCH))
812 physmem_copy_from_vm(d->vm,pkt_ptr+len1,ptxd->tdes[3],len2);
813 }
814
815 pkt_ptr += clen;
816 tot_len += clen;
817
818 /* Clear the OWN bit if this is not the first descriptor */
819 if (!(ptxd->tdes[1] & DEC21140_TXDESC_FS))
820 physmem_copy_u32_to_vm(d->vm,d->tx_current,0);
821
822 /* Go to the next descriptor */
823 txdesc_set_next(d,ptxd);
824
825 /*
826 * Copy the next txring descriptor (ignore setup frames that
827 * have both FS and LS bit cleared).
828 */
829 if (!(ptxd->tdes[1] & (DEC21140_TXDESC_LS|DEC21140_TXDESC_SET))) {
830 txdesc_read(d,d->tx_current,&ctxd);
831 ptxd = &ctxd;
832 } else
833 done = TRUE;
834 }while(!done);
835
836 if (tot_len != 0) {
837 #if DEBUG_TRANSMIT
838 DEC21140_LOG(d,"sending packet of %u bytes\n",tot_len);
839 mem_dump(log_file,pkt,tot_len);
840 #endif
841 /* rewrite ISL header if required */
842 cisco_isl_rewrite(pkt,tot_len);
843
844 /* send it on wire */
845 netio_send(d->nio,pkt,tot_len);
846 }
847
848 clear_txd0_own_bit:
849 /* Clear the OWN flag of the first descriptor */
850 physmem_copy_u32_to_vm(d->vm,tx_start,0);
851
852 /* Interrupt on completion ? */
853 if (txd0.tdes[1] & DEC21140_TXDESC_IC) {
854 d->csr[5] |= DEC21140_CSR5_TI;
855 dev_dec21140_update_irq_status(d);
856 }
857
858 return(TRUE);
859 }
860
861 /* Handle the TX ring */
862 static int dev_dec21140_handle_txring(struct dec21140_data *d)
863 {
864 int i;
865
866 for(i=0;i<DEC21140_TXRING_PASS_COUNT;i++)
867 if (!dev_dec21140_handle_txring_single(d))
868 break;
869
870 return(TRUE);
871 }
872
873 /*
874 * pci_dec21140_read()
875 *
876 * Read a PCI register.
877 */
878 static m_uint32_t pci_dec21140_read(cpu_gen_t *cpu,struct pci_device *dev,
879 int reg)
880 {
881 struct dec21140_data *d = dev->priv_data;
882
883 #if DEBUG_PCI_REGS
884 DEC21140_LOG(d,"read C%s(%u)\n",pci_cfgreg_name(reg),reg);
885 #endif
886
887 switch (reg) {
888 case DEC21140_PCI_CFID_REG_OFFSET:
889 return(0x00091011);
890 case DEC21140_PCI_CFRV_REG_OFFSET:
891 return(0x02000011);
892 case DEC21140_PCI_CBMA_REG_OFFSET:
893 return(d->dev->phys_addr);
894 default:
895 return(0);
896 }
897 }
898
899 /*
900 * pci_dec21140_write()
901 *
902 * Write a PCI register.
903 */
904 static void pci_dec21140_write(cpu_gen_t *cpu,struct pci_device *dev,
905 int reg,m_uint32_t value)
906 {
907 struct dec21140_data *d = dev->priv_data;
908
909 #if DEBUG_PCI_REGS
910 DEC21140_LOG(d,"write C%s(%u) value 0x%x\n",pci_cfgreg_name(reg),reg,value);
911 #endif
912
913 switch(reg) {
914 case DEC21140_PCI_CBMA_REG_OFFSET:
915 vm_map_device(cpu->vm,d->dev,(m_uint64_t)value);
916 DEC21140_LOG(d,"registers are mapped at 0x%x\n",value);
917 break;
918 }
919 }
920
921 /*
922 * dev_dec21140_init()
923 *
924 * Generic DEC21140 initialization code.
925 */
926 struct dec21140_data *dev_dec21140_init(vm_instance_t *vm,char *name,
927 struct pci_bus *pci_bus,int pci_device,
928 int irq)
929 {
930 struct dec21140_data *d;
931 struct pci_device *pci_dev;
932 struct vdevice *dev;
933
934 /* Allocate the private data structure for DEC21140 */
935 if (!(d = malloc(sizeof(*d)))) {
936 fprintf(stderr,"%s (DEC21140): out of memory\n",name);
937 return NULL;
938 }
939
940 memset(d,0,sizeof(*d));
941
942 /* Add as PCI device */
943 pci_dev = pci_dev_add(pci_bus,name,
944 DEC21140_PCI_VENDOR_ID,DEC21140_PCI_PRODUCT_ID,
945 pci_device,0,irq,
946 d,NULL,pci_dec21140_read,pci_dec21140_write);
947
948 if (!pci_dev) {
949 fprintf(stderr,"%s (DEC21140): unable to create PCI device.\n",name);
950 goto err_pci_dev;
951 }
952
953 /* Create the device itself */
954 if (!(dev = dev_create(name))) {
955 fprintf(stderr,"%s (DEC21140): unable to create device.\n",name);
956 goto err_dev;
957 }
958
959 d->name = name;
960 d->vm = vm;
961 d->pci_dev = pci_dev;
962 d->dev = dev;
963
964 /* Basic register setup */
965 d->csr[0] = 0xfff80000;
966 d->csr[5] = 0xfc000000;
967 d->csr[8] = 0xfffe0000;
968
969 dev->phys_addr = 0;
970 dev->phys_len = 0x20000;
971 dev->handler = dev_dec21140_access;
972 dev->priv_data = d;
973 return(d);
974
975 err_dev:
976 pci_dev_remove(pci_dev);
977 err_pci_dev:
978 free(d);
979 return NULL;
980 }
981
982 /* Remove a DEC21140 device */
983 void dev_dec21140_remove(struct dec21140_data *d)
984 {
985 if (d != NULL) {
986 pci_dev_remove(d->pci_dev);
987 vm_unbind_device(d->vm,d->dev);
988 cpu_group_rebuild_mts(d->vm->cpu_group);
989 free(d->dev);
990 free(d);
991 }
992 }
993
994 /* Bind a NIO to DEC21140 device */
995 int dev_dec21140_set_nio(struct dec21140_data *d,netio_desc_t *nio)
996 {
997 /* check that a NIO is not already bound */
998 if (d->nio != NULL)
999 return(-1);
1000
1001 d->nio = nio;
1002 d->tx_tid = ptask_add((ptask_callback)dev_dec21140_handle_txring,d,NULL);
1003 netio_rxl_add(nio,(netio_rx_handler_t)dev_dec21140_handle_rxring,d,NULL);
1004 return(0);
1005 }
1006
1007 /* Unbind a NIO from a DEC21140 device */
1008 void dev_dec21140_unset_nio(struct dec21140_data *d)
1009 {
1010 if (d->nio != NULL) {
1011 ptask_remove(d->tx_tid);
1012 netio_rxl_remove(d->nio);
1013 d->nio = NULL;
1014 }
1015 }

  ViewVC Help
Powered by ViewVC 1.1.26