/[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

Annotation of /trunk/dev_dec21140.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 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 dpavlin 1 /*
2 dpavlin 7 * Cisco router simlation platform.
3 dpavlin 1 * 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 dpavlin 7 #include "cpu.h"
35     #include "vm.h"
36 dpavlin 1 #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 dpavlin 2 /* Send up to 32 packets in a TX ring scan pass */
91     #define DEC21140_TXRING_PASS_COUNT 32
92 dpavlin 1
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 dpavlin 7 void *dev_dec21140_access(cpu_gen_t *cpu,struct vdevice *dev,
400 dpavlin 1 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 dpavlin 2 switch(reg) {
419     case 5:
420     /* Dynamically construct CSR5 */
421     *data = 0;
422 dpavlin 1
423 dpavlin 2 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 dpavlin 1
432 dpavlin 2 case 8:
433 dpavlin 4 /* CSR8 is cleared when read (missed frame counter) */
434 dpavlin 2 d->csr[reg] = 0;
435 dpavlin 4 *data = 0;
436 dpavlin 2 break;
437    
438     default:
439     *data = d->csr[reg];
440 dpavlin 1 }
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 dpavlin 4 /* Read a RX descriptor */
511 dpavlin 1 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 dpavlin 3 return(dev_dec21140_receive_pkt(d,pkt,pkt_len));
679 dpavlin 1
680 dpavlin 3 return(FALSE);
681 dpavlin 1 }
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 dpavlin 4 txdesc_read(d,tx_start,ptxd);
730 dpavlin 1
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 dpavlin 7 static m_uint32_t pci_dec21140_read(cpu_gen_t *cpu,struct pci_device *dev,
855 dpavlin 1 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 dpavlin 7 static void pci_dec21140_write(cpu_gen_t *cpu,struct pci_device *dev,
881 dpavlin 1 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 dpavlin 2 d->csr[5] = 0xfc000000;
943 dpavlin 1 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