be_mgmt.c (46388B)
1/* 2 * This file is part of the Emulex Linux Device Driver for Enterprise iSCSI 3 * Host Bus Adapters. Refer to the README file included with this package 4 * for driver version and adapter compatibility. 5 * 6 * Copyright (c) 2018 Broadcom. All Rights Reserved. 7 * The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of version 2 of the GNU General Public License as published 11 * by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful. ALL EXPRESS 14 * OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY 15 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 16 * OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH 17 * DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. 18 * See the GNU General Public License for more details, a copy of which 19 * can be found in the file COPYING included with this package. 20 * 21 * Contact Information: 22 * linux-drivers@broadcom.com 23 * 24 */ 25 26#include <linux/bsg-lib.h> 27#include <scsi/scsi_transport_iscsi.h> 28#include <scsi/scsi_bsg_iscsi.h> 29#include "be_mgmt.h" 30#include "be_iscsi.h" 31#include "be_main.h" 32 33unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl, 34 struct beiscsi_hba *phba, 35 struct bsg_job *job, 36 struct be_dma_mem *nonemb_cmd) 37{ 38 struct be_mcc_wrb *wrb; 39 struct be_sge *mcc_sge; 40 unsigned int tag = 0; 41 struct iscsi_bsg_request *bsg_req = job->request; 42 struct be_bsg_vendor_cmd *req = nonemb_cmd->va; 43 unsigned short region, sector_size, sector, offset; 44 45 nonemb_cmd->size = job->request_payload.payload_len; 46 memset(nonemb_cmd->va, 0, nonemb_cmd->size); 47 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; 48 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; 49 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3]; 50 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4]; 51 req->region = region; 52 req->sector = sector; 53 req->offset = offset; 54 55 if (mutex_lock_interruptible(&ctrl->mbox_lock)) 56 return 0; 57 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) { 58 case BEISCSI_WRITE_FLASH: 59 offset = sector * sector_size + offset; 60 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 61 OPCODE_COMMON_WRITE_FLASH, sizeof(*req)); 62 sg_copy_to_buffer(job->request_payload.sg_list, 63 job->request_payload.sg_cnt, 64 nonemb_cmd->va + offset, job->request_len); 65 break; 66 case BEISCSI_READ_FLASH: 67 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 68 OPCODE_COMMON_READ_FLASH, sizeof(*req)); 69 break; 70 default: 71 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 72 "BG_%d : Unsupported cmd = 0x%x\n\n", 73 bsg_req->rqst_data.h_vendor.vendor_cmd[0]); 74 75 mutex_unlock(&ctrl->mbox_lock); 76 return -EPERM; 77 } 78 79 wrb = alloc_mcc_wrb(phba, &tag); 80 if (!wrb) { 81 mutex_unlock(&ctrl->mbox_lock); 82 return 0; 83 } 84 85 mcc_sge = nonembedded_sgl(wrb); 86 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 87 job->request_payload.sg_cnt); 88 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 89 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 90 mcc_sge->len = cpu_to_le32(nonemb_cmd->size); 91 92 be_mcc_notify(phba, tag); 93 94 mutex_unlock(&ctrl->mbox_lock); 95 return tag; 96} 97 98/** 99 * mgmt_open_connection()- Establish a TCP CXN 100 * @phba: driver priv structure 101 * @dst_addr: Destination Address 102 * @beiscsi_ep: ptr to device endpoint struct 103 * @nonemb_cmd: ptr to memory allocated for command 104 * 105 * return 106 * Success: Tag number of the MBX Command issued 107 * Failure: Error code 108 **/ 109int mgmt_open_connection(struct beiscsi_hba *phba, 110 struct sockaddr *dst_addr, 111 struct beiscsi_endpoint *beiscsi_ep, 112 struct be_dma_mem *nonemb_cmd) 113{ 114 struct hwi_controller *phwi_ctrlr; 115 struct hwi_context_memory *phwi_context; 116 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr; 117 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr; 118 struct be_ctrl_info *ctrl = &phba->ctrl; 119 struct be_mcc_wrb *wrb; 120 struct tcp_connect_and_offload_in_v1 *req; 121 unsigned short def_hdr_id; 122 unsigned short def_data_id; 123 struct phys_addr template_address = { 0, 0 }; 124 struct phys_addr *ptemplate_address; 125 unsigned int tag = 0; 126 unsigned int i, ulp_num; 127 unsigned short cid = beiscsi_ep->ep_cid; 128 struct be_sge *sge; 129 130 if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) { 131 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 132 "BG_%d : unknown addr family %d\n", 133 dst_addr->sa_family); 134 return 0; 135 } 136 137 phwi_ctrlr = phba->phwi_ctrlr; 138 phwi_context = phwi_ctrlr->phwi_ctxt; 139 140 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num; 141 142 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num); 143 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num); 144 145 ptemplate_address = &template_address; 146 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address); 147 if (mutex_lock_interruptible(&ctrl->mbox_lock)) 148 return 0; 149 wrb = alloc_mcc_wrb(phba, &tag); 150 if (!wrb) { 151 mutex_unlock(&ctrl->mbox_lock); 152 return 0; 153 } 154 155 sge = nonembedded_sgl(wrb); 156 req = nonemb_cmd->va; 157 memset(req, 0, sizeof(*req)); 158 159 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1); 160 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 161 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD, 162 nonemb_cmd->size); 163 if (dst_addr->sa_family == PF_INET) { 164 __be32 s_addr = daddr_in->sin_addr.s_addr; 165 req->ip_address.ip_type = BEISCSI_IP_TYPE_V4; 166 req->ip_address.addr[0] = s_addr & 0x000000ff; 167 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8; 168 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16; 169 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24; 170 req->tcp_port = ntohs(daddr_in->sin_port); 171 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr; 172 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port); 173 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4; 174 } else { 175 /* else its PF_INET6 family */ 176 req->ip_address.ip_type = BEISCSI_IP_TYPE_V6; 177 memcpy(&req->ip_address.addr, 178 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); 179 req->tcp_port = ntohs(daddr_in6->sin6_port); 180 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port); 181 memcpy(&beiscsi_ep->dst6_addr, 182 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); 183 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6; 184 } 185 req->cid = cid; 186 i = phba->nxt_cqid++; 187 if (phba->nxt_cqid == phba->num_cpus) 188 phba->nxt_cqid = 0; 189 req->cq_id = phwi_context->be_cq[i].id; 190 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 191 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id); 192 req->defq_id = def_hdr_id; 193 req->hdr_ring_id = def_hdr_id; 194 req->data_ring_id = def_data_id; 195 req->do_offload = 1; 196 req->dataout_template_pa.lo = ptemplate_address->lo; 197 req->dataout_template_pa.hi = ptemplate_address->hi; 198 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 199 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 200 sge->len = cpu_to_le32(nonemb_cmd->size); 201 202 if (!is_chip_be2_be3r(phba)) { 203 req->hdr.version = MBX_CMD_VER1; 204 req->tcp_window_size = 0x8000; 205 req->tcp_window_scale_count = 2; 206 } 207 208 be_mcc_notify(phba, tag); 209 mutex_unlock(&ctrl->mbox_lock); 210 return tag; 211} 212 213/** 214 * beiscsi_exec_nemb_cmd()- execute non-embedded MBX cmd 215 * @phba: driver priv structure 216 * @nonemb_cmd: DMA address of the MBX command to be issued 217 * @cbfn: callback func on MCC completion 218 * @resp_buf: buffer to copy the MBX cmd response 219 * @resp_buf_len: response length to be copied 220 * 221 **/ 222static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba, 223 struct be_dma_mem *nonemb_cmd, 224 void (*cbfn)(struct beiscsi_hba *, 225 unsigned int), 226 void *resp_buf, u32 resp_buf_len) 227{ 228 struct be_ctrl_info *ctrl = &phba->ctrl; 229 struct be_mcc_wrb *wrb; 230 struct be_sge *sge; 231 unsigned int tag; 232 int rc = 0; 233 234 mutex_lock(&ctrl->mbox_lock); 235 wrb = alloc_mcc_wrb(phba, &tag); 236 if (!wrb) { 237 mutex_unlock(&ctrl->mbox_lock); 238 return -ENOMEM; 239 } 240 241 sge = nonembedded_sgl(wrb); 242 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1); 243 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 244 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma)); 245 sge->len = cpu_to_le32(nonemb_cmd->size); 246 247 if (cbfn) { 248 struct be_dma_mem *tag_mem; 249 250 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state); 251 ctrl->ptag_state[tag].cbfn = cbfn; 252 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state; 253 254 /* store DMA mem to be freed in callback */ 255 tag_mem->size = nonemb_cmd->size; 256 tag_mem->va = nonemb_cmd->va; 257 tag_mem->dma = nonemb_cmd->dma; 258 } 259 be_mcc_notify(phba, tag); 260 mutex_unlock(&ctrl->mbox_lock); 261 262 /* with cbfn set, its async cmd, don't wait */ 263 if (cbfn) 264 return 0; 265 266 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd); 267 268 /* copy the response, if any */ 269 if (resp_buf) 270 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len); 271 return rc; 272} 273 274static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba, 275 struct be_dma_mem *cmd, 276 u8 subsystem, u8 opcode, u32 size) 277{ 278 cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, size, &cmd->dma, 279 GFP_KERNEL); 280 if (!cmd->va) { 281 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 282 "BG_%d : Failed to allocate memory for if info\n"); 283 return -ENOMEM; 284 } 285 cmd->size = size; 286 be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size); 287 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 288 "BG_%d : subsystem %u cmd %u size %u\n", 289 subsystem, opcode, size); 290 return 0; 291} 292 293static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba, 294 struct be_dma_mem *cmd, int rc) 295{ 296 /* 297 * If FW is busy the DMA buffer is saved with the tag. When the cmd 298 * completes this buffer is freed. 299 */ 300 if (rc == -EBUSY) 301 return; 302 303 dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma); 304} 305 306static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag) 307{ 308 struct be_dma_mem *tag_mem; 309 310 /* status is ignored */ 311 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL); 312 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state; 313 if (tag_mem->size) { 314 dma_free_coherent(&phba->pcidev->dev, tag_mem->size, 315 tag_mem->va, tag_mem->dma); 316 tag_mem->size = 0; 317 } 318} 319 320int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, 321 struct be_set_eqd *set_eqd, int num) 322{ 323 struct be_cmd_req_modify_eq_delay *req; 324 struct be_dma_mem nonemb_cmd; 325 int i, rc; 326 327 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON, 328 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req)); 329 if (rc) 330 return rc; 331 332 req = nonemb_cmd.va; 333 req->num_eq = cpu_to_le32(num); 334 for (i = 0; i < num; i++) { 335 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id); 336 req->delay[i].phase = 0; 337 req->delay[i].delay_multiplier = 338 cpu_to_le32(set_eqd[i].delay_multiplier); 339 } 340 341 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl, 342 NULL, 0); 343 if (rc) { 344 /* 345 * Only free on failure. Async cmds are handled like -EBUSY 346 * where it's handled for us. 347 */ 348 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 349 } 350 return rc; 351} 352 353/** 354 * beiscsi_get_initiator_name - read initiator name from flash 355 * @phba: device priv structure 356 * @name: buffer pointer 357 * @cfg: fetch user configured 358 * 359 */ 360int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg) 361{ 362 struct be_dma_mem nonemb_cmd; 363 struct be_cmd_hba_name resp; 364 struct be_cmd_hba_name *req; 365 int rc; 366 367 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI, 368 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp)); 369 if (rc) 370 return rc; 371 372 req = nonemb_cmd.va; 373 if (cfg) 374 req->hdr.version = 1; 375 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, 376 &resp, sizeof(resp)); 377 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 378 if (rc) { 379 beiscsi_log(phba, KERN_ERR, 380 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 381 "BS_%d : Initiator Name MBX Failed\n"); 382 return rc; 383 } 384 rc = sprintf(name, "%s\n", resp.initiator_name); 385 return rc; 386} 387 388unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba) 389{ 390 struct be_ctrl_info *ctrl = &phba->ctrl; 391 struct be_mcc_wrb *wrb; 392 struct be_cmd_get_all_if_id_req *req; 393 struct be_cmd_get_all_if_id_req *pbe_allid; 394 unsigned int tag; 395 int status = 0; 396 397 if (mutex_lock_interruptible(&ctrl->mbox_lock)) 398 return -EINTR; 399 wrb = alloc_mcc_wrb(phba, &tag); 400 if (!wrb) { 401 mutex_unlock(&ctrl->mbox_lock); 402 return -ENOMEM; 403 } 404 405 req = embedded_payload(wrb); 406 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 407 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 408 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID, 409 sizeof(*req)); 410 be_mcc_notify(phba, tag); 411 mutex_unlock(&ctrl->mbox_lock); 412 413 status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 414 if (status) { 415 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 416 "BG_%d : %s failed: %d\n", __func__, status); 417 return -EBUSY; 418 } 419 420 pbe_allid = embedded_payload(wrb); 421 /* we now support only one interface per function */ 422 phba->interface_handle = pbe_allid->if_hndl_list[0]; 423 424 return status; 425} 426 427static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type) 428{ 429 u32 len; 430 431 len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN; 432 while (len && !ip[len - 1]) 433 len--; 434 return (len == 0); 435} 436 437static int beiscsi_if_mod_gw(struct beiscsi_hba *phba, 438 u32 action, u32 ip_type, u8 *gw) 439{ 440 struct be_cmd_set_def_gateway_req *req; 441 struct be_dma_mem nonemb_cmd; 442 int rt_val; 443 444 rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 445 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY, 446 sizeof(*req)); 447 if (rt_val) 448 return rt_val; 449 450 req = nonemb_cmd.va; 451 req->action = action; 452 req->ip_addr.ip_type = ip_type; 453 memcpy(req->ip_addr.addr, gw, 454 (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN); 455 rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); 456 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val); 457 return rt_val; 458} 459 460int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw) 461{ 462 struct be_cmd_get_def_gateway_resp gw_resp; 463 int rt_val; 464 465 memset(&gw_resp, 0, sizeof(gw_resp)); 466 rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp); 467 if (rt_val) { 468 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 469 "BG_%d : Failed to Get Gateway Addr\n"); 470 return rt_val; 471 } 472 473 if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) { 474 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type, 475 gw_resp.ip_addr.addr); 476 if (rt_val) { 477 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 478 "BG_%d : Failed to clear Gateway Addr Set\n"); 479 return rt_val; 480 } 481 } 482 483 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw); 484 if (rt_val) 485 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 486 "BG_%d : Failed to Set Gateway Addr\n"); 487 488 return rt_val; 489} 490 491int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type, 492 struct be_cmd_get_def_gateway_resp *resp) 493{ 494 struct be_cmd_get_def_gateway_req *req; 495 struct be_dma_mem nonemb_cmd; 496 int rc; 497 498 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 499 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY, 500 sizeof(*resp)); 501 if (rc) 502 return rc; 503 504 req = nonemb_cmd.va; 505 req->ip_type = ip_type; 506 507 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp, 508 sizeof(*resp)); 509 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 510 return rc; 511} 512 513static int 514beiscsi_if_clr_ip(struct beiscsi_hba *phba, 515 struct be_cmd_get_if_info_resp *if_info) 516{ 517 struct be_cmd_set_ip_addr_req *req; 518 struct be_dma_mem nonemb_cmd; 519 int rc; 520 521 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 522 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR, 523 sizeof(*req)); 524 if (rc) 525 return rc; 526 527 req = nonemb_cmd.va; 528 req->ip_params.record_entry_count = 1; 529 req->ip_params.ip_record.action = IP_ACTION_DEL; 530 req->ip_params.ip_record.interface_hndl = 531 phba->interface_handle; 532 req->ip_params.ip_record.ip_addr.size_of_structure = 533 sizeof(struct be_ip_addr_subnet_format); 534 req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type; 535 memcpy(req->ip_params.ip_record.ip_addr.addr, 536 if_info->ip_addr.addr, 537 sizeof(if_info->ip_addr.addr)); 538 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, 539 if_info->ip_addr.subnet_mask, 540 sizeof(if_info->ip_addr.subnet_mask)); 541 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); 542 if (rc < 0 || req->ip_params.ip_record.status) { 543 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 544 "BG_%d : failed to clear IP: rc %d status %d\n", 545 rc, req->ip_params.ip_record.status); 546 } 547 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 548 return rc; 549} 550 551static int 552beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip, 553 u8 *subnet, u32 ip_type) 554{ 555 struct be_cmd_set_ip_addr_req *req; 556 struct be_dma_mem nonemb_cmd; 557 uint32_t ip_len; 558 int rc; 559 560 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 561 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR, 562 sizeof(*req)); 563 if (rc) 564 return rc; 565 566 req = nonemb_cmd.va; 567 req->ip_params.record_entry_count = 1; 568 req->ip_params.ip_record.action = IP_ACTION_ADD; 569 req->ip_params.ip_record.interface_hndl = 570 phba->interface_handle; 571 req->ip_params.ip_record.ip_addr.size_of_structure = 572 sizeof(struct be_ip_addr_subnet_format); 573 req->ip_params.ip_record.ip_addr.ip_type = ip_type; 574 ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN; 575 memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len); 576 if (subnet) 577 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask, 578 subnet, ip_len); 579 580 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); 581 /** 582 * In some cases, host needs to look into individual record status 583 * even though FW reported success for that IOCTL. 584 */ 585 if (rc < 0 || req->ip_params.ip_record.status) { 586 __beiscsi_log(phba, KERN_ERR, 587 "BG_%d : failed to set IP: rc %d status %d\n", 588 rc, req->ip_params.ip_record.status); 589 if (req->ip_params.ip_record.status) 590 rc = -EINVAL; 591 } 592 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 593 return rc; 594} 595 596int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type, 597 u8 *ip, u8 *subnet) 598{ 599 struct be_cmd_get_if_info_resp *if_info; 600 struct be_cmd_rel_dhcp_req *reldhcp; 601 struct be_dma_mem nonemb_cmd; 602 int rc; 603 604 rc = beiscsi_if_get_info(phba, ip_type, &if_info); 605 if (rc) 606 return rc; 607 608 if (if_info->dhcp_state) { 609 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, 610 CMD_SUBSYSTEM_ISCSI, 611 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, 612 sizeof(*reldhcp)); 613 if (rc) 614 goto exit; 615 616 reldhcp = nonemb_cmd.va; 617 reldhcp->interface_hndl = phba->interface_handle; 618 reldhcp->ip_type = ip_type; 619 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); 620 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 621 if (rc < 0) { 622 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 623 "BG_%d : failed to release existing DHCP: %d\n", 624 rc); 625 goto exit; 626 } 627 } 628 629 /* first delete any IP set */ 630 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) { 631 rc = beiscsi_if_clr_ip(phba, if_info); 632 if (rc) 633 goto exit; 634 } 635 636 /* if ip == NULL then this is called just to release DHCP IP */ 637 if (ip) 638 rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type); 639exit: 640 kfree(if_info); 641 return rc; 642} 643 644int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type) 645{ 646 struct be_cmd_get_def_gateway_resp gw_resp; 647 struct be_cmd_get_if_info_resp *if_info; 648 struct be_cmd_set_dhcp_req *dhcpreq; 649 struct be_dma_mem nonemb_cmd; 650 u8 *gw; 651 int rc; 652 653 rc = beiscsi_if_get_info(phba, ip_type, &if_info); 654 if (rc) 655 return rc; 656 657 if (if_info->dhcp_state) { 658 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 659 "BG_%d : DHCP Already Enabled\n"); 660 goto exit; 661 } 662 663 /* first delete any IP set */ 664 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) { 665 rc = beiscsi_if_clr_ip(phba, if_info); 666 if (rc) 667 goto exit; 668 } 669 670 /* delete gateway settings if mode change is to DHCP */ 671 memset(&gw_resp, 0, sizeof(gw_resp)); 672 /* use ip_type provided in if_info */ 673 rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp); 674 if (rc) { 675 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 676 "BG_%d : Failed to Get Gateway Addr\n"); 677 goto exit; 678 } 679 gw = (u8 *)&gw_resp.ip_addr.addr; 680 if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) { 681 rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, 682 if_info->ip_addr.ip_type, gw); 683 if (rc) { 684 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 685 "BG_%d : Failed to clear Gateway Addr Set\n"); 686 goto exit; 687 } 688 } 689 690 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 691 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR, 692 sizeof(*dhcpreq)); 693 if (rc) 694 goto exit; 695 696 dhcpreq = nonemb_cmd.va; 697 dhcpreq->flags = 1; /* 1 - blocking; 0 - non-blocking */ 698 dhcpreq->retry_count = 1; 699 dhcpreq->interface_hndl = phba->interface_handle; 700 dhcpreq->ip_type = ip_type; 701 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); 702 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 703exit: 704 kfree(if_info); 705 return rc; 706} 707 708/** 709 * beiscsi_if_set_vlan()- Issue and wait for CMD completion 710 * @phba: device private structure instance 711 * @vlan_tag: VLAN tag 712 * 713 * Issue the MBX Cmd and wait for the completion of the 714 * command. 715 * 716 * returns 717 * Success: 0 718 * Failure: Non-Xero Value 719 **/ 720int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag) 721{ 722 int rc; 723 unsigned int tag; 724 725 tag = be_cmd_set_vlan(phba, vlan_tag); 726 if (!tag) { 727 beiscsi_log(phba, KERN_ERR, 728 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), 729 "BG_%d : VLAN Setting Failed\n"); 730 return -EBUSY; 731 } 732 733 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 734 if (rc) { 735 beiscsi_log(phba, KERN_ERR, 736 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX), 737 "BS_%d : VLAN MBX Cmd Failed\n"); 738 return rc; 739 } 740 return rc; 741} 742 743 744int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type, 745 struct be_cmd_get_if_info_resp **if_info) 746{ 747 struct be_cmd_get_if_info_req *req; 748 struct be_dma_mem nonemb_cmd; 749 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp); 750 int rc; 751 752 rc = beiscsi_if_get_handle(phba); 753 if (rc) 754 return rc; 755 756 do { 757 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, 758 CMD_SUBSYSTEM_ISCSI, 759 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, 760 ioctl_size); 761 if (rc) 762 return rc; 763 764 req = nonemb_cmd.va; 765 req->interface_hndl = phba->interface_handle; 766 req->ip_type = ip_type; 767 768 /* Allocate memory for if_info */ 769 *if_info = kzalloc(ioctl_size, GFP_KERNEL); 770 if (!*if_info) { 771 beiscsi_log(phba, KERN_ERR, 772 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 773 "BG_%d : Memory Allocation Failure\n"); 774 775 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, 776 -ENOMEM); 777 return -ENOMEM; 778 } 779 780 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info, 781 ioctl_size); 782 783 /* Check if the error is because of Insufficent_Buffer */ 784 if (rc == -EAGAIN) { 785 786 /* Get the new memory size */ 787 ioctl_size = ((struct be_cmd_resp_hdr *) 788 nonemb_cmd.va)->actual_resp_len; 789 ioctl_size += sizeof(struct be_cmd_req_hdr); 790 791 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 792 /* Free the virtual memory */ 793 kfree(*if_info); 794 } else { 795 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 796 break; 797 } 798 } while (true); 799 return rc; 800} 801 802int mgmt_get_nic_conf(struct beiscsi_hba *phba, 803 struct be_cmd_get_nic_conf_resp *nic) 804{ 805 struct be_dma_mem nonemb_cmd; 806 int rc; 807 808 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI, 809 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, 810 sizeof(*nic)); 811 if (rc) 812 return rc; 813 814 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic)); 815 beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); 816 return rc; 817} 818 819static void beiscsi_boot_process_compl(struct beiscsi_hba *phba, 820 unsigned int tag) 821{ 822 struct be_cmd_get_boot_target_resp *boot_resp; 823 struct be_cmd_resp_logout_fw_sess *logo_resp; 824 struct be_cmd_get_session_resp *sess_resp; 825 struct be_mcc_wrb *wrb; 826 struct boot_struct *bs; 827 int boot_work, status; 828 829 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) { 830 __beiscsi_log(phba, KERN_ERR, 831 "BG_%d : %s no boot work %lx\n", 832 __func__, phba->state); 833 return; 834 } 835 836 if (phba->boot_struct.tag != tag) { 837 __beiscsi_log(phba, KERN_ERR, 838 "BG_%d : %s tag mismatch %d:%d\n", 839 __func__, tag, phba->boot_struct.tag); 840 return; 841 } 842 bs = &phba->boot_struct; 843 boot_work = 1; 844 status = 0; 845 switch (bs->action) { 846 case BEISCSI_BOOT_REOPEN_SESS: 847 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL); 848 if (!status) 849 bs->action = BEISCSI_BOOT_GET_SHANDLE; 850 else 851 bs->retry--; 852 break; 853 case BEISCSI_BOOT_GET_SHANDLE: 854 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL); 855 if (!status) { 856 boot_resp = embedded_payload(wrb); 857 bs->s_handle = boot_resp->boot_session_handle; 858 } 859 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) { 860 bs->action = BEISCSI_BOOT_REOPEN_SESS; 861 bs->retry--; 862 } else { 863 bs->action = BEISCSI_BOOT_GET_SINFO; 864 } 865 break; 866 case BEISCSI_BOOT_GET_SINFO: 867 status = __beiscsi_mcc_compl_status(phba, tag, NULL, 868 &bs->nonemb_cmd); 869 if (!status) { 870 sess_resp = bs->nonemb_cmd.va; 871 memcpy(&bs->boot_sess, &sess_resp->session_info, 872 sizeof(struct mgmt_session_info)); 873 bs->action = BEISCSI_BOOT_LOGOUT_SESS; 874 } else { 875 __beiscsi_log(phba, KERN_ERR, 876 "BG_%d : get boot session info error : 0x%x\n", 877 status); 878 boot_work = 0; 879 } 880 dma_free_coherent(&phba->ctrl.pdev->dev, bs->nonemb_cmd.size, 881 bs->nonemb_cmd.va, bs->nonemb_cmd.dma); 882 bs->nonemb_cmd.va = NULL; 883 break; 884 case BEISCSI_BOOT_LOGOUT_SESS: 885 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL); 886 if (!status) { 887 logo_resp = embedded_payload(wrb); 888 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) { 889 __beiscsi_log(phba, KERN_ERR, 890 "BG_%d : FW boot session logout error : 0x%x\n", 891 logo_resp->session_status); 892 } 893 } 894 /* continue to create boot_kset even if logout failed? */ 895 bs->action = BEISCSI_BOOT_CREATE_KSET; 896 break; 897 default: 898 break; 899 } 900 901 /* clear the tag so no other completion matches this tag */ 902 bs->tag = 0; 903 if (!bs->retry) { 904 boot_work = 0; 905 __beiscsi_log(phba, KERN_ERR, 906 "BG_%d : failed to setup boot target: status %d action %d\n", 907 status, bs->action); 908 } 909 if (!boot_work) { 910 /* wait for next event to start boot_work */ 911 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state); 912 return; 913 } 914 schedule_work(&phba->boot_work); 915} 916 917/** 918 * beiscsi_boot_logout_sess()- Logout from boot FW session 919 * @phba: Device priv structure instance 920 * 921 * return 922 * the TAG used for MBOX Command 923 * 924 */ 925unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba) 926{ 927 struct be_ctrl_info *ctrl = &phba->ctrl; 928 struct be_mcc_wrb *wrb; 929 struct be_cmd_req_logout_fw_sess *req; 930 unsigned int tag; 931 932 mutex_lock(&ctrl->mbox_lock); 933 wrb = alloc_mcc_wrb(phba, &tag); 934 if (!wrb) { 935 mutex_unlock(&ctrl->mbox_lock); 936 return 0; 937 } 938 939 req = embedded_payload(wrb); 940 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 941 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 942 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET, 943 sizeof(struct be_cmd_req_logout_fw_sess)); 944 /* Use the session handle copied into boot_sess */ 945 req->session_handle = phba->boot_struct.boot_sess.session_handle; 946 947 phba->boot_struct.tag = tag; 948 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state); 949 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl; 950 951 be_mcc_notify(phba, tag); 952 mutex_unlock(&ctrl->mbox_lock); 953 954 return tag; 955} 956/** 957 * beiscsi_boot_reopen_sess()- Reopen boot session 958 * @phba: Device priv structure instance 959 * 960 * return 961 * the TAG used for MBOX Command 962 * 963 **/ 964unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba) 965{ 966 struct be_ctrl_info *ctrl = &phba->ctrl; 967 struct be_mcc_wrb *wrb; 968 struct be_cmd_reopen_session_req *req; 969 unsigned int tag; 970 971 mutex_lock(&ctrl->mbox_lock); 972 wrb = alloc_mcc_wrb(phba, &tag); 973 if (!wrb) { 974 mutex_unlock(&ctrl->mbox_lock); 975 return 0; 976 } 977 978 req = embedded_payload(wrb); 979 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 980 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 981 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS, 982 sizeof(struct be_cmd_reopen_session_resp)); 983 req->reopen_type = BE_REOPEN_BOOT_SESSIONS; 984 req->session_handle = BE_BOOT_INVALID_SHANDLE; 985 986 phba->boot_struct.tag = tag; 987 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state); 988 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl; 989 990 be_mcc_notify(phba, tag); 991 mutex_unlock(&ctrl->mbox_lock); 992 return tag; 993} 994 995 996/** 997 * beiscsi_boot_get_sinfo()- Get boot session info 998 * @phba: device priv structure instance 999 * 1000 * Fetches the boot_struct.s_handle info from FW. 1001 * return 1002 * the TAG used for MBOX Command 1003 * 1004 **/ 1005unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba) 1006{ 1007 struct be_ctrl_info *ctrl = &phba->ctrl; 1008 struct be_cmd_get_session_req *req; 1009 struct be_dma_mem *nonemb_cmd; 1010 struct be_mcc_wrb *wrb; 1011 struct be_sge *sge; 1012 unsigned int tag; 1013 1014 mutex_lock(&ctrl->mbox_lock); 1015 wrb = alloc_mcc_wrb(phba, &tag); 1016 if (!wrb) { 1017 mutex_unlock(&ctrl->mbox_lock); 1018 return 0; 1019 } 1020 1021 nonemb_cmd = &phba->boot_struct.nonemb_cmd; 1022 nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp); 1023 nonemb_cmd->va = dma_alloc_coherent(&phba->ctrl.pdev->dev, 1024 nonemb_cmd->size, 1025 &nonemb_cmd->dma, 1026 GFP_KERNEL); 1027 if (!nonemb_cmd->va) { 1028 mutex_unlock(&ctrl->mbox_lock); 1029 return 0; 1030 } 1031 1032 req = nonemb_cmd->va; 1033 memset(req, 0, sizeof(*req)); 1034 sge = nonembedded_sgl(wrb); 1035 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); 1036 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 1037 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION, 1038 sizeof(struct be_cmd_get_session_resp)); 1039 req->session_handle = phba->boot_struct.s_handle; 1040 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); 1041 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); 1042 sge->len = cpu_to_le32(nonemb_cmd->size); 1043 1044 phba->boot_struct.tag = tag; 1045 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state); 1046 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl; 1047 1048 be_mcc_notify(phba, tag); 1049 mutex_unlock(&ctrl->mbox_lock); 1050 return tag; 1051} 1052 1053unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async) 1054{ 1055 struct be_ctrl_info *ctrl = &phba->ctrl; 1056 struct be_mcc_wrb *wrb; 1057 struct be_cmd_get_boot_target_req *req; 1058 unsigned int tag; 1059 1060 mutex_lock(&ctrl->mbox_lock); 1061 wrb = alloc_mcc_wrb(phba, &tag); 1062 if (!wrb) { 1063 mutex_unlock(&ctrl->mbox_lock); 1064 return 0; 1065 } 1066 1067 req = embedded_payload(wrb); 1068 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 1069 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 1070 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET, 1071 sizeof(struct be_cmd_get_boot_target_resp)); 1072 1073 if (async) { 1074 phba->boot_struct.tag = tag; 1075 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state); 1076 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl; 1077 } 1078 1079 be_mcc_notify(phba, tag); 1080 mutex_unlock(&ctrl->mbox_lock); 1081 return tag; 1082} 1083 1084/** 1085 * beiscsi_boot_get_shandle()- Get boot session handle 1086 * @phba: device priv structure instance 1087 * @s_handle: session handle returned for boot session. 1088 * 1089 * return 1090 * Success: 1 1091 * Failure: negative 1092 * 1093 **/ 1094int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle) 1095{ 1096 struct be_cmd_get_boot_target_resp *boot_resp; 1097 struct be_mcc_wrb *wrb; 1098 unsigned int tag; 1099 int rc; 1100 1101 *s_handle = BE_BOOT_INVALID_SHANDLE; 1102 /* get configured boot session count and handle */ 1103 tag = __beiscsi_boot_get_shandle(phba, 0); 1104 if (!tag) { 1105 beiscsi_log(phba, KERN_ERR, 1106 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, 1107 "BG_%d : Getting Boot Target Info Failed\n"); 1108 return -EAGAIN; 1109 } 1110 1111 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 1112 if (rc) { 1113 beiscsi_log(phba, KERN_ERR, 1114 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, 1115 "BG_%d : MBX CMD get_boot_target Failed\n"); 1116 return -EBUSY; 1117 } 1118 1119 boot_resp = embedded_payload(wrb); 1120 /* check if there are any boot targets configured */ 1121 if (!boot_resp->boot_session_count) { 1122 __beiscsi_log(phba, KERN_INFO, 1123 "BG_%d : No boot targets configured\n"); 1124 return -ENXIO; 1125 } 1126 1127 /* only if FW has logged in to the boot target, s_handle is valid */ 1128 *s_handle = boot_resp->boot_session_handle; 1129 return 1; 1130} 1131 1132/** 1133 * beiscsi_drvr_ver_disp()- Display the driver Name and Version 1134 * @dev: ptr to device not used. 1135 * @attr: device attribute, not used. 1136 * @buf: contains formatted text driver name and version 1137 * 1138 * return 1139 * size of the formatted string 1140 **/ 1141ssize_t 1142beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr, 1143 char *buf) 1144{ 1145 return snprintf(buf, PAGE_SIZE, BE_NAME "\n"); 1146} 1147 1148/** 1149 * beiscsi_fw_ver_disp()- Display Firmware Version 1150 * @dev: ptr to device not used. 1151 * @attr: device attribute, not used. 1152 * @buf: contains formatted text Firmware version 1153 * 1154 * return 1155 * size of the formatted string 1156 **/ 1157ssize_t 1158beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, 1159 char *buf) 1160{ 1161 struct Scsi_Host *shost = class_to_shost(dev); 1162 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1163 1164 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str); 1165} 1166 1167/** 1168 * beiscsi_active_session_disp()- Display Sessions Active 1169 * @dev: ptr to device not used. 1170 * @attr: device attribute, not used. 1171 * @buf: contains formatted text Session Count 1172 * 1173 * return 1174 * size of the formatted string 1175 **/ 1176ssize_t 1177beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr, 1178 char *buf) 1179{ 1180 struct Scsi_Host *shost = class_to_shost(dev); 1181 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1182 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0; 1183 1184 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { 1185 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { 1186 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num); 1187 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num); 1188 len += scnprintf(buf+len, PAGE_SIZE - len, 1189 "ULP%d : %d\n", ulp_num, 1190 (total_cids - avlbl_cids)); 1191 } else 1192 len += scnprintf(buf+len, PAGE_SIZE - len, 1193 "ULP%d : %d\n", ulp_num, 0); 1194 } 1195 1196 return len; 1197} 1198 1199/** 1200 * beiscsi_free_session_disp()- Display Avaliable Session 1201 * @dev: ptr to device not used. 1202 * @attr: device attribute, not used. 1203 * @buf: contains formatted text Session Count 1204 * 1205 * return 1206 * size of the formatted string 1207 **/ 1208ssize_t 1209beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr, 1210 char *buf) 1211{ 1212 struct Scsi_Host *shost = class_to_shost(dev); 1213 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1214 uint16_t ulp_num, len = 0; 1215 1216 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { 1217 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) 1218 len += scnprintf(buf+len, PAGE_SIZE - len, 1219 "ULP%d : %d\n", ulp_num, 1220 BEISCSI_ULP_AVLBL_CID(phba, ulp_num)); 1221 else 1222 len += scnprintf(buf+len, PAGE_SIZE - len, 1223 "ULP%d : %d\n", ulp_num, 0); 1224 } 1225 1226 return len; 1227} 1228 1229/** 1230 * beiscsi_adap_family_disp()- Display adapter family. 1231 * @dev: ptr to device to get priv structure 1232 * @attr: device attribute, not used. 1233 * @buf: contains formatted text driver name and version 1234 * 1235 * return 1236 * size of the formatted string 1237 **/ 1238ssize_t 1239beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, 1240 char *buf) 1241{ 1242 uint16_t dev_id = 0; 1243 struct Scsi_Host *shost = class_to_shost(dev); 1244 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1245 1246 dev_id = phba->pcidev->device; 1247 switch (dev_id) { 1248 case BE_DEVICE_ID1: 1249 case OC_DEVICE_ID1: 1250 case OC_DEVICE_ID2: 1251 return snprintf(buf, PAGE_SIZE, 1252 "Obsolete/Unsupported BE2 Adapter Family\n"); 1253 case BE_DEVICE_ID2: 1254 case OC_DEVICE_ID3: 1255 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n"); 1256 case OC_SKH_ID1: 1257 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n"); 1258 default: 1259 return snprintf(buf, PAGE_SIZE, 1260 "Unknown Adapter Family: 0x%x\n", dev_id); 1261 } 1262} 1263 1264/** 1265 * beiscsi_phys_port_disp()- Display Physical Port Identifier 1266 * @dev: ptr to device not used. 1267 * @attr: device attribute, not used. 1268 * @buf: contains formatted text port identifier 1269 * 1270 * return 1271 * size of the formatted string 1272 **/ 1273ssize_t 1274beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr, 1275 char *buf) 1276{ 1277 struct Scsi_Host *shost = class_to_shost(dev); 1278 struct beiscsi_hba *phba = iscsi_host_priv(shost); 1279 1280 return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n", 1281 phba->fw_config.phys_port); 1282} 1283 1284void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, 1285 struct wrb_handle *pwrb_handle, 1286 struct be_mem_descriptor *mem_descr, 1287 struct hwi_wrb_context *pwrb_context) 1288{ 1289 struct iscsi_wrb *pwrb = pwrb_handle->pwrb; 1290 1291 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1292 max_send_data_segment_length, pwrb, 1293 params->dw[offsetof(struct amap_beiscsi_offload_params, 1294 max_send_data_segment_length) / 32]); 1295 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb, 1296 BE_TGT_CTX_UPDT_CMD); 1297 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1298 first_burst_length, 1299 pwrb, 1300 params->dw[offsetof(struct amap_beiscsi_offload_params, 1301 first_burst_length) / 32]); 1302 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb, 1303 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1304 erl) / 32] & OFFLD_PARAMS_ERL)); 1305 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb, 1306 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1307 dde) / 32] & OFFLD_PARAMS_DDE) >> 2); 1308 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb, 1309 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1310 hde) / 32] & OFFLD_PARAMS_HDE) >> 3); 1311 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb, 1312 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1313 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4); 1314 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb, 1315 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1316 imd) / 32] & OFFLD_PARAMS_IMD) >> 5); 1317 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn, 1318 pwrb, 1319 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1320 exp_statsn) / 32] + 1)); 1321 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx, 1322 pwrb, pwrb_handle->wrb_index); 1323 1324 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1325 max_burst_length, pwrb, params->dw[offsetof 1326 (struct amap_beiscsi_offload_params, 1327 max_burst_length) / 32]); 1328 1329 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb, 1330 pwrb, pwrb_handle->wrb_index); 1331 if (pwrb_context->plast_wrb) 1332 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1333 ptr2nextwrb, 1334 pwrb_context->plast_wrb, 1335 pwrb_handle->wrb_index); 1336 pwrb_context->plast_wrb = pwrb; 1337 1338 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1339 session_state, pwrb, 0); 1340 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack, 1341 pwrb, 1); 1342 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq, 1343 pwrb, 0); 1344 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb, 1345 0); 1346 1347 mem_descr += ISCSI_MEM_GLOBAL_HEADER; 1348 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1349 pad_buffer_addr_hi, pwrb, 1350 mem_descr->mem_array[0].bus_address.u.a32.address_hi); 1351 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, 1352 pad_buffer_addr_lo, pwrb, 1353 mem_descr->mem_array[0].bus_address.u.a32.address_lo); 1354} 1355 1356void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, 1357 struct wrb_handle *pwrb_handle, 1358 struct hwi_wrb_context *pwrb_context) 1359{ 1360 struct iscsi_wrb *pwrb = pwrb_handle->pwrb; 1361 1362 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1363 max_burst_length, pwrb, params->dw[offsetof 1364 (struct amap_beiscsi_offload_params, 1365 max_burst_length) / 32]); 1366 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1367 type, pwrb, 1368 BE_TGT_CTX_UPDT_CMD); 1369 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1370 ptr2nextwrb, 1371 pwrb, pwrb_handle->wrb_index); 1372 if (pwrb_context->plast_wrb) 1373 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1374 ptr2nextwrb, 1375 pwrb_context->plast_wrb, 1376 pwrb_handle->wrb_index); 1377 pwrb_context->plast_wrb = pwrb; 1378 1379 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx, 1380 pwrb, pwrb_handle->wrb_index); 1381 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1382 max_send_data_segment_length, pwrb, 1383 params->dw[offsetof(struct amap_beiscsi_offload_params, 1384 max_send_data_segment_length) / 32]); 1385 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1386 first_burst_length, pwrb, 1387 params->dw[offsetof(struct amap_beiscsi_offload_params, 1388 first_burst_length) / 32]); 1389 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1390 max_recv_dataseg_len, pwrb, 1391 params->dw[offsetof(struct amap_beiscsi_offload_params, 1392 max_recv_data_segment_length) / 32]); 1393 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1394 max_cxns, pwrb, BEISCSI_MAX_CXNS); 1395 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb, 1396 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1397 erl) / 32] & OFFLD_PARAMS_ERL)); 1398 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb, 1399 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1400 dde) / 32] & OFFLD_PARAMS_DDE) >> 2); 1401 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb, 1402 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1403 hde) / 32] & OFFLD_PARAMS_HDE) >> 3); 1404 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1405 ir2t, pwrb, 1406 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1407 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4); 1408 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb, 1409 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1410 imd) / 32] & OFFLD_PARAMS_IMD) >> 5); 1411 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1412 data_seq_inorder, 1413 pwrb, 1414 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1415 data_seq_inorder) / 32] & 1416 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6); 1417 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, 1418 pdu_seq_inorder, 1419 pwrb, 1420 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1421 pdu_seq_inorder) / 32] & 1422 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7); 1423 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t, 1424 pwrb, 1425 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1426 max_r2t) / 32] & 1427 OFFLD_PARAMS_MAX_R2T) >> 8); 1428 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn, 1429 pwrb, 1430 (params->dw[offsetof(struct amap_beiscsi_offload_params, 1431 exp_statsn) / 32] + 1)); 1432} 1433 1434unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba, 1435 struct beiscsi_endpoint *beiscsi_ep) 1436{ 1437 struct be_invalidate_connection_params_in *req; 1438 struct be_ctrl_info *ctrl = &phba->ctrl; 1439 struct be_mcc_wrb *wrb; 1440 unsigned int tag = 0; 1441 1442 mutex_lock(&ctrl->mbox_lock); 1443 wrb = alloc_mcc_wrb(phba, &tag); 1444 if (!wrb) { 1445 mutex_unlock(&ctrl->mbox_lock); 1446 return 0; 1447 } 1448 1449 req = embedded_payload(wrb); 1450 be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params), 1451 true, 0); 1452 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 1453 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION, 1454 sizeof(*req)); 1455 req->session_handle = beiscsi_ep->fw_handle; 1456 req->cid = beiscsi_ep->ep_cid; 1457 if (beiscsi_ep->conn) 1458 req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE; 1459 else 1460 req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST; 1461 /** 1462 * 0 - non-persistent targets 1463 * 1 - save session info on flash 1464 */ 1465 req->save_cfg = 0; 1466 be_mcc_notify(phba, tag); 1467 mutex_unlock(&ctrl->mbox_lock); 1468 return tag; 1469} 1470 1471unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba, 1472 struct beiscsi_endpoint *beiscsi_ep) 1473{ 1474 struct be_ctrl_info *ctrl = &phba->ctrl; 1475 struct be_mcc_wrb *wrb; 1476 struct be_tcp_upload_params_in *req; 1477 unsigned int tag; 1478 1479 mutex_lock(&ctrl->mbox_lock); 1480 wrb = alloc_mcc_wrb(phba, &tag); 1481 if (!wrb) { 1482 mutex_unlock(&ctrl->mbox_lock); 1483 return 0; 1484 } 1485 1486 req = embedded_payload(wrb); 1487 be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0); 1488 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD, 1489 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req)); 1490 req->id = beiscsi_ep->ep_cid; 1491 if (beiscsi_ep->conn) 1492 req->upload_type = BE_UPLOAD_TYPE_GRACEFUL; 1493 else 1494 req->upload_type = BE_UPLOAD_TYPE_ABORT; 1495 be_mcc_notify(phba, tag); 1496 mutex_unlock(&ctrl->mbox_lock); 1497 return tag; 1498} 1499 1500int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba, 1501 struct invldt_cmd_tbl *inv_tbl, 1502 unsigned int nents) 1503{ 1504 struct be_ctrl_info *ctrl = &phba->ctrl; 1505 struct invldt_cmds_params_in *req; 1506 struct be_dma_mem nonemb_cmd; 1507 struct be_mcc_wrb *wrb; 1508 unsigned int i, tag; 1509 struct be_sge *sge; 1510 int rc; 1511 1512 if (!nents || nents > BE_INVLDT_CMD_TBL_SZ) 1513 return -EINVAL; 1514 1515 nonemb_cmd.size = sizeof(union be_invldt_cmds_params); 1516 nonemb_cmd.va = dma_alloc_coherent(&phba->ctrl.pdev->dev, 1517 nonemb_cmd.size, &nonemb_cmd.dma, 1518 GFP_KERNEL); 1519 if (!nonemb_cmd.va) { 1520 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, 1521 "BM_%d : invldt_cmds_params alloc failed\n"); 1522 return -ENOMEM; 1523 } 1524 1525 mutex_lock(&ctrl->mbox_lock); 1526 wrb = alloc_mcc_wrb(phba, &tag); 1527 if (!wrb) { 1528 mutex_unlock(&ctrl->mbox_lock); 1529 dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size, 1530 nonemb_cmd.va, nonemb_cmd.dma); 1531 return -ENOMEM; 1532 } 1533 1534 req = nonemb_cmd.va; 1535 be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1); 1536 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 1537 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS, 1538 sizeof(*req)); 1539 req->ref_handle = 0; 1540 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE; 1541 for (i = 0; i < nents; i++) { 1542 req->table[i].icd = inv_tbl[i].icd; 1543 req->table[i].cid = inv_tbl[i].cid; 1544 req->icd_count++; 1545 } 1546 sge = nonembedded_sgl(wrb); 1547 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma)); 1548 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma)); 1549 sge->len = cpu_to_le32(nonemb_cmd.size); 1550 1551 be_mcc_notify(phba, tag); 1552 mutex_unlock(&ctrl->mbox_lock); 1553 1554 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); 1555 if (rc != -EBUSY) 1556 dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size, 1557 nonemb_cmd.va, nonemb_cmd.dma); 1558 return rc; 1559}