00001
00020
00021
00022
00023
00024 #include <stddef.h>
00025 #include "co_int.h"
00026 #include "co_bool.h"
00027 #include "rwnx_config.h"
00028 #include "dbg_assert.h"
00029
00030 #include "ke_config.h"
00031 #include "ke_task.h"
00032 #include "ke_env.h"
00033 #include "ke_queue.h"
00034 #include "ke_event.h"
00035 #include "ke_mem.h"
00036 #include "dbg.h"
00037
00038
00039 #include "mm_task.h"
00040 #include "dbg_task.h"
00041 #include "scan_task.h"
00042
00043 #if (NX_TDLS)
00044 #include "tdls_task.h"
00045 #endif
00046
00047 #if NX_UMAC_PRESENT
00048 #include "scanu_task.h"
00049 #include "me_task.h"
00050 #include "sm_task.h"
00051 #include "bam_task.h"
00052 #include "apm_task.h"
00053 #if RW_MESH_EN
00054 #include "mesh_task.h"
00055 #endif
00056 #endif
00057
00059 static const struct ke_task_desc TASK_DESC[TASK_MAX] =
00060 {
00061
00063 [TASK_MM] = {mm_state_handler, &mm_default_handler, mm_state, MM_STATE_MAX, MM_IDX_MAX},
00064
00066 [TASK_DBG] = {NULL, &dbg_default_handler, NULL, 1, 1},
00067
00068 #if NX_HW_SCAN
00070 [TASK_SCAN] = {NULL, &scan_default_handler, scan_state, SCAN_STATE_MAX, SCAN_IDX_MAX},
00071 #endif
00072
00073 #if (NX_TDLS)
00074 [TASK_TDLS] = {NULL, &tdls_default_handler, tdls_state, TDLS_STATE_MAX, TDLS_IDX_MAX},
00075 #endif
00076
00077 #if NX_UMAC_PRESENT
00079 [TASK_SCANU] = {scanu_state_handler, &scanu_default_handler, scanu_state, SCANU_STATE_MAX, SCANU_IDX_MAX},
00081 [TASK_ME] = {NULL, &me_default_handler, me_state, ME_STATE_MAX, ME_IDX_MAX},
00083 [TASK_SM] = {NULL, &sm_default_handler, sm_state, SM_STATE_MAX, SM_IDX_MAX},
00085 [TASK_BAM] = {NULL, &bam_default_handler, bam_state, BAM_STATE_MAX, BAM_IDX_MAX},
00086 #if NX_BEACONING
00088 [TASK_APM] = {NULL, &apm_default_handler, apm_state, APM_STATE_MAX, APM_IDX_MAX},
00089 #endif
00090 #if (RW_MESH_EN && NX_UMAC_PRESENT)
00092 [TASK_MESH] = {NULL, &mesh_default_handler, mesh_state, MESH_STATE_MAX, MESH_IDX_MAX},
00093 #endif //(RW_MESH_EN && NX_UMAC_PRESENT)
00094 #endif //(NX_UMAC_PRESENT)
00095 };
00096
00097
00098
00102 static bool cmp_dest_id(struct co_list_hdr const * msg, uint32_t dest_id)
00103 {
00104 return ((struct ke_msg*)msg)->dest_id == dest_id;
00105 }
00106
00118 static void ke_task_saved_update(ke_task_id_t const ke_task_id)
00119 {
00120 struct ke_msg * msg;
00121
00122 for(;;)
00123 {
00124
00125
00126 msg = (struct ke_msg*) ke_queue_extract(&ke_env.queue_saved,
00127 &cmp_dest_id,
00128 (uint32_t) ke_task_id);
00129
00130 if (msg == NULL) break;
00131
00132
00133
00134
00135 GLOBAL_INT_DISABLE();
00136 ke_queue_push(&ke_env.queue_sent, (struct co_list_hdr*)msg);
00137 GLOBAL_INT_RESTORE();
00138
00139
00140 ke_evt_set(KE_EVT_KE_MESSAGE_BIT);
00141 }
00142
00143 return;
00144 }
00145
00146
00159 void ke_state_set(ke_task_id_t const id,
00160 ke_state_t const state_id)
00161 {
00162 ke_state_t *ke_stateid_ptr = NULL;
00163 int idx = KE_IDX_GET(id);
00164 int type = KE_TYPE_GET(id);
00165
00166
00167 ASSERT_ERR(type < TASK_MAX);
00168 ASSERT_ERR(ke_task_local(type));
00169 ASSERT_ERR(idx < TASK_DESC[type].idx_max);
00170
00171
00172 ke_stateid_ptr = &TASK_DESC[type].state[idx];
00173
00174 ASSERT_ERR(ke_stateid_ptr);
00175
00176 dbg(D_KE D_INF "set tsk:%x:%x\n", id, state_id);
00177 TRACE_KERNEL(STATE, "set %kS", id, state_id);
00178
00179
00180 if (*ke_stateid_ptr != state_id)
00181 {
00182 *ke_stateid_ptr = state_id;
00183
00184
00185 ke_task_saved_update(id);
00186 }
00187 }
00188
00189
00199 ke_state_t ke_state_get(ke_task_id_t const id)
00200 {
00201 int idx = KE_IDX_GET(id);
00202 int type = KE_TYPE_GET(id);
00203
00204 ASSERT_ERR(type < TASK_MAX);
00205 ASSERT_ERR(ke_task_local(type));
00206 ASSERT_ERR(idx < TASK_DESC[type].idx_max);
00207
00208
00209 return TASK_DESC[type].state[idx];
00210 }
00211
00212
00224 static ke_msg_func_t ke_handler_search(ke_msg_id_t const msg_id,
00225 struct ke_state_handler const *state_handler)
00226 {
00227
00228 for (int i = (state_handler->msg_cnt-1); 0 <= i; i--)
00229 {
00230 if (state_handler->msg_table[i].id == msg_id)
00231 {
00232
00233 ASSERT_ERR(state_handler->msg_table[i].func);
00234
00235 return state_handler->msg_table[i].func;
00236 }
00237 }
00238
00239
00240 return NULL;
00241 }
00242
00254 static ke_msg_func_t ke_task_handler_get(ke_msg_id_t const msg_id,
00255 ke_task_id_t const task_id)
00256 {
00257 ke_msg_func_t func = NULL;
00258 int type = KE_TYPE_GET(task_id);
00259 int idx = KE_IDX_GET(task_id);
00260
00261 ASSERT_ERR(type < TASK_MAX);
00262 ASSERT_ERR(ke_task_local(type));
00263 ASSERT_ERR(idx < TASK_DESC[type].idx_max);
00264
00265 const struct ke_task_desc *desc = TASK_DESC + type;
00266
00267 ASSERT_ERR(desc);
00268
00269
00270 if (desc->state_handler)
00271 {
00272 func = ke_handler_search(msg_id, desc->state_handler + desc->state[idx]);
00273 }
00274
00275
00276 if (func == NULL && desc->default_handler)
00277 {
00278 func = ke_handler_search(msg_id, desc->default_handler);
00279 }
00280
00281 return func;
00282 }
00283
00284
00298 void ke_task_schedule(int dummy)
00299 {
00300
00301
00302 do
00303 {
00304 int msg_status;
00305 struct ke_msg *msg;
00306
00307 GLOBAL_INT_DISABLE();
00308 msg = (struct ke_msg*) ke_queue_pop(&ke_env.queue_sent);
00309 GLOBAL_INT_RESTORE();
00310 if (msg == NULL) break;
00311
00312
00313 ke_msg_func_t func = ke_task_handler_get(msg->id, msg->dest_id);
00314
00315
00316
00317
00318
00319 dbg(D_INF D_KE "Dispatching msg:%x from tsk:%x to tsk:%x\n",
00320 msg->id, msg->src_id, msg->dest_id);
00321 TRACE_KERNEL(MSG_LOCAL, "Dispatching %kM from %kT to %kT",
00322 msg->id, msg->src_id, msg->dest_id);
00323
00324
00325 if (func != NULL)
00326 {
00327 msg_status = func(msg->id, ke_msg2param(msg), msg->dest_id, msg->src_id);
00328 }
00329 else
00330 {
00331 dbg(D_CRT D_KE "No handler found for msg:%x from tsk:%x to tsk:%x\n",
00332 msg->id, msg->src_id, msg->dest_id);
00333 TRACE_KERNEL(ERR, "No handler found for %kM from %kT to %kT",
00334 msg->id, msg->src_id, msg->dest_id);
00335 msg_status = KE_MSG_CONSUMED;
00336 }
00337
00338 switch (msg_status)
00339 {
00340 case KE_MSG_CONSUMED:
00341
00342 ke_msg_free(msg);
00343
00344 case KE_MSG_NO_FREE:
00345 break;
00346
00347 case KE_MSG_SAVED:
00348
00349
00350 ke_queue_push(&ke_env.queue_saved, (struct co_list_hdr*) msg);
00351 break;
00352
00353 default:
00354 ASSERT_ERR(0);
00355 }
00356 } while(0);
00357
00358
00359 GLOBAL_INT_DISABLE();
00360 if (co_list_is_empty(&ke_env.queue_sent))
00361 ke_evt_clear(KE_EVT_KE_MESSAGE_BIT);
00362 GLOBAL_INT_RESTORE();
00363
00364 }
00365
00377 int ke_msg_discard(ke_msg_id_t const msgid,
00378 void const *param,
00379 ke_task_id_t const dest_id,
00380 ke_task_id_t const src_id)
00381 {
00382 return KE_MSG_CONSUMED;
00383 }
00384
00396 int ke_msg_save(ke_msg_id_t const msgid,
00397 void const *param,
00398 ke_task_id_t const dest_id,
00399 ke_task_id_t const src_id)
00400 {
00401 return KE_MSG_SAVED;
00402 }
00403