/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 *
 * $Author$
 * $Date$
 * $RCSfile: tlv_if.h,v $
 * $Revision$
 *
 *---------------------------------------------------------------------------*/

/** @file tlv_if.h
 *  Interface of demux driver
 */


#ifndef TLV_IF_H
#define TLV_IF_H

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
//#include "tlv.h"
#include "dmx_if.h"
#include "dmx_mm_if.h"
//-----------------------------------------------------------------------------
// Configurations
//-----------------------------------------------------------------------------
#define TLV_IP_FILTER_INDEX_NUM				(3)
#define TLV_IP_FILTER_INDEX_NUM_TOTAL		(TLV_IP_FILTER_INDEX_NUM * TLV_FRAMER_NUM)
#define TLV_PB_IP_FITTER_TOTAL_NUM             (6)

/// Function bitmap of PID operations
#define TLV_PID_FLAG_VALID              0x00000001  ///< Enabled or not
#define TLV_PID_FLAG_PID                0x00000002  ///< PID value
#define TLV_PID_FLAG_BUFFER             0x00000004  ///< Buffer control
#define TLV_PID_FLAG_CALLBACK           0x00000008  ///< Callback handler
#define TLV_PID_FLAG_SCRAMBLE_STATE     0x00000010  ///< Scrambling state
#define TLV_PID_FLAG_TS_INDEX           0x00000020  ///< TS index
#define TLV_PID_FLAG_PCR                0x00000040  ///< PCR mode
#define TLV_PID_FLAG_STEER              0x00000080  ///< Steering
#define TLV_PID_FLAG_DESC_MODE          0x00000100  ///< Descrambling mode, not use now
#define TLV_PID_FLAG_DEVICE_ID          0x00000200  ///< Device (decoder) ID
#define TLV_PID_FLAG_KEY_INDEX          0x00000400  ///< Key index
#define TLV_PID_FLAG_DATA_POINTERS      0x00000800  ///< Data pointers
#define TLV_PID_FLAG_PRIMARY            0x00001000  ///< Primary PID
#define TLV_PID_FLAG_STREAM_ID          0x00002000  ///< Stream ID
#define TLV_PID_FLAG_SUBSTREAM_ID       0x00004000  ///< Substream ID (SID)
#define TLV_PID_FLAG_INSTANCE_TAG       0x00008000  ///< for multiple instances
#define TLV_PID_FLAG_INPUTTYPE          0x00010000  ///< Input type (DTV, PS, MM..)
#define TLV_PID_FLAG_DISABLE_OUTPUT     0x00020000  ///< Disable FIFO output
#define TLV_PID_FLAG_FIFO_FULL          0x00040000  ///< FIFO FULL
#define TLV_PID_FLAG_LOCAL_TSINDEX      0x00080000  ///< send complete msg of es
#define TLV_PID_FLAG_SERIAL_NUMBER      0x00100000  ///< Serial nubmer
#define TLV_PID_FLAG_IP_INDEX           0x00200000  ///< Ip index
#define TLV_PID_FLAG_COMPLETE_MSG       0x00400000  ///< send complete msg of es
#define TLV_PID_FLAG_IS_PREBUFFER       0x00800000  ///< mark pid is prebuffer pid
#define TLV_PID_FLAG_KEY_TYPE           0x01000000  ///< ODD/EVEN key
#define TLV_PID_FLAG_NONE               0           ///< None
#define TLV_PID_FLAG_ALL                (0xffffffff & ~DMX_PID_FLAG_SCRAMBLE_STATE)


typedef enum
{
    DMX_TLV_CONN_TYPE_NONE = 0,
    DMX_TLV_CONN_TYPE_TUNER_0,
    DMX_TLV_CONN_TYPE_TUNER_1,
    DMX_TLV_CONN_TYPE_TUNER_3,
}DMX_TLV_CONN_TYPE_T;

#define DMX_TLV_IGNORE_CID	(0xFFFF)  //for DMX_TLV_IP_FILTER_T.u2Cid

typedef struct
{
    BOOL fgEnable;
    UINT8 u1TLVPacketType;
    UINT8 au1SrcIPAddr[16];
    UINT8 au1DstIPAddr[16];
    UINT16 u2SrcPort;
    UINT16 u2DstPort;
    UINT16 u2Cid;
    UINT16 u2TempCid;
    PFN_DMX_NOTIFY pfnNotify;
}DMX_TLV_IP_FILTER_T;

typedef enum
{
    APP_KEEP_ALL_SEQNUM,
    APP_KEEP_SPECIFIED_SEQNUM,
    APP_DROP_SPECIFIED_SEQNUM,
}TLV_APPDATA_FILTER_MODE_T;

