xref: /utopia/UTPA2-700.0.x/modules/dscmb/drv/nds/nds_flt.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file    drvNDS.c
98 /// @brief  NDS Driver Interface
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101 
102 //-------------------------------------------------------------------------------------------------
103 //  Include Files
104 //-------------------------------------------------------------------------------------------------
105 #include "MsCommon.h"
106 #ifdef MSOS_TYPE_LINUX
107 #include "string.h"
108 #endif
109 
110 #include "asmCPU.h"
111 #include "regNDS.h"
112 #include "drvNDS.h"
113 #include "halNDS.h"
114 #if defined(CHIP_U3)
115 #include "../tsp/drvTSP.h"
116 // TSP2 to TSP wrapper
117 #define E_TSP_OK                        DRVTSP_OK
118 #define E_TSP_FAIL                      DRVTSP_FAIL
119 #define E_TSP_FLT_SRC_TSIF0             E_DRVTSP_FLT_SOURCE_TYPE_LIVE
120 #define E_TSP_FLT_USER_SEC              E_DRVTSP_FLT_TYPE_SECTION
121 #define E_TSP_FLT_USER_PKT              E_DRVTSP_FLT_TYPE_PACKET
122 #define E_TSP_FLT_USER_EMM              E_DRVTSP_FLT_TYPE_EMM
123 #define E_TSP_FLT_USER_ECM              E_DRVTSP_FLT_TYPE_ECM
124 #define TSP_FltState                    DrvTSP_FltState
125 #define E_TSP_FLT_STATE_FREE            E_DRVTSP_FLT_STATE_FREE
126 #define TSP_PID_NULL                    DRVTSP_PID_NULL
127 #define MDrv_TSP_FLT_Alloc(i, p...)     MDrv_TSP_PidFlt_Alloc(0, p)
128 #define MDrv_TSP_FLT_SetPID(p...)       MDrv_TSP_PidFlt_SetPid(0, p)
129 #define MDrv_TSP_FLT_Enable(p...)       MDrv_TSP_PidFlt_Enable(0, p)
130 #define MDrv_TSP_FLT_Free(p...)         MDrv_TSP_PidFlt_Free(0, p)
131 #define MDrv_TSP_FLT_GetState(p...)     MDrv_TSP_PidFlt_GetState(0, p)
132 #else
133 #include "../tsp2/drvTSP2.h"
134 #endif
135 
136 #include "ddiNDS_HDI.h"
137 
138 #include "nds.h"
139 
140 #define NDS_FLT_DBG(_fmt, _args...)     { } // printf(_fmt, ##_args)
141 
142 
143 //-------------------------------------------------------------------------------------------------
144 //  Driver Compiler Options
145 //-------------------------------------------------------------------------------------------------
146 #define NDS_EMM_PASSIVE                 1
147 
148 //-------------------------------------------------------------------------------------------------
149 //  Local Defines
150 //-------------------------------------------------------------------------------------------------
151 
152 //FIXME: it's no use?
153 #define NDS_FLT_ENTRY()                 MsOS_ObtainMutex(_nds_flt_mutexid, MSOS_WAIT_FOREVER)
154 #define NDS_FLT_RETURN(_ret)            { MsOS_ReleaseMutex(_nds_flt_mutexid); return _ret; }
155 #define NDS_FLT_LOCK()                  MsOS_ObtainMutex(_nds_flt_mutexid, MSOS_WAIT_FOREVER)
156 #define NDS_FLT_UNLOCK()                MsOS_ReleaseMutex(_nds_flt_mutexid)
157 // -jerry
158 
159 #define NDS_EMM_EVENT_BUFFER            0x00000010      // 0x00000010-0x00000019
160 #define NDS_EMM_EVENT_BUFFER_MASK       0x0000000F
161 #define NDS_EMM_EVENT_OVERFLOW_HW       0x00000020
162 #define NDS_EMM_EVENT_OVERFLOW_SW       0x00000040
163 #define NDS_ECM_EVENT_FILTER            0x00FFFF00
164 #define NDS_ECM_EVENT_FILTER_SHFT       8
165 #define NDS_ECM_EVENT_OVERFLOW          0xFF000000
166 #define NDS_ECM_EVENT_OVERFLOW_SHFT     24
167 #define NDS_ALL_EVENT                   0xFFFFFFFF
168 
169 #define NDS_FLT_OS_AttachInterrupt(isr)  MsOS_AttachInterrupt(NDS_INT_EMM_ECM, isr)
170 #define NDS_FLT_OS_EnableInterrupt()     MsOS_EnableInterrupt(NDS_INT_EMM_ECM );
171 #define NDS_FLT_OS_DisableInterrupt()    MsOS_DisableInterrupt(NDS_INT_EMM_ECM );
172 #define NDS_FLT_OS_DetachInterrupt()     MsOS_DetachInterrupt(NDS_INT_EMM_ECM);
173 
174 
175 #define GET_4BYTE( cp )                 ( ( ( (MS_U32)(*cp) )<< 24 ) | ( ( (MS_U32)(*(cp+1)) ) << 16 ) | ( ( (MS_U32)(*(cp+2)) ) << 8 ) | ( (MS_U32)(*(cp+3)) ) )
176 
177 #define NDS_FLT_NULL                    0xFFFFFFFF
178 
179 #define NDS_FLT_TASK_STACK_SIZE         4096
180 
181 
182 //------------------------------------------------------------------------------------------
183 
184 //-------------------------------------------------------------------------------------------------
185 //  Local Structurs
186 //-------------------------------------------------------------------------------------------------
187 typedef struct _NDS_FLT_Dev
188 {
189     NDS_FLT_Param                   param;
190 
191 } NDS_FLT_Dev;
192 
193 
194 typedef struct
195 {
196     MS_U16                          pid;                                // PID status for REG_CAM_ECM_PID (W_ONLY)
197     MS_U32                          flt_id;
198 #if defined(CHIP_U3)
199     MS_U32                          buf_id;
200 #endif
201 
202     MS_U32                          x_connect;
203     MS_U8                           ecm_id;
204     MS_BOOL                         b_defined;
205 
206 #if NDS_ECM_SAME_PID_DROP_EN
207     MS_U8                           u8Drop;
208     MS_U8                           u8Ctrl;
209 #endif
210 
211 } NDS_ECM_Flt;
212 
213 
214 typedef struct
215 {
216     MS_U16                          pid;                                // PID status for REG_CAM_EMM_PID (W_ONLY)
217     MS_U32                          flt_id;
218 #if defined(CHIP_U3)
219     MS_U32                          buf_id;
220 #endif
221 
222     MS_U32                          x_connect;
223     MS_U8                           flt_ctrl;
224 
225 } NDS_EMM_Flt;
226 
227 //[NEW] Refine?
228 #define MAX_EMM_LIST_NUM            11 //(NDS_CAM_EMM_BUF_NUM+1) // N for N-1 slots
229 
230 MS_U8 _u8EmmRead = 0;
231 MS_U8 _u8EmmWrite = 0;
232 MS_U8 _u8EmmCur = 0;
233 
234 #define emmQueueInc()                                   \
235 {                                                       \
236     _u8EmmWrite++;                                      \
237     if (MAX_EMM_LIST_NUM <= _u8EmmWrite)                \
238     {                                                   \
239         _u8EmmWrite = 0;                                \
240     }                                                   \
241 }
242 
243 #define emmQueueDec()                                   \
244 {                                                       \
245     _u8EmmRead++;                                       \
246     if (MAX_EMM_LIST_NUM <= _u8EmmRead)                 \
247     {                                                   \
248         _u8EmmRead = 0;                                 \
249     }                                                   \
250 }
251 
252 #define emmQueueIsEmpty()       (_u8EmmRead == _u8EmmWrite)
253 #define emmQueueIsFull()        (0 == emmQueueFreeSize())
254 #define emmQueueUsedSize()      ((_u8EmmWrite >= _u8EmmRead) ? (_u8EmmWrite - _u8EmmRead) : (MAX_EMM_LIST_NUM - _u8EmmRead + _u8EmmWrite))
255 #define emmQueueFreeSize()      (MAX_EMM_LIST_NUM - emmQueueUsedSize() - 1)
256 #define emmQueueReset()         { _u8EmmRead = _u8EmmWrite = _u8EmmCur = 0 }
257 // -Jerry
258 
259 
260 //-------------------------------------------------------------------------------------------------
261 //  Global Variables
262 //-------------------------------------------------------------------------------------------------
263 
264 //-------------------------------------------------------------------------------------------------
265 //  Local Variables
266 //-------------------------------------------------------------------------------------------------
267 
268 static NDS_FLT_Dev                  _nds_flt_dev = {
269                                         .param.ecm_emm_addr = (MS_PHYADDR)NULL,
270                                         .param.pu8ecm_emm_buf = (MS_U8*)NULL,
271                                     };
272 
273 #if !defined(MSOS_TYPE_LINUX_KERNEL)
274 static MS_U32                       _nds_flt_stack[NDS_FLT_TASK_STACK_SIZE/sizeof(MS_U32)];
275 #endif
276 static MS_S32                       _nds_flt_eventid = -1, _nds_flt_mutexid = -1, _nds_flt_taskid = -1;
277 
278 static NDS_ECM_Flt                  _EcmFlt[NDS_CAM_ECM_FLT_NUM];
279 static NDS_EMM_Flt                  _EmmFlt;
280 
281 MS_U8                               _u8EmmBuf[MAX_EMM_LIST_NUM][NDS_CAM_FLT_BUF_SIZE];
282 MS_U8                               _u8EcmBuf[NDS_CAM_ECM_FLT_NUM][2][NDS_CAM_FLT_BUF_SIZE];
283 
284 extern void _verSC_PrintData(MS_U8 *pu8Data, MS_U16 u16DataLen);
285 
286 #if 0
287 extern NDS_Result NDS_RASP_DefineEcmFilter (NDS_ULONG Xconn , NDS_BYTE ecm_filter_num , NDS_BYTE ecm_filter_control);
288 extern NDS_Result NDS_RASP_DefineEcmPid (NDS_ULONG Xconn , NDS_BYTE ecm_filter_num ,NDS_USHORT Pid,NDS_BYTE odd_ecm_table_id,NDS_BYTE even_ecm_table_id );
289 #endif
290 
291 //-------------------------------------------------------------------------------------------------
292 //  Debug Functions
293 //-------------------------------------------------------------------------------------------------
294 
295 
296 //-------------------------------------------------------------------------------------------------
297 //  Local Functions
298 //-------------------------------------------------------------------------------------------------
299 
300 
301 //-------------------------------------------------------------------------------------------------
302 //  Global Functions
303 //-------------------------------------------------------------------------------------------------
304 
305 //[NEW] refine? is it necessary to reduce OVERFLOW?
306 MS_BOOL bEmmOverflow = TRUE;
307 // -Jerry
308 
309 
_EMM_FreeFilter(void)310 void _EMM_FreeFilter(void)
311 {
312     int                 i;
313 
314     MDrv_TSP_FLT_Enable(_EmmFlt.flt_id, FALSE);
315 #if defined(CHIP_U3)
316     MDrv_TSP_SecFlt_Free(0, _EmmFlt.buf_id);
317 #endif
318     MDrv_TSP_FLT_Free(_EmmFlt.flt_id);
319 
320     for (i = 0; i < NDS_CAM_EMM_BUF_NUM; i++)
321     {
322         memset(_u8EmmBuf[i], 0, NDS_CAM_FLT_BUF_SIZE);
323     }
324     memset((void*)MS_PA2KSEG1(_nds_flt_dev.param.ecm_emm_addr+NDS_CAM_ECM_BUFS_SIZE), 0, NDS_CAM_FLT_BUF_SIZE * NDS_CAM_EMM_BUF_NUM);
325     MsOS_FlushMemory();
326 
327     _EmmFlt.flt_id = NDS_FLT_NULL;
328     _EmmFlt.pid = TSP_PID_NULL;
329 
330     bEmmOverflow = TRUE;
331 }
332 
333 
_EMM_AllocFilter(MS_U32 x_connection,MS_U16 pid,MS_U8 emm_filter_control)334 MS_BOOL _EMM_AllocFilter(MS_U32 x_connection, MS_U16 pid, MS_U8 emm_filter_control)
335 {
336     if (NDS_FLT_NULL != _EmmFlt.flt_id)
337     {
338         TSP_FltState        eTspState;
339         TSP_Result          eTspRet = E_TSP_FAIL;
340         eTspRet = MDrv_TSP_FLT_GetState(_EmmFlt.flt_id, &eTspState);
341         if (eTspRet == E_TSP_OK && eTspState != E_TSP_FLT_STATE_FREE)
342         {
343             _EMM_FreeFilter();
344         }
345     }
346 
347 #if 0 // debugging
348     MS_U32          secbuf = 0x0, bufsize = 0x0;
349     MS_U32          secid;
350     if (secbuf != 0)
351     {
352         printf("[%s]-[%d] EMM debugging buffer enable\n", __FUNCTION__, __LINE__);
353         MDrv_TSP_FLT_Alloc(0, E_TSP_FLT_SRC_TSIF0 | E_TSP_FLT_USER_SEC, &_EmmFlt.flt_id);
354 //        MDrv_TSP_FLT_SetMode(_EmmFlt.flt_id, E_TSP_FLT_MODE_CONTI);
355         MDrv_TSP_SEC_Alloc(0, &secid);
356         MDrv_TSP_SEC_SetBuffer(secid, secbuf, bufsize);
357         MDrv_TSP_FLT_SelSEC(_EmmFlt.flt_id, secid);
358     }
359     else
360 #endif // debugging
361     if (E_TSP_OK != MDrv_TSP_FLT_Alloc(0, E_TSP_FLT_SRC_TSIF0 | E_TSP_FLT_USER_EMM, &_EmmFlt.flt_id))
362     {
363         return FALSE;
364     }
365 
366 #if defined(CHIP_U3)
367     if (E_TSP_OK != MDrv_TSP_SecFlt_Alloc(0, &_EmmFlt.buf_id))
368     {
369         return FALSE;
370     }
371     MDrv_TSP_PidFlt_SelSecFlt(0, _EmmFlt.flt_id, _EmmFlt.buf_id);
372     MDrv_TSP_SecFlt_SetMode(0, _EmmFlt.buf_id, E_DRVTSP_FLT_MODE_CONTI);
373     MDrv_TSP_SecFlt_SetBuffer(0, _EmmFlt.buf_id, (_nds_flt_dev.param.ecm_emm_addr + NDS_CAM_ECM_BUFS_SIZE), NDS_CAM_FLT_BUF_SIZE * NDS_CAM_EMM_BUF_NUM);
374 #endif
375 
376     MDrv_TSP_FLT_SetPID(_EmmFlt.flt_id, pid);
377     MDrv_TSP_FLT_Enable(_EmmFlt.flt_id, TRUE);
378 
379     _EmmFlt.pid = pid;
380     _EmmFlt.flt_ctrl = emm_filter_control;
381     _EmmFlt.x_connect = x_connection;
382 
383     return TRUE;
384 }
385 
386 
387 // Enable at EMM SetPid
_EMM_EnableFilter(MS_BOOL bEnable)388 void _EMM_EnableFilter(MS_BOOL bEnable)
389 {
390     MS_U16  emm_pid;
391 
392     if (bEnable)
393     {
394         emm_pid = _EmmFlt.pid & CAM_EMM_PID_MASK;
395         if (_EmmFlt.flt_ctrl & HDICA_EMM_RECEPTION_ENABLE)
396         {
397             emm_pid = emm_pid | CAM_EMM_PID_ENABLE;
398         }
399         if (_EmmFlt.flt_ctrl & HDICA_TABLE_ID_FILTERING_USE)
400         {
401             emm_pid = emm_pid | CAM_EMM_PID_TID_ENABLE;
402         }
403 
404         CAM_REG(REG_CAM_EMM_PID) = emm_pid;
405     }
406     else
407     {
408         // disable EMM filtering
409         CAM_REG(REG_CAM_EMM_PID) = _EmmFlt.pid; // Clear [15:14]
410     }
411 }
412 
413 
_ECM_FreeFilter(MS_U8 ecm_id)414 void _ECM_FreeFilter(MS_U8 ecm_id)
415 {
416     MDrv_TSP_FLT_Enable(_EcmFlt[ecm_id].flt_id, FALSE);
417 #if defined(CHIP_U3)
418     MDrv_TSP_SecFlt_Free(0, _EcmFlt[ecm_id].buf_id);
419 #endif
420     MDrv_TSP_FLT_Free(_EcmFlt[ecm_id].flt_id);
421 
422     memset(_u8EcmBuf[ecm_id][0], 0, NDS_CAM_FLT_BUF_SIZE);
423     memset(_u8EcmBuf[ecm_id][1], 0, NDS_CAM_FLT_BUF_SIZE);
424     memset((void*)MS_PA2KSEG1(_nds_flt_dev.param.ecm_emm_addr + NDS_CAM_FLT_BUF_SIZE*ecm_id), 0, NDS_CAM_FLT_BUF_SIZE);
425     MsOS_FlushMemory();
426 
427     _EcmFlt[ecm_id].flt_id = NDS_FLT_NULL;
428     _EcmFlt[ecm_id].pid = TSP_PID_NULL;
429     _EcmFlt[ecm_id].b_defined = FALSE;
430 }
431 
432 
_ECM_AllocFilter(MS_U32 x_connection,MS_U8 ecm_filter_num,MS_U16 pid)433 MS_BOOL _ECM_AllocFilter(MS_U32 x_connection, MS_U8 ecm_filter_num, MS_U16 pid)
434 {
435     if (NDS_FLT_NULL != _EcmFlt[ecm_filter_num].flt_id)
436     {
437         TSP_FltState        eTspState;
438         TSP_Result          eTspRet = E_TSP_OK;
439         eTspRet = MDrv_TSP_FLT_GetState(_EcmFlt[ecm_filter_num].flt_id, &eTspState);
440         if (eTspState != E_TSP_FLT_STATE_FREE && eTspRet == E_TSP_OK)
441         {
442             _ECM_FreeFilter(ecm_filter_num);
443         }
444     }
445 
446     if (E_TSP_OK != MDrv_TSP_FLT_Alloc(0, E_TSP_FLT_SRC_TSIF0 | E_TSP_FLT_USER_ECM, &_EcmFlt[ecm_filter_num].flt_id))
447     {
448         return FALSE;
449     }
450 #if defined(CHIP_U3)
451     if (E_TSP_OK != MDrv_TSP_SecFlt_Alloc(0, &_EcmFlt[ecm_filter_num].buf_id))
452     {
453         return FALSE;
454     }
455     MDrv_TSP_SecFlt_SetEcmIdx(0, _EcmFlt[ecm_filter_num].buf_id, _EcmFlt[ecm_filter_num].ecm_id);
456     MDrv_TSP_PidFlt_SelSecFlt(0, _EcmFlt[ecm_filter_num].flt_id, _EcmFlt[ecm_filter_num].buf_id);
457     MDrv_TSP_SecFlt_SetMode(0, _EcmFlt[ecm_filter_num].buf_id, E_DRVTSP_FLT_MODE_ONESHOT | E_DRVTSP_FLT_MODE_CRCCHK);
458     MDrv_TSP_SecFlt_SetBuffer(0, _EcmFlt[ecm_filter_num].buf_id, (_nds_flt_dev.param.ecm_emm_addr + (NDS_CAM_FLT_BUF_SIZE*ecm_filter_num)), NDS_CAM_FLT_BUF_SIZE);
459 #endif
460 
461     _EcmFlt[ecm_filter_num].pid = pid;
462     _EcmFlt[ecm_filter_num].ecm_id = ecm_filter_num;
463     _EcmFlt[ecm_filter_num].x_connect = x_connection;
464 
465     return TRUE;
466 }
467 
468 
469 // Enable at ECM Define
_ECM_EnableFilter(MS_U32 x_connection,MS_U8 u8Filter_num,MS_BOOL bEnable,MS_U8 u8Ctrl)470 void _ECM_EnableFilter(MS_U32 x_connection, MS_U8 u8Filter_num, MS_BOOL bEnable, MS_U8 u8Ctrl)
471 {
472     MS_BOOL             bFristSet = FALSE;
473     MS_U16              u16Pid = _EcmFlt[u8Filter_num].pid;
474     int                 i;
475 
476     if (_EcmFlt[u8Filter_num].flt_id != NDS_FLT_NULL)
477     {
478 #if NDS_ECM_SAME_PID_DROP_EN
479         if (bEnable)
480         {
481             _EcmFlt[u8Filter_num].u8Ctrl = u8Ctrl;
482             for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
483             {
484                 if (_EcmFlt[i].pid == u16Pid)
485                 {
486                     if (_EcmFlt[i].u8Ctrl > 0 && bFristSet == FALSE)
487                     {
488                         bFristSet = TRUE;
489                         _EcmFlt[i].u8Drop = 0;
490                     }
491                     else
492                     {
493                         _EcmFlt[i].u8Drop = 1;
494                     }
495                 }
496             }
497         }
498         else
499         {
500             _EcmFlt[u8Filter_num].u8Ctrl = 0;
501         }
502 #endif
503         if (bEnable)
504         {
505             // non-NULL PID to enable filter
506             MDrv_TSP_FLT_SetPID(_EcmFlt[u8Filter_num].flt_id, _EcmFlt[u8Filter_num].pid);
507         }
508         else
509         {
510             MDrv_TSP_FLT_SetPID(_EcmFlt[u8Filter_num].flt_id, TSP_PID_NULL);
511         }
512 
513         MDrv_TSP_FLT_Enable(_EcmFlt[u8Filter_num].flt_id, bEnable);
514     }
515 }
516 
517 
_NDS_REC_GetPktCount(MS_U32 x_connection,MS_U32 * hi_count,MS_U32 * lo_count)518 void _NDS_REC_GetPktCount(MS_U32 x_connection, MS_U32 *hi_count, MS_U32 *lo_count)
519 {
520     *hi_count = 0xFFFFFFFF;
521     *lo_count = 0xFFFFFFFF;
522 
523     return;
524 }
525 
526 
527 #ifdef MSOS_TYPE_LINUX_KERNEL
_NDS_FLT_Isr(int irq,void * dev_id)528 static irqreturn_t _NDS_FLT_Isr(int irq, void *dev_id)
529 #else
530 static void _NDS_FLT_Isr(InterruptNum eIntNum)
531 #endif
532 {
533     MS_U8               u8IntReg, emm_idx, u8EcmReg;
534     MS_U8               ecm_polarity;
535     int                 i;
536 
537     u8IntReg = CAM_REG(REG_CAM_CA_INT);
538 
539     // EMM
540     if (u8IntReg & (CAM_CA_INT_EMM_OVERFLOW))
541     {
542         CAM_REG(REG_CAM_CA_INT) = (CAM_CA_INT_MASK_RESET_MODE | CAM_CA_INT_EMM_OVERFLOW); // clear EMM overflow
543         CAM_REG(REG_CAM_CA_INT) = (CAM_CA_INT_ECM | CAM_CA_INT_EMM | CAM_CA_INT_EMM_OVERFLOW); // enable interrupt
544 
545 #if NDS_EMM_PASSIVE
546         if (bEmmOverflow == FALSE)
547         {
548             bEmmOverflow = TRUE;
549         }
550 #endif
551 
552         MsOS_SetEvent(_nds_flt_eventid, NDS_EMM_EVENT_BUFFER | NDS_EMM_EVENT_OVERFLOW_HW);
553     }
554     else if (u8IntReg & (CAM_CA_INT_EMM))
555     {
556         // @TODO: add R/W pointer of _u8EmmBuf
557         // Make sure no event lost at IPC
558         CAM_REG(REG_CAM_CA_INT) = (CAM_CA_INT_ECM | CAM_CA_INT_EMM | CAM_CA_INT_EMM_OVERFLOW);
559 
560         // u8EmmReg is Emm index 0~9, 0x1000 is ack.
561         emm_idx = CAM_REG(REG_CAM_EMM_INT_STAT) & CAM_EMM_INT_BUF_MASK;
562 
563 //[NEW] EMM queue management
564 // it's the only way to handle no-sync index for ACT at overflow
565 
566 #if NDS_EMM_PASSIVE
567         if (bEmmOverflow == FALSE)
568         {
569 #endif
570             if (emmQueueIsFull())
571             {
572 #if NDS_EMM_PASSIVE
573                 bEmmOverflow = TRUE;
574 #endif
575                 MsOS_SetEvent(_nds_flt_eventid, NDS_EMM_EVENT_BUFFER | NDS_EMM_EVENT_OVERFLOW_SW);
576             }
577             else
578             {
579                 MsOS_ReadMemory();
580                 memcpy(_u8EmmBuf[_u8EmmWrite], (void*)MS_PA2KSEG1(_nds_flt_dev.param.ecm_emm_addr+NDS_CAM_ECM_BUFS_SIZE+(NDS_CAM_FLT_BUF_SIZE*emm_idx)), 188);
581                 MsOS_SetEvent(_nds_flt_eventid, NDS_EMM_EVENT_BUFFER+emm_idx);
582                 emmQueueInc();
583             }
584 #if NDS_EMM_PASSIVE
585         }
586         else
587         {
588             MsOS_SetEvent(_nds_flt_eventid, NDS_EMM_EVENT_BUFFER);
589         }
590 #endif
591 // -jerry
592 
593         // Ack and Clear EMM interrupt
594         CAM_REG(REG_CAM_EMM_INT_STAT) = CAM_EMM_INT_ACK;
595     }
596 
597     // ECM
598     if (u8IntReg & (CAM_CA_INT_ECM))
599     {
600         u8EcmReg = CAM_REG(REG_CAM_ECM_INT_STAT);
601 
602         // bit0~5 to indicate six slot
603         for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
604         {
605             if (u8EcmReg & (0x1 << i))
606             {
607                 MS_U8   *pEcmData;
608 
609                 CAM_REG(REG_CAM_ECM_INT_STAT) = (0x1 << i);
610 
611 #if NDS_ECM_SAME_PID_DROP_EN
612                 if (_EcmFlt[i].u8Drop == 1)
613                     continue;
614 #endif
615 
616                 pEcmData = (void *)MS_PA2KSEG1(_nds_flt_dev.param.ecm_emm_addr+(NDS_CAM_FLT_BUF_SIZE*i));
617                 MsOS_ReadMemory();
618                 if (pEcmData[0] != 0x47)
619                 {
620                     continue; //_NDS_ASSERT_;
621                 }
622                 if (pEcmData[5] == 0x80)
623                 {
624                     ecm_polarity = 0; // EVEN
625                 }
626                 else if (pEcmData[5] == 0x81)
627                 {
628                     ecm_polarity = 1; // ODD
629                 }
630                 else
631                 {
632                     NDS_ASSERT(FALSE, , "[%s]-[%d]\n", __FUNCTION__, __LINE__);
633                 }
634 
635                 if (_u8EcmBuf[i][ecm_polarity][0] == 0) // if buffer empty
636                 {
637                     // @TODO: Manual Lock
638                     // Check auto/manual mode
639                     // Set correspondant setting
640 
641                     MsOS_ReadMemory();
642                     memcpy(_u8EcmBuf[i][ecm_polarity], pEcmData, 188);
643 
644                     // if ECM incomming at this time, the buffer could be dirty
645                     if (CAM_REG(REG_CAM_ECM_INT_STAT) & (0x1 << i))
646                     {
647                         // ECM overfolw
648                         MsOS_SetEvent(_nds_flt_eventid, 0x1 << (i + NDS_ECM_EVENT_OVERFLOW_SHFT));
649                         continue;
650                     }
651 
652                     MsOS_SetEvent(_nds_flt_eventid, (0x1 << (i*2 + NDS_ECM_EVENT_FILTER_SHFT)) << ecm_polarity);
653                 }
654                 else
655                 {
656                     //_NDS_ASSERT_;
657                     // ECM overfolw
658                     MsOS_SetEvent(_nds_flt_eventid, 0x1 << (i + NDS_ECM_EVENT_OVERFLOW_SHFT));
659                     break;
660                 }
661             }
662         }
663     }
664 #ifdef MSOS_TYPE_LINUX_KERNEL
665     return IRQ_HANDLED;
666 #else
667     // IRQ handled
668     NDS_FLT_OS_EnableInterrupt();
669 #endif
670 }
671 
672 
673 //[NEW]
674 MS_U32 emm_overflow_time = 0;
675 // -jerry
676 
677 
_NDS_FLT_IsrTask(void)678 static void _NDS_FLT_IsrTask(void)
679 {
680     MS_U32              u32Events, hi_count, lo_count;
681     XECM_MSG            ecm_msg;
682     XEMM_MSG            emm_msg;
683     int                 i, p;
684 
685     while(1)
686     {
687         MsOS_WaitEvent(_nds_flt_eventid, NDS_ALL_EVENT, &u32Events, E_OR_CLEAR, MSOS_WAIT_FOREVER);
688 
689         //u8EmmReg = CAM_REG(REG_CAM_EMM_INT_STAT);
690         //MsOS_DisableInterrupt(NDS_EMMECM_IRQ);
691 
692 #if (NDS_EMM_PASSIVE==0)
693         if (u32Events & (NDS_EMM_EVENT_OVERFLOW_HW | NDS_EMM_EVENT_OVERFLOW_SW))
694         {
695             NDS_FLT_LOCK(); // for disable interrupt protection
696             if (bEmmOverflow == FALSE)
697             {
698                 _EMM_EnableFilter(FALSE);
699                 bEmmOverflow = TRUE;
700             }
701             NDS_FLT_UNLOCK();
702         }
703 #endif
704 
705         for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
706         {
707             if (u32Events & (0x1 << (i + NDS_ECM_EVENT_OVERFLOW_SHFT)))
708             {
709                 printf("\n\nECM_OVERFLOW\n\n");
710                 //[FIXME] for ecm test , reset buffer at XCORECA_EcmReceived
711                 //memset(_u8EcmBuf[i][0], 0, 188);
712                 //memset(_u8EcmBuf[i][1], 0, 188);
713 
714                 ecm_msg.ecm_buf_ptr = _u8EcmBuf[i][0];
715                 ecm_msg.rcv_status  = ECM_OVERFLOW;
716                 _NDS_REC_GetPktCount(_EcmFlt[i].x_connect, &hi_count, &lo_count);
717 
718                 // if USER return fail, it will release the buffer
719                 //XCORECA_EcmReceived(0, &ecm_msg , hi_count, lo_count);
720                 XCORECA_EcmReceived(_EcmFlt[i].x_connect, &ecm_msg , hi_count, lo_count);
721                 //_NDS_ASSERT_;
722             }
723             else // if (u32Events & (0x1 << (i + NDS_ECM_EVENT_ODD_SHFT)))
724             {
725                 MS_U8   valid = (u32Events >> (i*2 + NDS_ECM_EVENT_FILTER_SHFT)) & 0x3;
726                 if (valid) // any ODD/EVEN buffer arrival
727                 {
728                     for (p = 0; p < 2; p++)
729                     {
730                         if ( (valid & (0x1<<p)) && _u8EcmBuf[i][p][0] == 0x47 && _u8EcmBuf[i][p][5] == (0x80|p)) // 0x80, 0x81
731                         {
732                             ecm_msg.ecm_filter_num = i;
733                             ecm_msg.ecm_buf_ptr    = _u8EcmBuf[i][p]+8;
734                             ecm_msg.ecm_polarity   = ((p==0) ? HDICA_EVEN_BUFFER : HDICA_ODD_BUFFER);
735                             ecm_msg.rcv_status     = ECM_OK;
736                             _NDS_REC_GetPktCount(_EcmFlt[i].x_connect, &hi_count, &lo_count);
737 
738                             // if USER return fail, it will release the buffer
739                             NDS_FLT_DBG("\n\nECM_RECV %d %d %ld\n\n", i, ecm_msg.ecm_polarity, MsOS_GetSystemTime());
740                             if (XCORECA_EcmReceived(_EcmFlt[i].x_connect, &ecm_msg , hi_count, lo_count) != CA_OK)
741                             {
742                                 XHDICA_ReleaseEcmBuffer(_EcmFlt[i].x_connect, ecm_msg.ecm_filter_num, ecm_msg.ecm_polarity, ecm_msg.ecm_buf_ptr);
743                             }
744                         }
745                     }
746                 }
747 
748             }
749         }
750 
751         // Issue all EMM received
752         if (u32Events & NDS_EMM_EVENT_BUFFER)
753         {
754             NDS_FLT_DBG("[%s][%d] ======> evt r c w s = %08x %02d %02d %02d %02d\n", __FUNCTION__, __LINE__, u32Events, _u8EmmRead, _u8EmmCur, _u8EmmWrite, u32UsedSize);
755 // #if NDS_EMM_PASSIVE
756 #if 0
757             if (_u8EmmCur != _u8EmmWrite)
758 #else // NDS_EMM_PASSIVE==0
759             MS_U32 u32UsedSize = ((_u8EmmWrite >= _u8EmmCur) ? (_u8EmmWrite - _u8EmmCur) : (MAX_EMM_LIST_NUM - _u8EmmCur + _u8EmmWrite));
760             for (; u32UsedSize > 0; u32UsedSize--)
761 #endif
762             // while (!emmQueueIsEmpty())
763             {
764                 if (_u8EmmBuf[_u8EmmCur][0] != 0x47)
765                 {
766                     NDS_FLT_DBG("[%s] %d is NULL\n", __FUNCTION__, _u8EmmCur);
767                     goto jump_next_emm;
768                     // MY_ASSERT(0);
769                 }
770                 emm_msg.emm_buf        = &_u8EmmBuf[_u8EmmCur][8]; // emm payload
771                 emm_msg.receive_status = EMM_OK;
772                 NDS_FLT_DBG("\n\nEMM_RECV %ld\n\n", MsOS_GetSystemTime());
773                 if (XCORECA_EmmReceived( _EmmFlt.x_connect, &emm_msg ) != CA_OK)
774                 {
775                     XHDICA_ReleaseEmmBuffer(_EmmFlt.x_connect, emm_msg.emm_buf);
776                 }
777 jump_next_emm:
778                 _u8EmmCur++;
779                 if (MAX_EMM_LIST_NUM <= _u8EmmCur)
780                 {
781                     _u8EmmCur = 0;
782                 }
783                 //emmQueueDec();
784             }
785         }
786 
787         if ( (u32Events & (NDS_EMM_EVENT_OVERFLOW_HW | NDS_EMM_EVENT_OVERFLOW_SW)) )
788         {
789             //MDrv_TSP_FLT_Enable(_EmmFlt.flt_id, FALSE);
790             //FIXME: remove it            emmQueueReset();
791 
792             NDS_FLT_DBG("[%s][%d] ======> evt r c w = %08x %02d %02d %02d\n", __FUNCTION__, __LINE__, u32Events, _u8EmmRead, _u8EmmCur, _u8EmmWrite);
793 
794             if (u32Events & NDS_EMM_EVENT_OVERFLOW_HW)
795             {
796                 printf("\n\nEMM_OVERFLOW(HW)\n\n");
797                 #if defined(CHIP_U3)
798                 MDrv_TSP_SecFlt_ResetBuffer(0, _EmmFlt.buf_id);
799                 #endif
800             }
801             if (u32Events & NDS_EMM_EVENT_OVERFLOW_SW)
802             {
803                 printf("\n\n\nEMM_OVERFLOW(SW)\n\n");
804             }
805             emm_msg.emm_buf        = NULL;
806             emm_msg.receive_status = EMM_OVERFLOW;
807 
808             XCORECA_EmmReceived(_EmmFlt.x_connect, &emm_msg);
809 
810             emm_overflow_time = MsOS_GetSystemTime();
811 /*
812             for (i = 0; i < NDS_CAM_EMM_BUF_NUM; i++)
813             {
814                 memset(_u8EmmBuf[i], 0, 188); // release all emm buf
815             }
816 */
817 
818 //FIXME: enable after all release!!
819 //            _EnableFilter(TRUE);
820         }
821 
822         u32Events = 0;
823 
824         // enable all interrupt
825         // @TODO: add R/W pointer of _u8EmmBuf to make sure no EMM lost.
826         // @NOTE: only effective for EMM now
827         CAM_REG(REG_CAM_CA_INT) = (CAM_CA_INT_ECM | CAM_CA_INT_EMM | CAM_CA_INT_EMM_OVERFLOW);
828 
829         //MsOS_DelayTask(5);
830     }
831 }
832 
833 
NDS_FLT_Init(NDS_FLT_Param * param)834 NDS_Result NDS_FLT_Init(NDS_FLT_Param *param)
835 {
836     int i;
837 
838     if ( ((MS_PHYADDR)NULL == param->ecm_emm_addr) ||
839          (param->ecm_emm_size < NDS_CAM_FLT_BUFS_SIZE) )
840     {
841         return E_NDS_FAIL;
842     }
843 
844     HAL_NDS_FLT_Init(param);
845     _nds_flt_dev.param.ecm_emm_addr = param->ecm_emm_addr;
846     _nds_flt_dev.param.pu8ecm_emm_buf = param->pu8ecm_emm_buf;
847     _nds_flt_dev.param.ecm_emm_size = param->ecm_emm_size;
848 
849     _EmmFlt.pid = TSP_PID_NULL;
850     _EmmFlt.flt_id = NDS_FLT_NULL;
851     for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
852     {
853         _EcmFlt[i].pid = TSP_PID_NULL;
854         _EcmFlt[i].flt_id = NDS_FLT_NULL;
855         _EcmFlt[i].b_defined = FALSE;
856 #if NDS_ECM_SAME_PID_DROP_EN
857         _EcmFlt[i].u8Ctrl = 0;
858         _EcmFlt[i].u8Drop = 0;
859 #endif
860     }
861 
862     for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
863     {
864         memset(_u8EcmBuf[i][0], 0, NDS_CAM_FLT_BUF_SIZE);
865         memset(_u8EcmBuf[i][1], 0, NDS_CAM_FLT_BUF_SIZE);
866     }
867     for (i = 0; i < MAX_EMM_LIST_NUM; i++)
868     {
869         memset(_u8EmmBuf[i], 0, NDS_CAM_FLT_BUF_SIZE);
870     }
871 
872 #if 1
873     //*((volatile unsigned int*)( 0xbf202d00 )) = 0x11;// allow TS packet to flow through CA module
874     //*((volatile unsigned int*)( 0xbf202d00 )) = 0x59;// 49:pvr, 59: live in+pvr
875 
876     //*((volatile unsigned int*)( 0xBF2216CC )) = 0x0080;//olny for FPGA of NSK ignored , set to 0 = disable all
877     //*((volatile unsigned int*)( 0xBF2018b0 )) = 0x0080;//accept_en
878     //*((volatile unsigned int*)( 0xBF203c50)) = 0x1022;//tsp clk
879     *((volatile unsigned int*)( 0xBF221840)) = 0x0010; // Descambler bank 2 enable  reg_latch_even_odd for ca_value
880 #endif
881 
882 #if 0 //------ for FPGA TSO ----
883 
884     *((volatile MS_U32*)0xbf202d78) = 0x027;//TS0 config only for ts out , 0x021:only video, clk/2 ,,, 0x27:all ts, clk/2
885     *((volatile MS_U32*)0xBF202AB0) = 0xbb32; //bypass VPID
886 #endif
887 
888     _nds_flt_eventid = MsOS_CreateEventGroup("NDS_FLT_Event");
889     MS_ASSERT(_nds_flt_eventid >= 0);
890 
891     _nds_flt_mutexid = MsOS_CreateMutex(E_MSOS_FIFO, "NDS_FLT_Mutex", MSOS_PROCESS_SHARED);
892     MS_ASSERT(_nds_flt_mutexid >= 0);
893 
894 #if defined(MSOS_TYPE_LINUX_KERNEL)
895     _nds_flt_taskid = MsOS_CreateTask(  (TaskEntry) _NDS_FLT_IsrTask,
896                                         (MS_U32)NULL,
897                                         (TaskPriority) (E_TASK_PRI_SYS+1),
898                                         TRUE,
899                                         NULL,
900                                         0,
901                                         "NDS_FLT_IsrTask");
902 #else
903     _nds_flt_taskid = MsOS_CreateTask(  (TaskEntry) _NDS_FLT_IsrTask,
904                                         (MS_U32)NULL,
905                                         (TaskPriority) (E_TASK_PRI_SYS+1),
906                                         TRUE,
907                                         _nds_flt_stack,
908                                         NDS_FLT_TASK_STACK_SIZE,
909                                         "NDS_FLT_IsrTask");
910 #endif
911     MS_ASSERT(_nds_flt_taskid >= 0);
912 
913     NDS_FLT_OS_AttachInterrupt(_NDS_FLT_Isr);
914     NDS_FLT_OS_EnableInterrupt();
915 
916     CAM_REG(REG_CAM_ECM_INT_STAT) = CAM_REG(REG_CAM_ECM_INT_STAT);
917     CAM_REG(REG_CAM_CA_INT) = CAM_CA_INT_EMM;
918     while (CAM_REG(REG_CAM_CA_INT) & CAM_CA_INT_EMM)
919     {
920         CAM_REG(REG_CAM_EMM_INT_STAT) = CAM_EMM_INT_ACK;
921     }
922     CAM_REG(REG_CAM_CA_INT) = 0;
923 
924     // Enable (unmask) all interrupts
925     CAM_REG(REG_CAM_CA_INT) = (CAM_CA_INT_ECM | CAM_CA_INT_EMM | CAM_CA_INT_EMM_OVERFLOW);
926 
927     return E_NDS_OK;
928 }
929 
930 
NDS_FLT_Exit(void)931 NDS_Result NDS_FLT_Exit(void)
932 {
933     // Disable (mask) all interrupts
934     CAM_REG(REG_CAM_CA_INT) = 0;
935 
936     NDS_FLT_OS_DisableInterrupt();
937     NDS_FLT_OS_DetachInterrupt();
938 
939     MsOS_DeleteTask(_nds_flt_taskid);
940     MsOS_DeleteMutex(_nds_flt_mutexid);
941     MsOS_DeleteEventGroup(_nds_flt_eventid);
942 
943     HAL_NDS_FLT_Exit();
944 
945     return E_NDS_OK;
946 }
947 
948 
949 // 7.2.1
XHDICA_SetEmmPid(NDS_ULONG x_connection,NDS_USHORT pid,NDS_BYTE emm_filter_control)950 NDS_STATUS XHDICA_SetEmmPid (NDS_ULONG  x_connection,
951                              NDS_USHORT pid,
952                              NDS_BYTE   emm_filter_control)
953 {
954     NDS_FUNC("[%s]-[%d] pid[0x%x]\n", __FUNCTION__, __LINE__, pid);
955 
956     NDS_FLT_ENTRY(); // for disable interrupt protection
957 
958     if ((pid < 2) || (pid > 0x1FFE))
959     {
960         NDS_DBG("[%s]-[%d]\n", __FUNCTION__, __LINE__);
961         NDS_FLT_RETURN(CA_REQUEST_NOT_SUPPORTED_BY_DRIVER);
962     }
963 
964     _EMM_EnableFilter(FALSE);
965 
966 #if 0
967     if (_EmmFlt.pid != TSP_PID_NULL)
968     {
969         NDS_ASSERT((_EmmFlt.pid == pid), CA_REQUEST_NOT_SUPPORTED_BY_DRIVER, "[%s]-[%d]\n", __FUNCTION__, __LINE__);
970     }
971 #endif
972     // @TODO:
973     // should filter and PID be disable and set to NULL for disabling EMM filter?
974 
975     // Save pid and allocate fitler
976     //_EmmFlt.pid = pid & CAM_EMM_PID_MASK; // Get new pid
977     _EMM_AllocFilter(x_connection, pid, emm_filter_control);
978 
979     // Enable EMM Filter
980     NDS_FLT_OS_DisableInterrupt();
981     bEmmOverflow = FALSE;
982     NDS_FLT_OS_EnableInterrupt();
983 
984     _EMM_EnableFilter(TRUE);
985 
986     NDS_FLT_RETURN(CA_OK);
987 }
988 
989 
990 // 7.2.2
991 /*-----------------
992 source byte --------------- byte 0 ---------------  --------------- byte 1 ---------------  ...    2,
993             msb                                lsb  msb                                lsb
994 source bit    7,   6,   5,   4,   3,   2,   1,   0,  15,  14,  13,  12,  11,  10,   9,   8, ... 25,  24, <= bit index
995 TID(lsn)        x         x         2         3         4         5         6         7     ...    F     <= tid index
996 
997             --------------- byte 0 ---------------  --------------- byte 1 ---------------
998 TID(lsn)      7    6    5    4    3    2    x    x   15   14   13   12   11   10    9    8               <= tid index
999 lsb           8   10   12   14    0    2    4    6   24   26   28   30   16   18   20   22               <= new position with old index
1000 msb          10   11   13   15    1    3    5    7   25   27   29   31   17   19   21   23               <= new position with old index
1001 ------------------*/
XHDICA_EmmSetTableIdFilter(NDS_ULONG x_connection,NDS_BYTE table_id[4])1002 NDS_STATUS XHDICA_EmmSetTableIdFilter (NDS_ULONG    x_connection,
1003                                        NDS_BYTE     table_id[4])
1004 {
1005     MS_U32              u32TMode;
1006     MS_U16              lsb = 0, msb = 0;
1007     int                 i;
1008 
1009     NDS_FUNC("[%s]-[%d] \n", __FUNCTION__, __LINE__);
1010 
1011     CAM_REG(REG_CAM_EMM_TID_MODE_L) = lsb;
1012     CAM_REG(REG_CAM_EMM_TID_MODE_H) = msb;
1013     CAM_REG(REG_CAM_EMM_TID) = 0x80; // EMM TID
1014 
1015     u32TMode = (table_id[0]<<24) | (table_id[1]<<16) | (table_id[2]<<8) | (table_id[3]);
1016     for (i = 2; i <= 0xF; i++) // 0x82-0x8F
1017     {
1018         lsb |= ( (u32TMode >> ((0xF-i)*2)     ) & 0x1 ) << i;
1019         msb |= ( (u32TMode >> (((0xF-i)*2)+1) ) & 0x1 ) << i;
1020     }
1021 
1022     CAM_REG(REG_CAM_EMM_TID_MODE_L) = lsb;
1023     CAM_REG(REG_CAM_EMM_TID_MODE_H) = msb;
1024 
1025 
1026     return CA_OK;
1027 }
1028 
1029 
1030 // 7.2.3
1031 /*
1032     data byte       0x01 0x23 0x45 0x67
1033     nds reg_mem     0x01 0x23 0x45 0x67
1034     nds reg_word    0x01234567
1035     mstar reg_word  0x01234567
1036     mstar_reg16     0x4567(L) 0x0123(H)
1037 */
XHDICA_SetPrivateEmmFilter(NDS_ULONG x_connection,EMM_REG * emm_reg)1038 NDS_STATUS XHDICA_SetPrivateEmmFilter (NDS_ULONG    x_connection,
1039                                        EMM_REG *    emm_reg)
1040 {
1041     NDS_FUNC("[%s]-[%d] \n", __FUNCTION__, __LINE__);
1042 
1043     CAM_REG(REG_CAM_EMM_DATA_ID_H(1)) = *(MS_U8*)(emm_reg->reg1_address+1) + (*(MS_U8*)(emm_reg->reg1_address)<<8);
1044     CAM_REG(REG_CAM_EMM_DATA_ID_L(1)) = *(MS_U8*)(emm_reg->reg1_address+3) + (*(MS_U8*)(emm_reg->reg1_address+2)<<8);
1045     CAM_REG(REG_CAM_EMM_MASK_ID_H(1)) = *(MS_U8*)(emm_reg->reg1_mask+1) + (*(MS_U8*)(emm_reg->reg1_mask)<<8);
1046     CAM_REG(REG_CAM_EMM_MASK_ID_L(1)) = *(MS_U8*)(emm_reg->reg1_mask+3) + (*(MS_U8*)(emm_reg->reg1_mask+2)<<8);
1047     CAM_REG(REG_CAM_EMM_DATA_ID_H(2)) = *(MS_U8*)(emm_reg->reg2_address+1) + (*(MS_U8*)(emm_reg->reg2_address)<<8);
1048     CAM_REG(REG_CAM_EMM_DATA_ID_L(2)) = *(MS_U8*)(emm_reg->reg2_address+3) + (*(MS_U8*)(emm_reg->reg2_address+2)<<8);
1049     CAM_REG(REG_CAM_EMM_MASK_ID_H(2)) = *(MS_U8*)(emm_reg->reg2_mask+1) + (*(MS_U8*)(emm_reg->reg2_mask)<<8);
1050     CAM_REG(REG_CAM_EMM_MASK_ID_L(2)) = *(MS_U8*)(emm_reg->reg2_mask+3) + (*(MS_U8*)(emm_reg->reg2_mask+2)<<8);
1051     CAM_REG(REG_CAM_EMM_DATA_ID_H(3)) = *(MS_U8*)(emm_reg->reg3_address+1) + (*(MS_U8*)(emm_reg->reg3_address)<<8);
1052     CAM_REG(REG_CAM_EMM_DATA_ID_L(3)) = *(MS_U8*)(emm_reg->reg3_address+3) + (*(MS_U8*)(emm_reg->reg3_address+2)<<8);
1053     CAM_REG(REG_CAM_EMM_MASK_ID_H(3)) = *(MS_U8*)(emm_reg->reg3_mask+1) + (*(MS_U8*)(emm_reg->reg3_mask)<<8);
1054     CAM_REG(REG_CAM_EMM_MASK_ID_L(3)) = *(MS_U8*)(emm_reg->reg3_mask+3) + (*(MS_U8*)(emm_reg->reg3_mask+2)<<8);
1055 
1056     return CA_OK;
1057 }
1058 
1059 
1060 // 7.2.5
XHDICA_ReleaseEmmBuffer(NDS_ULONG x_connection,NDS_BYTE * emm_buf)1061 NDS_STATUS XHDICA_ReleaseEmmBuffer (NDS_ULONG   x_connection,
1062                                     NDS_BYTE *  emm_buf)
1063 {
1064     NDS_FUNC("[%s]-[%d]\n", __FUNCTION__, __LINE__);
1065 
1066     NDS_FLT_DBG("free EMM %x\n", emm_buf);
1067 
1068     NDS_FLT_ENTRY(); // for disable interrupt protection
1069 
1070     if (emm_buf != NULL)
1071     {
1072         //_verSC_PrintData(emm_buf-8, 32);
1073 //[NEW]
1074         if (bEmmOverflow == TRUE)
1075         {
1076             NDS_FLT_DBG("(read, cur, write) = (%02d %02d %02d)\n", _u8EmmRead, _u8EmmCur, _u8EmmWrite);
1077             NDS_FLT_DBG("free Emm %d %02x %02x\n", MsOS_GetSystemTime() - emm_overflow_time, *(emm_buf), *(emm_buf-8));
1078         }
1079 // -jerry
1080 
1081         NDS_FLT_OS_DisableInterrupt();
1082         *(emm_buf) = 0;
1083         *(emm_buf-8) = 0;
1084         emmQueueDec();
1085 
1086 //[NEW]
1087         if ( (bEmmOverflow == TRUE) && (emmQueueIsEmpty()) )
1088         {
1089 #if (NDS_EMM_PASSIVE==0)
1090             _EMM_EnableFilter(TRUE);
1091 #endif
1092             bEmmOverflow = FALSE;
1093         }
1094 // -jerry
1095         NDS_FLT_OS_EnableInterrupt();
1096     }
1097     else
1098     {
1099         NDS_FLT_RETURN(CA_DRIVER_CAN_NOT_PERFORM_FUNCTION_NOW);
1100     }
1101 
1102 //    MsOS_DelayTask(5);
1103 
1104     NDS_FLT_RETURN(CA_OK);
1105 }
1106 
1107 
1108 // 8.2.1
XHDICA_DefineEcmPid(NDS_ULONG x_connection,NDS_BYTE ecm_filter_num,NDS_USHORT pid,NDS_BYTE odd_ecm_table_id,NDS_BYTE even_ecm_table_id)1109 NDS_STATUS XHDICA_DefineEcmPid (NDS_ULONG   x_connection,
1110                                 NDS_BYTE    ecm_filter_num,
1111                                 NDS_USHORT  pid,
1112                                 NDS_BYTE    odd_ecm_table_id,
1113                                 NDS_BYTE    even_ecm_table_id)
1114 {
1115     //MS_U16  ecm_pid;
1116     MS_U16  u16EcmTid = 0;
1117 
1118 #if 0
1119     if(x_connection == 1 )
1120     {
1121         NDS_RASP_DefineEcmPid(x_connection,ecm_filter_num,pid,odd_ecm_table_id,even_ecm_table_id);
1122         return CA_OK ;
1123     }
1124 #endif
1125 
1126 
1127     NDS_FUNC("(%ld)-[%s]-[%d] pid [0x%x]\n", MsOS_GetSystemTime(), __FUNCTION__, __LINE__, pid);
1128 
1129     if (ecm_filter_num >= NDS_CAM_ECM_FLT_NUM)
1130     {
1131         NDS_DBG("[%s]-[%d]\n", __FUNCTION__, __LINE__);
1132         return CA_REQUEST_NOT_SUPPORTED_BY_DRIVER;
1133     }
1134 
1135     // disable filter before setting
1136     _ECM_EnableFilter(x_connection, ecm_filter_num, FALSE, 0);
1137     CAM_REG(REG_CAM_ECM_PID(ecm_filter_num)) = pid & CAM_ECM_PID_MASK; // clear [15:13] for later DefineEcmPid
1138 
1139     u16EcmTid |= (even_ecm_table_id & CAM_ECM_TID_EVEN_MASK);
1140     u16EcmTid |= ((odd_ecm_table_id<<8) & CAM_ECM_TID_ODD_MASK);
1141     CAM_REG(REG_CAM_ECM_TID) = u16EcmTid;
1142 
1143     if (pid == 0xFFFF)
1144     {
1145         // disable the filter
1146         return CA_OK;
1147     }
1148 
1149     if ((pid < 0x2 || pid > 0x1FFE))
1150     {
1151         NDS_DBG("[%s]-[%d]\n", __FUNCTION__, __LINE__);
1152         return CA_REQUEST_NOT_SUPPORTED_BY_DRIVER;
1153     }
1154 
1155     // Save pid and allocate fitler
1156     //_EcmFlt[ecm_filter_num].pid = pid & CAM_ECM_PID_MASK;
1157     _ECM_AllocFilter(x_connection, ecm_filter_num, pid);
1158 
1159     return CA_OK;
1160 }
1161 
1162 
1163 //8.2.2
XHDICA_DefineEcmFilter(NDS_ULONG x_connection,NDS_BYTE ecm_filter_num,NDS_BYTE ecm_filter_control)1164 NDS_STATUS XHDICA_DefineEcmFilter (NDS_ULONG    x_connection,
1165                                    NDS_BYTE     ecm_filter_num,
1166                                    NDS_BYTE     ecm_filter_control)
1167 {
1168     MS_U16              ecm_pid = 0;
1169     int                 i;
1170 
1171     NDS_FUNC("[%s]-[%d] -- ecm_filter_num[%d]\n", __FUNCTION__, __LINE__, ecm_filter_num);
1172 
1173 #if 0
1174     if(x_connection == 1 )
1175     {
1176         NDS_RASP_DefineEcmFilter(x_connection,ecm_filter_num,ecm_filter_control);
1177         return CA_OK ;
1178     }
1179 #endif
1180 
1181 
1182     if (ecm_filter_num >= NDS_CAM_ECM_FLT_NUM)
1183     {
1184         NDS_DBG("[%s]-[%d]\n", __FUNCTION__, __LINE__);
1185         return CA_REQUEST_NOT_SUPPORTED_BY_DRIVER;
1186     }
1187     for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++) // 8.2.2 Note
1188     {
1189         if ( (i != ecm_filter_num) &&
1190              (_EcmFlt[i].pid == _EcmFlt[ecm_filter_num].pid) &&
1191              (_EcmFlt[i].x_connect == _EcmFlt[ecm_filter_num].x_connect) &&
1192              (_EcmFlt[i].b_defined == TRUE) )
1193         {
1194             return CA_ECM_PID_FILTER_ALREADY_DEFINED;
1195         }
1196     }
1197 
1198     // @FIXME: is it possible and return CA_OK?
1199     if ((_EcmFlt[ecm_filter_num].pid < 0x2 || _EcmFlt[ecm_filter_num].pid > 0x1FFE))
1200     {
1201         // Invaliad PID
1202         return CA_OK;
1203     }
1204 
1205     ecm_pid = _EcmFlt[ecm_filter_num].pid;
1206     if (ecm_filter_control & HDICA_ECM_FILTER_CONTROL_ENABLE_ODD_RECEPTION)
1207     {
1208         ecm_pid |= CAM_ECM_PID_TID_ODD;
1209     }
1210     if (ecm_filter_control & HDICA_ECM_FILTER_CONTROL_ENABLE_EVEN_RECEPTION)
1211     {
1212         ecm_pid |= CAM_ECM_PID_TID_EVEN;
1213     }
1214     if (ecm_filter_control & HDICA_ECM_ENABLE_RECEPTION)
1215     {
1216         ecm_pid |= CAM_ECM_PID_ENABLE;
1217         _EcmFlt[ecm_filter_num].b_defined = TRUE;
1218     }
1219     else
1220     {
1221         _EcmFlt[ecm_filter_num].b_defined = FALSE;
1222     }
1223 
1224     // Enable
1225     // NOTE: It's always AUTO for current NDS implementation
1226     CAM_REG(REG_CAM_ECM_PID(ecm_filter_num)) = 0; // disable filter & reset LOCK
1227     CAM_REG(REG_CAM_ECM_LOCK(ecm_filter_num)) |=  CAM_ECM_LOCK_AUTO(ecm_filter_num);
1228     CAM_REG(REG_CAM_ECM_PID(ecm_filter_num)) = ecm_pid;
1229 
1230     _ECM_EnableFilter(x_connection, ecm_filter_num, (ecm_filter_control & HDICA_ECM_ENABLE_RECEPTION) ? TRUE : FALSE, ecm_filter_control);
1231 
1232     return CA_OK;
1233 }
1234 
1235 
1236 // 8.2.4
XHDICA_ReleaseEcmBuffer(NDS_ULONG x_connection,NDS_BYTE ecm_filter_num,NDS_BYTE ecm_polarity,NDS_BYTE * ecm_buf)1237 NDS_STATUS XHDICA_ReleaseEcmBuffer (NDS_ULONG   x_connection,
1238                                     NDS_BYTE    ecm_filter_num,
1239                                     NDS_BYTE    ecm_polarity,
1240                                     NDS_BYTE *  ecm_buf)
1241 {
1242     NDS_FUNC("[%s]-[%d] \n", __FUNCTION__, __LINE__);
1243 
1244     NDS_FLT_DBG("free ECM %d %d\n", ecm_filter_num, ecm_polarity);
1245 
1246     NDS_FLT_ENTRY(); // for disable interrupt protection
1247 
1248     if (ecm_buf != NULL)
1249     {
1250         NDS_FLT_OS_DisableInterrupt();
1251         memset(ecm_buf-8, 0, 188);
1252         NDS_FLT_OS_EnableInterrupt();
1253 
1254         // @TODO: Manual UnLock
1255         // Check auto/manual mode
1256         // Set correspondant setting
1257     }
1258     else
1259     {
1260         NDS_FLT_RETURN(CA_DRIVER_CAN_NOT_PERFORM_FUNCTION_NOW);
1261     }
1262 
1263     NDS_FLT_RETURN(CA_OK);
1264 }
1265 
1266 
1267 // 8.2.5
XHDICA_ReleaseAllEcmBuffers(NDS_ULONG x_connection)1268 NDS_STATUS XHDICA_ReleaseAllEcmBuffers (NDS_ULONG   x_connection)
1269 {
1270     int                 i = 0;
1271 
1272     NDS_FUNC("[%s]-[%d] \n", __FUNCTION__, __LINE__);
1273 
1274     NDS_FLT_ENTRY(); // for disable interrupt protection
1275 
1276     for (i = 0; i < NDS_CAM_ECM_FLT_NUM; i++)
1277     {
1278         NDS_FLT_OS_DisableInterrupt();
1279         memset(_u8EcmBuf[i][0], 0, 188);
1280         memset(_u8EcmBuf[i][1], 0, 188);
1281         NDS_FLT_OS_EnableInterrupt();
1282     }
1283 
1284     NDS_FLT_RETURN(CA_OK);
1285 }
1286 
1287