summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
Diffstat (limited to 'cesar')
-rw-r--r--cesar/mac/sar/inc/bridge_dma.h6
-rw-r--r--cesar/mac/sar/src/bridge_dma.c10
-rw-r--r--cesar/mac/sar/src/sar.c96
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c8
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/misc.c8
-rw-r--r--cesar/mac/sar/test/unit_test/ecos/src/sar_call_back_ul.c4
6 files changed, 102 insertions, 30 deletions
diff --git a/cesar/mac/sar/inc/bridge_dma.h b/cesar/mac/sar/inc/bridge_dma.h
index 4cf857c7cf..3ef1f1d914 100644
--- a/cesar/mac/sar/inc/bridge_dma.h
+++ b/cesar/mac/sar/inc/bridge_dma.h
@@ -57,11 +57,13 @@ sar_bridge_dma_get_head (sar_bridge_dma_list_t *list);
/**
* Add a job to the TX/RX pending job list.
* \param list the bridge DMA list to add the job.
- * \param head the job MFS to add to the list.
+ * \param head first job MFS to add to the list.
+ * \param tail last job MFS to add to the list.
*/
void
sar_bridge_dma_add_pending_job (sar_bridge_dma_list_t *list,
- sar_job_mfs_t *head);
+ sar_job_mfs_t *head,
+ sar_job_mfs_t *tail);
/**
* Add a job to the bridge DMA list.
diff --git a/cesar/mac/sar/src/bridge_dma.c b/cesar/mac/sar/src/bridge_dma.c
index 78a023a6ac..7159d855a2 100644
--- a/cesar/mac/sar/src/bridge_dma.c
+++ b/cesar/mac/sar/src/bridge_dma.c
@@ -76,7 +76,8 @@ sar_bridge_dma_add_jobs (sar_bridge_dma_list_t *bridge_list,
void
sar_bridge_dma_add_pending_job (sar_bridge_dma_list_t *list,
- sar_job_mfs_t *head)
+ sar_job_mfs_t *head,
+ sar_job_mfs_t *tail)
{
dbg_assert (list);
dbg_assert (head);
@@ -84,15 +85,14 @@ sar_bridge_dma_add_pending_job (sar_bridge_dma_list_t *list,
if (list->head == NULL)
{
list->head = head;
- list->tail = head;
+ list->tail = tail;
}
else
{
list->tail->job.next = &head->job;
- list->tail = head;
+ list->tail = tail;
}
-
- head->job.next = NULL;
+ tail->job.next = NULL;
}
bool
diff --git a/cesar/mac/sar/src/sar.c b/cesar/mac/sar/src/sar.c
index 7c2e34b2ad..e64238d167 100644
--- a/cesar/mac/sar/src/sar.c
+++ b/cesar/mac/sar/src/sar.c
@@ -34,6 +34,10 @@
/** Time SAR thread sleeps. */
#define SAR_THREAD_DELAY_RTC 10
+/** Define the JOB length for the second job to avoid bridgedma bug see
+ * maria:#905. */
+#define SAR_BRGBUG_SECOND_JOB_LENGTH 16
+
/**
* Macro to poll the bridge DMA end.
* \param ctx the SAR context.
@@ -882,9 +886,6 @@ sar_bridge_dma_free_head_rx (sar_t *ctx, sar_job_mfs_t *job)
dbg_assert (ctx);
dbg_assert (job);
- arch_load_cache (((u32 *) job) + 3, 1);
- arch_load_cache (((u32 *) job) + 5, 1);
-
#if CONFIG_SAR_BRG_JOB_ERROR
dbg_assert (job->job.mf_header1 != 0xdeaddead);
#endif
@@ -1041,15 +1042,31 @@ sar_bridge_dma_free_head (sar_t *ctx)
sar_job_mfs_t *job;
phy_bridgedma_job_t *jobs;
dbg_assert (ctx);
-
/* Get the ended list of jobs from the bridge DMA. */
jobs = phy_bridgedma_jobs_get_ended (ctx->bridgedma_ctx);
-
while (jobs)
{
job = PARENT_OF (sar_job_mfs_t, job, jobs);
- jobs = jobs->next;
-
+ /* Load job data into cache. */
+ arch_load_cache (((u32 *) &job->job) + 5, 1);
+ /* Workaround bridge dma bug maria:#905. */
+ if (job->job.direction
+ && job->job.crc_store == false
+ && job->job.next
+ && job->job.next->header_len == 0)
+ {
+ /* Load job data into cache. */
+ arch_load_cache (((u32 *) &job->job.next) + 5, 1);
+ /* Release the second job. */
+ sar_job_mfs_t *j = PARENT_OF (sar_job_mfs_t, job, job->job.next);
+ /* Restore original job values. */
+ job->job.crc_error = j->job.crc_error;
+ job->job.data_len += j->job.data_len;
+ job->job.next = j->job.next;
+ /* Free the second job. */
+ blk_release (j);
+ }
+ jobs = job->job.next;
if (!ctx->activate)
sar_bridge_dma_free_header_not_activate (ctx, job);
else if (!job->job.direction)
@@ -1505,15 +1522,36 @@ sar_rx_mfs_detect_and_reconstitute_mf__create_job (sar_t *ctx, mfs_rx_t *mfs,
dbg_assert (mfs);
dbg_assert (sar_mf);
dbg_assert (pb_mf_ends);
-
job = sar_job_mfs_create_rx ();
job->mfs = (mfs_t *) mfs;
job->pb_quantity = sar_mf->qte;
job->tail = pb_mf_ends;
-
+ uint offset = mfs->head->header.mfbo;
sar_rx_job_desc_create (&job->job, mfs, mfs->head,
mfs->head->header.mfbo,
sar_mf);
+ uint icv_pos_end = sar_mf->length_complete + offset;
+ /* Workaround for bridgedma bug see maria:#905 */
+ if (sar_mf->length > SAR_BRGBUG_SECOND_JOB_LENGTH
+ && icv_pos_end % BLK_SIZE != 0
+ && icv_pos_end % BLK_SIZE <= 4)
+ {
+ sar_job_mfs_t *j2 = sar_job_mfs_create_rx ();
+ uint second_job_start =
+ (icv_pos_end - SAR_BRGBUG_SECOND_JOB_LENGTH - SAR_MF_ICV_SIZE);
+ pb_t *pb;
+ for (pb = mfs->head;
+ second_job_start > BLK_SIZE;
+ second_job_start -= BLK_SIZE, pb = pb->next);
+ j2->job.first_pb_desc = &pb->blk;
+ j2->job.header_len = 0;
+ j2->job.data_len = SAR_BRGBUG_SECOND_JOB_LENGTH;
+ j2->job.first_pb_offset = second_job_start;
+ j2->job.crc_reset = false;
+ job->job.next = &j2->job;
+ job->job.crc_store = false;
+ job->job.data_len -= SAR_BRGBUG_SECOND_JOB_LENGTH;
+ }
#if CONFIG_SAR_BRG_JOB_ERROR
job->job.mf_header1 = 0xdeaddead;
#endif
@@ -1651,12 +1689,30 @@ sar_rx_mfs_process (sar_t *ctx, mfs_rx_t * mfs, sar_reassembly_ctx_t *rea_ctx)
{
if (!slist_empty (rea_ctx->buffer_list., bare))
{
- job->job.data_addr = (u8*) slist_pop_front (rea_ctx->buffer_list.,
- bare);
- phy_bridgedma_start (ctx->bridgedma_ctx, &job->job, &job->job);
+ u8 *buffer =
+ (u8*) slist_pop_front (rea_ctx->buffer_list., bare);
+ job->job.data_addr = buffer;
+ /* Workaround for maria bug #905 */
+ if (job->job.next)
+ {
+ job->job.next->data_addr = buffer + job->job.data_len;
+ phy_bridgedma_start (
+ ctx->bridgedma_ctx, &job->job, job->job.next);
+ }
+ else
+ phy_bridgedma_start (
+ ctx->bridgedma_ctx, &job->job, &job->job);
}
else
- sar_bridge_dma_add_pending_job (&rea_ctx->jobs_pending_list, job);
+ {
+ if (job->job.next)
+ sar_bridge_dma_add_pending_job (
+ &rea_ctx->jobs_pending_list, job,
+ PARENT_OF (sar_job_mfs_t, job, job->job.next));
+ else
+ sar_bridge_dma_add_pending_job (
+ &rea_ctx->jobs_pending_list, job, job);
+ }
}
}
@@ -1666,7 +1722,7 @@ sar_rx_upper_layer_transmit_data (sar_t *sar_ctx, sar_reassembly_ctx_t *ctx)
sar_job_mfs_t *job_head = NULL;
sar_job_mfs_t *job_tail = NULL;
sar_job_mfs_t *job_current;
-
+ u8 *buffer;
dbg_assert (sar_ctx);
dbg_assert (ctx);
@@ -1676,8 +1732,16 @@ sar_rx_upper_layer_transmit_data (sar_t *sar_ctx, sar_reassembly_ctx_t *ctx)
{
if (job_head == NULL)
job_head = job_current;
- job_current->job.data_addr = (u8*) slist_pop_front (ctx->buffer_list.,
- bare);
+ buffer = (u8*) slist_pop_front (ctx->buffer_list., bare);
+ job_current->job.data_addr = buffer;
+ /* Work around maria:#905 */
+ if (job_current->job.crc_store == false)
+ {
+ phy_bridgedma_job_t *j = job_current->job.next;
+ dbg_assert (j);
+ j->data_addr = buffer + job_current->job.data_len;
+ job_current = PARENT_OF (sar_job_mfs_t, job, j);
+ }
job_tail = job_current;
job_current = PARENT_OF (sar_job_mfs_t, job, job_current->job.next);
}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c b/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
index 2f73595490..ffe327ddae 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/detect_mf.c
@@ -262,10 +262,16 @@ test_case_sar_detect_mf_all_pb_offset (test_t test)
job = sar_rx_mfs_detect_and_reconstitute_mf (ctx.sar, mfs);
test_fail_unless (job != NULL);
- test_fail_unless (job->job.data_len == 60);
+ /* Check segmentation with maria bug fixed see maria:#905 .*/
+ test_fail_unless (job->job.data_len == 60
+ || (job->job.next
+ && job->job.data_len +
+ job->job.next->data_len == 60));
test_fail_unless (((pb_t*) job->job.first_pb_desc) == pb_first);
/* Release the references. */
+ if (job->job.next)
+ blk_release (job->job.next);
blk_release (job);
blk_release (mfs);
}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/misc.c b/cesar/mac/sar/test/unit_test/ecos/src/misc.c
index 533efe9e8b..7bd058f66c 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/misc.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/misc.c
@@ -75,10 +75,10 @@ test_case_misc__cleanup_pending_jobs_add_rx_simulate_missing_pb (
t->sar, mfs, &sar_mf, pb_first->next->next);
if (data)
sar_bridge_dma_add_pending_job (
- &t->sar->data_ctx.jobs_pending_list, job);
+ &t->sar->data_ctx.jobs_pending_list, job, job);
else
sar_bridge_dma_add_pending_job (
- &t->sar->mme_ctx.jobs_pending_list, job);
+ &t->sar->mme_ctx.jobs_pending_list, job, job);
blk_release (mfs);
}
@@ -105,10 +105,10 @@ test_case_misc__add_pending_jobs_add_one_rx (sar_test_t *t, bool data)
t->sar, mfs, &sar_mf, pb_first->next->next);
if (data)
sar_bridge_dma_add_pending_job (
- &t->sar->data_ctx.jobs_pending_list, job);
+ &t->sar->data_ctx.jobs_pending_list, job, job);
else
sar_bridge_dma_add_pending_job (
- &t->sar->mme_ctx.jobs_pending_list, job);
+ &t->sar->mme_ctx.jobs_pending_list, job, job);
blk_release (mfs);
}
diff --git a/cesar/mac/sar/test/unit_test/ecos/src/sar_call_back_ul.c b/cesar/mac/sar/test/unit_test/ecos/src/sar_call_back_ul.c
index 5bb0d88b25..88c540dea0 100644
--- a/cesar/mac/sar/test/unit_test/ecos/src/sar_call_back_ul.c
+++ b/cesar/mac/sar/test/unit_test/ecos/src/sar_call_back_ul.c
@@ -114,7 +114,7 @@ test_case_rx_upper_layer_transmit_data (test_t test)
job->mfs = blk_alloc ();
job->pb_quantity = 1;
sar_bridge_dma_add_pending_job (
- &t.sar->data_ctx.jobs_pending_list, job);
+ &t.sar->data_ctx.jobs_pending_list, job, job);
}
job = INVALID_PTR;
@@ -144,7 +144,7 @@ test_case_rx_upper_layer_transmit_data (test_t test)
mfs_rx_init (&job->mfs->rx, false, false, 1, 1);
sar_bridge_dma_add_pending_job (&t.sar->data_ctx.jobs_pending_list,
- job);
+ job, job);
sar_data_buffer_add (t.sar, buffer[0]);
test_fail_unless (t.rea_done.buffer = job->job.data_addr);