source: svn/trunk/newcon3bcm2_21bu/dta/src/settop_api/bsettop_amessage_rave.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 24.5 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: $
11 * $brcm_Revision: $
12 * $brcm_Date: $
13 *      04/04/2012 created to support SCTE 55-2
14 *
15 * Module Description: message filtering module for SCTE 55-2
16 *
17 ***************************************************************************/
18
19#include "bsettop_amessage.h"
20#include "blst_slist.h"
21#include "ministd.h"
22
23#include "bstd.h"
24#include "bkni.h"
25#include "bdbg.h"
26#include "bxpt.h"
27#include "bxpt_rave.h"
28
29#include "bxpt_priv.h"
30#include "bchp_xpt_fe.h"
31
32#include "amsg_filter.h"
33#include "bos.h"
34#include "gist.h"
35
36BDBG_MODULE(amsg);
37
38#define MSG_VERBOSE 0
39#if MSG_VERBOSE & 1
40#define BDBG_MSG_1(x) BDBG_MSG(x)
41#else
42#define BDBG_MSG_1(x) BDBG_NOP()
43#endif
44
45/* fixed in 6 */
46#define START_PID_CHANNEL       OOB_DAVIC_PARSER /* for SCTE 55-2, we have to use all pass mode, MINI/PID_Table/SPID_Table are fixed also */
47#define B_INVALID_BAND          ((bband_t)(-1))
48#define FILTER_SIZE             4       /* CA/SI/Network/? */
49#define ATM_PACKET_SIZE         53
50#define AM_MAGIC                        0xA5A5A5A5
51#define AM_BUFFER_SIZE          (ATM_PACKET_SIZE * 512)
52#define AM_WAIT                         (-1)
53#define AM_POLL_INTERVAL        50
54#define MAX_CAP                         4
55#define FILTER_CAP                      0
56#define MAX_VPI_VCIS            4       /* CS/SI/Network/? */
57
58enum am_task_state_t {
59    AMS_NONE,
60    AMS_IDLE,
61    AMS_RUN
62};
63
64struct amessage_vpi_vci;
65
66struct amessage_stream {
67    BLST_S_ENTRY(amessage_stream)       next;
68    struct amessage_vpi_vci                     *am_vpi_vci;
69    struct afilter_state_t                      *amsg_filter;
70    amessage_callback                           callback;
71    amessage_callback                           overflow;
72    void                                                        *context;
73    void                                                        *priv;
74    unsigned int                                        cap_index;
75};
76
77BLST_S_HEAD(amessage_stream_list_t, amessage_stream);
78
79struct amessage_vpi_vci {
80    uint8_t             vpi;
81    uint16_t    vci;
82    struct amessage_stream_list_t filters;
83};
84
85struct amessage_capture {
86    bool in_use;
87    uint8_t * buffer_ptr;
88    uint32_t buffer_size;
89    BXPT_RaveCx_Handle rav_cx;
90    uint32_t buffer_threshold;
91};
92
93struct amessage_state {
94    uint32_t magic;
95    bband_t band;
96
97    b_task_t task;
98    b_mutex_t lock;
99    enum am_task_state_t task_state;
100
101    struct amessage_capture cap[MAX_CAP];
102    struct amessage_vpi_vci vpi_vci[MAX_VPI_VCIS];
103    struct amessage_stream_list_t free_filter;
104    struct amessage_stream dummy0[MAX_FILTERS];
105        int vpi_vci_pairs;                      /* tracking vpi/vci pairs in use */
106};
107
108static struct amessage_state am_st;
109
110#define AM_STACK_SIZE   0x400
111#define AM_PRIORITY             15              /* should we define it in the file bos_task_priorities.h? */
112static unsigned int             am_stack[AM_STACK_SIZE];
113static char * am_task_name = "amsg";
114
115static struct amessage_vpi_vci * am_find_vpi_vci(uint8_t vpi, uint16_t vci);
116static void * am_message_callback(void * context, size_t msg_size);
117static void am_parser_task(void * param);
118
119static BERR_Code am_rave_open(struct amessage_capture * cap);
120static BERR_Code am_rave_close(struct amessage_capture * cap);
121static BERR_Code am_rave_start(struct amessage_capture * cap);
122static BERR_Code am_rave_stop(struct amessage_capture * cap);
123static struct amessage_vpi_vci *am_rave_add_vpi_vci(struct amessage_capture * cap, uint8_t vpi, uint16_t vci);
124static BERR_Code am_rave_remove_vpi_vci(struct amessage_capture * cap, struct amessage_vpi_vci * am_vpi_vci);
125static BERR_Code am_rave_process_data(struct amessage_capture * cap);
126static BERR_Code am_rave_get_buffer(struct amessage_capture * cap, const void ** pbuffer, size_t * plength);
127static BERR_Code am_rave_read_complete(struct amessage_capture * cap, size_t consumed);
128
129static void am_set_input_band_config(int ib);
130static void am_set_parser_config(bband_t band);
131static BERR_Code am_allocate_capture(unsigned int * cap_index);
132static void am_free_capture(unsigned int cap_index);
133
134/*
135  Summary:
136  Initialize the message filter for ATM message.
137 */
138bresult amessage_init(void)
139{
140    int i;
141    b_task_params t_param;
142    bresult bres = b_ok;
143
144    BDBG_MSG_1(("%s", __PRETTY_FUNCTION__));
145    BKNI_Memset(&am_st, 0, sizeof(struct amessage_stream));
146    BLST_S_INIT(&am_st.free_filter);
147    for(i = 0; i < MAX_FILTERS; i ++){
148        BLST_S_INSERT_HEAD(&am_st.free_filter, &am_st.dummy0[i], next);
149    }
150    for(i = 0; i < MAX_VPI_VCIS; i ++){
151        //am_st.vpi_vci[i].vpi = 0;
152        //am_st.vpi_vci[i].vci = 0;
153        BLST_S_INIT(&am_st.vpi_vci[i].filters);
154    }
155    for(i = 0; i < MAX_CAP; i++){
156        am_st.cap[i].buffer_size = AM_BUFFER_SIZE;
157        //am_st.cap[i].in_use = false;
158    }
159    /* allocate filter capture */
160    //am_st.cap[FILTER_CAP].in_use = true;
161
162        /* TODO we need atm message processing */
163    amsg_init();
164
165    bres = bos_create_mutex(&am_st.lock);
166    if(b_ok != bres){
167        goto ExitFunc;
168    }
169    am_st.task_state = AMS_IDLE;
170    t_param.priority = AM_PRIORITY;
171    t_param.stack_size = AM_STACK_SIZE;
172    t_param.stack = am_stack;
173    t_param.name = am_task_name;
174    bres = bos_start_task(&am_st.task, &t_param, am_parser_task, NULL);
175    am_st.band = START_PID_CHANNEL;
176    am_st.magic = AM_MAGIC;
177
178ExitFunc:
179    return bres;
180}
181
182/*
183  Summary:
184  Cleanup the messages system for ATM message handling
185 */
186bresult amessage_uninit()
187{
188    am_st.magic = 0;
189        /* stop task? */
190    return b_ok;
191}
192
193/*
194  Summary:
195        Open a message stream for ATM based message handling
196 */
197amessage_stream_t amessage_open(void)
198{
199    amessage_stream_t st;
200
201        st = BLST_S_FIRST(&am_st.free_filter);
202        if(NULL != st){
203                BLST_S_REMOVE_HEAD(&am_st.free_filter, next);
204                st->cap_index = FILTER_CAP;
205        }
206        return st;
207}
208
209/*
210  Summary:
211        Close a message stream
212*/
213void amessage_close(amessage_stream_t stream)
214{
215        if(NULL != stream->am_vpi_vci){
216                if(b_ok != amessage_stop(stream)){
217                        BDBG_ERR(("%s",__func__));
218                }
219        }
220        BLST_S_INSERT_HEAD(&am_st.free_filter, stream, next);
221}
222
223/*
224Summary:
225        Initialize parameters structure
226*/
227void amessage_stream_params_init( amessage_stream_params_t *params, amessage_stream_t stream)
228{
229        int i;
230
231        if(NULL != params){
232                BKNI_Memset(params, 0, sizeof(amessage_stream_params_t));
233                params->band = B_INVALID_BAND;
234                params->vpi = 0;
235                params->vci = 0;
236                /* to filter VPI/VCI pair, we just need 4 bytes, since we have to parse the rest data using software */
237                for(i = 0; i < FILTER_SIZE; i++){
238                        params->filter.mask[i] = 0xFF;
239                        params->filter.excl[i] = 0xFF;
240                }
241        }
242}
243
244/*
245   Summary:
246        Capture message according to the parameters
247*/
248bresult amessage_start(const amessage_stream_params_t * params, amessage_stream_t stream)
249{
250        bresult  bres;
251        amsg_params_t am_params;
252        struct amessage_vpi_vci *new_vpi_vci = NULL;
253        BERR_Code berr;
254
255        BDBG_ASSERT(NULL != stream);
256        BDBG_ASSERT(NULL != params);
257
258        if((NULL == params->buffer) || (0 == params->buffer_size) || 
259                        (NULL == params->data_ready_callback) || B_INVALID_BAND == params->band){
260                BDBG_ERR(("%s invalid values",__func__));
261                bres = berr_invalid_parameter;
262                goto ExitFunc;
263        }
264
265        /* stream is already started and can not be started twice */
266        if(NULL != stream->am_vpi_vci){
267                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
268                bres = berr_invalid_parameter;
269                goto ExitFunc;
270        }
271        bres = bos_acquire_mutex(&am_st.lock, AM_WAIT);
272        if(b_ok != bres){
273                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
274                goto ExitFunc;
275        }
276
277        am_params.vpi = params->vpi;
278        am_params.vci = params->vci;
279        memcpy(am_params.filt.coef, params->filter.coef, FILTER_SIZE);
280        memcpy(am_params.filt.mask, params->filter.mask, FILTER_SIZE);
281        memcpy(am_params.filt.excl, params->filter.excl, FILTER_SIZE);
282        am_params.buffer = params->buffer;
283        am_params.buffer_size = params->buffer_size;
284        am_params.disable_hec_check = params->hec_disabled;
285        am_params.callback = am_message_callback;
286        am_params.context = (void*)stream;
287        stream->amsg_filter = amsg_set_filter(&am_params);
288        if(NULL == stream->amsg_filter){
289                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
290                bres = berr_not_supported;
291                goto ExitUnlock;
292        }
293        stream->callback = params->data_ready_callback;
294        stream->overflow = params->overflow;
295        stream->context = params->callback_context;
296        stream->priv = params->priv;
297
298        /* do we have vpi/vci pair in the filter list already? */
299        new_vpi_vci = am_find_vpi_vci(params->vpi, params->vci);
300        if (!new_vpi_vci) {
301                /* add vpi/vci first, and need to remove it if failed later */
302                new_vpi_vci = am_rave_add_vpi_vci(&am_st.cap[stream->cap_index], params->vpi, params->vci);
303                /* no vpi/vci? bail out, it should be error, need to check */
304                if (!new_vpi_vci) {
305                        BDBG_ERR(("%s: no vpi/vci pair resource?",__func__));
306                        amsg_remove_filter(stream->amsg_filter);
307                        stream->amsg_filter = NULL;
308                        goto ExitUnlock;
309                }
310        }
311        else {
312                /* have this filter already, so exit */
313                BDBG_WRN(("%s: vpi/vci (%d/%d) in use already!",__func__, params->vpi, params->vci));
314                goto ExitUnlock;
315        }
316
317        BLST_S_INSERT_HEAD(&new_vpi_vci->filters, stream, next);
318        stream->am_vpi_vci = new_vpi_vci;
319        am_st.band = params->band;
320        /* we need to open rave if it is not yet opened */
321        if(NULL == am_st.cap[stream->cap_index].rav_cx){
322                berr = am_rave_open(&am_st.cap[stream->cap_index]);
323                if(BERR_SUCCESS != berr){
324                        BDBG_ERR(("%s am_rave_open failed",__func__));
325                        bres = berr_out_of_memory;
326                        am_rave_remove_vpi_vci(&am_st.cap[stream->cap_index], new_vpi_vci);
327                        BLST_S_REMOVE(&new_vpi_vci->filters, stream, amessage_stream, next);
328                        amsg_remove_filter(stream->amsg_filter);
329                        stream->amsg_filter = NULL;
330                        goto ExitUnlock;
331                }
332        }
333        /* if it is first one */
334        if(1 == am_st.vpi_vci_pairs){
335                berr = BXPT_ConfigurePidChannel(GetXPT(), START_PID_CHANNEL, 0 /* don't have PID */, am_st.band);
336                if(BERR_SUCCESS != berr){
337                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
338                        bres = berr_external_error;
339                        am_rave_remove_vpi_vci(&am_st.cap[stream->cap_index], new_vpi_vci);
340                        BLST_S_REMOVE(&new_vpi_vci->filters, stream, amessage_stream, next);
341                        goto ExitUnlock;
342                }
343                berr = BXPT_EnablePidChannel(GetXPT(), START_PID_CHANNEL);
344                if(BERR_SUCCESS != berr){
345                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
346                        bres = berr_external_error;
347                        am_rave_remove_vpi_vci(&am_st.cap[stream->cap_index], new_vpi_vci);
348                        BLST_S_REMOVE(&new_vpi_vci->filters, stream, amessage_stream, next);
349                        amsg_remove_filter(stream->amsg_filter);
350                        stream->amsg_filter = NULL;
351                        goto ExitUnlock;
352                }
353        }
354
355        if ((am_st.task_state != AMS_RUN)){
356                am_set_input_band_config(OOB_IB);
357                am_set_parser_config(START_PID_CHANNEL);
358                berr = am_rave_start(&am_st.cap[stream->cap_index]);
359                if(BERR_SUCCESS != berr){
360                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
361                        bres = berr_external_error;
362                        am_rave_remove_vpi_vci(&am_st.cap[stream->cap_index], new_vpi_vci);
363                        BLST_S_REMOVE(&new_vpi_vci->filters, stream, amessage_stream, next);
364                        amsg_remove_filter(stream->amsg_filter);
365                        stream->amsg_filter = NULL;
366                        goto ExitUnlock;
367                }
368                if (am_st.task_state != AMS_RUN){
369                        am_st.task_state = AMS_RUN;
370                }
371        }
372        bres = b_ok;
373
374ExitUnlock:
375        if(b_ok != bos_release_mutex(&am_st.lock)){
376                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
377        } 
378ExitFunc:
379        return bres;
380}
381
382bresult amessage_stop(amessage_stream_t stream)
383{
384        BERR_Code berr;
385        bresult bres;
386        struct amessage_vpi_vci *am_vpi_vci;
387        BDBG_ASSERT(NULL != stream);
388
389        bres = bos_acquire_mutex(&am_st.lock, AM_WAIT);
390        if(b_ok != bres){
391                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
392                goto ExitFunc;
393        }
394
395        am_vpi_vci = stream->am_vpi_vci;
396        if(NULL != stream->amsg_filter){
397                amsg_remove_filter(stream->amsg_filter);
398                stream->amsg_filter = NULL;
399        }
400        if(NULL != am_vpi_vci){
401                BLST_S_REMOVE(&am_vpi_vci->filters, stream, amessage_stream, next);
402                stream->am_vpi_vci = NULL;
403
404                if(BLST_S_EMPTY(&am_vpi_vci->filters)){
405                        size_t i;
406
407                        berr = BXPT_DisablePidChannel(GetXPT(), START_PID_CHANNEL);
408                        if(BERR_SUCCESS != berr){
409                                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
410                                //goto ExitUnlock;
411                        }
412                        berr = am_rave_remove_vpi_vci(&am_st.cap[stream->cap_index], am_vpi_vci);
413                        if(BERR_SUCCESS != berr){
414                                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
415                                bres = berr_external_error;
416                                goto ExitUnlock;
417                        }
418
419                        for(i = 0; i < MAX_VPI_VCIS; i++){
420                                /* check if we have any vpi/vci pair to process */
421                                if(am_st.vpi_vci[i].vpi || am_st.vpi_vci[i].vpi){
422                                        break;
423                                }
424                        }
425                        amsg_reset_vpi_vci();
426                        if(MAX_VPI_VCIS == i){
427                                berr = am_rave_stop(&am_st.cap[stream->cap_index]);
428                                if(BERR_SUCCESS != berr){
429                                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
430                                        bres = berr_external_error;
431                                        goto ExitUnlock;
432                                }
433                                am_st.task_state = AMS_IDLE;
434                        }else{
435                                am_st.task_state = AMS_RUN;
436                        }
437                }
438        }
439ExitUnlock:
440        if(b_ok != bos_release_mutex(&am_st.lock)){
441                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
442        } 
443
444ExitFunc:
445        return bres;
446}
447
448bresult amessage_get_buffer(amessage_stream_t stream, const void ** pbuffer, size_t * plength)
449{
450        bresult bres;
451        BERR_Code berr;
452
453        bres = bos_acquire_mutex(&am_st.lock, AM_WAIT);
454        if(b_ok == bres){
455                berr = am_rave_get_buffer(&am_st.cap[stream->cap_index], pbuffer, plength);
456                if(BERR_SUCCESS != berr){
457                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
458                        bres = berr_external_error;
459                }
460                bos_release_mutex(&am_st.lock);
461        } 
462        return bres;
463}
464
465bresult amessage_read_complete(amessage_stream_t stream, size_t consumed)
466{
467        bresult bres;
468        BERR_Code berr;
469
470        bres = bos_acquire_mutex(&am_st.lock, AM_WAIT);
471        if (b_ok == bres) {
472                berr = am_rave_read_complete(&am_st.cap[stream->cap_index], consumed);
473                if(BERR_SUCCESS != berr){
474                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
475                        bres = berr_external_error;
476                }
477                bos_release_mutex(&am_st.lock);
478        } 
479        return bres;
480}
481
482struct amessage_vpi_vci *am_find_vpi_vci(uint8_t vpi, uint16_t vci)
483{
484        struct amessage_vpi_vci *res = NULL;
485        int i;
486
487        for(i = 0; i < MAX_VPI_VCIS; i++){
488                if((vpi == am_st.vpi_vci[i].vpi) && (vci == am_st.vpi_vci[i].vci)) {
489                        res = &am_st.vpi_vci[i];
490                        break;
491                }
492        }
493        return res;
494}
495
496/* reset vpi/vci */
497void am_reset_vpi_vci(uint8_t vpi, uint16_t vci)
498{
499        struct amessage_vpi_vci *res = NULL;
500        int i;
501
502        for(i = 0; i < MAX_VPI_VCIS; i++){
503                if((vpi == am_st.vpi_vci[i].vpi) && (vci == am_st.vpi_vci[i].vci)) {
504                        res = &am_st.vpi_vci[i];
505                        break;
506                }
507        }
508        return;
509}
510
511void * am_message_callback(void * context, size_t msg_size)
512{
513        void * new_buffer = NULL;
514        amessage_stream_t stream = (amessage_stream_t) context;
515
516        if(NULL != stream->callback){
517                new_buffer = (stream->callback)(stream->context, msg_size);
518        }
519        return new_buffer;
520}
521
522void am_parser_task(void * param)
523{
524        bresult bres;
525        BERR_Code berr;
526
527        while(1){
528                bres = bos_acquire_mutex(&am_st.lock, AM_WAIT);
529                if(b_ok == bres){
530                        if(AMS_RUN == am_st.task_state){
531                                berr = am_rave_process_data(&am_st.cap[FILTER_CAP]);
532                                if(BERR_SUCCESS != berr){
533                                        BDBG_ERR(("%s:%d", __FILE__, __LINE__));
534                                }
535                        }
536                        bres = bos_release_mutex(&am_st.lock);
537                        if(b_ok != bres){
538                                BDBG_ERR(("bos_release_mutex failed! exiting ..."));
539                                break;
540                        }
541                }
542                bos_sleep(AM_POLL_INTERVAL);
543        }
544}
545
546#define AM_RAVE_ALIGN 9
547#define AM_WRAP_THRESHOLD 0x100
548
549static  void * itb_ptr;
550
551BERR_Code am_rave_open(struct amessage_capture * cap)
552{
553        BERR_Code berr;
554        BAVC_XptContextMap map;
555        BAVC_CdbItbConfig cfg;
556
557        BKNI_Memset(&cfg, 0, sizeof(BAVC_CdbItbConfig));
558        cfg.Cdb.Length = cap->buffer_size - ATM_PACKET_SIZE + AM_WRAP_THRESHOLD;
559        /* DO we need Itb? */
560        cfg.Itb.Length = 0x300;
561        cfg.Cdb.Alignment = AM_RAVE_ALIGN;
562        cfg.Itb.Alignment = AM_RAVE_ALIGN;
563#if (BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE)
564        cfg.Cdb.LittleEndian = true;
565#else
566        cfg.Cdb.LittleEndian = false;
567#endif
568
569        berr = BXPT_Rave_AllocContext(GetRAVE(), BXPT_RaveCx_eRecord, &cfg, &cap->rav_cx);
570        if(BERR_SUCCESS != berr){
571                goto ExitFunc;
572        }
573        berr = BXPT_Rave_GetContextRegisters(cap->rav_cx, &map);
574        BDBG_ASSERT(BERR_SUCCESS == berr);
575        cap->buffer_ptr = (void*)BREG_Read32(GetREG(), map.CDB_Base);
576        berr = BMEM_ConvertOffsetToAddress(GetHEAP(), (unsigned)cap->buffer_ptr, (void**)&cap->buffer_ptr);
577        if(0 != cfg.Itb.Length){
578                itb_ptr = (void*)BREG_Read32(GetREG(), map.ITB_Base);
579                berr = BMEM_ConvertOffsetToAddress(GetHEAP(), (unsigned)itb_ptr, (void**)&itb_ptr);
580                BKNI_Memset(itb_ptr, 0, cfg.Itb.Length);
581        }
582ExitFunc:
583        return berr;
584}
585
586BERR_Code am_rave_close(struct amessage_capture * cap)
587{
588        BERR_Code berr;
589
590        if(NULL == cap->rav_cx){
591                return BERR_SUCCESS;
592        }
593        berr = BXPT_Rave_FreeContext(cap->rav_cx);
594        if(BERR_SUCCESS == berr){
595                cap->rav_cx = NULL;
596                cap->buffer_ptr = NULL;
597                cap->buffer_threshold = 0;
598        }
599        return berr;
600}
601
602BERR_Code am_rave_start(struct amessage_capture * cap)
603{
604        BERR_Code berr;
605        BXPT_Rave_RecordSettings rec_cfg;
606
607        berr = BXPT_Rave_FlushContext(cap->rav_cx);
608        if(BERR_SUCCESS != berr){
609                goto ExitError;
610        }
611        berr = BXPT_Rave_GetRecordConfig(cap->rav_cx, &rec_cfg);
612        if(BERR_SUCCESS != berr){
613                goto ExitError;
614        }
615        /* DirecTV mode? */
616        //rec_cfg.MpegMode = true;
617        rec_cfg.MpegMode = false;
618        rec_cfg.OutputFormat = BAVC_StreamType_eTsMpeg;
619        rec_cfg.UseTimeStamps = false;
620        rec_cfg.CountRecordedPackets = true;
621        rec_cfg.TsInitEn = false;
622        rec_cfg.StreamIdLo = 0xEF;
623        rec_cfg.StreamIdHi = 0xFF;
624        cap->buffer_threshold = cap->buffer_size/2;
625        rec_cfg.CdbUpperThreshold = cap->buffer_threshold/256;
626        rec_cfg.CdbLowerThreshold = 0x1;
627        rec_cfg.ItbUpperThreshold = 0x300;
628        rec_cfg.ItbLowerThreshold = 0x300;
629
630        /* extra settings for ATM handling */
631        rec_cfg.DisableContinuityCheck = true;
632        rec_cfg.DisablePacketErrors = true;
633
634        berr = BXPT_Rave_SetRecordConfig(cap->rav_cx, &rec_cfg);
635        if(BERR_SUCCESS != berr){
636                goto ExitError;
637        }
638        berr = BXPT_Rave_EnableContext(cap->rav_cx);
639        if(BERR_SUCCESS != berr){
640                goto ExitError;
641        }
642        /* we use a fixed PID channel */
643        if (b_ok == berr) {
644                berr = BXPT_Rave_AddPidChannel(cap->rav_cx, START_PID_CHANNEL, false);
645        }
646
647ExitError:
648        return berr;
649}
650
651BERR_Code am_rave_stop(struct amessage_capture * cap)
652{
653        BERR_Code berr;
654        BXPT_Rave_RecordSettings rec_cfg;
655
656        /* enable error checking */
657        berr = BXPT_Rave_GetRecordConfig(cap->rav_cx, &rec_cfg);
658        if (b_ok == berr) {
659                /* extra configuration for ATM packet handling */
660                rec_cfg.DisableContinuityCheck = false;
661                rec_cfg.DisablePacketErrors = false;
662                berr = BXPT_Rave_SetRecordConfig(cap->rav_cx, &rec_cfg);
663        }
664        berr = BXPT_Rave_DisableContext(cap->rav_cx);
665        if (b_ok == berr) {
666                berr = BXPT_Rave_RemovePidChannel(cap->rav_cx, START_PID_CHANNEL);
667        }
668        return berr;
669}
670
671struct amessage_vpi_vci *am_rave_add_vpi_vci(struct amessage_capture * cap, uint8_t vpi, uint16_t vci)
672{
673        int i;
674
675        /* add new VPI/VCI for filtering, TODO will add amessage filter instead in separate place */
676        for (i = 0; i < MAX_VPI_VCIS; i++) {
677                if ((0 == am_st.vpi_vci[i].vpi) && (0 == am_st.vpi_vci[i].vci)) {
678                        am_st.vpi_vci[i].vpi = vpi;
679                        am_st.vpi_vci[i].vci = vci;
680                        am_st.vpi_vci_pairs++;
681                        /* something wrong */
682                        if (am_st.vpi_vci_pairs >= MAX_VPI_VCIS) {
683                                am_st.vpi_vci_pairs = MAX_VPI_VCIS;
684                        }
685                        return &am_st.vpi_vci[i];
686                }
687        }
688        return NULL;
689}
690
691BERR_Code am_rave_remove_vpi_vci(struct amessage_capture * cap, struct amessage_vpi_vci * am_vpi_vci)
692{
693        BERR_Code berr = b_ok;
694        int i;
695
696        for (i = 0; i < am_st.vpi_vci_pairs; i++) {
697                /* if find match */
698                if ((am_vpi_vci->vpi == am_st.vpi_vci[i].vpi) && (am_vpi_vci->vpi == am_st.vpi_vci[i].vci)) {
699                        am_st.vpi_vci[i].vpi = 0;
700                        am_st.vpi_vci[i].vci = 0;
701                        am_st.vpi_vci_pairs--;
702                        /* something wrong */
703                        if (am_st.vpi_vci_pairs < 0) {
704                                am_st.vpi_vci_pairs = 0;
705                        }
706                        return b_ok;
707                }
708        }
709        return berr;
710}
711
712BERR_Code am_rave_process_data(struct amessage_capture * cap)
713{
714        BERR_Code berr;
715        BXPT_Rave_ContextPtrs ptrs;
716        BXPT_RaveCx_Status status;
717        size_t consumed;
718        void *buf_cached;
719
720        berr = BXPT_Rave_GetContextStatus(cap->rav_cx, &status);
721        if(BERR_SUCCESS != berr){
722                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
723                goto ExitFunc;
724        }
725        if((true == status.CdbOverflow) || (true == status.ItbOverflow)){
726                BDBG_ERR(("%s:%d cdb/itb(%d/%d) overflow ",__FILE__, __LINE__,status.CdbOverflow, status.ItbOverflow));
727        }
728
729        berr = BXPT_Rave_CheckBuffer(cap->rav_cx, &ptrs);
730        if(BERR_SUCCESS != berr){
731                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
732                goto ExitFunc;
733        }
734        if(0 != ptrs.Cdb.ByteCount){
735                berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.DataPtr, &buf_cached);
736                if (BERR_SUCCESS != berr) {
737                        buf_cached = ptrs.Cdb.DataPtr;
738                } else {       
739                        BMEM_Heap_FlushCache(GetHEAP(), buf_cached, ptrs.Cdb.ByteCount);
740                }
741                consumed = amsg_feed(buf_cached, ptrs.Cdb.ByteCount);
742                if(0 != ptrs.Cdb.WrapByteCount){
743                        berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.WrapDataPtr, &buf_cached);
744                        if (BERR_SUCCESS != berr) {
745                                buf_cached = ptrs.Cdb.WrapDataPtr;
746                        } else {
747                                BMEM_Heap_FlushCache(GetHEAP(), buf_cached, ptrs.Cdb.WrapByteCount);
748                        }
749                        consumed += amsg_feed(buf_cached, ptrs.Cdb.WrapByteCount);
750                }
751                berr = BXPT_Rave_UpdateReadOffset(cap->rav_cx, consumed, 0);
752        }
753ExitFunc:
754        return berr;
755}
756
757BERR_Code am_rave_get_buffer(struct amessage_capture * cap, const void ** pbuffer, size_t * plength)
758{
759        BERR_Code berr;
760        BXPT_Rave_ContextPtrs ptrs;
761        BXPT_RaveCx_Status status;
762        void *buf_cached;
763
764        berr = BXPT_Rave_GetContextStatus(cap->rav_cx, &status);
765        if(BERR_SUCCESS != berr){
766                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
767                goto ExitFunc;
768        }
769        if((true == status.CdbOverflow) || (true == status.ItbOverflow)){
770                BDBG_ERR(("%s:%d cdb/itb(%d/%d) overflow ",__FILE__, __LINE__,status.CdbOverflow, status.ItbOverflow));
771        }
772
773        berr = BXPT_Rave_CheckBuffer(cap->rav_cx, &ptrs);
774        if(BERR_SUCCESS != berr){
775                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
776                goto ExitFunc;
777        }
778        *plength = ptrs.Cdb.ByteCount;
779        berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.DataPtr, &buf_cached);
780        if (BERR_SUCCESS != berr) {
781                buf_cached = ptrs.Cdb.DataPtr;
782        } else {
783                BMEM_Heap_FlushCache(GetHEAP(), buf_cached, *plength);
784        } 
785        *pbuffer = buf_cached;
786ExitFunc:
787        return berr;
788}
789
790BERR_Code am_rave_read_complete(struct amessage_capture * cap, size_t consumed)
791{
792        return BXPT_Rave_UpdateReadOffset(cap->rav_cx, consumed, 0);
793}
794
795void am_set_input_band_config(int ib)
796{
797        BXPT_InputBandConfig ib_config;
798        BERR_Code berr;
799
800        ib_config.ClockPolSel = BXPT_Polarity_eActiveHigh;
801        ib_config.SyncPolSel = BXPT_Polarity_eActiveHigh;
802        ib_config.DataPolSel = BXPT_Polarity_eActiveHigh;
803        ib_config.ValidPolSel = BXPT_Polarity_eActiveHigh;
804        ib_config.ErrorPolSel = BXPT_Polarity_eActiveHigh;
805        ib_config.EnableErrorInput = false;
806        ib_config.SyncDetectEn = false;
807        ib_config.UseSyncAsValid = false;
808        ib_config.ForceValid = false;
809        ib_config.LsbFirst = false;
810        ib_config.IbPktLength = ATM_PACKET_SIZE;
811
812        berr = BXPT_SetInputBandConfig(GetXPT(), ib, &ib_config);
813        if(BERR_SUCCESS != berr){
814                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
815        }
816}
817
818void am_set_parser_config(bband_t band)
819{
820        uint32_t RegAddr, Reg;
821        BXPT_PidChannel_CC_Config cfg;
822        BXPT_ParserConfig       pCfg;
823
824        /*RLQ, we should use variable name of parser insteand band */
825
826        /* there is no XPT function to set register values we want, hack it here first */
827        /* The parser config registers are at consecutive addresses. */
828        RegAddr = BCHP_XPT_FE_MINI_PID_PARSER0_CTRL1 + (band * PARSER_REG_STEPSIZE);
829        Reg = BREG_Read32( GetREG(), RegAddr );
830
831        Reg &= ~( 
832                BCHP_MASK( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_PACKET_TYPE ) |
833                BCHP_MASK( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_TIMESTAMP_MODE ) |
834                BCHP_MASK( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_PKT_LENGTH ) |
835                BCHP_MASK( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_INPUT_SEL  )
836                );
837
838        Reg |= (
839                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_PACKET_TYPE, 0 ) |
840                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_ERROR_INPUT_TEI_IGNORE, 1 ) |
841                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_ACCEPT_NULL_PKT_PRE_MPOD, 1 ) |
842                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_ALL_PASS_CTRL_PRE_MPOD, 1 ) |
843                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_INPUT_SEL, OOB_IB ) |
844                BCHP_FIELD_DATA( XPT_FE_MINI_PID_PARSER0_CTRL1, PARSER_PKT_LENGTH, ATM_PACKET_SIZE )
845        );
846        BREG_Write32( GetREG(), RegAddr, Reg );
847       
848        /* all pass mode */
849        BXPT_ParserAllPassMode(GetXPT(), band, true);
850        /* for 7574 that has OOB */
851        BXPT_SetParserEnable(GetXPT(),band,true);
852        BXPT_DataSource DataSource;
853        unsigned int WhichSource;
854        BXPT_GetParserDataSource( GetXPT(), band,&DataSource,&WhichSource);
855        /* IB 9 for OOB */
856        WhichSource = OOB_IB;
857        BXPT_SetParserDataSource( GetXPT(), band,DataSource,WhichSource);
858
859        /* set FPP, ignore PCC and SCC for given channel */
860        BXPT_GetPidChannel_CC_Config(GetXPT(), band, &cfg);
861        cfg.Primary_CC_CheckEnable = false;
862        cfg.Secondary_CC_CheckEnable = false;
863        BXPT_SetPidChannel_CC_Config(GetXPT(), band, &cfg);
864
865        /* Accept packet with adaption filed of 00 from given parser */
866        BXPT_GetParserConfig(GetXPT(), band, &pCfg);
867        pCfg.AcceptAdapt00 = true;
868        BXPT_SetParserConfig(GetXPT(), band, &pCfg);
869}
870
871/* find an unused CAP context */
872BERR_Code am_allocate_capture(unsigned int * cap_index)
873{
874        unsigned int i;
875
876        for (i = 0; i < MAX_CAP; i++){
877                if(0 == am_st.cap[i].in_use){
878                        *cap_index = i;
879                        am_st.cap[i].in_use = true;
880                        return BERR_SUCCESS;
881                }
882        }
883        return BERR_OS_ERROR;
884}
885
886void am_free_capture(unsigned int cap_index)
887{
888        am_st.cap[cap_index].in_use = false;   
889}
Note: See TracBrowser for help on using the repository browser.