Merge "media: dvb: mpq: Secure demux API updates"
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 2c9a0b8..4701f69 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -3455,11 +3455,15 @@
struct sdmx_buff_descr data_buff_desc[DMX_MAX_DECODER_BUFFER_NUM];
u32 data_buf_num = DMX_MAX_DECODER_BUFFER_NUM;
enum sdmx_buf_mode buf_mode;
+ enum sdmx_raw_out_format ts_out_format = SDMX_188_OUTPUT;
+ u32 filter_flags = 0;
feed = dvbdmx_feed->priv;
if (mpq_dmx_is_sec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_SECTION_FILTER;
+ if (dvbdmx_feed->feed.sec.check_crc)
+ filter_flags |= SDMX_FILTER_FLAG_VERIFY_SECTION_CRC;
MPQ_DVB_DBG_PRINT("%s: SDMX_SECTION_FILTER\n", __func__);
} else if (mpq_dmx_is_pcr_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_PCR_FILTER;
@@ -3469,6 +3473,22 @@
MPQ_DVB_DBG_PRINT("%s: SDMX_SEPARATED_PES_FILTER\n", __func__);
} else if (mpq_dmx_is_rec_feed(dvbdmx_feed)) {
feed->filter_type = SDMX_RAW_FILTER;
+ switch (dvbdmx_feed->tsp_out_format) {
+ case (DMX_TSP_FORMAT_188):
+ ts_out_format = SDMX_188_OUTPUT;
+ break;
+ case (DMX_TSP_FORMAT_192_HEAD):
+ ts_out_format = SDMX_192_HEAD_OUTPUT;
+ break;
+ case (DMX_TSP_FORMAT_192_TAIL):
+ ts_out_format = SDMX_192_TAIL_OUTPUT;
+ break;
+ default:
+ MPQ_DVB_ERR_PRINT(
+ "%s: Unsupported TS output format %d\n",
+ __func__, dvbdmx_feed->tsp_out_format);
+ return -EINVAL;
+ }
MPQ_DVB_DBG_PRINT("%s: SDMX_RAW_FILTER\n", __func__);
} else {
feed->filter_type = SDMX_PES_FILTER;
@@ -3498,8 +3518,9 @@
feed->secondary_feed = 0;
MPQ_DVB_DBG_PRINT(
- "%s: Adding new sdmx filter, pid %d\n",
- __func__, dvbdmx_feed->pid);
+ "%s: Adding new sdmx filter, pid %d, flags=0x%X, ts_out_format=%d\n",
+ __func__, dvbdmx_feed->pid, filter_flags,
+ ts_out_format);
/* Meta-data initialization,
* Recording filters do no need meta-data buffers.
@@ -3534,7 +3555,9 @@
buf_mode,
data_buf_num,
data_buff_desc,
- &feed->sdmx_filter_handle);
+ &feed->sdmx_filter_handle,
+ ts_out_format,
+ filter_flags);
if (ret) {
MPQ_DVB_ERR_PRINT(
"%s: SDMX_add_filter failed. ret = %d\n",
@@ -3869,6 +3892,7 @@
{
int ret;
struct sdmx_metadata_header header;
+ struct sdmx_pes_counters counters;
struct dmx_data_ready data_event;
struct dmx_data_ready pes_event;
struct dvb_demux_feed *feed = mpq_feed->dvb_demux_feed;
@@ -3906,22 +3930,26 @@
while (sts->metadata_fill_count) {
if (dvb_ringbuffer_avail(&mpq_feed->metadata_buf) <
- sizeof(header)) {
+ (sizeof(header) + sizeof(counters))) {
MPQ_DVB_ERR_PRINT(
"%s: metadata_fill_count is %d but actual buffer has less than %d bytes\n",
__func__,
sts->metadata_fill_count,
- sizeof(header));
+ sizeof(header) + sizeof(counters));
break;
}
- dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *) &header,
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
sizeof(header));
MPQ_DVB_DBG_PRINT(
"%s: metadata header: start=%u, length=%u\n",
__func__, header.payload_start, header.payload_length);
sts->metadata_fill_count -= sizeof(header);
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+ sizeof(counters));
+ sts->metadata_fill_count -= sizeof(counters);
+
/* Notify new data in buffer */
data_event.status = DMX_OK;
data_event.data_length = header.payload_length;
@@ -3947,11 +3975,13 @@
pes_event.pes_end.pes_length_mismatch = 1;
if (sts->error_indicators & SDMX_FILTER_ERR_CONT_CNT_INVALID)
pes_event.pes_end.disc_indicator_set = 0;
- /* TODO: report these when SDMX returns them */
+
pes_event.pes_end.stc = 0;
- pes_event.pes_end.tei_counter = 0;
- pes_event.pes_end.cont_err_counter = 0;
- pes_event.pes_end.ts_packets_num = 0;
+ pes_event.pes_end.tei_counter = counters.transport_err_count;
+ pes_event.pes_end.cont_err_counter =
+ counters.continuity_err_count;
+ pes_event.pes_end.ts_packets_num =
+ counters.pes_ts_count;
ret = mpq_sdmx_check_ts_stall(mpq_demux, mpq_feed, sts, 0, 1);
if (ret) {
@@ -4024,6 +4054,7 @@
struct sdmx_filter_status *sts)
{
struct sdmx_metadata_header header;
+ struct sdmx_pes_counters counters;
int pes_header_offset;
struct ts_packet_header *ts_header;
struct ts_adaptation_field *ts_adapt;
@@ -4060,7 +4091,7 @@
struct mpq_adapter_video_meta_data meta_data;
pes_cnt++;
- /* Read header & metadata */
+ /* Read metadata header */
dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&header,
sizeof(header));
sts->metadata_fill_count -= sizeof(header);
@@ -4069,17 +4100,23 @@
__func__, header.payload_start, header.payload_length,
header.metadata_length);
- /* Read actual metadata */
+ /* Read metadata - PES counters */
+ dvb_ringbuffer_read(&mpq_feed->metadata_buf, (u8 *)&counters,
+ sizeof(counters));
+ sts->metadata_fill_count -= sizeof(counters);
+
+ /* Read metadata - TS & PES headers */
if (header.metadata_length < MAX_SDMX_METADATA_LENGTH)
dvb_ringbuffer_read(&mpq_feed->metadata_buf,
metadata_buf,
- header.metadata_length);
+ header.metadata_length - sizeof(counters));
else
MPQ_DVB_ERR_PRINT(
"%s: meta-data size=%d is too big for meta-data buffer=%d\n",
__func__, header.metadata_length,
MAX_SDMX_METADATA_LENGTH);
- sts->metadata_fill_count -= header.metadata_length;
+ sts->metadata_fill_count -=
+ (header.metadata_length - sizeof(counters));
ts_header = (struct ts_packet_header *)&metadata_buf[0];
if (1 == ts_header->adaptation_field_control) {
@@ -4119,6 +4156,16 @@
}
spin_lock(&mpq_feed->video_info.video_buffer_lock);
+
+ mpq_feed->video_info.tei_errs =
+ counters.transport_err_count;
+ mpq_feed->video_info.continuity_errs =
+ counters.continuity_err_count;
+ mpq_feed->video_info.ts_packets_num =
+ counters.pes_ts_count;
+ mpq_feed->video_info.ts_dropped_bytes =
+ counters.drop_count * mpq_demux->demux.ts_packet_size;
+
sbuf = mpq_feed->video_info.video_buffer;
if (sbuf == NULL) {
MPQ_DVB_ERR_PRINT(
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
index 0f91930..946b055 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
@@ -110,6 +110,8 @@
enum sdmx_filter filter_type;
struct sdmx_buff_descr meta_data_buf;
enum sdmx_buf_mode buffer_mode;
+ enum sdmx_raw_out_format ts_out_format;
+ u32 flags;
u32 num_data_bufs;
struct sdmx_buff_descr data_bufs[];
};
@@ -453,6 +455,9 @@
* @num_data_bufs: number of data buffers (use 1 for a ring buffer)
* @data_bufs: data buffers descriptors array
* @filter_handle: returned filter handle
+ * @ts_out_format: output format for raw filters
+ * @flags: optional flags for filter
+ * (currently only clear section CRC verification is supported)
*
* Return error code
*/
@@ -463,7 +468,9 @@
enum sdmx_buf_mode d_buf_mode,
u32 num_data_bufs,
struct sdmx_buff_descr *data_bufs,
- int *filter_handle)
+ int *filter_handle,
+ enum sdmx_raw_out_format ts_out_format,
+ u32 flags)
{
int res, cmd_len, rsp_len;
struct sdmx_add_filt_req *cmd;
@@ -493,6 +500,8 @@
cmd->session_handle = session_handle;
cmd->pid = (u32)pid;
cmd->filter_type = filterype;
+ cmd->ts_out_format = ts_out_format;
+ cmd->flags = flags;
if (meta_data_buf != NULL)
memcpy(&(cmd->meta_data_buf), meta_data_buf,
sizeof(struct sdmx_buff_descr));
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
index ffb9046..0bd04e8 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
@@ -27,24 +27,26 @@
#define SDMX_FILTER_ERR_INVALID_SCRAMBLE_BITS BIT(3)
#define SDMX_FILTER_ERR_KL_IND_NOT_SET BIT(4)
#define SDMX_FILTER_ERR_CAS_DECRYPT_ERROR BIT(5)
-#define SDMX_FILTER_ERR_SEC_VERIF_GENERAL_FAIL BIT(6)
-#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL BIT(7)
-#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL BIT(8)
-#define SDMX_FILTER_ERR_SEC_LEN_INVALID BIT(9)
-#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID BIT(10)
-#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID BIT(11)
-#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR BIT(12)
-#define SDMX_FILTER_ERR_CONT_CNT_INVALID BIT(13)
-#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE BIT(14)
-#define SDMX_FILTER_ERR_INVALID_PES_HDR BIT(15)
-#define SDMX_FILTER_ERR_INVALID_PES_LEN BIT(16)
-#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION BIT(17)
-#define SDMX_FILTER_ERR_SECURITY_FAULT BIT(18)
-#define SDMX_FILTER_ERR_IN_NS_BUFFER BIT(19)
+#define SDMX_FILTER_ERR_SEC_VERIF_CRC32_FAIL BIT(6)
+#define SDMX_FILTER_ERR_SEC_INTERNAL_MALLOC_FAIL BIT(7)
+#define SDMX_FILTER_ERR_SEC_LEN_INVALID BIT(8)
+#define SDMX_FILTER_ERR_SEC_PUSI_PTR_INVALID BIT(9)
+#define SDMX_FILTER_ERR_TS_SYNC_BYTE_INVALID BIT(10)
+#define SDMX_FILTER_ERR_TS_TRANSPORT_ERR BIT(11)
+#define SDMX_FILTER_ERR_CONT_CNT_INVALID BIT(12)
+#define SDMX_FILTER_ERR_CONT_CNT_DUPLICATE BIT(13)
+#define SDMX_FILTER_ERR_INVALID_PES_HDR BIT(14)
+#define SDMX_FILTER_ERR_INVALID_PES_LEN BIT(15)
+#define SDMX_FILTER_ERR_INVALID_PES_ENCRYPTION BIT(16)
+#define SDMX_FILTER_ERR_SECURITY_FAULT BIT(17)
+#define SDMX_FILTER_ERR_IN_NS_BUFFER BIT(18)
/* Filter-level status indicators */
#define SDMX_FILTER_STATUS_EOS BIT(0)
+/* Filter-level flags */
+#define SDMX_FILTER_FLAG_VERIFY_SECTION_CRC BIT(0)
+
#define SDMX_INVALID_SESSION_HANDLE (-1)
#define SDMX_INVALID_FILTER_HANDLE (-1)
@@ -103,6 +105,12 @@
SDMX_RAW_FILTER, /* Recording */
};
+enum sdmx_raw_out_format {
+ SDMX_188_OUTPUT,
+ SDMX_192_HEAD_OUTPUT,
+ SDMX_192_TAIL_OUTPUT
+};
+
struct sdmx_session_dbg_counters {
/* Total number of TS-packets input to SDMX. */
u32 ts_pkt_in;
@@ -130,6 +138,20 @@
u32 ts_pkt_key_not_ready;
};
+struct sdmx_pes_counters {
+ /* Number of TS packets with the TEI flag set */
+ u32 transport_err_count;
+
+ /* Number of TS packets with continuity counter errors */
+ u32 continuity_err_count;
+
+ /* Number of TS packets composing this PES frame */
+ u32 pes_ts_count;
+
+ /* Number of TS packets dropped due to full buffer */
+ u32 drop_count;
+};
+
struct sdmx_buff_descr {
/* Physical address where buffer starts */
void *base_addr;
@@ -204,7 +226,7 @@
int sdmx_add_filter(int session_handle, u16 pid, enum sdmx_filter filter_type,
struct sdmx_buff_descr *meta_data_buf, enum sdmx_buf_mode data_buf_mode,
u32 num_data_bufs, struct sdmx_buff_descr *data_bufs,
- int *filter_handle);
+ int *filter_handle, enum sdmx_raw_out_format ts_out_format, u32 flags);
int sdmx_remove_filter(int session_handle, int filter_handle);