00001
00019
00020
00021
00022
00023 #include <string.h>
00024
00025 #include "rwnx_config.h"
00026 #include "dbg_assert.h"
00027
00028 #include "co_math.h"
00029 #include "ke_mem.h"
00030 #include "ke_msg.h"
00031 #include "ke_task.h"
00032 #include "ke_event.h"
00033
00034 #include "tx_swdesc.h"
00035 #include "rxl_cntrl.h"
00036 #include "txl_buffer.h"
00037
00038 #include "dma.h"
00039 #include "ipc_emb.h"
00040 #include "ipc_shared.h"
00041
00042 #include "sysctrl.h"
00043
00044 #include "dbg.h"
00045
00046 #include "txl_cntrl.h"
00047 #if NX_AMPDU_TX
00048 #include "txl_agg.h"
00049 #endif
00050
00051 #if (NX_UMAC_PRESENT)
00052 #include "txu_cntrl.h"
00053 #endif //(NX_UMAC_PRESENT)
00054
00055
00056
00057
00058
00060 #define MSG_LLICTRL(irqenable) \
00061 ( (irqenable)?(IPC_DMA_LLI_IRQ_EN|(IPC_DMA_LLI_MSG << IPC_DMA_LLI_IRQ_POS)) : 0)
00062
00064 #define DBG_LLICTRL(irqenable) \
00065 ( (irqenable)?(IPC_DMA_LLI_IRQ_EN|(IPC_DMA_LLI_DBG << IPC_DMA_LLI_IRQ_POS)) : 0)
00066
00068 #if NX_BEACONING
00069 #define ALL_EVENTS_TX (KE_EVT_MACIF_TXDESC_AC0_BIT | KE_EVT_MACIF_TXDESC_AC1_BIT | \
00070 KE_EVT_MACIF_TXDESC_AC2_BIT | KE_EVT_MACIF_TXDESC_AC3_BIT | \
00071 KE_EVT_MACIF_TXDESC_BCN_BIT)
00072 #else
00073 #define ALL_EVENTS_TX (KE_EVT_MACIF_TXDESC_AC0_BIT | KE_EVT_MACIF_TXDESC_AC1_BIT | \
00074 KE_EVT_MACIF_TXDESC_AC2_BIT | KE_EVT_MACIF_TXDESC_AC3_BIT)
00075 #endif
00076
00078 #if NX_UMAC_PRESENT && NX_BEACONING
00079 #define HIGH_PRIO_EVT (KE_EVT_RXREADY_BIT | KE_EVT_PRIMARY_TBTT_BIT | KE_EVT_MACIF_TXDESC_BCN_BIT)
00080 #else
00081 #define HIGH_PRIO_EVT (KE_EVT_RXREADY_BIT | KE_EVT_PRIMARY_TBTT_BIT)
00082 #endif
00083
00084
00085
00086
00087
00089 const uint32_t ipc_emb_evt_bit[NX_TXQ_CNT] =
00090 {
00091 #if NX_BEACONING
00092 [AC_BCN] = KE_EVT_MACIF_TXDESC_BCN_BIT,
00093 #endif
00094 [AC_VO] = KE_EVT_MACIF_TXDESC_AC3_BIT,
00095 [AC_VI] = KE_EVT_MACIF_TXDESC_AC2_BIT,
00096 [AC_BE] = KE_EVT_MACIF_TXDESC_AC1_BIT,
00097 [AC_BK] = KE_EVT_MACIF_TXDESC_AC0_BIT,
00098 };
00099
00101 struct ipc_emb_env_tag ipc_emb_env;
00102
00104 const int nx_txdesc_cnt_msk[] =
00105 {
00106 NX_TXDESC_CNT0 - 1,
00107 NX_TXDESC_CNT1 - 1,
00108 NX_TXDESC_CNT2 - 1,
00109 NX_TXDESC_CNT3 - 1,
00110 #if (NX_BEACONING)
00111 NX_TXDESC_CNT4 - 1,
00112 #endif
00113 };
00114
00115
00116
00117
00118
00128 __INLINE void ipc_emb_txdesc_copy(struct txdesc *dst_local, volatile struct txdesc_host *src_shared)
00129 {
00130
00131 volatile uint32_t *src = (uint32_t*) &src_shared->api;
00132 uint32_t *dst = (uint32_t*) &dst_local->host;
00133
00134
00135
00136 for (unsigned int i = 0; i < (sizeof_b(struct txdesc_api)+3)/4; i++)
00137 {
00138 dst[i] = src[i];
00139 }
00140 }
00141
00142 uint8_t ipc_emb_tx_q_len(int queue_idx, int vif_idx)
00143 {
00144 volatile struct txdesc_host *ptr, *start, *end;
00145 uint8_t i = 0, index, nb = 0;
00146
00147 #if 1 //RW_MUMIMO_TX_EN
00148 for (i = 0; i < nx_txuser_cnt[queue_idx]; i++)
00149 {
00150 #endif
00151 index = ipc_emb_env.txdesc_idx[queue_idx][i] & nx_txdesc_cnt_msk[queue_idx];
00152 ptr = &ipc_emb_env.txdesc[queue_idx][i][index];
00153 end = &ipc_emb_env.txdesc[queue_idx][i][nx_txdesc_cnt_msk[queue_idx]];
00154 if (index == 0)
00155 start = NULL;
00156 else
00157 start = &ipc_emb_env.txdesc[queue_idx][i][0];
00158
00159 while (ptr->ready) {
00160 if (vif_idx == ptr->api.host.vif_idx)
00161 nb++;
00162 if (ptr == end) {
00163 if (start)
00164 {
00165 ptr = start;
00166 end = &ipc_emb_env.txdesc[queue_idx][i][index - 1];
00167 start = NULL;
00168 }
00169 else
00170 break;
00171 }
00172 else
00173 ptr++;
00174 }
00175 #if 1 // RW_MUMIMO_TX_EN
00176 }
00177 #endif
00178
00179 return nb;
00180 }
00181
00185 void ipc_emb_init(void)
00186 {
00187 int i;
00188
00189
00190 memset(&ipc_emb_env, 0, sizeof(ipc_emb_env));
00191
00192
00193 for (i = 0; i < RW_USER_MAX; i++)
00194 {
00195 ipc_emb_env.txdesc[0][i] = ipc_shared_env.txdesc0[i];
00196 ipc_emb_env.txdesc[1][i] = ipc_shared_env.txdesc1[i];
00197 ipc_emb_env.txdesc[2][i] = ipc_shared_env.txdesc2[i];
00198 ipc_emb_env.txdesc[3][i] = ipc_shared_env.txdesc3[i];
00199 #if (NX_BEACONING)
00200 ipc_emb_env.txdesc[4][i] = NULL;
00201 #endif
00202 }
00203 #if (NX_BEACONING)
00204 ipc_emb_env.txdesc[4][0] = ipc_shared_env.txdesc4[0];
00205 #endif
00206
00207 #if RW_MUMIMO_TX_EN
00208 for (i=0; i < IPC_TXQUEUE_CNT; i++)
00209 {
00210 ipc_emb_env.user_active[i] = (1 << nx_txuser_cnt[i]) - 1;
00211 }
00212 #endif
00213
00214
00215 #ifdef CFG_IPC_VER_10
00216 ipc_shared_env.comp_info.ipc_shared_version = 10;
00217 #else
00218 ipc_shared_env.comp_info.ipc_shared_version = 11;
00219 #endif
00220 ipc_shared_env.comp_info.msg_api= MSG_API_VER;
00221 ipc_shared_env.comp_info.msge2a_buf_cnt = IPC_MSGE2A_BUF_CNT;
00222 ipc_shared_env.comp_info.dbgbuf_cnt = IPC_DBGBUF_CNT;
00223 ipc_shared_env.comp_info.radarbuf_cnt = IPC_RADARBUF_CNT;
00224 ipc_shared_env.comp_info.unsuprxvecbuf_cnt = IPC_UNSUPRXVECBUF_CNT;
00225 ipc_shared_env.comp_info.rxbuf_cnt = IPC_RXBUF_CNT;
00226 #if NX_UMAC_PRESENT
00227 ipc_shared_env.comp_info.rxdesc_cnt= IPC_RXDESC_CNT;
00228 #endif //(NX_UMAC_PRESENT)
00229 ipc_shared_env.comp_info.bk_txq = NX_TXDESC_CNT0;
00230 ipc_shared_env.comp_info.be_txq = NX_TXDESC_CNT1;
00231 ipc_shared_env.comp_info.vi_txq = NX_TXDESC_CNT2;
00232 ipc_shared_env.comp_info.vo_txq = NX_TXDESC_CNT3;
00233 #if NX_BEACONING
00234 ipc_shared_env.comp_info.bcn_txq = NX_TXDESC_CNT4;
00235 #else
00236 ipc_shared_env.comp_info.bcn_txq = 0;
00237 #endif
00238 ipc_shared_env.comp_info.ipc_shared_size = sizeof_b(ipc_shared_env);
00239
00240
00241
00242 ipc_shared_env.msg_dma_desc.src = CPU2HW(&(ipc_shared_env.msg_e2a_buf));
00243
00244 ipc_shared_env.msg_dma_desc.length = sizeof_b(struct ipc_e2a_msg);
00245
00246 ipc_shared_env.msg_dma_desc.next = 0;
00247
00248 ipc_shared_env.msg_dma_desc.ctrl = MSG_LLICTRL(1);
00249
00250 ipc_shared_env.msg_e2a_buf.pattern = IPC_MSGE2A_VALID_PATTERN;
00251
00253
00254 ipc_shared_env.dbg_dma_desc.src = CPU2HW(&(ipc_shared_env.dbg_buf));
00255
00256 ipc_shared_env.dbg_dma_desc.length = sizeof_b(struct ipc_dbg_msg);
00257
00258 ipc_shared_env.dbg_dma_desc.next = 0;
00259
00260 ipc_shared_env.dbg_dma_desc.ctrl = DBG_LLICTRL(1);
00261
00262 ipc_shared_env.dbg_buf.pattern = IPC_DBG_VALID_PATTERN;
00263
00264
00265 ASSERT_ERR(ipc_emb_signature_get() == IPC_EMB_SIGNATURE_RESET);
00266
00267
00268 #ifdef CFG_IPC_VER_V10
00269 ipc_app2emb_line_sel_set(0);
00270 #else
00271 ipc_app2emb_line_sel_low_set(0);
00272 ipc_app2emb_line_sel_high_set(0);
00273 #endif
00274
00275 ipc_app2emb0_sel_setf(0);
00276 ipc_app2emb1_sel_setf(1);
00277 ipc_app2emb4_sel_setf(2);
00278 ipc_app2emb5_sel_setf(2);
00279 ipc_app2emb6_sel_setf(2);
00280
00281
00282 ipc_app2emb8_sel_setf(3);
00283 ipc_app2emb9_sel_setf(3);
00284 ipc_app2emb10_sel_setf(3);
00285 ipc_app2emb11_sel_setf(3);
00286 ipc_app2emb12_sel_setf(3);
00287
00288 #if (RW_USER_MAX > 1)
00289 ipc_app2emb13_sel_setf(3);
00290 ipc_app2emb14_sel_setf(3);
00291 ipc_app2emb15_sel_setf(3);
00292 ipc_app2emb16_sel_setf(3);
00293 #endif
00294
00295 #if (RW_USER_MAX > 2)
00296 ipc_app2emb17_sel_setf(3);
00297 ipc_app2emb18_sel_setf(3);
00298 ipc_app2emb19_sel_setf(3);
00299 ipc_app2emb20_sel_setf(3);
00300 #endif
00301
00302 #if (RW_USER_MAX > 3)
00303 ipc_app2emb21_sel_setf(3);
00304 ipc_app2emb22_sel_setf(3);
00305 ipc_app2emb23_sel_setf(3);
00306 ipc_app2emb24_sel_setf(3);
00307 #endif
00308
00309
00310 ipc_app2emb_unmask_set(IPC_IRQ_A2E_ALL);
00311 }
00312
00319 void ipc_emb_tx_flow_off(void)
00320 {
00321
00322 ipc_app2emb_unmask_clear(IPC_IRQ_A2E_TXDESC);
00323
00324
00325 ke_evt_clear(ALL_EVENTS_TX);
00326 }
00327
00328 void ipc_emb_tx_flow_on(void)
00329 {
00330
00331 ipc_app2emb_unmask_set(IPC_IRQ_A2E_TXDESC);
00332
00333
00334
00335 }
00336
00337
00338 void ipc_emb_tx_irq(void)
00339 {
00340
00341 uint32_t stat = ipc_app2emb_status_get() & IPC_IRQ_A2E_TXDESC;
00342
00343 if (stat)
00344 {
00345
00346 PROF_TX_IPC_IRQ_SET();
00347
00348
00349 ke_evt_set(ipc_emb_tx_evt_field(stat));
00350
00351
00352 ipc_app2emb_unmask_clear(stat);
00353
00354
00355 ipc_app2emb_ack_clear(stat);
00356
00357
00358 PROF_TX_IPC_IRQ_CLR();
00359 }
00360 }
00361
00362
00366 void ipc_emb_tx_evt(int queue_idx)
00367 {
00368 volatile struct txdesc_host *txdesc_src;
00369 uint32_t evt_bit = ipc_emb_evt_bit[queue_idx];
00370 bool pushed = false;
00371 int i = 0;
00372
00373
00374 PROF_TX_MACIF_EVT_SET();
00375
00376
00377 ke_evt_clear(evt_bit);
00378
00379 #if RW_MUMIMO_TX_EN
00380
00381 for (i = 0; i < nx_txuser_cnt[queue_idx]; i++)
00382 #endif
00383 {
00384 struct txdesc *txdesc_base = txdesc_array[queue_idx][i];
00385 volatile struct txdesc_host *txdesc_src_base = ipc_emb_env.txdesc[queue_idx][i];
00386 uint32_t *txdesc_idx = &ipc_emb_env.txdesc_idx[queue_idx][i];
00387
00388 #if RW_MUMIMO_TX_EN
00389 bool stop_user = false;
00390
00391
00392 if (!(ipc_emb_env.user_active[queue_idx] & CO_BIT(i)))
00393 continue;
00394 #endif
00395
00396 txdesc_src = &txdesc_src_base[*txdesc_idx & nx_txdesc_cnt_msk[queue_idx]];
00397
00398
00399 while (txdesc_src->ready)
00400 {
00401 struct txdesc *txdesc_new;
00402
00403
00404 #if NX_UMAC_PRESENT && NX_BEACONING
00405 if (!(evt_bit & KE_EVT_MACIF_TXDESC_BCN_BIT))
00406 #endif
00407 {
00408 if (ke_evt_get() & HIGH_PRIO_EVT)
00409 {
00410
00411 PROF_TX_MACIF_EVT_CLR();
00412
00413
00414 ke_evt_set(evt_bit);
00415 return;
00416 }
00417 }
00418
00419
00420 ipc_app2emb_ack_clear(CO_BIT(i + RW_USER_MAX * queue_idx + IPC_IRQ_A2E_TXDESC_FIRSTBIT));
00421
00422
00423 txdesc_new = &txdesc_base[*txdesc_idx & nx_txdesc_cnt_msk[queue_idx]];
00424
00425
00426 ipc_emb_txdesc_copy(txdesc_new, txdesc_src);
00427
00428
00429 txdesc_new->lmac.agg_desc = NULL;
00430 txdesc_new->lmac.hw_desc->cfm.status = 0;
00431 #if (RW_BFMER_EN)
00432 txdesc_new->lmac.bfr_node = NULL;
00433 #endif //(RW_BFMER_EN)
00434 #if (NX_UMAC_PRESENT)
00435 txdesc_new->umac.buf_control = NULL;
00436 #endif
00437
00438 #if RW_MUMIMO_TX_EN
00439 ASSERT_ERR(i == get_user_pos(txdesc_new));
00440 stop_user =
00441 #endif
00442 #if (NX_UMAC_PRESENT)
00443
00444 txu_cntrl_push(txdesc_new, queue_idx);
00445 #else
00446
00447 txl_cntrl_push(txdesc_new, queue_idx);
00448 #endif //(NX_UMAC_PRESENT)
00449
00450
00451 pushed = true;
00452
00453
00454 txdesc_src->ready = 0;
00455
00456
00457 (*txdesc_idx)++;
00458
00459 #if RW_MUMIMO_TX_EN
00460
00461 if (stop_user)
00462 break;
00463 #endif
00464
00465
00466 txdesc_src = &txdesc_src_base[*txdesc_idx & nx_txdesc_cnt_msk[queue_idx]];
00467 }
00468
00469 #if RW_MUMIMO_TX_EN
00470
00471 if (stop_user)
00472 {
00473
00474 ipc_emb_env.user_active[queue_idx] &= ~CO_BIT(i);
00475
00476 continue;
00477 }
00478 #endif
00479 }
00480
00481
00482 if (pushed)
00483 {
00484 #if (NX_AMPDU_TX)
00485
00486 txl_agg_check(queue_idx);
00487 #endif //(NX_AMPDU_TX)
00488 }
00489
00490
00491 #if RW_MUMIMO_TX_EN
00492 ipc_app2emb_unmask_set((ipc_emb_env.user_active[queue_idx] << (RW_USER_MAX * queue_idx + IPC_IRQ_A2E_TXDESC_FIRSTBIT))
00493 & IPC_IRQ_A2E_TXDESC);
00494 #else
00495 ipc_app2emb_unmask_set(CO_BIT(queue_idx + IPC_IRQ_A2E_TXDESC_FIRSTBIT)
00496 & IPC_IRQ_A2E_TXDESC);
00497 #endif
00498
00499
00500 PROF_TX_MACIF_EVT_CLR();
00501 }
00502
00509 void ipc_emb_cfmback_irq(void)
00510 {
00511
00512 uint32_t stat = ipc_app2emb_status_get();
00513
00514 if (stat & IPC_IRQ_A2E_RXBUF_BACK)
00515 {
00516
00517 ipc_app2emb_unmask_clear(IPC_IRQ_A2E_RXBUF_BACK);
00518
00519
00520 ipc_app2emb_ack_clear(IPC_IRQ_A2E_RXBUF_BACK);
00521
00522
00523
00524 ke_evt_set(KE_EVT_RXREADY_BIT);
00525 }
00526
00527 #if NX_UMAC_PRESENT
00528 if (stat & IPC_IRQ_A2E_RXDESC_BACK)
00529 {
00530
00531 ipc_app2emb_unmask_clear(IPC_IRQ_A2E_RXDESC_BACK);
00532
00533
00534 ipc_app2emb_ack_clear(IPC_IRQ_A2E_RXDESC_BACK);
00535
00536
00537
00538 ke_evt_set(KE_EVT_RXUREADY_BIT);
00539 }
00540 #endif
00541 }
00542
00555 static uint32_t ipc_emb_hostmsgbuf_get(void)
00556 {
00557 uint32_t hostmsgbuf;
00558
00559 do
00560 {
00561
00562 hostmsgbuf = ipc_shared_env.msg_e2a_hostbuf_addr[ipc_emb_env.ipc_msge2a_buf_idx];
00563
00564
00565 if (hostmsgbuf == 0)
00566 break;
00567
00568
00569 ipc_shared_env.msg_e2a_hostbuf_addr[ipc_emb_env.ipc_msge2a_buf_idx] = 0;
00570
00571
00572 ipc_emb_env.ipc_msge2a_buf_idx = (ipc_emb_env.ipc_msge2a_buf_idx + 1)%IPC_MSGE2A_BUF_CNT;
00573 } while(0);
00574
00575 return hostmsgbuf;
00576 }
00577
00590 static uint32_t ipc_emb_hostdbgbuf_get(void)
00591 {
00592 uint32_t hostdbgbuf;
00593
00594 do
00595 {
00596
00597 hostdbgbuf = ipc_shared_env.dbg_hostbuf_addr[ipc_emb_env.ipc_dbg_buf_idx];
00598
00599
00600 if (hostdbgbuf == 0)
00601 break;
00602
00603
00604 ipc_shared_env.dbg_hostbuf_addr[ipc_emb_env.ipc_dbg_buf_idx] = 0;
00605
00606
00607 ipc_emb_env.ipc_dbg_buf_idx = (ipc_emb_env.ipc_dbg_buf_idx + 1)%IPC_DBGBUF_CNT;
00608 } while(0);
00609
00610 return hostdbgbuf;
00611 }
00612
00613
00614
00615
00616 uint32_t ipc_emb_hostdbgdumpbuf_get(void)
00617 {
00618 uint32_t hostdbgdumpbuf;
00619
00620 do
00621 {
00622
00623 hostdbgdumpbuf = ipc_shared_env.la_dbginfo_addr;
00624
00625
00626 if (hostdbgdumpbuf == 0)
00627 break;
00628
00629
00630 ipc_shared_env.la_dbginfo_addr = 0;
00631 } while(0);
00632
00633 return (hostdbgdumpbuf);
00634 }
00635
00636
00637
00638
00639 bool ipc_emb_hostrxbuf_check(void)
00640 {
00641
00642
00643 ipc_app2emb_ack_clear(IPC_IRQ_A2E_RXBUF_BACK);
00644
00645
00646 #if (NX_UMAC_PRESENT)
00647 if (ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx].dma_addr == 0)
00648 #else
00649 if (ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx] == 0)
00650 #endif //(NX_UMAC_PRESENT)
00651 {
00652
00653
00654 ipc_app2emb_unmask_set(IPC_IRQ_A2E_RXBUF_BACK);
00655
00656 return (false);
00657 }
00658
00659 return (true);
00660 }
00661
00662 #if (NX_UMAC_PRESENT)
00663 uint32_t ipc_emb_hostrxbuf_get(uint32_t *host_id)
00664 #else
00665 uint32_t ipc_emb_hostrxbuf_get(void)
00666 #endif //(NX_UMAC_PRESENT)
00667 {
00668 uint32_t host_buf_dma_addr;
00669
00670 RX_HOSTBUF_IDX_CLR();
00671 RX_HOSTBUF_IDX_SET(ipc_emb_env.ipc_rxbuf_idx);
00672
00673
00674 #if (NX_UMAC_PRESENT)
00675 host_buf_dma_addr = ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx].dma_addr;
00676 #else
00677 host_buf_dma_addr = ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx];
00678 #endif //(NX_UMAC_PRESENT)
00679
00680
00681
00682 ASSERT_ERR(host_buf_dma_addr != 0);
00683
00684 #if (NX_UMAC_PRESENT)
00685
00686 ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx].dma_addr = 0;
00687
00688 *host_id = ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx].hostid;
00689 #else
00690
00691 ipc_shared_env.host_rxbuf[ipc_emb_env.ipc_rxbuf_idx] = 0;
00692 #endif //(NX_UMAC_PRESENT)
00693
00694
00695 ipc_emb_env.ipc_rxbuf_idx = (ipc_emb_env.ipc_rxbuf_idx + 1) % IPC_RXBUF_CNT;
00696
00697 return host_buf_dma_addr;
00698 }
00699
00700 #if (NX_UMAC_PRESENT)
00701
00702
00703
00704 bool ipc_emb_hostrxdesc_check(void)
00705 {
00706
00707
00708 ipc_app2emb_ack_clear(IPC_IRQ_A2E_RXDESC_BACK);
00709
00710
00711 if (ipc_shared_env.host_rxdesc[ipc_emb_env.ipc_rxdesc_idx].dma_addr == 0)
00712 {
00713
00714
00715 ipc_app2emb_unmask_set(IPC_IRQ_A2E_RXDESC_BACK);
00716
00717 return false;
00718 }
00719
00720 return true;
00721 }
00722
00723 uint32_t ipc_emb_hostrxdesc_get(void)
00724 {
00725 uint32_t host_desc_dma_addr;
00726
00727
00728 host_desc_dma_addr = ipc_shared_env.host_rxdesc[ipc_emb_env.ipc_rxdesc_idx].dma_addr;
00729
00730 if (host_desc_dma_addr)
00731 {
00732
00733 ipc_shared_env.host_rxdesc[ipc_emb_env.ipc_rxdesc_idx].dma_addr = 0;
00734
00735
00736 ipc_emb_env.ipc_rxdesc_idx = (ipc_emb_env.ipc_rxdesc_idx + 1) % IPC_RXDESC_CNT;
00737 }
00738
00739 return (host_desc_dma_addr);
00740 }
00741 #endif //(NX_UMAC_PRESENT)
00742
00743
00744
00745
00746 uint32_t ipc_emb_hostradarbuf_get(void)
00747 {
00748 uint32_t hostbuf;
00749
00750 do
00751 {
00752
00753 hostbuf = ipc_shared_env.radarbuf_hostbuf[ipc_emb_env.ipc_radar_buf_idx];
00754
00755
00756 if (hostbuf == 0)
00757 break;
00758
00759
00760 ipc_shared_env.radarbuf_hostbuf[ipc_emb_env.ipc_radar_buf_idx] = 0;
00761
00762
00763 ipc_emb_env.ipc_radar_buf_idx = (ipc_emb_env.ipc_radar_buf_idx + 1)%IPC_RADARBUF_CNT;
00764
00765 } while(0);
00766
00767 return hostbuf;
00768 }
00769
00770 #if NX_UF_EN
00771 uint32_t ipc_emb_hostunsuprxvectbuf_get(void)
00772 {
00773 uint32_t hostbuf;
00774
00775
00776 hostbuf = ipc_shared_env.unsuprxvecbuf_hostbuf[ipc_emb_env.ipc_unsup_rx_vec_buf_idx];
00777
00778 if (hostbuf == 0)
00779 return 0;
00780
00781
00782 ipc_shared_env.unsuprxvecbuf_hostbuf[ipc_emb_env.ipc_unsup_rx_vec_buf_idx] = 0;
00783
00784
00785 ipc_emb_env.ipc_unsup_rx_vec_buf_idx = (ipc_emb_env.ipc_unsup_rx_vec_buf_idx + 1)%IPC_UNSUPRXVECBUF_CNT;
00786
00787 return hostbuf;
00788 }
00789 #endif
00790
00791
00792
00793
00794 void ipc_emb_rxdata_ind(void)
00795 {
00796
00797 LED_ON(LED_RX);
00798
00799
00800 PROF_RX_IPC_IND_SET();
00801
00802
00803 ipc_emb2app_trigger_set(IPC_IRQ_E2A_RXDESC);
00804
00805
00806 PROF_RX_IPC_IND_CLR();
00807
00808
00809 LED_OFF(LED_RX);
00810 }
00811
00812 void ipc_emb_radar_event_ind(void)
00813 {
00814
00815 ipc_emb2app_trigger_set(IPC_IRQ_E2A_RADAR);
00816 }
00817
00818 #if NX_UF_EN
00819 void ipc_emb_unsup_rx_vec_event_ind(void)
00820 {
00821
00822 ipc_emb2app_trigger_set(IPC_IRQ_E2A_UNSUP_RX_VEC);
00823 }
00824 #endif
00825
00826 void ipc_emb_txcfm_ind(uint32_t queue_bits)
00827 {
00828
00829 ipc_emb2app_trigger_set(queue_bits << IPC_IRQ_E2A_TXCFM_POS);
00830 }
00831
00832 void ipc_emb_prim_tbtt_ind(void)
00833 {
00834
00835 ipc_emb2app_trigger_set(IPC_IRQ_E2A_TBTT_PRIM);
00836 }
00837
00838 void ipc_emb_sec_tbtt_ind(void)
00839 {
00840
00841 ipc_emb2app_trigger_set(IPC_IRQ_E2A_TBTT_SEC);
00842 }
00843
00852 static void ipc_emb_kmsg_hdlr(struct ke_msg *kmsg_ipc)
00853 {
00854 int i;
00855
00856
00857 struct ke_msg *kmsg_dst = (struct ke_msg*)
00858 ke_malloc(sizeof(struct ke_msg) + kmsg_ipc->param_len);
00859 ASSERT_ERR(kmsg_dst != NULL);
00860
00861 kmsg_dst->hdr.next = NULL;
00862 kmsg_dst->id = kmsg_ipc->id;
00863 kmsg_dst->dest_id = kmsg_ipc->dest_id;
00864 kmsg_dst->src_id = TASK_API;
00865 kmsg_dst->param_len = kmsg_ipc->param_len;
00866
00867
00868 uint32_t *src = kmsg_ipc->param;
00869 uint32_t *dst = kmsg_dst->param;
00870 for (i = 0; i < kmsg_dst->param_len; i+=4)
00871 {
00872 *dst++ = *src++;
00873 }
00874
00875
00876 kmsg_ipc->src_id = ipc_emb_env.ipc_msgacke2a_cnt++;
00877
00878
00879 ASSERT_ERR(ke_task_local(kmsg_dst->dest_id));
00880
00881 ipc_emb2app_trigger_set(IPC_IRQ_E2A_MSG_ACK);
00882
00883
00884 ke_msg_send(ke_msg2param(kmsg_dst));
00885 }
00886
00887
00894 void ipc_emb_msg_irq(void)
00895 {
00896 PROF_MSG_IRQ_SET();
00897
00898
00899 if (ipc_app2emb_status_get() & IPC_IRQ_A2E_MSG)
00900 {
00901
00902 ke_evt_set(KE_EVT_MACIF_MSG_BIT);
00903
00904
00905 ipc_app2emb_unmask_clear(IPC_IRQ_A2E_MSG);
00906 }
00907
00908 PROF_MSG_IRQ_CLR();
00909 }
00910
00911
00918 void ipc_emb_msg_evt(int dummy)
00919 {
00920 struct ipc_a2e_msg * msg_buf;
00921
00922
00923 uint32_t status_irq = ipc_app2emb_rawstatus_get();
00924
00925 while (status_irq & IPC_IRQ_A2E_MSG)
00926 {
00927
00928 ipc_app2emb_ack_clear(IPC_IRQ_A2E_MSG);
00929
00930
00931 msg_buf = (struct ipc_a2e_msg *)&(ipc_shared_env.msg_a2e_buf);
00932
00933
00934 ipc_emb_kmsg_hdlr((struct ke_msg*)msg_buf);
00935
00936 status_irq = ipc_app2emb_rawstatus_get();
00937 }
00938
00939
00940 ke_evt_clear(KE_EVT_MACIF_MSG_BIT);
00941
00942
00943 ipc_app2emb_unmask_set(IPC_IRQ_A2E_MSG);
00944
00945 return;
00946 }
00947
00948 void ipc_emb_kmsg_fwd(const struct ke_msg *kmsg_src)
00949 {
00950 uint32_t host_msg_buf;
00951 struct ipc_e2a_msg *msg = (struct ipc_e2a_msg *) &(ipc_shared_env.msg_e2a_buf);
00952 struct dma_desc *msg_dma_desc = (struct dma_desc *) &(ipc_shared_env.msg_dma_desc);
00953
00954 PROF_MSG_FWD_SET();
00955
00956
00957 host_msg_buf = ipc_emb_hostmsgbuf_get();
00958
00959
00960 ASSERT_ERR(host_msg_buf != 0);
00961
00962
00963 msg->id = kmsg_src->id;
00964 msg->param_len = kmsg_src->param_len * CHAR_LEN;
00965
00966 if(kmsg_src->param_len != 0)
00967 {
00968 ASSERT_ERR(kmsg_src->param_len <= sizeof(msg->param));
00969 memcpy(msg->param, kmsg_src->param, kmsg_src->param_len);
00970 }
00971
00972
00973 ke_msg_free(kmsg_src);
00974
00975
00976
00977
00978 msg_dma_desc->dest = host_msg_buf;
00979
00980
00981 dma_push(msg_dma_desc, msg_dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
00982
00983 PROF_MSG_FWD_CLR();
00984
00985 }
00986
00987
00988
00989
00990 void ipc_emb_msg_dma_int_handler(void)
00991 {
00992 PROF_MSG_IPC_IND_SET();
00993
00994
00995 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_MSG + DMA_LLI_IRQ_LSB));
00996
00997
00998 ipc_emb2app_trigger_set(IPC_IRQ_E2A_MSG);
00999
01000 PROF_MSG_IPC_IND_CLR();
01001 }
01002
01003
01004
01005
01006 void ipc_emb_print_fwd(bool poll, const uint32_t len, char *string)
01007 {
01008 uint32_t host_dbg_buf;
01009 struct ipc_dbg_msg *dbg_msg = (struct ipc_dbg_msg *) &(ipc_shared_env.dbg_buf);
01010 struct dma_desc *dbg_dma_desc = (struct dma_desc *) &(ipc_shared_env.dbg_dma_desc);
01011 uint32_t copy_len;
01012
01013
01014
01015 copy_len = len + 1;
01016
01017
01018 host_dbg_buf = ipc_emb_hostdbgbuf_get();
01019
01020
01021
01022 if (host_dbg_buf == 0) {
01023 return;
01024 }
01025
01026
01027 if (len >= IPC_DBG_PARAM_SIZE)
01028 {
01029 string[IPC_DBG_PARAM_SIZE - 3] = '*';
01030 string[IPC_DBG_PARAM_SIZE - 2] = '\n';
01031 string[IPC_DBG_PARAM_SIZE - 1] = 0;
01032 copy_len = IPC_DBG_PARAM_SIZE;
01033 }
01034
01035
01036 co_pack8p(CPU2HW(dbg_msg->string), (uint8_t *)string, copy_len);
01037
01038
01039
01040
01041 dbg_dma_desc->dest = host_dbg_buf;
01042
01043
01044 GLOBAL_INT_DISABLE();
01045
01046
01047 dma_push(dbg_dma_desc, dbg_dma_desc, IPC_DMA_CHANNEL_CTRL_RX);
01048
01049
01050 if (poll)
01051 {
01052 dma_lli_poll(IPC_DMA_LLI_DBG + DMA_LLI_IRQ_LSB);
01053
01054 ipc_emb_dbg_dma_int_handler();
01055 }
01056
01057
01058 GLOBAL_INT_RESTORE();
01059
01060 }
01061
01062
01063
01064
01065 void ipc_emb_dbg_dma_int_handler(void)
01066 {
01067
01068 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DBG + DMA_LLI_IRQ_LSB));
01069
01070
01071 ipc_emb2app_trigger_set(IPC_IRQ_E2A_DBG);
01072
01073 }
01074