source: svn/trunk/newcon3bcm2_21bu/dta/src/settop_api/bsettop_smessage_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: 26.6 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2008, 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 *
14 * Module Description: message filtering module
15 *
16 ***************************************************************************/
17
18#include "bsettop_smessage.h"
19#include "blst_slist.h"
20#include "ministd.h"
21
22#include "bstd.h"
23#include "bkni.h"
24#include "bdbg.h"
25#include "bxpt.h"
26#include "bxpt_rave.h"
27#include "bchp_xpt_fe.h"
28
29#include "msg_filter.h"
30#include "bos.h"
31#include "gist.h"
32BDBG_MODULE(smsg);
33
34#define MSG_VERBOSE 0
35#if MSG_VERBOSE & 1
36#define BDBG_MSG_1(x) BDBG_MSG(x)
37#else
38#define BDBG_MSG_1(x) BDBG_NOP()
39#endif
40
41#define START_PID_CHANNEL 8
42#define B_INVALID_PID 0xFFFF
43#define B_INVALID_PID_CHANNEL SMESSAGE_INVALID_CHANNEL
44#define B_INVALID_BAND ((bband_t)(-1))
45#define FILTER_SIZE 16
46#define TS_PACKET_SIZE 188
47#define SM_MAGIC 0xBADBABE0
48#define SM_BUFFER_SIZE (188 * 512)
49#define SM_WAIT (-1)
50#define SM_POLL_INTERVAL 50
51#define MAX_CAP 4
52#define FILTER_CAP 0
53
54enum sm_task_state_t {
55    STS_NONE,
56    STS_IDLE,
57    STS_RUN
58};
59
60struct smessage_pid;
61
62struct smessage_stream {
63    BLST_S_ENTRY(smessage_stream) next;
64    smessage_format format;
65    struct smessage_pid * sm_pid;
66    struct filter_state_t * msg_filter;
67    smessage_callback callback;
68    smessage_callback overflow;
69    void * context;
70    void *priv;
71    unsigned int cap_index;
72};
73
74BLST_S_HEAD(smessage_stream_list_t, smessage_stream);
75
76struct smessage_pid {
77    uint16_t pid;
78    uint16_t pid_channel;
79    uint16_t user_pid_channel;
80    struct smessage_stream_list_t filters;
81};
82
83struct smessage_capture {
84    bool in_use;
85    uint8_t * buffer_ptr;
86    uint32_t buffer_size;
87    BXPT_RaveCx_Handle rav_cx;
88    uint32_t buffer_threshold;
89};
90
91struct smessage_state {
92    uint32_t magic;
93    bband_t band;
94
95    b_task_t task;
96    b_mutex_t lock;
97    enum sm_task_state_t task_state;
98
99    struct smessage_capture cap[MAX_CAP];
100    struct smessage_pid pids[MAX_PIDS];
101    struct smessage_stream_list_t free_filter;
102    struct smessage_stream dummy0[MAX_FILTERS];
103};
104
105static struct smessage_state sm_st;
106
107#define SM_STACK_SIZE 0x100             /* changed from 0x400 */
108#define SM_PRIORITY 16
109static unsigned int sm_stack[SM_STACK_SIZE];
110static char * sm_task_name = "msg";
111
112static struct smessage_pid * sm_find_pid(uint16_t pid);
113static void * sm_message_callback(void * context, size_t msg_size);
114static void sm_parser_task(void * param);
115
116static BERR_Code sm_rave_open(struct smessage_capture * cap);
117static BERR_Code sm_rave_close(struct smessage_capture * cap);
118static BERR_Code sm_rave_start(struct smessage_capture * cap);
119static BERR_Code sm_rave_stop(struct smessage_capture * cap);
120static BERR_Code sm_rave_add_pid(struct smessage_capture * cap, struct smessage_pid * sm_pid);
121static BERR_Code sm_rave_remove_pid(struct smessage_capture * cap, struct smessage_pid * sm_pid);
122static BERR_Code sm_rave_process_data(struct smessage_capture * cap);
123static BERR_Code sm_rave_get_buffer(struct smessage_capture * cap, const void ** pbuffer, size_t * plength);
124static BERR_Code sm_rave_read_complete(struct smessage_capture * cap, size_t consumed);
125
126static void sm_set_input_band_config(bband_t band);
127static void sm_set_parser_config(bband_t band);
128static BERR_Code sm_allocate_capture(unsigned int * cap_index);
129static void sm_free_capture(unsigned int cap_index);
130
131/*
132  Summary:
133  Initialize the message system.
134 */
135bresult smessage_init(void *decode_cfgs)
136{
137    int i;
138    b_task_params t_param;
139    bresult bres = b_ok;
140    BDBG_MSG_1(("%s", __PRETTY_FUNCTION__));
141    BKNI_Memset(&sm_st, 0, sizeof(struct smessage_stream));
142    BLST_S_INIT(&sm_st.free_filter);
143    for(i = 0; i < MAX_FILTERS; i ++){
144        BLST_S_INSERT_HEAD(&sm_st.free_filter, &sm_st.dummy0[i], next);
145    }
146    for(i = 0; i < MAX_PIDS; i ++){
147        sm_st.pids[i].pid = B_INVALID_PID;
148        sm_st.pids[i].pid_channel = START_PID_CHANNEL + i;
149        sm_st.pids[i].user_pid_channel = B_INVALID_PID_CHANNEL;
150        BLST_S_INIT(&sm_st.pids[i].filters);
151    }
152
153    for(i = 0; i < MAX_CAP; i++){
154        sm_st.cap[i].buffer_size = SM_BUFFER_SIZE;
155        sm_st.cap[i].in_use = 0;
156    }
157    /* allocate filter capture */
158    sm_st.cap[FILTER_CAP].in_use = 1;
159
160    msg_init();
161
162    bres = bos_create_mutex(&sm_st.lock);
163    if(b_ok != bres){
164        goto ExitFunc;
165    }
166    sm_st.task_state = STS_IDLE;
167    t_param.priority = SM_PRIORITY;
168    t_param.stack_size = SM_STACK_SIZE;
169    t_param.stack = sm_stack;
170    t_param.name = sm_task_name;
171    bres = bos_start_task(&sm_st.task, &t_param, sm_parser_task, NULL);
172    sm_st.band = B_INVALID_BAND;
173    sm_st.magic = SM_MAGIC;
174ExitFunc:
175    return bres;
176}
177
178/*
179  Summary:
180  Cleanup the messages system
181 */
182bresult smessage_uninit()
183{
184    sm_st.magic = 0;
185    return b_ok;
186}
187
188/*
189  Summary:
190  Open a message stream for a particular format of data
191 */
192smessage_stream_t smessage_open(smessage_format format)
193{
194    smessage_stream_t st;
195    unsigned int cap_index;
196    BERR_Code berr;
197
198    st = NULL;
199    switch (format){
200    case smessage_format_psi:
201    case smessage_format_tsc:
202        st = BLST_S_FIRST(&sm_st.free_filter);
203        if(NULL != st){
204            BLST_S_REMOVE_HEAD(&sm_st.free_filter, next);
205            st->format = format;
206            st->cap_index = FILTER_CAP;
207        }
208        break;
209    case smessage_format_ts:
210        /* Ideally we should open rave in this function but we do not have
211         buffer size yet so we can not do it. We defer opening rave to start
212         function */
213        berr = sm_allocate_capture(&cap_index);
214        if(BERR_SUCCESS != berr){
215            break;
216        }
217        st = BLST_S_FIRST(&sm_st.free_filter);
218        if(NULL != st){
219            BLST_S_REMOVE_HEAD(&sm_st.free_filter, next);
220            st->format = format;
221            st->cap_index = cap_index;
222        }else{
223            sm_free_capture(cap_index);
224        }
225    default:
226        break;
227    }
228    return st;
229}
230/*
231  Summary:
232  Close a message stream
233 */
234void smessage_close(smessage_stream_t stream)
235{
236    BERR_Code berr;
237    if(NULL != stream->sm_pid){
238        if(b_ok != smessage_stop(stream)){
239            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
240        }
241    }
242    if(smessage_format_ts == stream->format){
243        berr = sm_rave_close(&sm_st.cap[stream->cap_index]);
244        if(BERR_SUCCESS == berr){
245            sm_free_capture(stream->cap_index);
246        }else{
247            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
248        }
249    }
250    BLST_S_INSERT_HEAD(&sm_st.free_filter, stream, next);
251}
252
253/*
254  Summary:
255  Initialize parameters structure
256*/
257void smessage_stream_params_init( smessage_stream_params_t *params, smessage_stream_t stream)
258{
259    int i;
260    if(NULL != params){
261        BKNI_Memset(params, 0, sizeof(smessage_stream_params_t));
262        params->band = B_INVALID_BAND;
263        params->pid = B_INVALID_PID;
264        params->pid_channel = B_INVALID_PID_CHANNEL;
265        for(i = 0; i < FILTER_SIZE; i++){
266            params->filter.mask[i] = 0xFF;
267            params->filter.excl[i] = 0xFF;
268        }
269    }
270}
271
272/*
273  Summary:
274  Capture message according to the parameters
275 */
276bresult smessage_start(const smessage_stream_params_t * params, smessage_stream_t stream)
277{
278    bresult  bres;
279    msg_params_t m_params;
280    struct smessage_pid * new_pid;
281    BERR_Code berr;
282    bool adding_pid;
283   
284    BDBG_ASSERT(NULL != stream);
285    BDBG_ASSERT(NULL != params);
286    switch(stream->format){
287    case smessage_format_psi:
288    case smessage_format_tsc:
289        if((NULL == params->buffer) || (0 == params->buffer_size) || 
290           (NULL == params->data_ready_callback)){
291            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
292            bres = berr_invalid_parameter;
293            goto ExitFunc;
294        }
295        break;
296    case smessage_format_ts:
297        if(0 == params->buffer_size){
298            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
299            bres = berr_invalid_parameter;
300            goto ExitFunc;
301        }
302        break;
303    default:
304            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
305            bres = berr_invalid_parameter;
306            goto ExitFunc;
307    }
308    if(B_INVALID_BAND == params->band){
309        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
310        bres = berr_invalid_parameter;
311        goto ExitFunc;
312    }
313    /* we only can accept user pid channel if it is outside of managed range */
314    if(B_INVALID_PID_CHANNEL != params->pid_channel){
315        if((START_PID_CHANNEL <= params->pid_channel) && ((START_PID_CHANNEL+MAX_PIDS) > params->pid_channel)){
316            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
317            bres = berr_invalid_parameter;
318            goto ExitFunc;
319        }
320    }
321
322    /* stream is already started and can not be started twice */
323    if(NULL != stream->sm_pid){
324        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
325        bres = berr_invalid_parameter;
326        goto ExitFunc;
327    }
328    bres = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
329    if(b_ok != bres){
330        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
331        goto ExitFunc;
332    }
333
334    adding_pid = 0;
335    /* allocate new pid or reuse existing pid */
336    new_pid = sm_find_pid(params->pid);
337    if(NULL == new_pid){        /* find empty pid slot */
338        new_pid = sm_find_pid(B_INVALID_PID);
339        if(NULL == new_pid){
340            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
341            bres = berr_not_supported;
342            goto ExitUnlock;
343        }
344        adding_pid = 1;
345    }
346
347    m_params.pid = params->pid;
348    memcpy(m_params.filt.coef, params->filter.coef, FILTER_SIZE);
349    memcpy(m_params.filt.mask, params->filter.mask, FILTER_SIZE);
350    memcpy(m_params.filt.excl, params->filter.excl, FILTER_SIZE);
351    m_params.capture_ts = (smessage_format_tsc == stream->format);
352    m_params.buffer = params->buffer;
353    m_params.buffer_size = params->buffer_size;
354    m_params.disable_crc_check = params->crc_disabled;
355    m_params.callback = sm_message_callback;
356    m_params.context = (void*)stream;
357    switch(stream->format){
358    case smessage_format_psi:
359    case smessage_format_tsc:
360        stream->msg_filter = msg_set_filter(&m_params);
361        if(NULL == stream->msg_filter){
362            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
363            bres = berr_not_supported;
364            goto ExitUnlock;
365        }
366        break;
367    case smessage_format_ts:
368        stream->msg_filter = NULL;
369        break;
370    }
371    stream->callback = params->data_ready_callback;
372    stream->overflow = params->overflow;
373    stream->context = params->callback_context;
374    stream->priv = params->priv;
375
376    new_pid->pid = params->pid;
377    new_pid->user_pid_channel = params->pid_channel;
378    BLST_S_INSERT_HEAD(&new_pid->filters, stream, next);
379    stream->sm_pid = new_pid;
380    sm_st.band = params->band;
381    /* we need to open rave if it is not yet opened */
382    if(NULL == sm_st.cap[stream->cap_index].rav_cx){
383        if(smessage_format_ts == stream->format){
384            sm_st.cap[stream->cap_index].buffer_size = m_params.buffer_size;
385        }
386        berr = sm_rave_open(&sm_st.cap[stream->cap_index]);
387        if(BERR_SUCCESS != berr){
388            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
389            bres = berr_out_of_memory;
390            goto ExitUnlock;
391        }
392    }
393    if(1 == adding_pid){
394        uint16_t pid_channel;
395
396        pid_channel = (B_INVALID_PID_CHANNEL == new_pid->user_pid_channel) ? new_pid->pid_channel : new_pid->user_pid_channel;
397        berr = sm_rave_add_pid(&sm_st.cap[stream->cap_index], new_pid);
398        if(BERR_SUCCESS != berr){
399            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
400            bres = berr_external_error;
401            goto ExitUnlock;
402        }
403        berr = BXPT_ConfigurePidChannel(GetXPT(), pid_channel, new_pid->pid, sm_st.band);
404        if(BERR_SUCCESS != berr){
405            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
406            bres = berr_external_error;
407            goto ExitUnlock;
408        }
409        berr = BXPT_EnablePidChannel(GetXPT(), pid_channel);
410        if(BERR_SUCCESS != berr){
411            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
412            bres = berr_external_error;
413            goto ExitUnlock;
414        }
415    }
416
417    if((sm_st.task_state != STS_RUN) || (smessage_format_ts == stream->format)){
418        sm_set_input_band_config(sm_st.band);
419        sm_set_parser_config(sm_st.band);
420        berr = sm_rave_start(&sm_st.cap[stream->cap_index]);
421        if(BERR_SUCCESS != berr){
422            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
423            bres = berr_external_error;
424            goto ExitUnlock;
425        }
426        if((sm_st.task_state != STS_RUN) && (smessage_format_ts != stream->format)){
427            sm_st.task_state = STS_RUN;
428        }
429    }
430    bres = b_ok;
431
432ExitUnlock:
433    if(b_ok != bos_release_mutex(&sm_st.lock)){
434        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
435    } 
436ExitFunc:
437    return bres;
438}
439
440bresult smessage_stop(smessage_stream_t stream)
441{
442    BERR_Code berr;
443    bresult bres;
444    struct smessage_pid * sm_pid;
445    BDBG_ASSERT(NULL != stream);
446
447    bres = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
448    if(b_ok != bres){
449        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
450        goto ExitFunc;
451    }
452
453    sm_pid = stream->sm_pid;
454    if(NULL != stream->msg_filter){
455        msg_remove_filter(stream->msg_filter);
456        stream->msg_filter = NULL;
457    }
458    if(NULL != sm_pid){
459        BLST_S_REMOVE(&sm_pid->filters, stream, smessage_stream, next);
460        stream->sm_pid = NULL;
461   
462        if(BLST_S_EMPTY(&sm_pid->filters)){
463            size_t i;
464            uint16_t pid_channel;
465
466            pid_channel = (B_INVALID_PID_CHANNEL == sm_pid->user_pid_channel) ? sm_pid->pid_channel : sm_pid->user_pid_channel;
467            berr = BXPT_DisablePidChannel(GetXPT(), pid_channel);
468            if(BERR_SUCCESS != berr){
469                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
470                bres = berr_external_error;
471                goto ExitUnlock;
472            }
473            berr = sm_rave_remove_pid(&sm_st.cap[stream->cap_index], sm_pid);
474            if(BERR_SUCCESS != berr){
475                BDBG_ERR(("%s:%d",__FILE__, __LINE__));
476                bres = berr_external_error;
477                goto ExitUnlock;
478            }
479
480            sm_pid->pid = B_INVALID_PID;
481            sm_pid->user_pid_channel = B_INVALID_PID_CHANNEL;
482            switch(stream->format){
483            case smessage_format_tsc:
484            case smessage_format_psi:
485                for(i = 0; i < MAX_PIDS; i++){
486                    /* check if we have any pids to process */
487                    if(B_INVALID_PID != sm_st.pids[i].pid){
488                        break;
489                    }
490                }
491                msg_reset_pids();
492                if(MAX_PIDS == i){
493                    berr = sm_rave_stop(&sm_st.cap[stream->cap_index]);
494                    if(BERR_SUCCESS != berr){
495                        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
496                        bres = berr_external_error;
497                        goto ExitUnlock;
498                    }
499                    sm_st.task_state = STS_IDLE;
500                }else{
501                    sm_st.task_state = STS_RUN;
502                }
503                break;
504            case smessage_format_ts:
505                berr = sm_rave_stop(&sm_st.cap[stream->cap_index]);
506                if(BERR_SUCCESS != berr){
507                    BDBG_ERR(("%s:%d",__FILE__, __LINE__));
508                    bres = berr_external_error;
509                    goto ExitUnlock;
510                }
511                sm_st.cap[stream->cap_index].buffer_size = SM_BUFFER_SIZE;
512                break;
513            }
514        }
515    }
516ExitUnlock:
517    if(b_ok != bos_release_mutex(&sm_st.lock)){
518        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
519    } 
520
521ExitFunc:
522    return bres;
523}
524
525bresult smessage_get_buffer(smessage_stream_t stream, const void ** pbuffer, size_t * plength)
526{
527    bresult bres;
528    BERR_Code berr;
529    bres = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
530    if(b_ok != bres){
531        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
532        goto ExitFunc;
533    }
534
535    berr = sm_rave_get_buffer(&sm_st.cap[stream->cap_index], pbuffer, plength);
536    if(BERR_SUCCESS != berr){
537        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
538        bres = berr_external_error;
539    }
540
541    if(b_ok != bos_release_mutex(&sm_st.lock)){
542        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
543    } 
544ExitFunc:
545    return bres;
546}
547
548bresult smessage_read_complete(smessage_stream_t stream, size_t consumed)
549{
550    bresult bres;
551    BERR_Code berr;
552    bres = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
553    if(b_ok != bres){
554        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
555        goto ExitFunc;
556    }
557
558    berr = sm_rave_read_complete(&sm_st.cap[stream->cap_index], consumed);
559    if(BERR_SUCCESS != berr){
560        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
561        bres = berr_external_error;
562    }
563
564    if(b_ok != bos_release_mutex(&sm_st.lock)){
565        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
566    } 
567ExitFunc:
568    return bres;
569}
570
571struct smessage_pid * sm_find_pid(uint16_t pid)
572{
573    struct smessage_pid * res;
574    int i;
575    res = NULL;
576    for(i = 0; i < MAX_PIDS; i++){
577        if(pid == sm_st.pids[i].pid){
578            res = &sm_st.pids[i];
579            goto ExitFunc;
580        }
581    }
582
583ExitFunc:
584    return res;
585}
586
587void * sm_message_callback(void * context, size_t msg_size)
588{
589    void * new_buffer = NULL;
590    smessage_stream_t stream = (smessage_stream_t) context;
591   
592    if(NULL != stream->callback){
593        new_buffer = (stream->callback)(stream->context, msg_size);
594    }
595    return new_buffer;
596}
597
598void sm_parser_task(void * param)
599{
600    bresult bres;
601    BERR_Code berr;
602
603    while(1){
604        bres = bos_acquire_mutex(&sm_st.lock, SM_WAIT);
605        if(b_ok == bres){
606            if(STS_RUN == sm_st.task_state){
607                berr = sm_rave_process_data(&sm_st.cap[FILTER_CAP]);
608                if(BERR_SUCCESS != berr){
609                    BDBG_ERR(("%s:%d", __FILE__, __LINE__));
610                }
611
612            }
613            bres = bos_release_mutex(&sm_st.lock);
614            if(b_ok != bres){
615                BDBG_ERR(("bos_release_mutex failed! exiting ..."));
616                break;
617            }
618        }
619        bos_sleep(SM_POLL_INTERVAL);
620   }
621}
622
623#define SM_RAVE_ALIGN 9
624#define SM_WRAP_THRESHOLD 0x100
625
626static  void * itb_ptr;
627
628BERR_Code sm_rave_open(struct smessage_capture * cap)
629{
630    BERR_Code berr;
631    BAVC_XptContextMap map;
632    BAVC_CdbItbConfig cfg;
633
634    BKNI_Memset(&cfg, 0, sizeof(BAVC_CdbItbConfig));
635    cfg.Cdb.Length = cap->buffer_size - TS_PACKET_SIZE + SM_WRAP_THRESHOLD;
636    /* we need larger buffer than default threshold (0x300) */
637    cfg.Itb.Length = 0x500;
638    cfg.Cdb.Alignment = SM_RAVE_ALIGN;
639    cfg.Itb.Alignment = SM_RAVE_ALIGN;
640#if (BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE)
641    cfg.Cdb.LittleEndian = true;
642#else
643    cfg.Cdb.LittleEndian = false;
644#endif
645   
646    berr = BXPT_Rave_AllocContext(GetRAVE(), BXPT_RaveCx_eRecord, &cfg, &cap->rav_cx);
647    if(BERR_SUCCESS != berr){
648        goto ExitFunc;
649    }
650    berr = BXPT_Rave_GetContextRegisters(cap->rav_cx, &map);
651    BDBG_ASSERT(BERR_SUCCESS == berr);
652    cap->buffer_ptr = (void*)BREG_Read32(GetREG(), map.CDB_Base);
653    berr = BMEM_ConvertOffsetToAddress(GetHEAP(), (unsigned)cap->buffer_ptr, (void**)&cap->buffer_ptr);
654        if(0 != cfg.Itb.Length){
655                itb_ptr = (void*)BREG_Read32(GetREG(), map.ITB_Base);
656                berr = BMEM_ConvertOffsetToAddress(GetHEAP(), (unsigned)itb_ptr, (void**)&itb_ptr);
657                BKNI_Memset(itb_ptr, 0, cfg.Itb.Length);
658        }
659ExitFunc:
660    return berr;
661}
662
663BERR_Code sm_rave_close(struct smessage_capture * cap)
664{
665    BERR_Code berr;
666    if(NULL == cap->rav_cx){
667        berr = BERR_SUCCESS;
668        goto ExitFunc;
669    }
670    berr = BXPT_Rave_FreeContext(cap->rav_cx);
671    if(BERR_SUCCESS == berr){
672        cap->rav_cx = NULL;
673        cap->buffer_ptr = NULL;
674        cap->buffer_threshold = 0;
675    }
676ExitFunc:
677    return berr;
678}
679
680BERR_Code sm_rave_start(struct smessage_capture * cap)
681{
682    BERR_Code berr;
683    BXPT_Rave_RecordSettings rec_cfg;
684
685    berr = BXPT_Rave_FlushContext(cap->rav_cx);
686    if(BERR_SUCCESS != berr){
687        goto ExitError;
688    }
689    berr = BXPT_Rave_GetRecordConfig(cap->rav_cx, &rec_cfg);
690    if(BERR_SUCCESS != berr){
691        goto ExitError;
692    }
693
694    rec_cfg.MpegMode = true;
695    rec_cfg.OutputFormat = BAVC_StreamType_eTsMpeg;
696    rec_cfg.UseTimeStamps = false;
697    rec_cfg.CountRecordedPackets = true;
698    rec_cfg.TsInitEn = false;
699    rec_cfg.StreamIdLo = 0xEF;
700    rec_cfg.StreamIdHi = 0xFF;
701    cap->buffer_threshold = cap->buffer_size/2;
702    rec_cfg.CdbUpperThreshold = cap->buffer_threshold/256;
703    rec_cfg.CdbLowerThreshold = 0x1;
704    rec_cfg.ItbUpperThreshold = 0x400;
705    rec_cfg.ItbLowerThreshold = 0x400;
706
707    berr = BXPT_Rave_SetRecordConfig(cap->rav_cx, &rec_cfg);
708    if(BERR_SUCCESS != berr){
709        goto ExitError;
710    }
711    berr = BXPT_Rave_EnableContext(cap->rav_cx);
712    if(BERR_SUCCESS != berr){
713        goto ExitError;
714    }
715
716ExitError:
717    return berr;
718}
719
720BERR_Code sm_rave_stop(struct smessage_capture * cap)
721{
722    BERR_Code berr;
723
724    berr = BXPT_Rave_DisableContext(cap->rav_cx);
725
726    return (berr);
727}
728
729BERR_Code sm_rave_add_pid(struct smessage_capture * cap, struct smessage_pid * sm_pid)
730{
731    BERR_Code berr;
732    uint16_t pid_channel;
733
734    pid_channel = (B_INVALID_PID_CHANNEL == sm_pid->user_pid_channel) ? sm_pid->pid_channel : sm_pid->user_pid_channel;
735    berr = BXPT_Rave_AddPidChannel(cap->rav_cx, pid_channel, false);
736
737    return berr;
738}
739
740BERR_Code sm_rave_remove_pid(struct smessage_capture * cap, struct smessage_pid * sm_pid)
741{
742    BERR_Code berr;
743    uint16_t pid_channel;
744
745    pid_channel = (B_INVALID_PID_CHANNEL == sm_pid->user_pid_channel) ? sm_pid->pid_channel : sm_pid->user_pid_channel;
746    berr = BXPT_Rave_RemovePidChannel(cap->rav_cx, sm_pid->pid_channel);
747
748    return berr;
749}
750
751BERR_Code sm_rave_process_data(struct smessage_capture * cap)
752{
753    BERR_Code berr;
754    BXPT_Rave_ContextPtrs ptrs;
755    BXPT_RaveCx_Status status;
756    size_t consumed;
757    void *buf_cached;
758
759    berr = BXPT_Rave_GetContextStatus(cap->rav_cx, &status);
760    if(BERR_SUCCESS != berr){
761        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
762        goto ExitFunc;
763    }
764    if((true == status.CdbOverflow) || (true == status.ItbOverflow)){
765        BDBG_ERR(("%s:%d cdb/itb(%d/%d) overflow ",__FILE__, __LINE__,status.CdbOverflow, status.ItbOverflow));
766    }
767
768    berr = BXPT_Rave_CheckBuffer(cap->rav_cx, &ptrs);
769    if(BERR_SUCCESS != berr){
770        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
771        goto ExitFunc;
772    }
773    if(0 != ptrs.Cdb.ByteCount){
774        berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.DataPtr, &buf_cached);
775        if (BERR_SUCCESS != berr) {
776            buf_cached = ptrs.Cdb.DataPtr;
777        } else {       
778                BMEM_Heap_FlushCache(GetHEAP(), buf_cached, ptrs.Cdb.ByteCount);
779        }
780        consumed = msg_feed(buf_cached, ptrs.Cdb.ByteCount);
781        if(0 != ptrs.Cdb.WrapByteCount){
782            berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.WrapDataPtr, &buf_cached);
783            if (BERR_SUCCESS != berr) {
784                buf_cached = ptrs.Cdb.WrapDataPtr;
785            } else {
786                BMEM_Heap_FlushCache(GetHEAP(), buf_cached, ptrs.Cdb.WrapByteCount);
787            }
788            consumed += msg_feed(buf_cached, ptrs.Cdb.WrapByteCount);
789        }
790        berr = BXPT_Rave_UpdateReadOffset(cap->rav_cx, consumed, 0);
791    }
792ExitFunc:
793    return berr;
794}
795
796BERR_Code sm_rave_get_buffer(struct smessage_capture * cap, const void ** pbuffer, size_t * plength)
797{
798    BERR_Code berr;
799    BXPT_Rave_ContextPtrs ptrs;
800    BXPT_RaveCx_Status status;
801    void *buf_cached;
802
803    berr = BXPT_Rave_GetContextStatus(cap->rav_cx, &status);
804    if(BERR_SUCCESS != berr){
805        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
806        goto ExitFunc;
807    }
808    if((true == status.CdbOverflow) || (true == status.ItbOverflow)){
809        BDBG_ERR(("%s:%d cdb/itb(%d/%d) overflow ",__FILE__, __LINE__,status.CdbOverflow, status.ItbOverflow));
810    }
811
812    berr = BXPT_Rave_CheckBuffer(cap->rav_cx, &ptrs);
813        if(BERR_SUCCESS != berr){
814            BDBG_ERR(("%s:%d",__FILE__, __LINE__));
815            goto ExitFunc;
816        }
817    *plength = ptrs.Cdb.ByteCount;
818    berr = BMEM_Heap_ConvertAddressToCached(GetHEAP(), (void *)ptrs.Cdb.DataPtr, &buf_cached);
819    if (BERR_SUCCESS != berr) {
820        buf_cached = ptrs.Cdb.DataPtr;
821    } else {
822        BMEM_Heap_FlushCache(GetHEAP(), buf_cached, *plength);
823    } 
824    *pbuffer = buf_cached;
825ExitFunc:
826    return berr;
827}
828
829BERR_Code sm_rave_read_complete(struct smessage_capture * cap, size_t consumed)
830{
831    BERR_Code berr;
832
833    berr =  BXPT_Rave_UpdateReadOffset(cap->rav_cx, consumed, 0);
834
835    return berr;
836}
837
838void sm_set_input_band_config(bband_t band)
839{
840    BXPT_InputBandConfig ib_config;
841    BERR_Code berr;
842    ib_config.ClockPolSel = BXPT_Polarity_eActiveHigh;
843    ib_config.SyncPolSel = BXPT_Polarity_eActiveHigh;
844    ib_config.DataPolSel = BXPT_Polarity_eActiveHigh;
845    ib_config.ValidPolSel = BXPT_Polarity_eActiveHigh;
846    ib_config.ErrorPolSel = BXPT_Polarity_eActiveHigh;
847    ib_config.EnableErrorInput = false;
848    ib_config.SyncDetectEn = false;
849    ib_config.UseSyncAsValid = false;
850    ib_config.ForceValid = false;
851    ib_config.LsbFirst = false;
852    ib_config.IbPktLength = 0xbc;
853#if (BCHP_CHIP == 3563)
854    ib_config.ParallelInputSel = true;
855#endif
856    berr = BXPT_SetInputBandConfig(GetXPT(), band, &ib_config);
857    if(BERR_SUCCESS != berr){
858        BDBG_ERR(("%s:%d",__FILE__, __LINE__));
859    }
860}
861
862#define SM_PARSER 0
863
864void sm_set_parser_config(bband_t band)
865{
866#if 1 /* should already be done  */
867        /* for 7574 that has OOB */
868        BXPT_SetParserEnable(GetXPT(),band,true);
869#if (BCHP_CHIP == 7552)   
870        {
871                BXPT_DataSource DataSource;
872                unsigned int WhichSource;
873                BXPT_GetParserDataSource( GetXPT(), SM_PARSER,&DataSource,&WhichSource);
874                WhichSource = PARSER_BAND;
875                BXPT_SetParserDataSource( GetXPT(), SM_PARSER,DataSource,WhichSource);
876        }
877#endif
878#else
879    BXPT_ParserConfig config;
880   
881#if (BCHP_CHIP == 7002)   
882    BDBG_ASSERT(band < 3);
883#elif (BCHP_CHIP == 3563)
884    BDBG_ASSERT(band < 5);
885#endif
886
887    BXPT_GetParserConfig(GetXPT(), SM_PARSER, &config);
888    config.Reg |= BCHP_FIELD_DATA(XPT_FE_PARSER0_CTRL1, PARSER_INPUT_SEL, band) | BCHP_FIELD_DATA(XPT_FE_PARSER0_CTRL1, PARSER_ENABLE, 1);
889    BXPT_SetParserConfig(GetXPT(), SM_PARSER, &config);
890#endif
891}
892
893BERR_Code sm_allocate_capture(unsigned int * cap_index)
894{
895    BERR_Code berr;
896    unsigned int i;
897    for( i = 0; i < MAX_CAP; i ++){
898        if(0 == sm_st.cap[i].in_use){
899            break;
900        }
901    }
902    if(MAX_CAP == i){
903        berr = BERR_OS_ERROR;
904    }else{
905        *cap_index = i;
906        sm_st.cap[i].in_use = 1;
907        berr = BERR_SUCCESS;
908    }
909    return berr;
910}
911
912void sm_free_capture(unsigned int cap_index)
913{
914    sm_st.cap[cap_index].in_use = 0;   
915}
Note: See TracBrowser for help on using the repository browser.