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