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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (14 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 28018 byte(s)
dynamips-0.2.6-RC3

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

  ViewVC Help
Powered by ViewVC 1.1.26