typedef enum
{
    TLV_NTP_STC_NON,
    TLV_NTP_STC_16M,
    TLV_NTP_STC_27M,
    TLV_NTP_STC_16M_27M,
}TLV_NTP_MODE_T;

/// PID data structure
typedef struct
{
    BOOL fgEnable;                  ///< Enable or disable
    BOOL fgAllocateBuffer;          ///< Allocate buffer
    BOOL fgPrimary;                 ///< Primary PID
    BOOL fgFifoFull;                ///<Pid buffer fifo full
    UINT8 u1TsIndex;                ///< TS index
    UINT8 u1LocalTsIndex;           //local tsindex for ci+1.4
    UINT8 u1Channel;                ///video id
    UINT8 u1DeviceId;               ///< Device ID
    UINT8 u1KeyIndex;               ///< Descramble key index
    BOOL fgEven;                   ///< EVEN/ODD key
    UINT8 u1SteerMode;              ///< Steering mode
    UINT16 u2Pid;                   ///< PID
    UPTR  u4BufAddr;               ///< Buffer address
    USIZE u4BufSize;               ///< Buffer size
    UPTR  u4Rp;                    ///< Read pointer
    UPTR  u4Wp;                    ///< Write pointer
    USIZE  u4PeakBufFull;           ///< Peak buffer fullness, to estimate
    ///< required ES FIFO size
    DMX_PCR_MODE_T ePcrMode;        ///< PCR mode
    DMX_PID_TYPE_T ePidType;        ///< PID type
    DMX_DESC_MODE_T eDescMode;      ///< Descramble mode
    PFN_DMX_NOTIFY pfnNotify;       ///< Callback function
    void* pvNotifyTag;              ///< Tag value of callback function
    PFN_DMX_NOTIFY pfnScramble;     ///< Callback function of scramble state
    void* pvScrambleTag;            ///< Tag value of scramble callback function
    void *pvInstanceTag;            ///< Tag for supporting multiple instances (used only by v-dec)
    UINT8 u1ChannelId;
    DMX_INPUT_TYPE_T eInputType;
    DMX_SOURCE_T eSource;

    BOOL fgDisableFifoOutput;
    BOOL fgIsAudPreBufPid;

    //IOMMU
    BOOL fgIommuEnable;                   ///Enable or disable output IOMMU
    BOOL fg64BitIommuEnable;        //Enable or disable 64bit output IOMMU
    UINT8 u1ContainAD;              ///< Audio description (0: no-AD, 1: AD, 2: decided by driver)
    UINT8 u1SerialNumber;

    UINT8 u1PhyIpIdx;
    UINT8 u1VirIpIdx;
} TLV_PID_T;

typedef struct
{
    BOOL fgIsFvr;
    BOOL fgEnable;                  ///< Enable or disable
    BOOL fgCheckCrc;                ///< Check CRC or not
    BOOL fgShiftHwFilter;           ///< TRUE: shift HW filter to offset+7
    BOOL fg16ByteHwFilter;           ///<TRUE: use 16 bit hardware section filter
    UINT8 u1Pidx;                   ///< PID index, 0 ~ 64
    UINT8 u1Tsidx;                  ///< Ts index , 0~ 3
    UINT8 u1Offset;                 ///< Offset
    UINT8 au1Data[16];              ///< Pattern
    UINT8 au1Mask[16];              ///< Mask
    UINT8 au1PosNeg[16];            ///< Positive or negative
    DMX_GENFILTER_MODE_T eMode;
} TLV_FILTER_GENERIC_T;

typedef struct
{
    UINT64 u4SecAddr;                   ///< Section address, kernel address
    UINT64 u4SecLen;                    ///< Section length
    UINT8 u1SerialNumber;               ///< Serial number
    UINT32 au4MatchBitmap[SEC_CNT];               ///< Match section filter bitmap
} TLV_NOTIFY_INFO_SI_T;

typedef struct
{ 
    UINT64 u8DataAddr;                  ///< Data address, kernel address
    UINT32 u4DataSize;                  ///< Data size
    UINT64 u8Pts;
    UINT8 u1SerialNumber;               ///< Serial number
}TLV_NOTIFY_INFO_TIMED_MPU_T;

typedef struct
{ 
   UINT64 u8DataAddr;                  ///< Data address, kernel address
   UINT32 u4DataSize;                  ///< Data size
   UINT8 u1SerialNumber;               ///< Serial number
}TLV_NOTIFY_INFO_NON_TIMED_MPU_T;

typedef struct
{ 
   UINT64 u8DataAddr;                  ///< Data address, kernel address
   UINT32 u4DataSize;                  ///< Data size
   UINT8 u1SerialNumber;               ///< Serial number
}TLV_NOTIFY_INFO_MFU_T;

