1 
   2 
   3 #include "lm5710.h"
   4 #include "command.h"
   5 #include "everest_l5cm_constants.h"
   6 #include "lm_l5if.h"
   7 
   8 static lm_status_t lm_sc_post_init_request(
   9     IN  struct _lm_device_t *pdev,
  10     IN  lm_iscsi_state_t *iscsi,
  11     IN  lm_iscsi_slow_path_request_t *sp_req,
  12     OUT u8_t *command,
  13     OUT u64_t *data)
  14 {
  15     DbgMessage(pdev, VERBOSEl5sp, "##lm__post_initiate_offload_request\n");
  16     DbgBreakIf(iscsi->hdr.status != STATE_STATUS_INIT_CONTEXT);
  17 
  18     *command = ISCSI_RAMROD_CMD_ID_INIT;
  19     *data = iscsi->ctx_phys.as_u64;
  20 
  21     return LM_STATUS_PENDING;   
  22 }
  23 
  24 
  25 
  26 static lm_status_t lm_sc_post_update_request(
  27     IN  struct _lm_device_t *pdev,
  28     IN  lm_iscsi_state_t *iscsi,
  29     IN  lm_iscsi_slow_path_request_t *sp_req,
  30     OUT u8_t *command,
  31     OUT u64_t *data)
  32 {
  33     struct protocol_common_spe     spe       = {0};
  34 
  35     DbgMessage(pdev, VERBOSEl5sp, "##lm__post_initiate_offload_request\n");
  36     DbgBreakIf(iscsi->hdr.status != STATE_STATUS_NORMAL);
  37 
  38     *command = ISCSI_RAMROD_CMD_ID_UPDATE_CONN;
  39     spe.data.phy_address.hi = iscsi->sp_req_data.phys_addr.as_u32.high;
  40     spe.data.phy_address.lo = iscsi->sp_req_data.phys_addr.as_u32.low;
  41     *data = *((u64_t*)(&(spe.data.phy_address)));
  42 
  43     return LM_STATUS_PENDING;   
  44 }
  45 
  46 
  47 
  48 /* Desciption:
  49  *  post slow path request of given type for given iscsi state
  50  * Assumptions:
  51  *  - caller initialized request->type according to his specific request
  52  *  - caller allocated space for request->data, according to the specific request type
  53  *  - all previous slow path requests for given tcp state are already completed
  54  * Returns:
  55  *  PENDING, SUCCESS or any failure */
  56 lm_status_t lm_sc_post_slow_path_request(
  57     IN  struct _lm_device_t *pdev,
  58     IN  lm_iscsi_state_t *iscsi,
  59     IN  lm_iscsi_slow_path_request_t *request)
  60 {
  61     lm_status_t lm_status = LM_STATUS_SUCCESS;
  62     u64_t       data      = 0;
  63     u8_t        command   = 0;
  64     
  65     DbgBreakIf(!(pdev && iscsi && request));
  66     DbgMessage(pdev, VERBOSEl5sp, "### lm_sc_post_slow_path_request cid=%d, type=%d\n", iscsi->cid, request->type);
  67 
  68     switch (request->type)
  69     {
  70     /* NirV: called under lock, iscsi_state is being changed */
  71     case SP_REQUEST_SC_INIT:
  72         lm_status = lm_sc_post_init_request(pdev, iscsi, request, &command, &data);
  73         break;
  74 
  75     case SP_REQUEST_SC_UPDATE:    
  76         lm_status = lm_sc_post_update_request(pdev, iscsi, request, &command, &data);
  77         break;
  78 
  79     default:
  80         lm_status = LM_STATUS_FAILURE;
  81         DbgBreakMsg("Illegal slow path request type!\n");
  82         break;
  83     }
  84 
  85     if (lm_status == LM_STATUS_PENDING)
  86     {
  87         DbgMessage(pdev, VERBOSEl5sp,
  88                    "calling lm_command_post, cid=%d, command=%d, con_type=%d, data=%lx\n",
  89                    iscsi->cid, command, ISCSI_CONNECTION_TYPE, data);
  90         lm_command_post(pdev, iscsi->cid, command, CMD_PRIORITY_NORMAL, ISCSI_CONNECTION_TYPE/*ulp*/, data);  
  91     }
  92 
  93     request->status = lm_status; 
  94     return lm_status;
  95 }
  96 
  97 
  98 
  99 /* Desciption:
 100  *  initiate a caller allocated lm iscsi state
 101  * Assumptions:
 102  *  - caller already zeroed given iscsi state
 103  * Returns:
 104  *  SUCCESS or any failure */
 105 lm_status_t lm_sc_init_iscsi_state(
 106     struct _lm_device_t *pdev,
 107     lm_state_block_t *state_blk,
 108     lm_iscsi_state_t *iscsi)
 109 {
 110     DbgMessage(pdev, VERBOSEl5sp, "###lm_sc_init_iscsi_state, ptr=%p\n", iscsi);
 111     DbgBreakIf(!(pdev && state_blk && iscsi));
 112 
 113     iscsi->hdr.state_blk     = state_blk;
 114     iscsi->hdr.state_id      = STATE_ID_UNKNOWN;
 115     iscsi->hdr.status        = STATE_STATUS_INIT;
 116     d_list_push_tail(&pdev->iscsi_info.run_time.iscsi_list, &iscsi->hdr.link);
 117 
 118     // NirV: sc: future statistics update
 119 
 120     /* the rest of the iscsi state's fields that require initialization value other than 0, 
 121      * will be initialized later (when lm_sc_init_iscsi_context is called) */
 122    
 123     return LM_STATUS_SUCCESS;
 124 }
 125 
 126 
 127 
 128 /* Desciption:
 129  *  delete iscsi state from lm _except_ from actual freeing of memory.
 130  *  the task of freeing of memory is done in lm_sc_free_iscsi_state()
 131  * Assumptions:
 132  *  global toe lock is taken by the caller 
 133  */
 134 void lm_sc_del_iscsi_state(
 135     struct _lm_device_t *pdev,
 136     lm_iscsi_state_t *iscsi)
 137 {
 138     u8_t notify_fw = 1;
 139 
 140     DbgMessage(pdev, VERBOSEl5sp, "###lm_sc_del_iscsi_state\n");
 141     DbgBreakIf(!(pdev && iscsi));
 142     DbgBreakIf(iscsi->hdr.status >= STATE_STATUS_OFFLOAD_PENDING && 
 143                iscsi->hdr.status < STATE_STATUS_UPLOAD_DONE);
 144 
 145     /* just a moment before we delete this connection, lets take it's info... */
 146     /*lm_tcp_collect_stats(pdev, tcp);*/
 147 
 148     d_list_remove_entry(
 149         &pdev->iscsi_info.run_time.iscsi_list,
 150         &iscsi->hdr.link);
 151     /*pdev->iscsi_info.stats.total_upld++;*/
 152 
 153 
 154   /* tcp->cid could have not been initialized if delete of state 
 155      is a result of a failed initialization */
 156     DbgBreakIf(iscsi->hdr.status != STATE_STATUS_UPLOAD_DONE && 
 157                iscsi->hdr.status != STATE_STATUS_INIT_OFFLOAD_ERR);
 158 
 159     if (iscsi->hdr.status == STATE_STATUS_INIT_OFFLOAD_ERR) {
 160         notify_fw = 0;
 161     }        
 162       
 163     lm_free_cid_resc(pdev, ISCSI_CONNECTION_TYPE, iscsi->cid, notify_fw);
 164 
 165     iscsi->hdr.state_blk     = NULL;  
 166     iscsi->cid = 0;
 167     iscsi->ctx_virt = NULL;
 168     iscsi->ctx_phys.as_u64 = 0;
 169 } /* lm_sc_del_iscsi_state */
 170 
 171 
 172 /* clean up the lm_fcoe_state */
 173 void
 174 lm_fc_del_fcoe_state(
 175     struct _lm_device_t             *pdev,
 176     lm_fcoe_state_t                 *fcoe)
 177 {
 178     DbgMessage(pdev, VERBOSEl5sp, "###lm_fc_del_fcoe_state\n");
 179     DbgBreakIf(!(pdev && fcoe));
 180     /*
 181     DbgBreakIf(fcoe->hdr.status >= STATE_STATUS_OFFLOAD_PENDING && 
 182                fcoe->hdr.status < STATE_STATUS_UPLOAD_DONE);
 183     */
 184 
 185     /* remove the lm_fcoe_state from the state list */
 186     d_list_remove_entry(&pdev->fcoe_info.run_time.fcoe_list, &fcoe->hdr.link);
 187 
 188   /* tcp->cid could have not been initialized if delete of state 
 189      is a result of a failed initialization */
 190 
 191     /*
 192     DbgBreakIf(fcoe->hdr.status != STATE_STATUS_UPLOAD_DONE && 
 193                fcoe->hdr.status != STATE_STATUS_INIT_OFFLOAD_ERR);
 194     */
 195 } /* lm_fc_del_fcoe_state */
 196 
 197 
 198 
 199 lm_status_t
 200 lm_fc_init_fcoe_state(
 201     struct _lm_device_t             *pdev,
 202     lm_state_block_t                *state_blk,
 203     lm_fcoe_state_t                 *fcoe)
 204 {
 205     DbgMessage(pdev, VERBOSEl5sp, "###lm_fc_init_fcoe_state, ptr=%p\n", fcoe);
 206     DbgBreakIf(!(pdev && state_blk && fcoe));
 207 
 208     fcoe->hdr.state_blk     = state_blk;
 209     fcoe->hdr.state_id      = STATE_ID_UNKNOWN;
 210     fcoe->hdr.status        = STATE_STATUS_INIT;
 211     d_list_push_tail(&pdev->fcoe_info.run_time.fcoe_list, &fcoe->hdr.link);
 212 
 213     /* the rest of the fcoe state's fields that require initialization value other than 0, 
 214      * will be initialized later (when lm_fc_init_fcoe_context is called) */
 215    
 216     return LM_STATUS_SUCCESS;
 217 }
 218 
 219 
 220 
 221 void lm_sc_init_sp_req_type(
 222     struct _lm_device_t          * pdev, 
 223     lm_iscsi_state_t             * iscsi, 
 224     lm_iscsi_slow_path_request_t * lm_req, 
 225     void                         * req_input_data)
 226 {
 227     void *update_kwqe_virt;
 228     struct protocol_common_spe spe = {0};
 229 
 230     switch(lm_req->type) {  
 231     case SP_REQUEST_SC_INIT:
 232         break;
 233     case SP_REQUEST_SC_UPDATE: 
 234 
 235         spe.data.phy_address.hi = iscsi->sp_req_data.phys_addr.as_u32.high;
 236         spe.data.phy_address.lo = iscsi->sp_req_data.phys_addr.as_u32.low;
 237 
 238         update_kwqe_virt = &iscsi->sp_req_data.virt_addr->update_ctx.kwqe;
 239         mm_memcpy(update_kwqe_virt, req_input_data, sizeof(struct iscsi_kwqe_conn_update));
 240 
 241         break;
 242     default:
 243         DbgBreakMsg("lm_sc_init_sp_req_type: Illegal slow path request type!\n");
 244     }
 245 } /* lm_init_sp_req_type */