#include "lm5710.h"
#include "command.h"
#include "everest_l5cm_constants.h"
#include "lm_l5if.h"
static lm_status_t lm_sc_post_init_request(
IN struct _lm_device_t *pdev,
IN lm_iscsi_state_t *iscsi,
IN lm_iscsi_slow_path_request_t *sp_req,
OUT u8_t *command,
OUT u64_t *data)
{
DbgMessage(pdev, VERBOSEl5sp, "##lm__post_initiate_offload_request\n");
DbgBreakIf(iscsi->hdr.status != STATE_STATUS_INIT_CONTEXT);
*command = ISCSI_RAMROD_CMD_ID_INIT;
*data = iscsi->ctx_phys.as_u64;
return LM_STATUS_PENDING;
}
static lm_status_t lm_sc_post_update_request(
IN struct _lm_device_t *pdev,
IN lm_iscsi_state_t *iscsi,
IN lm_iscsi_slow_path_request_t *sp_req,
OUT u8_t *command,
OUT u64_t *data)
{
struct protocol_common_spe spe = {0};
DbgMessage(pdev, VERBOSEl5sp, "##lm__post_initiate_offload_request\n");
DbgBreakIf(iscsi->hdr.status != STATE_STATUS_NORMAL);
*command = ISCSI_RAMROD_CMD_ID_UPDATE_CONN;
spe.data.phy_address.hi = iscsi->sp_req_data.phys_addr.as_u32.high;
spe.data.phy_address.lo = iscsi->sp_req_data.phys_addr.as_u32.low;
*data = *((u64_t*)(&(spe.data.phy_address)));
return LM_STATUS_PENDING;
}
lm_status_t lm_sc_post_slow_path_request(
IN struct _lm_device_t *pdev,
IN lm_iscsi_state_t *iscsi,
IN lm_iscsi_slow_path_request_t *request)
{
lm_status_t lm_status = LM_STATUS_SUCCESS;
u64_t data = 0;
u8_t command = 0;
DbgBreakIf(!(pdev && iscsi && request));
DbgMessage(pdev, VERBOSEl5sp, "### lm_sc_post_slow_path_request cid=%d, type=%d\n", iscsi->cid, request->type);
switch (request->type)
{
case SP_REQUEST_SC_INIT:
lm_status = lm_sc_post_init_request(pdev, iscsi, request, &command, &data);
break;
case SP_REQUEST_SC_UPDATE:
lm_status = lm_sc_post_update_request(pdev, iscsi, request, &command, &data);
break;
default:
lm_status = LM_STATUS_FAILURE;
DbgBreakMsg("Illegal slow path request type!\n");
break;
}
if (lm_status == LM_STATUS_PENDING)
{
DbgMessage(pdev, VERBOSEl5sp,
"calling lm_command_post, cid=%d, command=%d, con_type=%d, data=%lx\n",
iscsi->cid, command, ISCSI_CONNECTION_TYPE, data);
lm_command_post(pdev, iscsi->cid, command, CMD_PRIORITY_NORMAL, ISCSI_CONNECTION_TYPE, data);
}
request->status = lm_status;
return lm_status;
}
lm_status_t lm_sc_init_iscsi_state(
struct _lm_device_t *pdev,
lm_state_block_t *state_blk,
lm_iscsi_state_t *iscsi)
{
DbgMessage(pdev, VERBOSEl5sp, "###lm_sc_init_iscsi_state, ptr=%p\n", iscsi);
DbgBreakIf(!(pdev && state_blk && iscsi));
iscsi->hdr.state_blk = state_blk;
iscsi->hdr.state_id = STATE_ID_UNKNOWN;
iscsi->hdr.status = STATE_STATUS_INIT;
d_list_push_tail(&pdev->iscsi_info.run_time.iscsi_list, &iscsi->hdr.link);
return LM_STATUS_SUCCESS;
}
void lm_sc_del_iscsi_state(
struct _lm_device_t *pdev,
lm_iscsi_state_t *iscsi)
{
u8_t notify_fw = 1;
DbgMessage(pdev, VERBOSEl5sp, "###lm_sc_del_iscsi_state\n");
DbgBreakIf(!(pdev && iscsi));
DbgBreakIf(iscsi->hdr.status >= STATE_STATUS_OFFLOAD_PENDING &&
iscsi->hdr.status < STATE_STATUS_UPLOAD_DONE);
d_list_remove_entry(
&pdev->iscsi_info.run_time.iscsi_list,
&iscsi->hdr.link);
DbgBreakIf(iscsi->hdr.status != STATE_STATUS_UPLOAD_DONE &&
iscsi->hdr.status != STATE_STATUS_INIT_OFFLOAD_ERR);
if (iscsi->hdr.status == STATE_STATUS_INIT_OFFLOAD_ERR) {
notify_fw = 0;
}
lm_free_cid_resc(pdev, ISCSI_CONNECTION_TYPE, iscsi->cid, notify_fw);
iscsi->hdr.state_blk = NULL;
iscsi->cid = 0;
iscsi->ctx_virt = NULL;
iscsi->ctx_phys.as_u64 = 0;
}
void
lm_fc_del_fcoe_state(
struct _lm_device_t *pdev,
lm_fcoe_state_t *fcoe)
{
DbgMessage(pdev, VERBOSEl5sp, "###lm_fc_del_fcoe_state\n");
DbgBreakIf(!(pdev && fcoe));
d_list_remove_entry(&pdev->fcoe_info.run_time.fcoe_list, &fcoe->hdr.link);
}
lm_status_t
lm_fc_init_fcoe_state(
struct _lm_device_t *pdev,
lm_state_block_t *state_blk,
lm_fcoe_state_t *fcoe)
{
DbgMessage(pdev, VERBOSEl5sp, "###lm_fc_init_fcoe_state, ptr=%p\n", fcoe);
DbgBreakIf(!(pdev && state_blk && fcoe));
fcoe->hdr.state_blk = state_blk;
fcoe->hdr.state_id = STATE_ID_UNKNOWN;
fcoe->hdr.status = STATE_STATUS_INIT;
d_list_push_tail(&pdev->fcoe_info.run_time.fcoe_list, &fcoe->hdr.link);
return LM_STATUS_SUCCESS;
}
void lm_sc_init_sp_req_type(
struct _lm_device_t * pdev,
lm_iscsi_state_t * iscsi,
lm_iscsi_slow_path_request_t * lm_req,
void * req_input_data)
{
void *update_kwqe_virt;
struct protocol_common_spe spe = {0};
switch(lm_req->type) {
case SP_REQUEST_SC_INIT:
break;
case SP_REQUEST_SC_UPDATE:
spe.data.phy_address.hi = iscsi->sp_req_data.phys_addr.as_u32.high;
spe.data.phy_address.lo = iscsi->sp_req_data.phys_addr.as_u32.low;
update_kwqe_virt = &iscsi->sp_req_data.virt_addr->update_ctx.kwqe;
mm_memcpy(update_kwqe_virt, req_input_data, sizeof(struct iscsi_kwqe_conn_update));
break;
default:
DbgBreakMsg("lm_sc_init_sp_req_type: Illegal slow path request type!\n");
}
}