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