summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlefranc2007-07-09 16:57:51 +0000
committerlefranc2007-07-09 16:57:51 +0000
commitbf1cefe5fcbfc6904b2cdbb12e0f023db98839af (patch)
treec153eee6179865fdfc8fcc2fa289c7dab947e925
parent441a38bb5709be9f384a41d92de49f05b40b5101 (diff)
- added station to bridgedma context
- added schedule + callback before bridgedma_start returns git-svn-id: svn+ssh://pessac/svn/cesar/trunk@458 017c9cb6-072f-447c-8318-d5b54f68fe89
-rw-r--r--hal/phy/bridgedma.h2
-rw-r--r--hal/phy/maximus/inc/maximus_bridgedma_ctx.h3
-rw-r--r--hal/phy/maximus/src/maximus_bridgedma.c60
3 files changed, 54 insertions, 11 deletions
diff --git a/hal/phy/bridgedma.h b/hal/phy/bridgedma.h
index 8740f465d9..7702fa1433 100644
--- a/hal/phy/bridgedma.h
+++ b/hal/phy/bridgedma.h
@@ -26,7 +26,7 @@ struct phy_bridgedma_job_t
/** Mac frame header length */
u32 header_len:4;,
u32 :12;,
- /** Length of data in ethernet buffer. max 1538 */
+ /** Length of data in ethernet buffer. max 1518 */
u32 data_len:11;,
u32 :5;)
/** Pointer to the pb descriptor list head */
diff --git a/hal/phy/maximus/inc/maximus_bridgedma_ctx.h b/hal/phy/maximus/inc/maximus_bridgedma_ctx.h
index 33ab76dcbc..56778d8791 100644
--- a/hal/phy/maximus/inc/maximus_bridgedma_ctx.h
+++ b/hal/phy/maximus/inc/maximus_bridgedma_ctx.h
@@ -14,6 +14,7 @@
*/
#include "lib/crc.h"
#include "hal/phy/bridgedma.h"
+#include "host/station.h"
/** 1 byte is processed into 5ns, so 8 bytes per tick (40ns) */
#define BRIDGEDMA_BYTE_PER_TICK 8
@@ -38,6 +39,8 @@ struct phy_bridgedma_t
void *user_data;
phy_bridgedma_cb_t bridgedma_cb;
phy_deferred_cb_t deferred_cb;
+ station_ctx_t *station_ctx;
+ netclock_callback_t netclock_cb;
};
#ifdef UNIT_TEST
diff --git a/hal/phy/maximus/src/maximus_bridgedma.c b/hal/phy/maximus/src/maximus_bridgedma.c
index 36439f6571..4920fc0255 100644
--- a/hal/phy/maximus/src/maximus_bridgedma.c
+++ b/hal/phy/maximus/src/maximus_bridgedma.c
@@ -16,6 +16,7 @@
#include "hal/phy/maximus/inc/maximus_interrupts.h"
#include "hal/phy/maximus/inc/maximus_phy_ctx.h"
#include "hal/phy/maximus/inc/maximus_bridgedma_ctx.h"
+#include <stdlib.h>
#define HPAV_CRC32_GENERATOR 0x04c11db7
#define HPAV_CRC32_INIT 0xffffffff
@@ -25,6 +26,12 @@
#define ETH_BUFFER_SIZE(job) (ETH_BUFFER_MASK(job) + 1)
#define ETH_BUFFER_ADDR(job) (unsigned char *)((unsigned long)job->data_addr & ETH_BUFFER_MASK(job))
+struct job_cb_data
+{
+ phy_bridgedma_t *ctx;
+ int is_it;
+};
+
/**
* Initialise the Bridge DMA.
* \param user_data User data passed to any callback
@@ -44,6 +51,7 @@ phy_bridgedma_init (void *user_data, phy_bridgedma_cb_t bridgedma_cb,
bridgedma_ctx.bridgedma_cb = bridgedma_cb;
bridgedma_ctx.deferred_cb = deferred_cb;
bridgedma_ctx.status.stop = 1;
+ bridgedma_ctx.station_ctx = &my_station;
bridgedma_ctx.crc_ctx.width = 32;
bridgedma_ctx.crc_ctx.generator = HPAV_CRC32_GENERATOR;
@@ -53,7 +61,6 @@ phy_bridgedma_init (void *user_data, phy_bridgedma_cb_t bridgedma_cb,
bridgedma_ctx.crc_ctx.xorout = 0xffffffff;
bridgedma_ctx.crc_ctx.reg_init = 0;
bridgedma_ctx.crc_ctx.table.t32 = enc_tab;
-
crc_init(&bridgedma_ctx.crc_ctx);
return &bridgedma_ctx;
@@ -70,6 +77,12 @@ phy_bridgedma_uninit (phy_bridgedma_t *ctx)
}
+static int _compute_duration(unsigned int length)
+{
+ return (length / BRIDGEDMA_BYTE_PER_TICK + 1
+ + (int) ((double)BRIDGEDMA_ADD_MAX_TICK * (rand() / (RAND_MAX + 1.0))));
+}
+
/**
* Fragment a mac_frame data into one or several PBs.
* Mac frame data MUST NOT cross the mac frame buffer boundary (going at beginning of circular buffer)
@@ -132,7 +145,6 @@ _job_process(phy_bridgedma_t *ctx, phy_bridgedma_job_t *job)
unsigned char * mac_ptr, *data_ptr;
blk_t *pb_current;
unsigned long icv_final, icv_compare;
-
ctx->job_current = job;
@@ -230,13 +242,25 @@ _job_process(phy_bridgedma_t *ctx, phy_bridgedma_job_t *job)
}
}
- /* check interrupt raising */
- if(job->job_it)
- maximus_pending_isrs |= (1 << PHY_HAL_INTERRUPT_BRIDGEDMA);
-
return 0;
}
+static void _job_process_cb(void *data)
+{
+ struct job_cb_data *job_data;
+
+ dbg_assert(data);
+ job_data = (struct job_cb_data *)data;
+
+ /* refresh bridge dam status */
+ job_data->ctx->status.running = 0;
+ job_data->ctx->status.stop = 1;
+ /* check interrupt raising */
+ if(job_data->is_it)
+ maximus_pending_isrs |= (1 << PHY_HAL_INTERRUPT_BRIDGEDMA);
+
+ return;
+}
/**
* Enqueue and start a list of jobs.
@@ -253,6 +277,10 @@ phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
phy_bridgedma_job_t *job_last)
{
phy_bridgedma_job_t *job_current;
+ unsigned int total_length;
+ static struct job_cb_data job_data;
+ unsigned long duration;
+ netclock_id_t netclock_id;
dbg_assert(ctx);
dbg_assert(job_first);
@@ -262,15 +290,27 @@ phy_bridgedma_start (phy_bridgedma_t *ctx, phy_bridgedma_job_t *job_first,
ctx->job_first = job_first;
memset(&ctx->status, '\0', sizeof(phy_bridgedma_status_t));
ctx->status.running = 1;
+ total_length = 0;
+ job_data.ctx = ctx;
+ job_data.is_it = 0;
do {
_job_process(ctx, job_current);
+ total_length += job_current->data_len;
job_current = job_current->next;
+ job_data.is_it |= job_current->job_it;
} while ((job_current != NULL)
&& !job_current->last);
-
- ctx->status.running = 0;
- ctx->status.stop = 1;
-
+
+ /* schedule the process duration */
+ duration = _compute_duration(total_length);
+ netclock_schedule(ctx->station_ctx->netclock,
+ &ctx->netclock_cb,
+ NETWORK_CLOCK_TYPE_PHY,
+ ctx->station_ctx->current_tick_tck + duration,
+ _job_process_cb,
+ &job_data,
+ &netclock_id);
+
return;
}