Merge branch 'parisc-4.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux-2.6-block.git] / drivers / scsi / be2iscsi / be_mgmt.c
CommitLineData
6733b39a 1/**
c4f39bda 2 * Copyright (C) 2005 - 2015 Emulex
6733b39a
JK
3 * All rights reserved.
4 *
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.
9 *
4627de93 10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com)
6733b39a
JK
11 *
12 * Contact Information:
4627de93 13 * linux-drivers@avagotech.com
6733b39a 14 *
c4f39bda 15 * Emulex
255fa9a3
JK
16 * 3333 Susan Street
17 * Costa Mesa, CA 92626
6733b39a
JK
18 */
19
ffce3e2e
JK
20#include <linux/bsg-lib.h>
21#include <scsi/scsi_transport_iscsi.h>
22#include <scsi/scsi_bsg_iscsi.h>
6733b39a
JK
23#include "be_mgmt.h"
24#include "be_iscsi.h"
7a158003
JSJ
25#include "be_main.h"
26
27/* UE Status Low CSR */
28static const char * const desc_ue_status_low[] = {
29 "CEV",
30 "CTX",
31 "DBUF",
32 "ERX",
33 "Host",
34 "MPU",
35 "NDMA",
36 "PTC ",
37 "RDMA ",
38 "RXF ",
39 "RXIPS ",
40 "RXULP0 ",
41 "RXULP1 ",
42 "RXULP2 ",
43 "TIM ",
44 "TPOST ",
45 "TPRE ",
46 "TXIPS ",
47 "TXULP0 ",
48 "TXULP1 ",
49 "UC ",
50 "WDMA ",
51 "TXULP2 ",
52 "HOST1 ",
53 "P0_OB_LINK ",
54 "P1_OB_LINK ",
55 "HOST_GPIO ",
56 "MBOX ",
57 "AXGMAC0",
58 "AXGMAC1",
59 "JTAG",
60 "MPU_INTPEND"
61};
62
63/* UE Status High CSR */
64static const char * const desc_ue_status_hi[] = {
65 "LPCMEMHOST",
66 "MGMT_MAC",
67 "PCS0ONLINE",
68 "MPU_IRAM",
69 "PCS1ONLINE",
70 "PCTL0",
71 "PCTL1",
72 "PMEM",
73 "RR",
74 "TXPB",
75 "RXPP",
76 "XAUI",
77 "TXP",
78 "ARM",
79 "IPC",
80 "HOST2",
81 "HOST3",
82 "HOST4",
83 "HOST5",
84 "HOST6",
85 "HOST7",
86 "HOST8",
87 "HOST9",
88 "NETC",
89 "Unknown",
90 "Unknown",
91 "Unknown",
92 "Unknown",
93 "Unknown",
94 "Unknown",
95 "Unknown",
96 "Unknown"
97};
98
99/*
100 * beiscsi_ue_detec()- Detect Unrecoverable Error on adapter
101 * @phba: Driver priv structure
102 *
103 * Read registers linked to UE and check for the UE status
104 **/
105void beiscsi_ue_detect(struct beiscsi_hba *phba)
106{
107 uint32_t ue_hi = 0, ue_lo = 0;
108 uint32_t ue_mask_hi = 0, ue_mask_lo = 0;
109 uint8_t i = 0;
110
111 if (phba->ue_detected)
112 return;
113
114 pci_read_config_dword(phba->pcidev,
115 PCICFG_UE_STATUS_LOW, &ue_lo);
116 pci_read_config_dword(phba->pcidev,
117 PCICFG_UE_STATUS_MASK_LOW,
118 &ue_mask_lo);
119 pci_read_config_dword(phba->pcidev,
120 PCICFG_UE_STATUS_HIGH,
121 &ue_hi);
122 pci_read_config_dword(phba->pcidev,
123 PCICFG_UE_STATUS_MASK_HI,
124 &ue_mask_hi);
125
126 ue_lo = (ue_lo & ~ue_mask_lo);
127 ue_hi = (ue_hi & ~ue_mask_hi);
128
129
130 if (ue_lo || ue_hi) {
131 phba->ue_detected = true;
132 beiscsi_log(phba, KERN_ERR,
133 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
134 "BG_%d : Error detected on the adapter\n");
135 }
136
137 if (ue_lo) {
138 for (i = 0; ue_lo; ue_lo >>= 1, i++) {
139 if (ue_lo & 1)
140 beiscsi_log(phba, KERN_ERR,
141 BEISCSI_LOG_CONFIG,
142 "BG_%d : UE_LOW %s bit set\n",
143 desc_ue_status_low[i]);
144 }
145 }
146
147 if (ue_hi) {
148 for (i = 0; ue_hi; ue_hi >>= 1, i++) {
149 if (ue_hi & 1)
150 beiscsi_log(phba, KERN_ERR,
151 BEISCSI_LOG_CONFIG,
152 "BG_%d : UE_HIGH %s bit set\n",
153 desc_ue_status_hi[i]);
154 }
155 }
156}
c7acc5b8 157
73af08e1
JK
158int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
159 struct be_set_eqd *set_eqd, int num)
160{
161 struct be_ctrl_info *ctrl = &phba->ctrl;
162 struct be_mcc_wrb *wrb;
163 struct be_cmd_req_modify_eq_delay *req;
090e2184 164 unsigned int tag;
73af08e1
JK
165 int i;
166
c03a50f7 167 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
168 wrb = alloc_mcc_wrb(phba, &tag);
169 if (!wrb) {
c03a50f7 170 mutex_unlock(&ctrl->mbox_lock);
090e2184 171 return 0;
73af08e1
JK
172 }
173
73af08e1 174 req = embedded_payload(wrb);
73af08e1
JK
175 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
176 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
177 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
178
179 req->num_eq = cpu_to_le32(num);
180 for (i = 0; i < num; i++) {
181 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
182 req->delay[i].phase = 0;
183 req->delay[i].delay_multiplier =
184 cpu_to_le32(set_eqd[i].delay_multiplier);
185 }
186
cdde6682 187 be_mcc_notify(phba, tag);
c03a50f7 188 mutex_unlock(&ctrl->mbox_lock);
73af08e1
JK
189 return tag;
190}
191
9aef4200
JSJ
192/**
193 * mgmt_reopen_session()- Reopen a session based on reopen_type
194 * @phba: Device priv structure instance
195 * @reopen_type: Type of reopen_session FW should do.
196 * @sess_handle: Session Handle of the session to be re-opened
197 *
198 * return
199 * the TAG used for MBOX Command
200 *
201 **/
202unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
203 unsigned int reopen_type,
204 unsigned int sess_handle)
205{
206 struct be_ctrl_info *ctrl = &phba->ctrl;
207 struct be_mcc_wrb *wrb;
208 struct be_cmd_reopen_session_req *req;
090e2184 209 unsigned int tag;
9aef4200 210
99bc5d55
JSJ
211 beiscsi_log(phba, KERN_INFO,
212 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
213 "BG_%d : In bescsi_get_boot_target\n");
214
c03a50f7 215 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
216 wrb = alloc_mcc_wrb(phba, &tag);
217 if (!wrb) {
c03a50f7 218 mutex_unlock(&ctrl->mbox_lock);
090e2184 219 return 0;
9aef4200
JSJ
220 }
221
9aef4200 222 req = embedded_payload(wrb);
9aef4200
JSJ
223 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
224 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
225 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
226 sizeof(struct be_cmd_reopen_session_resp));
227
228 /* set the reopen_type,sess_handle */
229 req->reopen_type = reopen_type;
230 req->session_handle = sess_handle;
231
cdde6682 232 be_mcc_notify(phba, tag);
c03a50f7 233 mutex_unlock(&ctrl->mbox_lock);
9aef4200
JSJ
234 return tag;
235}
236
0e43895e 237unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
c7acc5b8
JK
238{
239 struct be_ctrl_info *ctrl = &phba->ctrl;
240 struct be_mcc_wrb *wrb;
0e43895e 241 struct be_cmd_get_boot_target_req *req;
090e2184 242 unsigned int tag;
c7acc5b8 243
99bc5d55
JSJ
244 beiscsi_log(phba, KERN_INFO,
245 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
246 "BG_%d : In bescsi_get_boot_target\n");
247
c03a50f7 248 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
249 wrb = alloc_mcc_wrb(phba, &tag);
250 if (!wrb) {
c03a50f7 251 mutex_unlock(&ctrl->mbox_lock);
090e2184 252 return 0;
c7acc5b8
JK
253 }
254
c7acc5b8 255 req = embedded_payload(wrb);
c7acc5b8
JK
256 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
257 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
258 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
0e43895e 259 sizeof(struct be_cmd_get_boot_target_resp));
c7acc5b8 260
cdde6682 261 be_mcc_notify(phba, tag);
c03a50f7 262 mutex_unlock(&ctrl->mbox_lock);
c7acc5b8
JK
263 return tag;
264}
265
0e43895e
MC
266unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
267 u32 boot_session_handle,
268 struct be_dma_mem *nonemb_cmd)
c7acc5b8
JK
269{
270 struct be_ctrl_info *ctrl = &phba->ctrl;
271 struct be_mcc_wrb *wrb;
090e2184 272 unsigned int tag;
0e43895e
MC
273 struct be_cmd_get_session_req *req;
274 struct be_cmd_get_session_resp *resp;
c7acc5b8
JK
275 struct be_sge *sge;
276
99bc5d55
JSJ
277 beiscsi_log(phba, KERN_INFO,
278 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
279 "BG_%d : In beiscsi_get_session_info\n");
280
c03a50f7 281 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
282 wrb = alloc_mcc_wrb(phba, &tag);
283 if (!wrb) {
c03a50f7 284 mutex_unlock(&ctrl->mbox_lock);
090e2184 285 return 0;
c7acc5b8
JK
286 }
287
288 nonemb_cmd->size = sizeof(*resp);
289 req = nonemb_cmd->va;
290 memset(req, 0, sizeof(*req));
c7acc5b8 291 sge = nonembedded_sgl(wrb);
c7acc5b8
JK
292 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
293 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
294 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
295 sizeof(*resp));
296 req->session_handle = boot_session_handle;
297 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
298 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
299 sge->len = cpu_to_le32(nonemb_cmd->size);
300
cdde6682 301 be_mcc_notify(phba, tag);
c03a50f7 302 mutex_unlock(&ctrl->mbox_lock);
c7acc5b8
JK
303 return tag;
304}
6733b39a 305
53aefe25
JB
306/**
307 * mgmt_get_port_name()- Get port name for the function
308 * @ctrl: ptr to Ctrl Info
309 * @phba: ptr to the dev priv structure
310 *
311 * Get the alphanumeric character for port
312 *
313 **/
314int mgmt_get_port_name(struct be_ctrl_info *ctrl,
315 struct beiscsi_hba *phba)
316{
317 int ret = 0;
318 struct be_mcc_wrb *wrb;
319 struct be_cmd_get_port_name *ioctl;
320
321 mutex_lock(&ctrl->mbox_lock);
322 wrb = wrb_from_mbox(&ctrl->mbox_mem);
323 memset(wrb, 0, sizeof(*wrb));
324 ioctl = embedded_payload(wrb);
325
326 be_wrb_hdr_prepare(wrb, sizeof(*ioctl), true, 0);
327 be_cmd_hdr_prepare(&ioctl->h.req_hdr, CMD_SUBSYSTEM_COMMON,
328 OPCODE_COMMON_GET_PORT_NAME,
329 EMBED_MBX_MAX_PAYLOAD_SIZE);
330 ret = be_mbox_notify(ctrl);
331 phba->port_name = 0;
332 if (!ret) {
333 phba->port_name = ioctl->p.resp.port_names >>
334 (phba->fw_config.phys_port * 8) & 0xff;
335 } else {
336 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
337 "BG_%d : GET_PORT_NAME ret 0x%x status 0x%x\n",
338 ret, ioctl->h.resp_hdr.status);
339 }
340
341 if (phba->port_name == 0)
342 phba->port_name = '?';
343
344 mutex_unlock(&ctrl->mbox_lock);
345 return ret;
346}
347
843ae752
JK
348/**
349 * mgmt_get_fw_config()- Get the FW config for the function
350 * @ctrl: ptr to Ctrl Info
351 * @phba: ptr to the dev priv structure
352 *
353 * Get the FW config and resources available for the function.
354 * The resources are created based on the count received here.
355 *
356 * return
357 * Success: 0
358 * Failure: Non-Zero Value
359 **/
03a12310 360int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
6733b39a
JK
361 struct beiscsi_hba *phba)
362{
363 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
4570f161
JB
364 struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
365 uint32_t cid_count, icd_count;
366 int status = -EINVAL;
367 uint8_t ulp_num = 0;
6733b39a 368
c03a50f7 369 mutex_lock(&ctrl->mbox_lock);
6733b39a 370 memset(wrb, 0, sizeof(*wrb));
4570f161 371 be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
6733b39a 372
4570f161 373 be_cmd_hdr_prepare(&pfw_cfg->hdr, CMD_SUBSYSTEM_COMMON,
843ae752
JK
374 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
375 EMBED_MBX_MAX_PAYLOAD_SIZE);
4570f161
JB
376
377 if (be_mbox_notify(ctrl)) {
378 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
379 "BG_%d : Failed in mgmt_get_fw_config\n");
380 goto fail_init;
381 }
382
383 /* FW response formats depend on port id */
384 phba->fw_config.phys_port = pfw_cfg->phys_port;
385 if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
386 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
387 "BG_%d : invalid physical port id %d\n",
388 phba->fw_config.phys_port);
389 goto fail_init;
390 }
391
392 /* populate and check FW config against min and max values */
393 if (!is_chip_be2_be3r(phba)) {
394 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
395 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
396 if (phba->fw_config.eqid_count == 0 ||
397 phba->fw_config.eqid_count > 2048) {
398 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
399 "BG_%d : invalid EQ count %d\n",
400 phba->fw_config.eqid_count);
401 goto fail_init;
402 }
403 if (phba->fw_config.cqid_count == 0 ||
404 phba->fw_config.cqid_count > 4096) {
405 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
406 "BG_%d : invalid CQ count %d\n",
68c26a3a 407 phba->fw_config.cqid_count);
4570f161 408 goto fail_init;
68c26a3a 409 }
4570f161
JB
410 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
411 "BG_%d : EQ_Count : %d CQ_Count : %d\n",
412 phba->fw_config.eqid_count,
413 phba->fw_config.cqid_count);
414 }
68c26a3a 415
4570f161
JB
416 /**
417 * Check on which all ULP iSCSI Protocol is loaded.
418 * Set the Bit for those ULP. This set flag is used
419 * at all places in the code to check on which ULP
420 * iSCSi Protocol is loaded
421 **/
422 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
423 if (pfw_cfg->ulp[ulp_num].ulp_mode &
424 BEISCSI_ULP_ISCSI_INI_MODE) {
425 set_bit(ulp_num, &phba->fw_config.ulp_supported);
426
427 /* Get the CID, ICD and Chain count for each ULP */
428 phba->fw_config.iscsi_cid_start[ulp_num] =
429 pfw_cfg->ulp[ulp_num].sq_base;
430 phba->fw_config.iscsi_cid_count[ulp_num] =
431 pfw_cfg->ulp[ulp_num].sq_count;
432
433 phba->fw_config.iscsi_icd_start[ulp_num] =
434 pfw_cfg->ulp[ulp_num].icd_base;
435 phba->fw_config.iscsi_icd_count[ulp_num] =
436 pfw_cfg->ulp[ulp_num].icd_count;
437
438 phba->fw_config.iscsi_chain_start[ulp_num] =
439 pfw_cfg->chain_icd[ulp_num].chain_base;
440 phba->fw_config.iscsi_chain_count[ulp_num] =
441 pfw_cfg->chain_icd[ulp_num].chain_count;
442
443 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
444 "BG_%d : Function loaded on ULP : %d\n"
445 "\tiscsi_cid_count : %d\n"
446 "\tiscsi_cid_start : %d\n"
447 "\t iscsi_icd_count : %d\n"
448 "\t iscsi_icd_start : %d\n",
449 ulp_num,
450 phba->fw_config.
451 iscsi_cid_count[ulp_num],
452 phba->fw_config.
453 iscsi_cid_start[ulp_num],
454 phba->fw_config.
455 iscsi_icd_count[ulp_num],
456 phba->fw_config.
457 iscsi_icd_start[ulp_num]);
7da50879 458 }
4570f161 459 }
843ae752 460
4570f161
JB
461 if (phba->fw_config.ulp_supported == 0) {
462 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
463 "BG_%d : iSCSI initiator mode not set: ULP0 %x ULP1 %x\n",
464 pfw_cfg->ulp[BEISCSI_ULP0].ulp_mode,
465 pfw_cfg->ulp[BEISCSI_ULP1].ulp_mode);
466 goto fail_init;
467 }
843ae752 468
4570f161
JB
469 /**
470 * ICD is shared among ULPs. Use icd_count of any one loaded ULP
471 **/
472 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
473 if (test_bit(ulp_num, &phba->fw_config.ulp_supported))
474 break;
475 icd_count = phba->fw_config.iscsi_icd_count[ulp_num];
476 if (icd_count == 0 || icd_count > 65536) {
477 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
478 "BG_%d: invalid ICD count %d\n", icd_count);
479 goto fail_init;
480 }
843ae752 481
4570f161
JB
482 cid_count = BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP0) +
483 BEISCSI_GET_CID_COUNT(phba, BEISCSI_ULP1);
484 if (cid_count == 0 || cid_count > 4096) {
843ae752 485 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
4570f161
JB
486 "BG_%d: invalid CID count %d\n", cid_count);
487 goto fail_init;
6733b39a
JK
488 }
489
4570f161
JB
490 /**
491 * Check FW is dual ULP aware i.e. can handle either
492 * of the protocols.
493 */
494 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
495 BEISCSI_FUNC_DUA_MODE);
496
497 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
498 "BG_%d : DUA Mode : 0x%x\n",
499 phba->fw_config.dual_ulp_aware);
500
501 /* all set, continue using this FW config */
502 status = 0;
503fail_init:
c03a50f7 504 mutex_unlock(&ctrl->mbox_lock);
6733b39a
JK
505 return status;
506}
507
03a12310 508int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
bfead3b2 509 struct beiscsi_hba *phba)
6733b39a
JK
510{
511 struct be_dma_mem nonemb_cmd;
512 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
513 struct be_mgmt_controller_attributes *req;
514 struct be_sge *sge = nonembedded_sgl(wrb);
515 int status = 0;
516
517 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
518 sizeof(struct be_mgmt_controller_attributes),
519 &nonemb_cmd.dma);
520 if (nonemb_cmd.va == NULL) {
99bc5d55
JSJ
521 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
522 "BG_%d : Failed to allocate memory for "
523 "mgmt_check_supported_fw\n");
d3ad2bb3 524 return -ENOMEM;
6733b39a
JK
525 }
526 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
527 req = nonemb_cmd.va;
f98c96b0 528 memset(req, 0, sizeof(*req));
c03a50f7 529 mutex_lock(&ctrl->mbox_lock);
6733b39a
JK
530 memset(wrb, 0, sizeof(*wrb));
531 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
532 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
533 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
534 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
535 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
536 sge->len = cpu_to_le32(nonemb_cmd.size);
6733b39a
JK
537 status = be_mbox_notify(ctrl);
538 if (!status) {
539 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
99bc5d55
JSJ
540 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
541 "BG_%d : Firmware Version of CMD : %s\n"
542 "Firmware Version is : %s\n"
543 "Developer Build, not performing version check...\n",
544 resp->params.hba_attribs
545 .flashrom_version_string,
546 resp->params.hba_attribs.
547 firmware_version_string);
548
bfead3b2
JK
549 phba->fw_config.iscsi_features =
550 resp->params.hba_attribs.iscsi_features;
99bc5d55
JSJ
551 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
552 "BM_%d : phba->fw_config.iscsi_features = %d\n",
553 phba->fw_config.iscsi_features);
22661e25
JK
554 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
555 firmware_version_string, BEISCSI_VER_STRLEN);
6733b39a 556 } else
99bc5d55
JSJ
557 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
558 "BG_%d : Failed in mgmt_check_supported_fw\n");
c03a50f7 559 mutex_unlock(&ctrl->mbox_lock);
6733b39a
JK
560 if (nonemb_cmd.va)
561 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
562 nonemb_cmd.va, nonemb_cmd.dma);
563
6733b39a
JK
564 return status;
565}
566
ffce3e2e
JK
567unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
568 struct beiscsi_hba *phba,
569 struct bsg_job *job,
570 struct be_dma_mem *nonemb_cmd)
571{
572 struct be_cmd_resp_hdr *resp;
daa8dc08
JK
573 struct be_mcc_wrb *wrb;
574 struct be_sge *mcc_sge;
ffce3e2e
JK
575 unsigned int tag = 0;
576 struct iscsi_bsg_request *bsg_req = job->request;
577 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
578 unsigned short region, sector_size, sector, offset;
579
580 nonemb_cmd->size = job->request_payload.payload_len;
581 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
582 resp = nonemb_cmd->va;
583 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
584 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
585 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
586 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
587 req->region = region;
588 req->sector = sector;
589 req->offset = offset;
ffce3e2e 590
c03a50f7
JB
591 if (mutex_lock_interruptible(&ctrl->mbox_lock))
592 return 0;
ffce3e2e
JK
593 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
594 case BEISCSI_WRITE_FLASH:
595 offset = sector * sector_size + offset;
596 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
597 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
598 sg_copy_to_buffer(job->request_payload.sg_list,
599 job->request_payload.sg_cnt,
600 nonemb_cmd->va + offset, job->request_len);
601 break;
602 case BEISCSI_READ_FLASH:
603 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
604 OPCODE_COMMON_READ_FLASH, sizeof(*req));
605 break;
606 default:
99bc5d55
JSJ
607 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
608 "BG_%d : Unsupported cmd = 0x%x\n\n",
609 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
610
c03a50f7 611 mutex_unlock(&ctrl->mbox_lock);
ffce3e2e
JK
612 return -ENOSYS;
613 }
614
090e2184
JB
615 wrb = alloc_mcc_wrb(phba, &tag);
616 if (!wrb) {
c03a50f7 617 mutex_unlock(&ctrl->mbox_lock);
090e2184 618 return 0;
ffce3e2e
JK
619 }
620
daa8dc08 621 mcc_sge = nonembedded_sgl(wrb);
ffce3e2e
JK
622 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
623 job->request_payload.sg_cnt);
624 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
625 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
626 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
ffce3e2e 627
cdde6682 628 be_mcc_notify(phba, tag);
ffce3e2e 629
c03a50f7 630 mutex_unlock(&ctrl->mbox_lock);
ffce3e2e
JK
631 return tag;
632}
633
bd41c2bd
JK
634/**
635 * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
636 * @phba: pointer to dev priv structure
637 * @ulp_num: ULP number.
638 *
639 * return
640 * Success: 0
641 * Failure: Non-Zero Value
642 **/
643int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
6733b39a
JK
644{
645 struct be_ctrl_info *ctrl = &phba->ctrl;
090e2184
JB
646 struct be_mcc_wrb *wrb;
647 struct iscsi_cleanup_req *req;
cdde6682
JB
648 unsigned int tag;
649 int status;
6733b39a 650
c03a50f7 651 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
652 wrb = alloc_mcc_wrb(phba, &tag);
653 if (!wrb) {
cdde6682
JB
654 mutex_unlock(&ctrl->mbox_lock);
655 return -EBUSY;
656 }
6733b39a 657
090e2184 658 req = embedded_payload(wrb);
6733b39a
JK
659 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
660 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
661 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
662
bd41c2bd
JK
663 req->chute = (1 << ulp_num);
664 req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
665 req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
6733b39a 666
2e4e8f65
JB
667 be_mcc_notify(phba, tag);
668 status = be_mcc_compl_poll(phba, tag);
6733b39a 669 if (status)
99bc5d55
JSJ
670 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
671 "BG_%d : mgmt_epfw_cleanup , FAILED\n");
c03a50f7 672 mutex_unlock(&ctrl->mbox_lock);
6733b39a
JK
673 return status;
674}
675
03a12310 676unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
4183122d 677 struct invalidate_command_table *inv_tbl,
3cbb7a74
JK
678 unsigned int num_invalidate, unsigned int cid,
679 struct be_dma_mem *nonemb_cmd)
680
6733b39a 681{
6733b39a 682 struct be_ctrl_info *ctrl = &phba->ctrl;
756d29c8
JK
683 struct be_mcc_wrb *wrb;
684 struct be_sge *sge;
6733b39a 685 struct invalidate_commands_params_in *req;
090e2184 686 unsigned int i, tag;
756d29c8 687
c03a50f7 688 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
689 wrb = alloc_mcc_wrb(phba, &tag);
690 if (!wrb) {
c03a50f7 691 mutex_unlock(&ctrl->mbox_lock);
090e2184 692 return 0;
756d29c8 693 }
6733b39a 694
3cbb7a74 695 req = nonemb_cmd->va;
f98c96b0 696 memset(req, 0, sizeof(*req));
756d29c8 697 sge = nonembedded_sgl(wrb);
6733b39a
JK
698
699 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
700 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
701 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
702 sizeof(*req));
703 req->ref_handle = 0;
704 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
4183122d
JK
705 for (i = 0; i < num_invalidate; i++) {
706 req->table[i].icd = inv_tbl->icd;
707 req->table[i].cid = inv_tbl->cid;
708 req->icd_count++;
709 inv_tbl++;
710 }
3cbb7a74
JK
711 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
712 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
713 sge->len = cpu_to_le32(nonemb_cmd->size);
6733b39a 714
cdde6682 715 be_mcc_notify(phba, tag);
c03a50f7 716 mutex_unlock(&ctrl->mbox_lock);
756d29c8 717 return tag;
6733b39a
JK
718}
719
03a12310 720unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
6733b39a
JK
721 struct beiscsi_endpoint *beiscsi_ep,
722 unsigned short cid,
723 unsigned short issue_reset,
724 unsigned short savecfg_flag)
725{
726 struct be_ctrl_info *ctrl = &phba->ctrl;
756d29c8
JK
727 struct be_mcc_wrb *wrb;
728 struct iscsi_invalidate_connection_params_in *req;
729 unsigned int tag = 0;
6733b39a 730
c03a50f7 731 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
732 wrb = alloc_mcc_wrb(phba, &tag);
733 if (!wrb) {
c03a50f7 734 mutex_unlock(&ctrl->mbox_lock);
090e2184 735 return 0;
756d29c8 736 }
6733b39a 737
090e2184 738 req = embedded_payload(wrb);
6733b39a
JK
739 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
740 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
741 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
742 sizeof(*req));
743 req->session_handle = beiscsi_ep->fw_handle;
744 req->cid = cid;
745 if (issue_reset)
746 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
747 else
748 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
749 req->save_cfg = savecfg_flag;
cdde6682 750 be_mcc_notify(phba, tag);
c03a50f7 751 mutex_unlock(&ctrl->mbox_lock);
756d29c8 752 return tag;
6733b39a
JK
753}
754
03a12310 755unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
6733b39a
JK
756 unsigned short cid, unsigned int upload_flag)
757{
758 struct be_ctrl_info *ctrl = &phba->ctrl;
756d29c8
JK
759 struct be_mcc_wrb *wrb;
760 struct tcp_upload_params_in *req;
090e2184 761 unsigned int tag;
6733b39a 762
c03a50f7 763 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
764 wrb = alloc_mcc_wrb(phba, &tag);
765 if (!wrb) {
c03a50f7 766 mutex_unlock(&ctrl->mbox_lock);
090e2184 767 return 0;
756d29c8 768 }
6733b39a 769
090e2184 770 req = embedded_payload(wrb);
6733b39a
JK
771 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
772 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
773 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
774 req->id = (unsigned short)cid;
775 req->upload_type = (unsigned char)upload_flag;
cdde6682 776 be_mcc_notify(phba, tag);
c03a50f7 777 mutex_unlock(&ctrl->mbox_lock);
756d29c8 778 return tag;
6733b39a
JK
779}
780
1e4be6ff
JK
781/**
782 * mgmt_open_connection()- Establish a TCP CXN
783 * @dst_addr: Destination Address
784 * @beiscsi_ep: ptr to device endpoint struct
785 * @nonemb_cmd: ptr to memory allocated for command
786 *
787 * return
788 * Success: Tag number of the MBX Command issued
789 * Failure: Error code
790 **/
6733b39a
JK
791int mgmt_open_connection(struct beiscsi_hba *phba,
792 struct sockaddr *dst_addr,
3cbb7a74
JK
793 struct beiscsi_endpoint *beiscsi_ep,
794 struct be_dma_mem *nonemb_cmd)
6733b39a
JK
795{
796 struct hwi_controller *phwi_ctrlr;
797 struct hwi_context_memory *phwi_context;
798 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
799 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
800 struct be_ctrl_info *ctrl = &phba->ctrl;
756d29c8 801 struct be_mcc_wrb *wrb;
b3c202dc 802 struct tcp_connect_and_offload_in_v1 *req;
6733b39a
JK
803 unsigned short def_hdr_id;
804 unsigned short def_data_id;
805 struct phys_addr template_address = { 0, 0 };
806 struct phys_addr *ptemplate_address;
756d29c8 807 unsigned int tag = 0;
1e4be6ff 808 unsigned int i, ulp_num;
6733b39a 809 unsigned short cid = beiscsi_ep->ep_cid;
3cbb7a74 810 struct be_sge *sge;
6733b39a 811
291fef26
JB
812 if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
813 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
814 "BG_%d : unknown addr family %d\n",
815 dst_addr->sa_family);
816 return -EINVAL;
817 }
818
6733b39a
JK
819 phwi_ctrlr = phba->phwi_ctrlr;
820 phwi_context = phwi_ctrlr->phwi_ctxt;
1e4be6ff
JK
821
822 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
823
824 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
825 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
6733b39a
JK
826
827 ptemplate_address = &template_address;
828 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
c03a50f7
JB
829 if (mutex_lock_interruptible(&ctrl->mbox_lock))
830 return 0;
090e2184
JB
831 wrb = alloc_mcc_wrb(phba, &tag);
832 if (!wrb) {
c03a50f7 833 mutex_unlock(&ctrl->mbox_lock);
090e2184 834 return 0;
756d29c8 835 }
3cbb7a74 836
090e2184 837 sge = nonembedded_sgl(wrb);
3cbb7a74
JK
838 req = nonemb_cmd->va;
839 memset(req, 0, sizeof(*req));
6733b39a 840
b3c202dc 841 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
6733b39a
JK
842 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
843 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
b3c202dc 844 nonemb_cmd->size);
6733b39a
JK
845 if (dst_addr->sa_family == PF_INET) {
846 __be32 s_addr = daddr_in->sin_addr.s_addr;
847 req->ip_address.ip_type = BE2_IPV4;
0e43895e
MC
848 req->ip_address.addr[0] = s_addr & 0x000000ff;
849 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
850 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
851 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
6733b39a
JK
852 req->tcp_port = ntohs(daddr_in->sin_port);
853 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
854 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
855 beiscsi_ep->ip_type = BE2_IPV4;
291fef26
JB
856 } else {
857 /* else its PF_INET6 family */
6733b39a 858 req->ip_address.ip_type = BE2_IPV6;
0e43895e 859 memcpy(&req->ip_address.addr,
6733b39a
JK
860 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
861 req->tcp_port = ntohs(daddr_in6->sin6_port);
862 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
863 memcpy(&beiscsi_ep->dst6_addr,
864 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
865 beiscsi_ep->ip_type = BE2_IPV6;
6733b39a
JK
866 }
867 req->cid = cid;
bfead3b2
JK
868 i = phba->nxt_cqid++;
869 if (phba->nxt_cqid == phba->num_cpus)
870 phba->nxt_cqid = 0;
871 req->cq_id = phwi_context->be_cq[i].id;
99bc5d55
JSJ
872 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
873 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
6733b39a
JK
874 req->defq_id = def_hdr_id;
875 req->hdr_ring_id = def_hdr_id;
876 req->data_ring_id = def_data_id;
877 req->do_offload = 1;
878 req->dataout_template_pa.lo = ptemplate_address->lo;
879 req->dataout_template_pa.hi = ptemplate_address->hi;
3cbb7a74
JK
880 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
881 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
882 sge->len = cpu_to_le32(nonemb_cmd->size);
b3c202dc
JK
883
884 if (!is_chip_be2_be3r(phba)) {
885 req->hdr.version = MBX_CMD_VER1;
886 req->tcp_window_size = 0;
887 req->tcp_window_scale_count = 2;
888 }
889
cdde6682 890 be_mcc_notify(phba, tag);
c03a50f7 891 mutex_unlock(&ctrl->mbox_lock);
756d29c8 892 return tag;
6733b39a 893}
bfead3b2 894
0e43895e 895unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
bfead3b2
JK
896{
897 struct be_ctrl_info *ctrl = &phba->ctrl;
6ac999ef
JB
898 struct be_mcc_wrb *wrb;
899 struct be_cmd_get_all_if_id_req *req;
900 struct be_cmd_get_all_if_id_req *pbe_allid;
901 unsigned int tag;
0e43895e
MC
902 int status = 0;
903
c03a50f7
JB
904 if (mutex_lock_interruptible(&ctrl->mbox_lock))
905 return -EINTR;
090e2184
JB
906 wrb = alloc_mcc_wrb(phba, &tag);
907 if (!wrb) {
c03a50f7 908 mutex_unlock(&ctrl->mbox_lock);
6ac999ef
JB
909 return -ENOMEM;
910 }
911
6ac999ef 912 req = embedded_payload(wrb);
0e43895e
MC
913 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
914 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
915 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
916 sizeof(*req));
cdde6682 917 be_mcc_notify(phba, tag);
c03a50f7 918 mutex_unlock(&ctrl->mbox_lock);
6ac999ef 919
88840332 920 status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
6ac999ef 921 if (status) {
99bc5d55
JSJ
922 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
923 "BG_%d : Failed in mgmt_get_all_if_id\n");
6ac999ef 924 return -EBUSY;
0e43895e 925 }
6ac999ef
JB
926
927 pbe_allid = embedded_payload(wrb);
928 phba->interface_handle = pbe_allid->if_hndl_list[0];
0e43895e
MC
929
930 return status;
931}
932
e175defe
JSJ
933/*
934 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
935 * @phba: Driver priv structure
936 * @nonemb_cmd: Address of the MBX command issued
937 * @resp_buf: Buffer to copy the MBX cmd response
938 * @resp_buf_len: respone lenght to be copied
939 *
940 **/
0e43895e
MC
941static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
942 struct be_dma_mem *nonemb_cmd, void *resp_buf,
943 int resp_buf_len)
944{
945 struct be_ctrl_info *ctrl = &phba->ctrl;
daa8dc08 946 struct be_mcc_wrb *wrb;
0e43895e
MC
947 struct be_sge *sge;
948 unsigned int tag;
949 int rc = 0;
bfead3b2 950
c03a50f7 951 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
952 wrb = alloc_mcc_wrb(phba, &tag);
953 if (!wrb) {
c03a50f7 954 mutex_unlock(&ctrl->mbox_lock);
0e43895e
MC
955 rc = -ENOMEM;
956 goto free_cmd;
756d29c8 957 }
daa8dc08 958
0e43895e 959 sge = nonembedded_sgl(wrb);
0e43895e
MC
960 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
961 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
e175defe 962 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
0e43895e 963 sge->len = cpu_to_le32(nonemb_cmd->size);
bfead3b2 964
cdde6682 965 be_mcc_notify(phba, tag);
c03a50f7 966 mutex_unlock(&ctrl->mbox_lock);
0e43895e 967
88840332 968 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
1957aa7f
JK
969
970 if (resp_buf)
971 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
972
e175defe 973 if (rc) {
1957aa7f 974 /* Check if the MBX Cmd needs to be re-issued */
1f536d49
JK
975 if (rc == -EAGAIN)
976 return rc;
977
1957aa7f 978 beiscsi_log(phba, KERN_WARNING,
99bc5d55 979 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
e175defe
JSJ
980 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
981
1957aa7f
JK
982 if (rc != -EBUSY)
983 goto free_cmd;
984 else
985 return rc;
0e43895e 986 }
0e43895e
MC
987free_cmd:
988 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
989 nonemb_cmd->va, nonemb_cmd->dma);
990 return rc;
991}
992
993static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
994 int iscsi_cmd, int size)
995{
7c845eb5 996 cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
0e43895e 997 if (!cmd->va) {
99bc5d55
JSJ
998 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
999 "BG_%d : Failed to allocate memory for if info\n");
0e43895e
MC
1000 return -ENOMEM;
1001 }
0e43895e
MC
1002 cmd->size = size;
1003 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
1004 return 0;
bfead3b2
JK
1005}
1006
0e43895e
MC
1007static int
1008mgmt_static_ip_modify(struct beiscsi_hba *phba,
1009 struct be_cmd_get_if_info_resp *if_info,
1010 struct iscsi_iface_param_info *ip_param,
1011 struct iscsi_iface_param_info *subnet_param,
1012 uint32_t ip_action)
1013{
1014 struct be_cmd_set_ip_addr_req *req;
1015 struct be_dma_mem nonemb_cmd;
1016 uint32_t ip_type;
1017 int rc;
1018
1019 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1020 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
1021 sizeof(*req));
1022 if (rc)
1023 return rc;
1024
1025 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1026 BE2_IPV6 : BE2_IPV4 ;
1027
1028 req = nonemb_cmd.va;
1029 req->ip_params.record_entry_count = 1;
1030 req->ip_params.ip_record.action = ip_action;
1031 req->ip_params.ip_record.interface_hndl =
1032 phba->interface_handle;
1033 req->ip_params.ip_record.ip_addr.size_of_structure =
1034 sizeof(struct be_ip_addr_subnet_format);
1035 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
1036
1037 if (ip_action == IP_ACTION_ADD) {
1038 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
a41a9ad3 1039 sizeof(req->ip_params.ip_record.ip_addr.addr));
0e43895e
MC
1040
1041 if (subnet_param)
1042 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
a41a9ad3
MC
1043 subnet_param->value,
1044 sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
0e43895e
MC
1045 } else {
1046 memcpy(req->ip_params.ip_record.ip_addr.addr,
a41a9ad3
MC
1047 if_info->ip_addr.addr,
1048 sizeof(req->ip_params.ip_record.ip_addr.addr));
0e43895e
MC
1049
1050 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
a41a9ad3
MC
1051 if_info->ip_addr.subnet_mask,
1052 sizeof(req->ip_params.ip_record.ip_addr.subnet_mask));
0e43895e
MC
1053 }
1054
1055 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1056 if (rc < 0)
99bc5d55
JSJ
1057 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1058 "BG_%d : Failed to Modify existing IP Address\n");
0e43895e
MC
1059 return rc;
1060}
1061
1062static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
1063 uint32_t gtway_action, uint32_t param_len)
1064{
1065 struct be_cmd_set_def_gateway_req *req;
1066 struct be_dma_mem nonemb_cmd;
1067 int rt_val;
1068
1069
1070 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1071 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
1072 sizeof(*req));
1073 if (rt_val)
1074 return rt_val;
1075
1076 req = nonemb_cmd.va;
1077 req->action = gtway_action;
1078 req->ip_addr.ip_type = BE2_IPV4;
1079
a41a9ad3 1080 memcpy(req->ip_addr.addr, gt_addr, sizeof(req->ip_addr.addr));
0e43895e
MC
1081
1082 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1083}
1084
1085int mgmt_set_ip(struct beiscsi_hba *phba,
1086 struct iscsi_iface_param_info *ip_param,
1087 struct iscsi_iface_param_info *subnet_param,
1088 uint32_t boot_proto)
1089{
1090 struct be_cmd_get_def_gateway_resp gtway_addr_set;
1f536d49 1091 struct be_cmd_get_if_info_resp *if_info;
0e43895e
MC
1092 struct be_cmd_set_dhcp_req *dhcpreq;
1093 struct be_cmd_rel_dhcp_req *reldhcp;
1094 struct be_dma_mem nonemb_cmd;
1095 uint8_t *gtway_addr;
1096 uint32_t ip_type;
1097 int rc;
1098
3c9d903b
JB
1099 rc = mgmt_get_all_if_id(phba);
1100 if (rc)
1101 return rc;
0e43895e 1102
0e43895e
MC
1103 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1104 BE2_IPV6 : BE2_IPV4 ;
1105
1106 rc = mgmt_get_if_info(phba, ip_type, &if_info);
beff6549 1107 if (rc)
0e43895e
MC
1108 return rc;
1109
1110 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1f536d49 1111 if (if_info->dhcp_state) {
99bc5d55
JSJ
1112 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1113 "BG_%d : DHCP Already Enabled\n");
6d67726b 1114 goto exit;
0e43895e
MC
1115 }
1116 /* The ip_param->len is 1 in DHCP case. Setting
1117 proper IP len as this it is used while
1118 freeing the Static IP.
1119 */
1120 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1121 IP_V6_LEN : IP_V4_LEN;
1122
1123 } else {
1f536d49 1124 if (if_info->dhcp_state) {
0e43895e 1125
1f536d49 1126 memset(if_info, 0, sizeof(*if_info));
0e43895e
MC
1127 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1128 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1129 sizeof(*reldhcp));
1130
1131 if (rc)
6d67726b 1132 goto exit;
0e43895e
MC
1133
1134 reldhcp = nonemb_cmd.va;
1135 reldhcp->interface_hndl = phba->interface_handle;
1136 reldhcp->ip_type = ip_type;
1137
1138 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1139 if (rc < 0) {
99bc5d55
JSJ
1140 beiscsi_log(phba, KERN_WARNING,
1141 BEISCSI_LOG_CONFIG,
1142 "BG_%d : Failed to Delete existing dhcp\n");
6d67726b 1143 goto exit;
0e43895e
MC
1144 }
1145 }
1146 }
1147
1148 /* Delete the Static IP Set */
1f536d49
JK
1149 if (if_info->ip_addr.addr[0]) {
1150 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
0e43895e
MC
1151 IP_ACTION_DEL);
1152 if (rc)
6d67726b 1153 goto exit;
0e43895e
MC
1154 }
1155
1156 /* Delete the Gateway settings if mode change is to DHCP */
1157 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1158 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1159 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1160 if (rc) {
99bc5d55
JSJ
1161 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1162 "BG_%d : Failed to Get Gateway Addr\n");
6d67726b 1163 goto exit;
0e43895e
MC
1164 }
1165
1166 if (gtway_addr_set.ip_addr.addr[0]) {
1167 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1168 rc = mgmt_modify_gateway(phba, gtway_addr,
1169 IP_ACTION_DEL, IP_V4_LEN);
1170
1171 if (rc) {
99bc5d55
JSJ
1172 beiscsi_log(phba, KERN_WARNING,
1173 BEISCSI_LOG_CONFIG,
1174 "BG_%d : Failed to clear Gateway Addr Set\n");
6d67726b 1175 goto exit;
0e43895e
MC
1176 }
1177 }
1178 }
1179
1180 /* Set Adapter to DHCP/Static Mode */
1181 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1182 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1183 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1184 sizeof(*dhcpreq));
1185 if (rc)
6d67726b 1186 goto exit;
0e43895e
MC
1187
1188 dhcpreq = nonemb_cmd.va;
1189 dhcpreq->flags = BLOCKING;
1190 dhcpreq->retry_count = 1;
1191 dhcpreq->interface_hndl = phba->interface_handle;
1192 dhcpreq->ip_type = BE2_DHCP_V4;
1193
6d67726b 1194 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
0e43895e 1195 } else {
6d67726b 1196 rc = mgmt_static_ip_modify(phba, if_info, ip_param,
0e43895e
MC
1197 subnet_param, IP_ACTION_ADD);
1198 }
1199
6d67726b
ML
1200exit:
1201 kfree(if_info);
0e43895e
MC
1202 return rc;
1203}
1204
1205int mgmt_set_gateway(struct beiscsi_hba *phba,
1206 struct iscsi_iface_param_info *gateway_param)
1207{
1208 struct be_cmd_get_def_gateway_resp gtway_addr_set;
1209 uint8_t *gtway_addr;
1210 int rt_val;
1211
1212 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1213 rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1214 if (rt_val) {
99bc5d55
JSJ
1215 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1216 "BG_%d : Failed to Get Gateway Addr\n");
0e43895e
MC
1217 return rt_val;
1218 }
1219
1220 if (gtway_addr_set.ip_addr.addr[0]) {
1221 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1222 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1223 gateway_param->len);
1224 if (rt_val) {
99bc5d55
JSJ
1225 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1226 "BG_%d : Failed to clear Gateway Addr Set\n");
0e43895e
MC
1227 return rt_val;
1228 }
1229 }
1230
1231 gtway_addr = (uint8_t *)&gateway_param->value;
1232 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1233 gateway_param->len);
1234
1235 if (rt_val)
99bc5d55
JSJ
1236 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1237 "BG_%d : Failed to Set Gateway Addr\n");
0e43895e
MC
1238
1239 return rt_val;
1240}
1241
1242int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1243 struct be_cmd_get_def_gateway_resp *gateway)
1244{
1245 struct be_cmd_get_def_gateway_req *req;
1246 struct be_dma_mem nonemb_cmd;
1247 int rc;
1248
1249 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1250 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1251 sizeof(*gateway));
1252 if (rc)
1253 return rc;
1254
1255 req = nonemb_cmd.va;
1256 req->ip_type = ip_type;
1257
1258 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1259 sizeof(*gateway));
1260}
1261
1262int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1f536d49 1263 struct be_cmd_get_if_info_resp **if_info)
0e43895e
MC
1264{
1265 struct be_cmd_get_if_info_req *req;
1266 struct be_dma_mem nonemb_cmd;
1f536d49 1267 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
0e43895e
MC
1268 int rc;
1269
3c9d903b
JB
1270 rc = mgmt_get_all_if_id(phba);
1271 if (rc)
1272 return rc;
0e43895e 1273
1f536d49
JK
1274 do {
1275 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1276 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1277 ioctl_size);
1278 if (rc)
1279 return rc;
0e43895e 1280
1f536d49
JK
1281 req = nonemb_cmd.va;
1282 req->interface_hndl = phba->interface_handle;
1283 req->ip_type = ip_type;
1284
1285 /* Allocate memory for if_info */
1286 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1287 if (!*if_info) {
1288 beiscsi_log(phba, KERN_ERR,
1289 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1290 "BG_%d : Memory Allocation Failure\n");
1291
1292 /* Free the DMA memory for the IOCTL issuing */
1293 pci_free_consistent(phba->ctrl.pdev,
1294 nonemb_cmd.size,
1295 nonemb_cmd.va,
1296 nonemb_cmd.dma);
1297 return -ENOMEM;
1298 }
1299
1300 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1301 ioctl_size);
0e43895e 1302
1f536d49
JK
1303 /* Check if the error is because of Insufficent_Buffer */
1304 if (rc == -EAGAIN) {
1305
1306 /* Get the new memory size */
1307 ioctl_size = ((struct be_cmd_resp_hdr *)
1308 nonemb_cmd.va)->actual_resp_len;
1309 ioctl_size += sizeof(struct be_cmd_req_hdr);
1310
1311 /* Free the previous allocated DMA memory */
1312 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1313 nonemb_cmd.va,
1314 nonemb_cmd.dma);
1315
1316 /* Free the virtual memory */
1317 kfree(*if_info);
1318 } else
1319 break;
1320 } while (true);
1321 return rc;
0e43895e
MC
1322}
1323
1324int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1325 struct be_cmd_get_nic_conf_resp *nic)
1326{
1327 struct be_dma_mem nonemb_cmd;
1328 int rc;
1329
1330 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1331 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1332 sizeof(*nic));
1333 if (rc)
1334 return rc;
1335
1336 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1337}
1338
1339
1340
2177199d
JSJ
1341unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1342{
090e2184 1343 unsigned int tag;
2177199d
JSJ
1344 struct be_mcc_wrb *wrb;
1345 struct be_cmd_hba_name *req;
1346 struct be_ctrl_info *ctrl = &phba->ctrl;
1347
c03a50f7
JB
1348 if (mutex_lock_interruptible(&ctrl->mbox_lock))
1349 return 0;
090e2184
JB
1350 wrb = alloc_mcc_wrb(phba, &tag);
1351 if (!wrb) {
c03a50f7 1352 mutex_unlock(&ctrl->mbox_lock);
090e2184 1353 return 0;
2177199d
JSJ
1354 }
1355
2177199d 1356 req = embedded_payload(wrb);
2177199d
JSJ
1357 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1358 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1359 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1360 sizeof(*req));
1361
cdde6682 1362 be_mcc_notify(phba, tag);
c03a50f7 1363 mutex_unlock(&ctrl->mbox_lock);
2177199d
JSJ
1364 return tag;
1365}
c62eef0d 1366
9aef4200
JSJ
1367/**
1368 * be_mgmt_get_boot_shandle()- Get the session handle
1369 * @phba: device priv structure instance
1370 * @s_handle: session handle returned for boot session.
1371 *
1372 * Get the boot target session handle. In case of
1373 * crashdump mode driver has to issue and MBX Cmd
1374 * for FW to login to boot target
1375 *
1376 * return
1377 * Success: 0
1378 * Failure: Non-Zero value
1379 *
1380 **/
1381int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1382 unsigned int *s_handle)
1383{
1384 struct be_cmd_get_boot_target_resp *boot_resp;
1385 struct be_mcc_wrb *wrb;
e175defe 1386 unsigned int tag;
9aef4200 1387 uint8_t boot_retry = 3;
e175defe 1388 int rc;
9aef4200
JSJ
1389
1390 do {
1391 /* Get the Boot Target Session Handle and Count*/
1392 tag = mgmt_get_boot_target(phba);
1393 if (!tag) {
99bc5d55
JSJ
1394 beiscsi_log(phba, KERN_ERR,
1395 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1396 "BG_%d : Getting Boot Target Info Failed\n");
9aef4200 1397 return -EAGAIN;
e175defe
JSJ
1398 }
1399
88840332 1400 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
e175defe 1401 if (rc) {
99bc5d55
JSJ
1402 beiscsi_log(phba, KERN_ERR,
1403 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
e175defe 1404 "BG_%d : MBX CMD get_boot_target Failed\n");
9aef4200
JSJ
1405 return -EBUSY;
1406 }
e175defe 1407
9aef4200
JSJ
1408 boot_resp = embedded_payload(wrb);
1409
1410 /* Check if the there are any Boot targets configured */
1411 if (!boot_resp->boot_session_count) {
99bc5d55
JSJ
1412 beiscsi_log(phba, KERN_INFO,
1413 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1414 "BG_%d ;No boot targets configured\n");
9aef4200
JSJ
1415 return -ENXIO;
1416 }
1417
1418 /* FW returns the session handle of the boot session */
1419 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1420 *s_handle = boot_resp->boot_session_handle;
1421 return 0;
1422 }
1423
1424 /* Issue MBX Cmd to FW to login to the boot target */
1425 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1426 INVALID_SESS_HANDLE);
1427 if (!tag) {
99bc5d55
JSJ
1428 beiscsi_log(phba, KERN_ERR,
1429 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1430 "BG_%d : mgmt_reopen_session Failed\n");
9aef4200 1431 return -EAGAIN;
e175defe
JSJ
1432 }
1433
88840332 1434 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
e175defe 1435 if (rc) {
99bc5d55
JSJ
1436 beiscsi_log(phba, KERN_ERR,
1437 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
e175defe
JSJ
1438 "BG_%d : mgmt_reopen_session Failed");
1439 return rc;
9aef4200 1440 }
9aef4200
JSJ
1441 } while (--boot_retry);
1442
1443 /* Couldn't log into the boot target */
99bc5d55
JSJ
1444 beiscsi_log(phba, KERN_ERR,
1445 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1446 "BG_%d : Login to Boot Target Failed\n");
9aef4200
JSJ
1447 return -ENXIO;
1448}
6f72238e
JSJ
1449
1450/**
1451 * mgmt_set_vlan()- Issue and wait for CMD completion
1452 * @phba: device private structure instance
1453 * @vlan_tag: VLAN tag
1454 *
1455 * Issue the MBX Cmd and wait for the completion of the
1456 * command.
1457 *
1458 * returns
1459 * Success: 0
1460 * Failure: Non-Xero Value
1461 **/
1462int mgmt_set_vlan(struct beiscsi_hba *phba,
1463 uint16_t vlan_tag)
1464{
e175defe
JSJ
1465 int rc;
1466 unsigned int tag;
6f72238e
JSJ
1467
1468 tag = be_cmd_set_vlan(phba, vlan_tag);
1469 if (!tag) {
1470 beiscsi_log(phba, KERN_ERR,
1471 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1472 "BG_%d : VLAN Setting Failed\n");
1473 return -EBUSY;
e175defe 1474 }
6f72238e 1475
88840332 1476 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
e175defe 1477 if (rc) {
6f72238e
JSJ
1478 beiscsi_log(phba, KERN_ERR,
1479 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
e175defe
JSJ
1480 "BS_%d : VLAN MBX Cmd Failed\n");
1481 return rc;
6f72238e 1482 }
e175defe 1483 return rc;
6f72238e 1484}
5cac7596
JSJ
1485
1486/**
1487 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1488 * @dev: ptr to device not used.
1489 * @attr: device attribute, not used.
1490 * @buf: contains formatted text driver name and version
1491 *
1492 * return
1493 * size of the formatted string
1494 **/
1495ssize_t
1496beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1497 char *buf)
1498{
1499 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1500}
acb9693c 1501
22661e25
JK
1502/**
1503 * beiscsi_fw_ver_disp()- Display Firmware Version
1504 * @dev: ptr to device not used.
1505 * @attr: device attribute, not used.
1506 * @buf: contains formatted text Firmware version
1507 *
1508 * return
1509 * size of the formatted string
1510 **/
1511ssize_t
1512beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1513 char *buf)
1514{
1515 struct Scsi_Host *shost = class_to_shost(dev);
1516 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1517
1518 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1519}
1520
7ad4dfe1 1521/**
6103c1f7 1522 * beiscsi_active_session_disp()- Display Sessions Active
7ad4dfe1
JK
1523 * @dev: ptr to device not used.
1524 * @attr: device attribute, not used.
1525 * @buf: contains formatted text Session Count
1526 *
1527 * return
1528 * size of the formatted string
1529 **/
1530ssize_t
6103c1f7 1531beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
7ad4dfe1
JK
1532 char *buf)
1533{
1534 struct Scsi_Host *shost = class_to_shost(dev);
1535 struct beiscsi_hba *phba = iscsi_host_priv(shost);
0a3db7c0
JK
1536 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1537
1538 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1539 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1540 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1541 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1542 len += snprintf(buf+len, PAGE_SIZE - len,
1543 "ULP%d : %d\n", ulp_num,
1544 (total_cids - avlbl_cids));
1545 } else
1546 len += snprintf(buf+len, PAGE_SIZE - len,
1547 "ULP%d : %d\n", ulp_num, 0);
1548 }
7ad4dfe1 1549
0a3db7c0 1550 return len;
7ad4dfe1
JK
1551}
1552
6103c1f7
JK
1553/**
1554 * beiscsi_free_session_disp()- Display Avaliable Session
1555 * @dev: ptr to device not used.
1556 * @attr: device attribute, not used.
1557 * @buf: contains formatted text Session Count
1558 *
1559 * return
1560 * size of the formatted string
1561 **/
1562ssize_t
1563beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1564 char *buf)
1565{
1566 struct Scsi_Host *shost = class_to_shost(dev);
1567 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1568 uint16_t ulp_num, len = 0;
1569
1570 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1571 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1572 len += snprintf(buf+len, PAGE_SIZE - len,
1573 "ULP%d : %d\n", ulp_num,
1574 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1575 else
1576 len += snprintf(buf+len, PAGE_SIZE - len,
1577 "ULP%d : %d\n", ulp_num, 0);
1578 }
1579
1580 return len;
1581}
1582
26000db7
JSJ
1583/**
1584 * beiscsi_adap_family_disp()- Display adapter family.
1585 * @dev: ptr to device to get priv structure
1586 * @attr: device attribute, not used.
1587 * @buf: contains formatted text driver name and version
1588 *
1589 * return
1590 * size of the formatted string
1591 **/
1592ssize_t
1593beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1594 char *buf)
1595{
1596 uint16_t dev_id = 0;
1597 struct Scsi_Host *shost = class_to_shost(dev);
1598 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1599
1600 dev_id = phba->pcidev->device;
1601 switch (dev_id) {
1602 case BE_DEVICE_ID1:
1603 case OC_DEVICE_ID1:
1604 case OC_DEVICE_ID2:
1605 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1606 break;
1607 case BE_DEVICE_ID2:
1608 case OC_DEVICE_ID3:
1609 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1610 break;
1611 case OC_SKH_ID1:
1612 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1613 break;
1614 default:
1615 return snprintf(buf, PAGE_SIZE,
b23f7a09 1616 "Unknown Adapter Family: 0x%x\n", dev_id);
26000db7
JSJ
1617 break;
1618 }
1619}
1620
d3fea9af
JK
1621/**
1622 * beiscsi_phys_port()- Display Physical Port Identifier
1623 * @dev: ptr to device not used.
1624 * @attr: device attribute, not used.
1625 * @buf: contains formatted text port identifier
1626 *
1627 * return
1628 * size of the formatted string
1629 **/
1630ssize_t
1631beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1632 char *buf)
1633{
1634 struct Scsi_Host *shost = class_to_shost(dev);
1635 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1636
1637 return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1638 phba->fw_config.phys_port);
1639}
26000db7 1640
acb9693c
JSJ
1641void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1642 struct wrb_handle *pwrb_handle,
340c99e9
JSJ
1643 struct be_mem_descriptor *mem_descr,
1644 struct hwi_wrb_context *pwrb_context)
acb9693c
JSJ
1645{
1646 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1647
1648 memset(pwrb, 0, sizeof(*pwrb));
1649 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1650 max_send_data_segment_length, pwrb,
1651 params->dw[offsetof(struct amap_beiscsi_offload_params,
1652 max_send_data_segment_length) / 32]);
1653 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1654 BE_TGT_CTX_UPDT_CMD);
1655 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1656 first_burst_length,
1657 pwrb,
1658 params->dw[offsetof(struct amap_beiscsi_offload_params,
1659 first_burst_length) / 32]);
1660 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1661 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1662 erl) / 32] & OFFLD_PARAMS_ERL));
1663 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1664 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1665 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1666 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1667 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1668 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1669 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1670 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1671 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1672 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1673 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1674 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1675 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1676 pwrb,
1677 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1678 exp_statsn) / 32] + 1));
1679 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1680 pwrb, pwrb_handle->wrb_index);
1681
1682 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1683 max_burst_length, pwrb, params->dw[offsetof
1684 (struct amap_beiscsi_offload_params,
1685 max_burst_length) / 32]);
1686
1687 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
340c99e9
JSJ
1688 pwrb, pwrb_handle->wrb_index);
1689 if (pwrb_context->plast_wrb)
1690 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1691 ptr2nextwrb,
1692 pwrb_context->plast_wrb,
1693 pwrb_handle->wrb_index);
1694 pwrb_context->plast_wrb = pwrb;
1695
acb9693c
JSJ
1696 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1697 session_state, pwrb, 0);
1698 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1699 pwrb, 1);
1700 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1701 pwrb, 0);
1702 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1703 0);
1704
1705 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1706 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1707 pad_buffer_addr_hi, pwrb,
1708 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1709 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1710 pad_buffer_addr_lo, pwrb,
1711 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1712}
1713
1714void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
340c99e9
JSJ
1715 struct wrb_handle *pwrb_handle,
1716 struct hwi_wrb_context *pwrb_context)
acb9693c
JSJ
1717{
1718 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1719
1720 memset(pwrb, 0, sizeof(*pwrb));
1721
acb9693c
JSJ
1722 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1723 max_burst_length, pwrb, params->dw[offsetof
1724 (struct amap_beiscsi_offload_params,
1725 max_burst_length) / 32]);
1726 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1727 type, pwrb,
1728 BE_TGT_CTX_UPDT_CMD);
1729 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1730 ptr2nextwrb,
340c99e9
JSJ
1731 pwrb, pwrb_handle->wrb_index);
1732 if (pwrb_context->plast_wrb)
1733 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1734 ptr2nextwrb,
1735 pwrb_context->plast_wrb,
1736 pwrb_handle->wrb_index);
1737 pwrb_context->plast_wrb = pwrb;
1738
acb9693c
JSJ
1739 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1740 pwrb, pwrb_handle->wrb_index);
1741 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1742 max_send_data_segment_length, pwrb,
1743 params->dw[offsetof(struct amap_beiscsi_offload_params,
1744 max_send_data_segment_length) / 32]);
1745 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1746 first_burst_length, pwrb,
1747 params->dw[offsetof(struct amap_beiscsi_offload_params,
1748 first_burst_length) / 32]);
1749 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
7331613e
JK
1750 max_recv_dataseg_len, pwrb,
1751 params->dw[offsetof(struct amap_beiscsi_offload_params,
1752 max_recv_data_segment_length) / 32]);
acb9693c
JSJ
1753 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1754 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1755 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1756 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1757 erl) / 32] & OFFLD_PARAMS_ERL));
1758 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1759 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1760 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1761 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1762 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1763 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1764 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1765 ir2t, pwrb,
1766 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1767 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1768 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1769 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1770 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1771 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1772 data_seq_inorder,
1773 pwrb,
1774 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1775 data_seq_inorder) / 32] &
1776 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1777 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1778 pdu_seq_inorder,
1779 pwrb,
1780 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1781 pdu_seq_inorder) / 32] &
1782 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1783 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1784 pwrb,
1785 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1786 max_r2t) / 32] &
1787 OFFLD_PARAMS_MAX_R2T) >> 8);
1788 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1789 pwrb,
1790 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1791 exp_statsn) / 32] + 1));
1792}
3f4134c1
JSJ
1793
1794/**
1795 * beiscsi_logout_fw_sess()- Firmware Session Logout
1796 * @phba: Device priv structure instance
1797 * @fw_sess_handle: FW session handle
1798 *
1799 * Logout from the FW established sessions.
1800 * returns
1801 * Success: 0
1802 * Failure: Non-Zero Value
1803 *
1804 */
1805int beiscsi_logout_fw_sess(struct beiscsi_hba *phba,
1806 uint32_t fw_sess_handle)
1807{
1808 struct be_ctrl_info *ctrl = &phba->ctrl;
1809 struct be_mcc_wrb *wrb;
1810 struct be_cmd_req_logout_fw_sess *req;
1811 struct be_cmd_resp_logout_fw_sess *resp;
1812 unsigned int tag;
1813 int rc;
1814
1815 beiscsi_log(phba, KERN_INFO,
1816 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1817 "BG_%d : In bescsi_logout_fwboot_sess\n");
1818
c03a50f7 1819 mutex_lock(&ctrl->mbox_lock);
090e2184
JB
1820 wrb = alloc_mcc_wrb(phba, &tag);
1821 if (!wrb) {
c03a50f7 1822 mutex_unlock(&ctrl->mbox_lock);
3f4134c1
JSJ
1823 beiscsi_log(phba, KERN_INFO,
1824 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
1825 "BG_%d : MBX Tag Failure\n");
1826 return -EINVAL;
1827 }
1828
3f4134c1 1829 req = embedded_payload(wrb);
3f4134c1
JSJ
1830 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1831 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1832 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
1833 sizeof(struct be_cmd_req_logout_fw_sess));
1834
1835 /* Set the session handle */
1836 req->session_handle = fw_sess_handle;
cdde6682 1837 be_mcc_notify(phba, tag);
c03a50f7 1838 mutex_unlock(&ctrl->mbox_lock);
3f4134c1 1839
88840332 1840 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
3f4134c1
JSJ
1841 if (rc) {
1842 beiscsi_log(phba, KERN_ERR,
1843 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1844 "BG_%d : MBX CMD FW_SESSION_LOGOUT_TARGET Failed\n");
1845 return -EBUSY;
1846 }
1847
1848 resp = embedded_payload(wrb);
1849 if (resp->session_status !=
1850 BEISCSI_MGMT_SESSION_CLOSE) {
1851 beiscsi_log(phba, KERN_ERR,
1852 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1853 "BG_%d : FW_SESSION_LOGOUT_TARGET resp : 0x%x\n",
1854 resp->session_status);
1855 rc = -EINVAL;
1856 }
1857
1858 return rc;
1859}