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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 dpavlin 1 /*
2     * Cisco C7200 (Predator) Simulation Platform.
3     * Copyright (C) 2005-2006 Christophe Fillot. All rights reserved.
4     *
5     * EEPROM types:
6     * - 0x3d: PA-4B
7     * - 0x3e: PA-8B
8     *
9     * Vernon Missouri offered a PA-4B.
10     *
11     * It is based on the Munich32 chip:
12     * http://www.infineon.com//upload/Document/cmc_upload/migrated_files/document_files/Datasheet/m32_34m.pdf
13     *
14     * There is also one TP3420A per BRI port.
15     */
16    
17     #include <stdio.h>
18     #include <stdlib.h>
19     #include <string.h>
20     #include <unistd.h>
21     #include <errno.h>
22     #include <pthread.h>
23     #include <assert.h>
24    
25     #include "mips64.h"
26     #include "dynamips.h"
27     #include "memory.h"
28     #include "device.h"
29     #include "net.h"
30     #include "net_io.h"
31     #include "ptask.h"
32     #include "dev_c7200.h"
33    
34     /* Debugging flags */
35     #define DEBUG_ACCESS 1
36     #define DEBUG_TRANSMIT 0
37     #define DEBUG_RECEIVE 0
38    
39     /* PCI vendor/product codes */
40     #define BRI_PCI_VENDOR_ID 0x10ee
41     #define BRI_PCI_PRODUCT_ID 0x4013
42    
43     /* Memory used by the munich32 chip */
44     #define MUNICH32_MEM_SIZE 0x40000
45    
46     /* Maximum packet size */
47     #define M32_MAX_PKT_SIZE 8192
48    
49     /* 32 timeslots and 32 channels for a Munich32 chip */
50     #define M32_NR_TIMESLOTS 32
51     #define M32_NR_CHANNELS 32
52    
53     /* Offsets */
54     #define M32_OFFSET_TS 0x0c /* Timeslots */
55     #define M32_OFFSET_CHAN 0x8c /* Channel specification */
56     #define M32_OFFSET_CRDA 0x28c /* Current RX descriptor address */
57     #define M32_OFFSET_CTDA 0x30c /* Current TX descriptor address */
58    
59     /* Action Specification */
60     #define M32_AS_PCM_MASK 0xE0000000 /* PCM Highway Format */
61     #define M32_AS_PCM_SHIFT 29
62     #define M32_AS_MFL_MASK 0x1FFF0000 /* Maximum Frame Length */
63     #define M32_AS_MFL_SHIFT 16
64     #define M32_AS_IN 0x00008000 /* Initialization Procedure */
65     #define M32_AS_ICO 0x00004000 /* Initialize Channel Only */
66     #define M32_AS_CHAN_MASK 0x00001F00 /* Channel Number */
67     #define M32_AS_CHAN_SHIFT 8
68     #define M32_AS_IM 0x00000080 /* Interrupt Mask */
69     #define M32_AS_RES 0x00000040 /* Reset */
70     #define M32_AS_LOOPS_MASK 0x00000038 /* Loops (LOC,LOOP,LOOPI) */
71     #define M32_AS_LOOPS_SHIFT 3
72     #define M32_AS_IA 0x00000004 /* Interrupt Attention */
73    
74     /* Interrupt Information */
75     #define M32_II_INT 0x80000000 /* Interrupt */
76     #define M32_II_VN3 0x20000000 /* Silicon version number */
77     #define M32_II_VN2 0x10000000
78     #define M32_II_VN1 0x08000000
79     #define M32_II_FRC 0x04000000 /* Framing bits changed */
80     #define M32_II_ARACK 0x00008000 /* Action Request Acknowledge */
81     #define M32_II_ARF 0x00004000 /* Action Request Failed */
82     #define M32_II_HI 0x00002000 /* Host Initiated Interrupt */
83     #define M32_II_FI 0x00001000 /* Frame Indication */
84     #define M32_II_IFC 0x00000800 /* Idle Flag Change */
85     #define M32_II_SF 0x00000400 /* Short Frame */
86     #define M32_II_ERR 0x00000200 /* Error condition */
87     #define M32_II_FO 0x00000100 /* Overflow/Underflow */
88     #define M32_II_RT 0x00000020 /* Direction (Transmit/Receive Int) */
89    
90     /* Timeslot Assignment */
91     #define M32_TS_TTI 0x20000000 /* Transmit Timeslot Inhibit */
92     #define M32_TS_TCN_MASK 0x1F000000 /* Transmit Channel Number Mask */
93     #define M32_TS_TCN_SHIFT 24
94     #define M32_TS_TFM_MASK 0x00FF0000 /* Transmit Fill Mask */
95     #define M32_TS_TFM_SHIFT 16
96     #define M32_TS_RTI 0x00002000 /* Receive Timeslot Inhibit */
97     #define M32_TS_RCN_MASK 0x00001F00 /* Receive Channel Number Mask */
98     #define M32_TS_RCN_SHIFT 8
99     #define M32_TS_RFM_MASK 0x000000FF /* Receive Fill Mask */
100     #define M32_TS_RFM_SHIFT 0
101    
102     /* Transmit Descriptor */
103     #define M32_TXDESC_FE 0x80000000 /* Frame End */
104     #define M32_TXDESC_HOLD 0x40000000 /* Hold=0: usable by Munich */
105     #define M32_TXDESC_HI 0x20000000 /* Host Initiated Interrupt */
106     #define M32_TXDESC_NO_MASK 0x1FFF0000 /* Number of bytes */
107     #define M32_TXDESC_NO_SHIFT 16
108     #define M32_TXDESC_V110 0x00008000 /* V.110/X.30 frame */
109     #define M32_TXDESC_CSM 0x00000800 /* CRC Select per Message */
110     #define M32_TXDESC_FNUM 0x000001FF /* Inter-Frame Time-Fill chars */
111    
112     /* Munich32 TX descriptor */
113     struct m32_tx_desc {
114     m_uint32_t params; /* Size + Flags */
115     m_uint32_t tdp; /* Transmit Data Pointer */
116     m_uint32_t ntdp; /* Next Transmit Descriptor Pointer */
117     };
118    
119     /* Receive Descriptor (parameters) */
120     #define M32_RXDESC_HOLD 0x40000000 /* Hold */
121     #define M32_RXDESC_HI 0x20000000 /* Host Initiated Interrupt */
122     #define M32_RXDESC_NO_MASK 0x1FFF0000 /* Size of receive data section */
123     #define M32_RXDESC_NO_SHIFT 16
124    
125     /* Receive Descriptor (status) */
126     #define M32_RXDESC_FE 0x80000000 /* Frame End */
127     #define M32_RXDESC_C 0x40000000
128     #define M32_RXDESC_BNO_MASK 0x1FFF0000 /* Bytes stored in data section */
129     #define M32_RXDESC_BNO_SHIFT 16
130     #define M32_RXDESC_SF 0x00004000
131     #define M32_RXDESC_LOSS 0x00002000 /* Error in sync pattern */
132     #define M32_RXDESC_CRCO 0x00001000 /* CRC error */
133     #define M32_RXDESC_NOB 0x00000800 /* Bit content not divisible by 8 */
134     #define M32_RXDESC_LFD 0x00000400 /* Long Frame Detected */
135     #define M32_RXDESC_RA 0x00000200 /* Receive Abort */
136     #define M32_RXDESC_ROF 0x00000100 /* Overflow of internal buffer */
137    
138     /* Munich32 RX descriptor */
139     struct m32_rx_desc {
140     m_uint32_t params; /* RX parameters (hold, hi, ...) */
141     m_uint32_t status; /* Status */
142     m_uint32_t rdp; /* Receive Data Pointer */
143     m_uint32_t nrdp; /* Next Receive Descriptor Pointer */
144     };
145    
146     /* Munich32 channel */
147     struct m32_channel {
148     m_uint32_t status;
149     m_uint32_t frda;
150     m_uint32_t ftda;
151     m_uint32_t itbs;
152    
153     /* Physical addresses of current RX and TX descriptors */
154     m_uint32_t rx_current,tx_current;
155    
156     /* Poll mode */
157     u_int poll_mode;
158     };
159    
160     /* Munich32 chip data */
161     struct m32_data {
162     /* Virtual machine */
163     vm_instance_t *vm;
164    
165     /* TX ring scanner task id */
166     ptask_id_t tx_tid;
167    
168     /* Interrupt Queue */
169     m_uint32_t iq_base_addr;
170     m_uint32_t iq_cur_addr;
171     u_int iq_size;
172    
173     /* Timeslots */
174     m_uint32_t timeslots[M32_NR_TIMESLOTS];
175    
176     /* Channels */
177     struct m32_channel channels[M32_NR_CHANNELS];
178    
179     /* Embedded config memory */
180     m_uint32_t cfg_mem[MUNICH32_MEM_SIZE/4];
181     };
182    
183     /* === TP3420 SID === */
184    
185     /* Activation / Desactivation */
186     #define TP3420_SID_NOP 0xFF /* No Operation */
187     #define TP3420_SID_PDN 0x00 /* Power Down */
188     #define TP3420_SID_PUP 0x20 /* Power Up */
189     #define TP3420_SID_DR 0x01 /* Deactivation Request */
190     #define TP3420_SID_FI2 0x02 /* Force Info 2 (NT Only) */
191     #define TP3420_SID_MMA 0x1F /* Monitor Mode Activation */
192    
193     /* Device Modes */
194     #define TP3420_SID_NTA 0x04 /* NT Mode, Adaptive Sampling */
195     #define TP3420_SID_NTF 0x05 /* NT Mode, Fixed Sampling */
196     #define TP3420_SID_TES 0x06 /* TE Mode, Digital System Interface Slave */
197     #define TP3420_SID_TEM 0x07 /* TE Mode, Digital System Interface Master */
198    
199     /* Digital Interface Formats */
200     #define TP3420_SID_DIF1 0x08 /* Digital System Interface Format 1 */
201     #define TP3420_SID_DIF2 0x09 /* Digital System Interface Format 2 */
202     #define TP3420_SID_DIF3 0x0A /* Digital System Interface Format 3 */
203     #define TP3420_SID_DIF4 0x0B /* Digital System Interface Format 4 */
204    
205     /* BCLK Frequency Settings */
206     #define TP3420_SID_BCLK1 0x98 /* Set BCLK to 2.048 Mhz */
207     #define TP3420_SID_BCLK2 0x99 /* Set BCLK to 256 Khz */
208     #define TP3420_SID_BCLK3 0x9A /* Set BCLK to 512 Khz */
209     #define TP3420_SID_BCLK4 0x9B /* Set BCLK to 2.56 Mhz */
210    
211     /* B Channel Exchange */
212     #define TP3420_SID_BDIR 0x0C /* B Channels Mapped Direct (B1->B1,B2->B2) */
213     #define TP3420_SID_BEX 0x0D /* B Channels Exchanged (B1->B2,B2->B1) */
214    
215     /* D Channel Access */
216     #define TP3420_SID_DREQ1 0x0E /* D Channel Request, Class 1 Message */
217     #define TP3420_SID_DREQ2 0x0F /* D Channel Request, Class 2 Message */
218    
219     /* D Channel Access Control */
220     #define TP3420_SID_DACCE 0x90 /* Enable D-Channel Access Mechanism */
221     #define TP3420_SID_DACCD 0x91 /* Disable D-Channel Access Mechanism */
222     #define TP3420_SID_EBIT0 0x96 /* Force Echo Bit to 0 */
223     #define TP3420_SID_EBITI 0x97 /* Force Echo Bit to Inverted Received D bit */
224     #define TP3420_SID_EBITN 0x9C /* Reset EBITI and EBIT0 to Normal Condition */
225     #define TP3420_SID_DCKE 0xF1 /* D Channel Clock Enable */
226    
227     /* End Of Message (EOM) Interrupt */
228     #define TP3420_SID_EIE 0x10 /* EOM Interrupt Enabled */
229     #define TP3420_SID_EID 0x11 /* EOM Interrupt Disabled */
230    
231     /* B1 Channel Enable/Disable */
232     #define TP3420_SID_B1E 0x14 /* B1 Channel Enabled */
233     #define TP3420_SID_B1D 0x15 /* B1 Channel Disabled */
234    
235     /* B2 Channel Enable/Disable */
236     #define TP3420_SID_B2E 0x16 /* B2 Channel Enabled */
237     #define TP3420_SID_B2D 0x17 /* B2 Channel Disabled */
238    
239     /* Loopback Tests Modes */
240     #define TP3420_SID_CAL 0x1B /* Clear All Loopbacks */
241    
242     /* Control Device State Reading */
243     #define TP3420_SID_ENST 0x92 /* Enable the Device State Output on NOCST */
244     #define TP3420_SID_DISST 0x93 /* Disable the Device State Output on NOCST */
245    
246     /* PIN Signal Selection */
247     #define TP3420_SID_PINDEF 0xE0 /* Redefine PIN signals */
248    
249     /* TP3420 Status Register */
250     #define TP3420_SR_LSD 0x02 /* Line Signal Detected Far-End */
251     #define TP3420_SR_AP 0x03 /* Activation Pending */
252     #define TP3420_SR_AI 0x0C /* Activation Indication */
253     #define TP3420_SR_EI 0x0E /* Error Indication */
254     #define TP3420_SR_DI 0x0F /* Deactivation Indication */
255     #define TP3420_SR_EOM 0x06 /* End of D-channel TX message */
256     #define TP3420_SR_CON 0x07 /* Lost Contention for D channel */
257    
258     /* NO Change Return status */
259     #define TP3420_SR_NOC 0x00 /* NOC Status after DISST command */
260     #define TP3420_SR_NOCST 0x80 /* NOC Status after ENST command */
261    
262     /* BRI Channel Index */
263     #define BRI_CHAN_INDEX_B1 0
264     #define BRI_CHAN_INDEX_B2 1
265     #define BRI_CHAN_INDEX_D 2
266    
267     /* PA-4B Data */
268     struct pa_4b_data {
269     char *name;
270    
271     /* Virtual machine */
272     vm_instance_t *vm;
273    
274     /* Virtual device */
275     struct vdevice *dev;
276    
277     /* PCI device information */
278     struct pci_device *pci_dev;
279    
280     /* NetIO descriptor */
281     netio_desc_t *nio;
282    
283     /* Munich32 data and base offset */
284     struct m32_data m32_data;
285     u_int m32_offset;
286     };
287    
288     /* Log a PA-4B/PA-8B message */
289     #define BRI_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
290    
291     /* Read a configuration word */
292     static inline m_uint32_t m32_get_cfgw(struct m32_data *d,m_uint32_t offset)
293     {
294     return(d->cfg_mem[offset >> 2]);
295     }
296    
297     /* Write a configuration word */
298     static inline void m32_set_cfgw(struct m32_data *d,m_uint32_t offset,
299     m_uint32_t val)
300     {
301     d->cfg_mem[offset >> 2] = val;
302     }
303    
304     /* Post an interrupt into the interrupt queue */
305     static int m32_post_interrupt(struct m32_data *d,m_uint32_t iq_value)
306     {
307     if (!d->iq_base_addr)
308     return(-1);
309    
310     /* The INT bit is mandatory */
311     iq_value |= M32_II_INT;
312    
313     #if 0
314     printf("M32: Posting interrupt iq_val=0x%8.8x at 0x%8.8x\n",
315     iq_value,d->iq_cur_addr);
316     #endif
317    
318     physmem_copy_u32_to_vm(d->vm,d->iq_cur_addr,iq_value);
319     d->iq_cur_addr += sizeof(m_uint32_t);
320    
321     if (d->iq_cur_addr >= (d->iq_base_addr + d->iq_size))
322     d->iq_cur_addr = d->iq_base_addr;
323    
324     return(0);
325     }
326    
327     /* Fetch a timeslot assignment */
328     static int m32_fetch_ts_assign(struct m32_data *d,u_int ts_id)
329     {
330     m_uint32_t offset;
331    
332     offset = M32_OFFSET_TS + (ts_id * sizeof(m_uint32_t));
333     d->timeslots[ts_id] = m32_get_cfgw(d,offset);
334     return(0);
335     }
336    
337     /* Fetch all timeslot assignments */
338     static int m32_fetch_all_ts(struct m32_data *d)
339     {
340     m_uint32_t offset = M32_OFFSET_TS;
341     u_int i;
342    
343     for(i=0;i<M32_NR_TIMESLOTS;i++,offset+=sizeof(m_uint32_t))
344     d->timeslots[i] = m32_get_cfgw(d,offset);
345    
346     return(0);
347     }
348    
349     /* Show timeslots assignments (debugging) */
350     static void m32_show_ts_assign(struct m32_data *d)
351     {
352     m_uint32_t ts;
353     u_int i;
354    
355     printf("MUNICH32 timeslots:\n");
356    
357     for(i=0;i<M32_NR_TIMESLOTS;i++) {
358     ts = d->timeslots[i];
359    
360     if ((ts & (M32_TS_TTI|M32_TS_RTI)) != (M32_TS_TTI|M32_TS_RTI)) {
361     printf(" Timeslot %2u: ",i);
362    
363     if (!(ts & M32_TS_TTI)) {
364     printf("TCN=%2u TFM=0x%2.2x ",
365     (ts & M32_TS_TCN_MASK) >> M32_TS_TCN_SHIFT,
366     (ts & M32_TS_TFM_MASK) >> M32_TS_TFM_SHIFT);
367     }
368    
369     if (!(ts & M32_TS_RTI)) {
370     printf("RCN=%2u RFM=0x%2.2x",
371     (ts & M32_TS_RCN_MASK) >> M32_TS_RCN_SHIFT,
372     (ts & M32_TS_RFM_MASK) >> M32_TS_RFM_SHIFT);
373     }
374    
375     printf("\n");
376     }
377     }
378    
379     printf("\n");
380     }
381    
382     /* Show info about a channels (debugging) */
383     static void m32_show_channel(struct m32_data *d,u_int chan_id)
384     {
385     struct m32_channel *chan;
386    
387     chan = &d->channels[chan_id];
388     printf("M32 Channel %u:\n",chan_id);
389     printf(" Status : 0x%8.8x\n",chan->status);
390     printf(" FRDA : 0x%8.8x\n",chan->frda);
391     printf(" FTDA : 0x%8.8x\n",chan->ftda);
392     printf(" ITBS : 0x%8.8x\n",chan->itbs);
393     }
394    
395     /* Fetch a channel specification */
396     static int m32_fetch_chan_spec(struct m32_data *d,u_int chan_id)
397     {
398     struct m32_channel *chan;
399     m_uint32_t offset;
400    
401     offset = M32_OFFSET_CHAN + (chan_id * 4 * sizeof(m_uint32_t));
402     chan = &d->channels[chan_id];
403    
404     chan->status = m32_get_cfgw(d,offset);
405     chan->frda = m32_get_cfgw(d,offset+4);
406     chan->ftda = m32_get_cfgw(d,offset+8);
407     chan->itbs = m32_get_cfgw(d,offset+12);
408    
409     chan->poll_mode = 0;
410     chan->rx_current = chan->frda;
411     chan->tx_current = chan->ftda;
412    
413     m32_set_cfgw(d,M32_OFFSET_CTDA+(chan_id*4),chan->tx_current);
414    
415     #if 1
416     if (chan_id == 2) {
417     printf("M32: Fetched channel %u\n",chan_id);
418     //m32_show_ts_assign(d);
419     m32_show_channel(d,chan_id);
420     }
421     #endif
422     return(0);
423     }
424    
425     /* Fetch all channel specifications */
426     static void m32_fetch_all_chan_spec(struct m32_data *d)
427     {
428     u_int i;
429    
430     for(i=0;i<M32_NR_CHANNELS;i++)
431     m32_fetch_chan_spec(d,i);
432     }
433    
434     /* Try to acquire the specified TX descriptor */
435     static int m32_tx_acquire(struct m32_data *d,m_uint32_t txd_addr,
436     struct m32_tx_desc *txd)
437     {
438     m_uint32_t params;
439    
440     if (!(params = physmem_copy_u32_from_vm(d->vm,txd_addr)) & M32_TXDESC_HOLD)
441     return(FALSE);
442    
443     txd->params = params;
444     txd->tdp = physmem_copy_u32_from_vm(d->vm,txd_addr+4);
445     txd->ntdp = physmem_copy_u32_from_vm(d->vm,txd_addr+8);
446     return(TRUE);
447     }
448    
449     /* Try to acquire the next TX descriptor */
450     static int m32_tx_acquire_next(struct m32_data *d,m_uint32_t *txd_addr)
451     {
452     m_uint32_t params;
453    
454     /* HOLD bit must be reset */
455     if ((params = physmem_copy_u32_from_vm(d->vm,*txd_addr)) & M32_TXDESC_HOLD)
456     return(FALSE);
457    
458     *txd_addr = physmem_copy_u32_from_vm(d->vm,(*txd_addr)+8);
459     return(TRUE);
460     }
461    
462     /* Scan a channel TX ring */
463     static inline int m32_tx_scan(struct m32_data *d,u_int chan_id)
464     {
465     struct m32_channel *chan = &d->channels[chan_id];
466     m_uint8_t pkt[M32_MAX_PKT_SIZE];
467     struct m32_tx_desc txd;
468     m_uint32_t pkt_len;
469    
470     if (!chan->tx_current)
471     return(FALSE);
472    
473     switch(chan->poll_mode) {
474     case 0:
475     m32_set_cfgw(d,M32_OFFSET_CTDA+(chan_id*4),chan->tx_current);
476    
477     /* Try to transmit data */
478     if (!m32_tx_acquire(d,chan->tx_current,&txd))
479     return(FALSE);
480    
481     printf("M32: TX scanner for channel %u (tx_current=0x%8.8x)\n",
482     chan_id,chan->tx_current);
483    
484     printf("M32: params=0x%8.8x, next=0x%8.8x.\n",txd.params,txd.ntdp);
485    
486     /* The descriptor has been acquired */
487     pkt_len = (txd.params & M32_TXDESC_NO_MASK) >> M32_TXDESC_NO_SHIFT;
488     physmem_copy_from_vm(d->vm,pkt,txd.tdp,pkt_len);
489    
490     printf("M32: data_ptr=0x%x, len=%u\n",txd.tdp,pkt_len);
491     mem_dump(stdout,pkt,pkt_len);
492    
493     /* Poll the next descriptor (wait for HOLD bit to be reset */
494     chan->poll_mode = 1;
495    
496     if (txd.params & M32_TXDESC_FE) {
497     m32_post_interrupt(d,M32_II_FI | chan_id);
498     vm_set_irq(d->vm,2);
499     }
500    
501     break;
502    
503     case 1:
504     if (!m32_tx_acquire_next(d,&chan->tx_current))
505     return(FALSE);
506    
507     printf("M32: branching on next descriptor 0x%x\n",chan->tx_current);
508     chan->poll_mode = 0;
509     break;
510     }
511    
512     return(TRUE);
513     }
514    
515     /* Scan the all channel TX rings */
516     static void m32_tx_scan_all_channels(struct m32_data *d)
517     {
518     u_int i;
519    
520     for(i=0;i<M32_NR_CHANNELS;i++)
521     m32_tx_scan(d,i);
522     }
523    
524     /*
525     * Handle an action request.
526     *
527     * IN, ICO and RES bits are mutually exclusive.
528     */
529     static int m32_action_req(struct m32_data *d,m_uint32_t action)
530     {
531     u_int chan_id;
532    
533     /* Define a new Interrupt Queue */
534     if (action & M32_AS_IA) {
535     d->iq_base_addr = d->iq_cur_addr = m32_get_cfgw(d,4);
536     d->iq_size = ((m32_get_cfgw(d,8) & 0xFF) + 1) * 16 * sizeof(m_uint32_t);
537     }
538    
539     /* Initialization Procedure */
540     if (action & M32_AS_IN) {
541     /* Fetch all timeslots assignments */
542     m32_fetch_all_ts(d);
543    
544     /* Fetch specification of the specified channel */
545     chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;
546     m32_fetch_chan_spec(d,chan_id);
547    
548     /* Generate acknowledge */
549     if (!(action & M32_AS_IM))
550     m32_post_interrupt(d,M32_II_ARACK);
551     }
552    
553     /* Initialize Channel Only */
554     if (action & M32_AS_ICO) {
555     /* Fetch specification of the specified channel */
556     chan_id = (action & M32_AS_CHAN_MASK) >> M32_AS_CHAN_SHIFT;
557     m32_fetch_chan_spec(d,chan_id);
558    
559     /* Generate acknowledge */
560     if (!(action & M32_AS_IM))
561     m32_post_interrupt(d,M32_II_ARACK);
562     }
563    
564     /* Reset */
565     if (action & M32_AS_RES) {
566     /* Fetch all timeslots assignments */
567     m32_fetch_all_ts(d);
568    
569     /* Fetch all channel specifications */
570     m32_fetch_all_chan_spec(d);
571    
572     /* Generate acknowledge */
573     if (!(action & M32_AS_IM))
574     m32_post_interrupt(d,M32_II_ARACK);
575     }
576    
577     return(0);
578     }
579    
580     /* Munich32 general access function */
581     static void *m32_gen_access(struct m32_data *d,cpu_mips_t *cpu,
582     m_uint32_t offset,u_int op_size,u_int op_type,
583     m_uint64_t *data)
584     {
585     u_int p;
586    
587     switch(offset) {
588     /* Action Specification */
589     case 0x0:
590     if (op_type == MTS_WRITE)
591     m32_action_req(d,*data);
592     return NULL;
593    
594     /* Configuration memory */
595     default:
596     switch(op_size) {
597     case 4:
598     if (op_type == MTS_READ)
599     *data = m32_get_cfgw(d,offset);
600     else
601     m32_set_cfgw(d,offset,*data);
602     break;
603    
604     case 1:
605     if (op_type == MTS_READ) {
606     *data = m32_get_cfgw(d,offset & ~0x03);
607     *data >>= (24 - ((offset & 0x03) << 3));
608     *data &= 0xFF;
609     } else {
610     printf("UNSUPPORTED(1)!!!!\n");
611     }
612     break;
613    
614     case 2:
615     if (op_type == MTS_READ) {
616     *data = m32_get_cfgw(d,offset & ~0x03);
617     *data >>= (16 - ((offset & 0x03) << 3));
618     *data &= 0xFFFF;
619     } else {
620     printf("UNSUPPORTED(2)!!!!\n");
621     }
622     break;
623    
624     case 8:
625     if (op_type == MTS_READ) {
626     *data = (m_uint64_t)m32_get_cfgw(d,offset) << 32;
627     *data |= m32_get_cfgw(d,offset+4);
628     } else {
629     printf("UNSUPPORTED(8)!!!!\n");
630     }
631     break;
632    
633     default:
634     printf("UNSUPPORTED (size=%u)!!!\n",op_size);
635     }
636     }
637    
638     return NULL;
639     }
640    
641     /*
642     * pa_4b_access()
643     */
644     void *pa_4b_access(cpu_mips_t *cpu,struct vdevice *dev,m_uint32_t offset,
645     u_int op_size,u_int op_type,m_uint64_t *data)
646     {
647     struct pa_4b_data *d = dev->priv_data;
648     static m_uint32_t test1,test2,test3;
649    
650     if (op_type == MTS_READ)
651     *data = 0xFFFFFFFF;
652    
653     #if DEBUG_ACCESS
654     if (offset >= MUNICH32_MEM_SIZE) {
655     if (op_type == MTS_READ) {
656     cpu_log(cpu,d->name,"read access to offset = 0x%x, pc = 0x%llx "
657     "(op_size=%u)\n",offset,cpu->pc,op_size);
658     } else {
659     cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "
660     "val = 0x%llx (op_size=%u)\n",offset,cpu->pc,*data,op_size);
661     }
662     }
663     #endif
664    
665     /* Specific cases */
666     switch(offset) {
667     case 0x40008:
668     if (op_type == MTS_READ)
669     *data = 0xFF;
670     break;
671    
672     case 0x40030:
673     if (op_type == MTS_READ)
674     *data = 0xFF;
675     break;
676    
677     case 0x40000:
678     if (op_type == MTS_READ)
679     *data = 0xFFFF;
680     break;
681    
682     case 0x40020:
683     if (op_type == MTS_READ)
684     *data = 0xFFFFFFFF; //test2;
685     else
686     test2 = *data;
687     break;
688    
689     case 0x40021:
690     if (op_type == MTS_READ)
691     *data = 0xFF; //test3;
692     else
693     test3 = *data;
694     break;
695    
696     case 0x40023:
697     if (op_type == MTS_READ)
698     *data = 0xFF;
699     break;
700    
701     case 0x40040:
702     if (op_type == MTS_READ)
703     *data = 0x04;
704     break;
705    
706     /* Channels enabled ? */
707     case 0x40044:
708     if (op_type == MTS_READ)
709     *data = 0xFF; /* 0x02 */
710     break;
711    
712     /* SID */
713     case 0x40050:
714     if (op_type == MTS_WRITE) {
715     test1 = *data;
716     } else {
717     switch(test1) {
718     case TP3420_SID_PUP:
719     *data = TP3420_SR_AI;
720     vm_set_irq(d->vm,C7200_PA_MGMT_IRQ);
721     break;
722     case TP3420_SID_ENST:
723     *data = 0xB0;
724     break;
725     default:
726     *data = 0x03;
727     break;
728     }
729     }
730     break;
731    
732     default:
733     if (offset < MUNICH32_MEM_SIZE)
734     return(m32_gen_access(&d->m32_data,cpu,offset - d->m32_offset,
735     op_size,op_type,data));
736     }
737    
738     return NULL;
739     }
740    
741     /*
742     * pci_munich32_read()
743     */
744     static m_uint32_t pci_munich32_read(cpu_mips_t *cpu,struct pci_device *dev,
745     int reg)
746     {
747     struct pa_4b_data *d = dev->priv_data;
748    
749     #if DEBUG_ACCESS
750     BRI_LOG(d,"read PCI register 0x%x\n",reg);
751     #endif
752     switch(reg) {
753     case PCI_REG_BAR0:
754     return(d->dev->phys_addr);
755     default:
756     return(0);
757     }
758     }
759    
760     /*
761     * pci_munich32_write()
762     */
763     static void pci_munich32_write(cpu_mips_t *cpu,struct pci_device *dev,
764     int reg,m_uint32_t value)
765     {
766     struct pa_4b_data *d = dev->priv_data;
767    
768     #if DEBUG_ACCESS
769     BRI_LOG(d,"write 0x%x to PCI register 0x%x\n",value,reg);
770     #endif
771    
772     switch(reg) {
773     case PCI_REG_BAR0:
774     vm_map_device(cpu->vm,d->dev,(m_uint64_t)value);
775     BRI_LOG(d,"registers are mapped at 0x%x\n",value);
776     break;
777     }
778     }
779    
780     /*
781     * dev_c7200_bri_init()
782     *
783     * Add a PA-4B/PA-8B port adapter into specified slot.
784     */
785     int dev_c7200_pa_bri_init(c7200_t *router,char *name,u_int pa_bay)
786     {
787     struct pci_device *pci_dev;
788     struct pa_4b_data *d;
789     struct vdevice *dev;
790    
791     /* Allocate the private data structure for PA-4B chip */
792     if (!(d = malloc(sizeof(*d)))) {
793     fprintf(stderr,"%s (PA-4B): out of memory\n",name);
794     return(-1);
795     }
796    
797     memset(d,0,sizeof(*d));
798     d->m32_offset = 0x08;
799     d->m32_data.vm = router->vm;
800    
801     /* Set the EEPROM */
802 dpavlin 3 c7200_pa_set_eeprom(router,pa_bay,cisco_eeprom_find_pa("PA-4B"));
803 dpavlin 1
804     /* Add as PCI device PA-4B */
805     pci_dev = pci_dev_add(router->pa_bay[pa_bay].pci_map,name,
806     BRI_PCI_VENDOR_ID,BRI_PCI_PRODUCT_ID,
807     0,0,C7200_NETIO_IRQ,d,
808     NULL,pci_munich32_read,pci_munich32_write);
809    
810     if (!pci_dev) {
811     fprintf(stderr,"%s (PA-4B): unable to create PCI device.\n",name);
812     return(-1);
813     }
814    
815     /* Create the PA-4B structure */
816     d->name = name;
817     d->pci_dev = pci_dev;
818     d->vm = router->vm;
819    
820     /* Create the device itself */
821     if (!(dev = dev_create(name))) {
822     fprintf(stderr,"%s (PA-4B): unable to create device.\n",name);
823     return(-1);
824     }
825    
826     dev->phys_len = 0x800000;
827     dev->handler = pa_4b_access;
828    
829     /* Store device info */
830     dev->priv_data = d;
831     d->dev = dev;
832    
833     /* Map this device to the VM */
834     vm_bind_device(router->vm,dev);
835    
836     /* Store device info into the router structure */
837     return(c7200_pa_set_drvinfo(router,pa_bay,d));
838     }
839    
840     /* Remove a PA-4B from the specified slot */
841     int dev_c7200_pa_bri_shutdown(c7200_t *router,u_int pa_bay)
842     {
843     struct c7200_pa_bay *bay;
844     struct pa_4b_data *d;
845    
846     if (!(bay = c7200_pa_get_info(router,pa_bay)))
847     return(-1);
848    
849     d = bay->drv_info;
850    
851     /* Remove the PA EEPROM */
852     c7200_pa_unset_eeprom(router,pa_bay);
853    
854     /* Remove the PCI device */
855     pci_dev_remove(d->pci_dev);
856    
857     /* Remove the device from the CPU address space */
858     vm_unbind_device(router->vm,d->dev);
859     cpu_group_rebuild_mts(router->vm->cpu_group);
860    
861     /* Free the device structure itself */
862     free(d->dev);
863     free(d);
864     return(0);
865     }
866    
867     /* Bind a Network IO descriptor to a specific port */
868     int dev_c7200_pa_bri_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,
869     netio_desc_t *nio)
870     {
871     struct pa_4b_data *d;
872    
873     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
874     return(-1);
875    
876     if (d->nio != NULL)
877     return(-1);
878    
879     d->nio = nio;
880    
881     /* TEST */
882     d->m32_data.tx_tid = ptask_add((ptask_callback)m32_tx_scan_all_channels,&d->m32_data,NULL);
883    
884     //netio_rxl_add(nio,(netio_rx_handler_t)dev_pa_4b_handle_rxring,d,NULL);
885     return(0);
886     }
887    
888     /* Bind a Network IO descriptor to a specific port */
889     int dev_c7200_pa_bri_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id)
890     {
891     struct pa_4b_data *d;
892    
893     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))
894     return(-1);
895    
896     if (d->nio) {
897     /* TEST */
898     ptask_remove(d->m32_data.tx_tid);
899    
900     //netio_rxl_remove(d->nio);
901     d->nio = NULL;
902     }
903     return(0);
904     }
905    
906     /* PA-4B driver */
907     struct c7200_pa_driver dev_c7200_pa_4b_driver = {
908     "PA-4B", 0,
909     dev_c7200_pa_bri_init,
910     dev_c7200_pa_bri_shutdown,
911     dev_c7200_pa_bri_set_nio,
912     dev_c7200_pa_bri_unset_nio,
913 dpavlin 2 NULL,
914 dpavlin 1 };

  ViewVC Help
Powered by ViewVC 1.1.26