int fjes_hw_request_info(struct fjes_hw *hw) { union fjes_device_command_req *req_buf = hw->hw_info.req_buf; union fjes_device_command_res *res_buf = hw->hw_info.res_buf; enum fjes_dev_command_response_e ret; int result; memset(req_buf, 0, hw->hw_info.req_buf_size); memset(res_buf, 0, hw->hw_info.res_buf_size); req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN; res_buf->info.length = 0; res_buf->info.code = 0; ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO); trace_fjes_hw_request_info(hw, res_buf); result = 0; if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) != res_buf->info.length) { trace_fjes_hw_request_info_err("Invalid res_buf"); result = -ENOMSG; } else if (ret == FJES_CMD_STATUS_NORMAL) { switch (res_buf->info.code) { case FJES_CMD_REQ_RES_CODE_NORMAL: result = 0; break; default: result = -EPERM; break; } } else { switch (ret) { case FJES_CMD_STATUS_UNKNOWN: result = -EPERM; break; case FJES_CMD_STATUS_TIMEOUT: trace_fjes_hw_request_info_err("Timeout"); result = -EBUSY; break; case FJES_CMD_STATUS_ERROR_PARAM: result = -EPERM; break; case FJES_CMD_STATUS_ERROR_STATUS: result = -EPERM; break; default: result = -EPERM; break; } } return result; }
int fjes_hw_stop_debug(struct fjes_hw *hw) { union fjes_device_command_req *req_buf = hw->hw_info.req_buf; union fjes_device_command_res *res_buf = hw->hw_info.res_buf; enum fjes_dev_command_response_e ret; int result = 0; if (!hw->hw_info.trace) return -EPERM; memset(req_buf, 0, hw->hw_info.req_buf_size); memset(res_buf, 0, hw->hw_info.res_buf_size); req_buf->stop_trace.length = FJES_DEV_COMMAND_STOP_DBG_REQ_LEN; res_buf->stop_trace.length = 0; res_buf->stop_trace.code = 0; ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_STOP_DEBUG); trace_fjes_hw_stop_debug(res_buf); if (res_buf->stop_trace.length != FJES_DEV_COMMAND_STOP_DBG_RES_LEN) { trace_fjes_hw_stop_debug_err("Invalid res_buf"); result = -ENOMSG; } else if (ret == FJES_CMD_STATUS_NORMAL) { switch (res_buf->stop_trace.code) { case FJES_CMD_REQ_RES_CODE_NORMAL: result = 0; hw->debug_mode = 0; break; default: result = -EPERM; break; } } else { switch (ret) { case FJES_CMD_STATUS_UNKNOWN: result = -EPERM; break; case FJES_CMD_STATUS_TIMEOUT: result = -EBUSY; trace_fjes_hw_stop_debug_err("Busy Timeout"); break; case FJES_CMD_STATUS_ERROR_PARAM: case FJES_CMD_STATUS_ERROR_STATUS: default: result = -EPERM; break; } } return result; }
int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid) { union fjes_device_command_req *req_buf = hw->hw_info.req_buf; union fjes_device_command_res *res_buf = hw->hw_info.res_buf; struct fjes_device_shared_info *share = hw->hw_info.share; enum fjes_dev_command_response_e ret; int timeout; int result; if (!hw->base) return -EPERM; if (!req_buf || !res_buf || !share) return -EPERM; if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit)) return 0; memset(req_buf, 0, hw->hw_info.req_buf_size); memset(res_buf, 0, hw->hw_info.res_buf_size); req_buf->unshare_buffer.length = FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN; req_buf->unshare_buffer.epid = dest_epid; res_buf->unshare_buffer.length = 0; res_buf->unshare_buffer.code = 0; ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER); timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000; while ((ret == FJES_CMD_STATUS_NORMAL) && (res_buf->unshare_buffer.length == FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) && (res_buf->unshare_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) && (timeout > 0)) { msleep(200 + hw->my_epid * 20); timeout -= (200 + hw->my_epid * 20); res_buf->unshare_buffer.length = 0; res_buf->unshare_buffer.code = 0; ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER); } result = 0; if (res_buf->unshare_buffer.length != FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) { result = -ENOMSG; } else if (ret == FJES_CMD_STATUS_NORMAL) { switch (res_buf->unshare_buffer.code) { case FJES_CMD_REQ_RES_CODE_NORMAL: result = 0; clear_bit(dest_epid, &hw->hw_info.buffer_share_bit); break; case FJES_CMD_REQ_RES_CODE_BUSY: result = -EBUSY; break; default: result = -EPERM; break; } } else { switch (ret) { case FJES_CMD_STATUS_UNKNOWN: result = -EPERM; break; case FJES_CMD_STATUS_TIMEOUT: result = -EBUSY; break; case FJES_CMD_STATUS_ERROR_PARAM: case FJES_CMD_STATUS_ERROR_STATUS: default: result = -EPERM; break; } } return result; }
int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid, struct ep_share_mem_info *buf_pair) { union fjes_device_command_req *req_buf = hw->hw_info.req_buf; union fjes_device_command_res *res_buf = hw->hw_info.res_buf; enum fjes_dev_command_response_e ret; int page_count; int timeout; int i, idx; void *addr; int result; if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit)) return 0; memset(req_buf, 0, hw->hw_info.req_buf_size); memset(res_buf, 0, hw->hw_info.res_buf_size); req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN( buf_pair->tx.size, buf_pair->rx.size); req_buf->share_buffer.epid = dest_epid; idx = 0; req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size; page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE; for (i = 0; i < page_count; i++) { addr = ((u8 *)(buf_pair->tx.buffer)) + (i * EP_BUFFER_INFO_SIZE); req_buf->share_buffer.buffer[idx++] = (__le64)(page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr)); } req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size; page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE; for (i = 0; i < page_count; i++) { addr = ((u8 *)(buf_pair->rx.buffer)) + (i * EP_BUFFER_INFO_SIZE); req_buf->share_buffer.buffer[idx++] = (__le64)(page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr)); } res_buf->share_buffer.length = 0; res_buf->share_buffer.code = 0; ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER); timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000; while ((ret == FJES_CMD_STATUS_NORMAL) && (res_buf->share_buffer.length == FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) && (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) && (timeout > 0)) { msleep(200 + hw->my_epid * 20); timeout -= (200 + hw->my_epid * 20); res_buf->share_buffer.length = 0; res_buf->share_buffer.code = 0; ret = fjes_hw_issue_request_command( hw, FJES_CMD_REQ_SHARE_BUFFER); } result = 0; if (res_buf->share_buffer.length != FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) result = -ENOMSG; else if (ret == FJES_CMD_STATUS_NORMAL) { switch (res_buf->share_buffer.code) { case FJES_CMD_REQ_RES_CODE_NORMAL: result = 0; set_bit(dest_epid, &hw->hw_info.buffer_share_bit); break; case FJES_CMD_REQ_RES_CODE_BUSY: result = -EBUSY; break; default: result = -EPERM; break; } } else { switch (ret) { case FJES_CMD_STATUS_UNKNOWN: result = -EPERM; break; case FJES_CMD_STATUS_TIMEOUT: result = -EBUSY; break; case FJES_CMD_STATUS_ERROR_PARAM: case FJES_CMD_STATUS_ERROR_STATUS: default: result = -EPERM; break; } } return result; }
int fjes_hw_start_debug(struct fjes_hw *hw) { union fjes_device_command_req *req_buf = hw->hw_info.req_buf; union fjes_device_command_res *res_buf = hw->hw_info.res_buf; enum fjes_dev_command_response_e ret; int page_count; int result = 0; void *addr; int i; if (!hw->hw_info.trace) return -EPERM; memset(hw->hw_info.trace, 0, FJES_DEBUG_BUFFER_SIZE); memset(req_buf, 0, hw->hw_info.req_buf_size); memset(res_buf, 0, hw->hw_info.res_buf_size); req_buf->start_trace.length = FJES_DEV_COMMAND_START_DBG_REQ_LEN(hw->hw_info.trace_size); req_buf->start_trace.mode = hw->debug_mode; req_buf->start_trace.buffer_len = hw->hw_info.trace_size; page_count = hw->hw_info.trace_size / FJES_DEBUG_PAGE_SIZE; for (i = 0; i < page_count; i++) { addr = ((u8 *)hw->hw_info.trace) + i * FJES_DEBUG_PAGE_SIZE; req_buf->start_trace.buffer[i] = (__le64)(page_to_phys(vmalloc_to_page(addr)) + offset_in_page(addr)); } res_buf->start_trace.length = 0; res_buf->start_trace.code = 0; trace_fjes_hw_start_debug_req(req_buf); ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_START_DEBUG); trace_fjes_hw_start_debug(res_buf); if (res_buf->start_trace.length != FJES_DEV_COMMAND_START_DBG_RES_LEN) { result = -ENOMSG; trace_fjes_hw_start_debug_err("Invalid res_buf"); } else if (ret == FJES_CMD_STATUS_NORMAL) { switch (res_buf->start_trace.code) { case FJES_CMD_REQ_RES_CODE_NORMAL: result = 0; break; default: result = -EPERM; break; } } else { switch (ret) { case FJES_CMD_STATUS_UNKNOWN: result = -EPERM; break; case FJES_CMD_STATUS_TIMEOUT: trace_fjes_hw_start_debug_err("Busy Timeout"); result = -EBUSY; break; case FJES_CMD_STATUS_ERROR_PARAM: case FJES_CMD_STATUS_ERROR_STATUS: default: result = -EPERM; break; } } return result; }