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