/[dynamips]/trunk/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

Contents of /trunk/dev_c7200_bri.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (11 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 26467 byte(s)
make working copy

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

  ViewVC Help
Powered by ViewVC 1.1.26