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 */ 246