/*tlv_mulmm_if.c*/
EXTERN UINT8 TLV_MUL_GetAvailableInst(DMX_TLV_CONN_TYPE_T eConnType);
EXTERN UINT8 TLV_MUL_GetAvailablePidx(UINT8 u1Inst);
EXTERN UINT8 TLV_MUL_GetAvailableFilter(UINT8 u1Inst);
EXTERN BOOL TLV_MUL_GetTsIdx(UINT8 u1Inst);

EXTERN BOOL TLV_MUL_FreeInst(UINT8 u1Inst);
EXTERN BOOL TLV_MUL_FreePidx(UINT8 u1Pidx);
EXTERN BOOL TLV_MUL_FreeFilter(UINT8 u1FilterIdx);

EXTERN BOOL TLV_SI_GetBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, UPTR u4FrameAddr,
                                    USIZE u4SkipSize, USIZE u4CopySize, UCHAR* pu1Dest);
EXTERN BOOL TLV_SI_UnlockBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, USIZE u4Size, UPTR u4FrameAddr);
EXTERN BOOL TLV_SI_FlushBuffer(UINT8 u1Pidx);

EXTERN BOOL TLV_MFU_GetBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, UPTR u4FrameAddr,
                                    USIZE u4SkipSize, USIZE u4CopySize, UCHAR* pu1Dest);
EXTERN BOOL TLV_MFU_UnlockBuffer(UINT8 u1Pidx, UINT8 u1SerialNumber, USIZE u4Size, UPTR u4FrameAddr);
EXTERN BOOL TLV_MFU_FlushBuffer(UINT8 u1Pidx);

EXTERN BOOL TLV_APP_StartFilter(UINT8 u1Pidx, UINT32 u4TimeDelt, UINT32 u4Count, 
                                UINT32 u4SeqNum, TLV_APPDATA_FILTER_MODE_T eMode);
EXTERN BOOL TLV_APP_StopFilter(UINT8 u1Pidx);

EXTERN VOID TLV_EnableLeapSecondWorkAround(BOOL fgEnable, UINT8 u1Indicator);
EXTERN void TLV_EnablePtsLog(BOOL fgEnable);


EXTERN BOOL TLV_MUL_MoveData(UINT8 u1Inst, DMX_MM_DATA_T *prData);
EXTERN BOOL TLV_MUL_MoveDataEx(UINT8 u1Inst, DMX_MM_DATA_T *prData, BOOL fgBypassMixSync, BOOL fgBypassIpFilter, BOOL fgBypassPidFilter);

/*tlv_if.c*/
EXTERN BOOL TLV_SetIpUdpFilter(UINT8 u1FilterIdx,  const DMX_TLV_IP_FILTER_T *prIpUdpFilter);
EXTERN BOOL TLV_SetPid(UINT8 u1Pidx,  UINT32 u4Flags, const TLV_PID_T *prPid);
EXTERN BOOL TLV_FreePid(UINT8 u1Pidx);

EXTERN BOOL TLV_SetNtpIpUdpFilter(UINT8 u1Pidx,  UINT8 u1StcId, const DMX_TLV_IP_FILTER_T* prIpUdpFilter);

EXTERN BOOL TLV_SetSI(UINT8 u1Pidx,  const DMX_TLV_IP_FILTER_T* prIpUdpFilter);

EXTERN BOOL TLV_GetPidFifoInfo(UINT8 u1Pidx, UPTR *pu4BufStart, UPTR *pu4BufEnd, UPTR *pu4Rp, UPTR *pu4Wp, UINT32 *pu4DataSize);

EXTERN BOOL TLV_UpdateReadPointer(UINT8 u1Pidx, UPTR u4Rp, UPTR u4FrameAddr);


EXTERN BOOL TLV_SetFramerModeEx(UINT8 u1Framer, DMX_FRAMER_MODE_T eMode, 
                                    BOOL fgBypassMixSync, BOOL fgBypassIpFilter, BOOL fgBypassPidFilter);
EXTERN BOOL TLV_SetFrontEndEx(UINT8 u1Idx, DMX_FRONTEND_T eFrontEnd);
EXTERN BOOL TLV_SetTransmissionMode(UINT8 u1TsIdx, DMX_FRAMER_MODE_T eMode);
EXTERN UINT8 TLV_GetAvailableVirIpFilterIdx(UINT8 u1Inst);
EXTERN BOOL TLV_FreeVirIpFilterIdx(UINT8 u1VirFilterIdx);
EXTERN BOOL TLV_SetStcId(UINT8 u1TlvIdx, UINT8 u1StcId);
EXTERN BOOL TLV_SelNtpMode(TLV_NTP_MODE_T eNtpMode);
EXTERN BOOL TLV_ResetLeapIndicator(UINT8 u1TlvIdx, UINT8 u1StcId);
#endif  // DMX_IF_H

