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