/[dynamips]/upstream/dynamips-0.2.6-RC1/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 /upstream/dynamips-0.2.6-RC1/dev_dec21140.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Sat Oct 6 16:03:58 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 28124 byte(s)
import dynamips-0.2.6-RC1

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

  ViewVC Help
Powered by ViewVC 1.1.26