/[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 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/dev_dec21140.c
File MIME type: text/plain
File size: 28021 byte(s)
dynamips-0.2.7-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26