// +FHDR------------------------------------------------------------ // Copyright (c) 2022 SmartLogic. // ALL RIGHTS RESERVED // ----------------------------------------------------------------- // Filename : msg_transfer_layer.c // Author : xianfeng.du // Created On : 2022-06-29 // Last Modified : // ----------------------------------------------------------------- // Description: // // // -FHDR------------------------------------------------------------ #include #include #include "mem_sections.h" #include "ucp_printf.h" #include "pet_sm_mgt.h" #include "msg_transfer_mem.h" #include "msg_transfer_mbuffer.h" static inline int8_t get_queue_id(uint16_t type_id, uint16_t cu_flag) { int8_t que_id = -1; switch (type_id) { case CU_SPLIT: if (cu_flag == U_PLANE) { que_id = UCP4008_TRAFFIC_NR_eMBB_DATA; } else { que_id = UCP4008_TRAFFIC_NR_eMBB_CTRL; } break; case OAM: que_id = UCP4008_TRAFFIC_OAM; break; default: UCP_PRINT_ERROR("get_queue_id doesn't support transfer_type[%d] .",type_id); break; } return que_id; } static inline void get_queue_info(uint16_t inst_id, uint16_t que_id, uint32_t handle_id, queue_info_s* queue_info) { MsgQueueLocalMgt_t* pMsgQueueLocalMgt = get_msg_queue_local_mgt(); MsgQueueCfg_t* pLocalQueueCfg = (MsgQueueCfg_t *)&pMsgQueueLocalMgt->localQueueCfg[inst_id][que_id]; PetSmLocalMgt_t* pPetSmLocalMgt = get_pet_sm_local_mgt(); MsgQueueCfg_t* pCommonQueueCfg = pPetSmLocalMgt->pQueueCfg[inst_id][que_id]; pLocalQueueCfg->handler.value = handle_id; pLocalQueueCfg->tx_queue.block_num = queue_info->tx_block_num; pLocalQueueCfg->tx_queue.block_size = queue_info->tx_block_size; pLocalQueueCfg->rx_queue.block_num = queue_info->rx_block_num; pLocalQueueCfg->rx_queue.block_size = queue_info->rx_block_size; pLocalQueueCfg->rx_queue.rx_callback = queue_info->rx_callback; memcpy((void *)&pCommonQueueCfg->handler, (void *)&pLocalQueueCfg->handler, sizeof(HandleId_t)); memcpy((void *)&pCommonQueueCfg->tx_queue, (void *)&pLocalQueueCfg->rx_queue, sizeof(QueueCfg_t)); memcpy((void *)&pCommonQueueCfg->rx_queue, (void *)&pLocalQueueCfg->tx_queue, sizeof(QueueCfg_t)); msg_transfer_queue_setup(inst_id, que_id); return; } int32_t msg_transfer_init(uint16_t port_index, uint16_t transfer_type, uint16_t inst_id, const transfer_type_info_s* transfer_type_info) { if (port_index >= MAX_PORT_NUM) { UCP_PRINT_ERROR("msg_transfer_init port_index[%d] error.",port_index); return FAILURE; } if (transfer_type > OAM) { UCP_PRINT_ERROR("msg_transfer_init transfer_type[%d] error.",transfer_type); return FAILURE; } if (inst_id >= MAX_INSTANCE_NUM) { UCP_PRINT_ERROR("msg_transfer_init inst_id[%d] error.",inst_id); return FAILURE; } uint16_t que_id; HandleId_t handler; handler.port_id = (uint8_t)port_index; handler.inst_id = (uint8_t)inst_id; handler.type_id = (uint8_t)transfer_type; switch (transfer_type) { case CU_SPLIT: que_id = UCP4008_TRAFFIC_NR_eMBB_DATA; get_queue_info(inst_id, que_id, handler.value, (queue_info_s *)&transfer_type_info->queue_uplane_info); que_id = UCP4008_TRAFFIC_NR_eMBB_CTRL; get_queue_info(inst_id, que_id, handler.value, (queue_info_s *)&transfer_type_info->queue_cplane_info); break; case OAM: que_id = UCP4008_TRAFFIC_OAM; get_queue_info(inst_id, que_id, handler.value, (queue_info_s *)&transfer_type_info->queue_cplane_info); break; default: UCP_PRINT_ERROR("msg_transfer_init doesn't support transfer_type[%d] .",transfer_type); //break; return FAILURE; } return (int32_t)handler.value; } int32_t msg_transfer_send_start(int32_t handle_id, uint16_t cu_flag) { HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; int8_t que_id = get_queue_id(type_id, cu_flag); if (que_id < 0) { UCP_PRINT_ERROR("msg_transfer_send_start,UNINITIALIZED_QUEUE"); return UNINITIALIZED_QUEUE; } msg_queue_dl_block_init(inst_id,que_id); return SUCCESS; } int32_t msg_transfer_alloc_msg(int32_t handle_id, uint16_t cu_flag, uint32_t bufSize, char** buf, uint32_t* availableSize, uint32_t* offset) { HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; int8_t que_id = get_queue_id(type_id, cu_flag); if (que_id < 0) { *(uint64_t *)buf = 0; *availableSize = 0; *offset = 0; UCP_PRINT_ERROR("msg_transfer_alloc_msg,UNINITIALIZED_QUEUE"); return UNINITIALIZED_QUEUE; } MsgQueueLocalMgt_t* pMsgQueueLocalMgt = get_msg_queue_local_mgt(); MsgQueueLocalInfo_t* ch = (MsgQueueLocalInfo_t*)&pMsgQueueLocalMgt->localDlQueue[inst_id][que_id]; if (0 == ch->msgCnt) { msg_queue_dl_alloc_buf(inst_id,que_id); } *(uint64_t *)buf = ch->bufAddr + ch->offset; *availableSize = ch->availableSize; *offset = ch->offset; ch->msgCnt++; UCP_PRINT_LOG("msg_transfer_alloc_msg,buf:0x%lx,availableSize:0x%08x,offset:0x%08x", *(uint64_t *)buf, ch->availableSize, ch->offset); return SUCCESS; } int32_t msg_transfer_send_msg(int32_t handle_id, uint16_t cu_flag, uint8_t* msg_ptr, uint32_t offset, uint32_t msg_len) { HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; int8_t que_id = get_queue_id(type_id, cu_flag); if (que_id < 0) { UCP_PRINT_ERROR("msg_transfer_alloc_msg,UNINITIALIZED_QUEUE"); return UNINITIALIZED_QUEUE; } MsgQueueLocalMgt_t* pMsgQueueLocalMgt = get_msg_queue_local_mgt(); MsgQueueLocalInfo_t* ch = (MsgQueueLocalInfo_t*)&pMsgQueueLocalMgt->localDlQueue[inst_id][que_id]; ch->availableSize -= msg_len; ch->offset += msg_len; UCP_PRINT_LOG("msg_transfer_send_msg,buf:0x%lx,availableSize:0x%08x,offset:0x%08x", (ch->bufAddr+ch->offset), ch->availableSize, ch->offset); return SUCCESS; } int32_t msg_transfer_send_end(int32_t handle_id, uint16_t cu_flag) { HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; int8_t que_id = get_queue_id(type_id, cu_flag); if (que_id < 0) { UCP_PRINT_ERROR("msg_transfer_send_end,UNINITIALIZED_QUEUE"); return UNINITIALIZED_QUEUE; } msg_queue_dl_put_buf(inst_id,que_id); return SUCCESS; } int32_t msg_transfer_receive(int32_t handle_id, uint16_t cu_flag, uint32_t offset, uint32_t len, uint8_t** msg_ptr) { uint32_t handledLength = 0; int32_t remainedLength = 0; uint8_t *buf, *temp; MsgMemBufAttr_t* mbuf; HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; int8_t que_id = get_queue_id(type_id, cu_flag); if (que_id < 0) { return UNINITIALIZED_QUEUE; } MsgQueueLocalMgt_t* pMsgQueueLocalMgt = get_msg_queue_local_mgt(); MsgQueueCfg_t* pQueueCfg = (MsgQueueCfg_t *)&pMsgQueueLocalMgt->localQueueCfg[inst_id][que_id]; buf = msg_queue_ul_get_buf(inst_id,que_id); if (buf == NULL) { return EMPTY_QUEUE; } //*msg_ptr = buf; mbuf = MSG_MBUF_ATTR(buf); remainedLength = mbuf->msgSize; temp = buf; do { handledLength = pQueueCfg->rx_queue.rx_callback((char *)temp, remainedLength); remainedLength -= handledLength; temp += handledLength; } while(remainedLength > 0); return SUCCESS; } int32_t msg_transfer_close(int32_t handle_id) { HandleId_t handler; handler.value= (uint32_t)handle_id; //uint8_t port_id = handler.port_id; uint8_t inst_id = handler.inst_id; uint8_t type_id = handler.type_id; if (type_id == CU_SPLIT) { msg_transfer_queue_free(inst_id, UCP4008_TRAFFIC_NR_eMBB_DATA); msg_transfer_queue_free(inst_id, UCP4008_TRAFFIC_NR_eMBB_CTRL); } else { msg_transfer_queue_free(inst_id, UCP4008_TRAFFIC_OAM); } return SUCCESS; }