blob: b2fcac78feaa995430fe62e4cd2587735313dabb [file] [log] [blame]
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05301/**
Jayamohan Kallickal533c1652013-04-05 20:38:34 -07002 * Copyright (C) 2005 - 2013 Emulex
Jayamohan Kallickal6733b392009-09-05 07:36:35 +05303 * 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 *
Jayamohan Kallickal255fa9a2011-03-25 14:23:57 -070010 * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053011 *
12 * Contact Information:
Jayamohan Kallickal255fa9a2011-03-25 14:23:57 -070013 * linux-drivers@emulex.com
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053014 *
Jayamohan Kallickal255fa9a2011-03-25 14:23:57 -070015 * Emulex
16 * 3333 Susan Street
17 * Costa Mesa, CA 92626
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053018 */
19
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -050020#include <linux/bsg-lib.h>
21#include <scsi/scsi_transport_iscsi.h>
22#include <scsi/scsi_bsg_iscsi.h>
Jayamohan Kallickal6733b392009-09-05 07:36:35 +053023#include "be_mgmt.h"
24#include "be_iscsi.h"
John Soni Jose7a158002012-10-20 04:45:51 +053025#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}
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530157
John Soni Jose9aef4202012-08-20 23:00:08 +0530158/**
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
John Soni Jose99bc5d52012-08-20 23:00:18 +0530177 beiscsi_log(phba, KERN_INFO,
178 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
179 "BG_%d : In bescsi_get_boot_target\n");
180
John Soni Jose9aef4202012-08-20 23:00:08 +0530181 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
Mike Christie0e438952012-04-03 23:41:51 -0500205unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530206{
207 struct be_ctrl_info *ctrl = &phba->ctrl;
208 struct be_mcc_wrb *wrb;
Mike Christie0e438952012-04-03 23:41:51 -0500209 struct be_cmd_get_boot_target_req *req;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530210 unsigned int tag = 0;
211
John Soni Jose99bc5d52012-08-20 23:00:18 +0530212 beiscsi_log(phba, KERN_INFO,
213 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
214 "BG_%d : In bescsi_get_boot_target\n");
215
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530216 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,
Mike Christie0e438952012-04-03 23:41:51 -0500229 sizeof(struct be_cmd_get_boot_target_resp));
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530230
231 be_mcc_notify(phba);
232 spin_unlock(&ctrl->mbox_lock);
233 return tag;
234}
235
Mike Christie0e438952012-04-03 23:41:51 -0500236unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
237 u32 boot_session_handle,
238 struct be_dma_mem *nonemb_cmd)
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530239{
240 struct be_ctrl_info *ctrl = &phba->ctrl;
241 struct be_mcc_wrb *wrb;
242 unsigned int tag = 0;
Mike Christie0e438952012-04-03 23:41:51 -0500243 struct be_cmd_get_session_req *req;
244 struct be_cmd_get_session_resp *resp;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530245 struct be_sge *sge;
246
John Soni Jose99bc5d52012-08-20 23:00:18 +0530247 beiscsi_log(phba, KERN_INFO,
248 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
249 "BG_%d : In beiscsi_get_session_info\n");
250
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530251 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}
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530280
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700281/**
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 **/
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530293int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530294 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,
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700306 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
307 EMBED_MBX_MAX_PAYLOAD_SIZE);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530308 status = be_mbox_notify(ctrl);
309 if (!status) {
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700310 uint8_t ulp_num = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530311 struct be_fw_cfg *pfw_cfg;
312 pfw_cfg = req;
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700313
Jayamohan Kallickal68c26a32013-09-28 15:35:54 -0700314 if (!is_chip_be2_be3r(phba)) {
315 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
316 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
317
318 beiscsi_log(phba, KERN_INFO,
319 BEISCSI_LOG_INIT,
320 "BG_%d : EQ_Count : %d CQ_Count : %d\n",
321 phba->fw_config.eqid_count,
322 phba->fw_config.cqid_count);
323 }
324
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700325 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
326 if (pfw_cfg->ulp[ulp_num].ulp_mode &
327 BEISCSI_ULP_ISCSI_INI_MODE)
328 set_bit(ulp_num,
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -0700329 &phba->fw_config.ulp_supported);
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700330
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530331 phba->fw_config.phys_port = pfw_cfg->phys_port;
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700332 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
333 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
334
335 phba->fw_config.iscsi_cid_start[ulp_num] =
336 pfw_cfg->ulp[ulp_num].sq_base;
337 phba->fw_config.iscsi_cid_count[ulp_num] =
338 pfw_cfg->ulp[ulp_num].sq_count;
339
340 phba->fw_config.iscsi_icd_start[ulp_num] =
341 pfw_cfg->ulp[ulp_num].icd_base;
342 phba->fw_config.iscsi_icd_count[ulp_num] =
343 pfw_cfg->ulp[ulp_num].icd_count;
344
345 phba->fw_config.iscsi_chain_start[ulp_num] =
346 pfw_cfg->chain_icd[ulp_num].chain_base;
347 phba->fw_config.iscsi_chain_count[ulp_num] =
348 pfw_cfg->chain_icd[ulp_num].chain_count;
349
350 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
351 "BG_%d : Function loaded on ULP : %d\n"
352 "\tiscsi_cid_count : %d\n"
Jayamohan Kallickalcf987b72013-09-28 15:35:59 -0700353 "\tiscsi_cid_start : %d\n"
354 "\t iscsi_icd_count : %d\n"
355 "\t iscsi_icd_start : %d\n",
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700356 ulp_num,
357 phba->fw_config.
358 iscsi_cid_count[ulp_num],
359 phba->fw_config.
Jayamohan Kallickalcf987b72013-09-28 15:35:59 -0700360 iscsi_cid_start[ulp_num],
361 phba->fw_config.
362 iscsi_icd_count[ulp_num],
363 phba->fw_config.
364 iscsi_icd_start[ulp_num]);
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700365 }
Jayamohan Kallickal7da50872010-01-05 05:04:12 +0530366 }
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700367
368 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
369 BEISCSI_FUNC_DUA_MODE);
370
371 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
372 "BG_%d : DUA Mode : 0x%x\n",
373 phba->fw_config.dual_ulp_aware);
374
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530375 } else {
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700376 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
John Soni Jose99bc5d52012-08-20 23:00:18 +0530377 "BG_%d : Failed in mgmt_get_fw_config\n");
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700378 status = -EINVAL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530379 }
380
381 spin_unlock(&ctrl->mbox_lock);
382 return status;
383}
384
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530385int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530386 struct beiscsi_hba *phba)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530387{
388 struct be_dma_mem nonemb_cmd;
389 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
390 struct be_mgmt_controller_attributes *req;
391 struct be_sge *sge = nonembedded_sgl(wrb);
392 int status = 0;
393
394 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
395 sizeof(struct be_mgmt_controller_attributes),
396 &nonemb_cmd.dma);
397 if (nonemb_cmd.va == NULL) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530398 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
399 "BG_%d : Failed to allocate memory for "
400 "mgmt_check_supported_fw\n");
Jayamohan Kallickald3ad2bb2010-07-22 04:16:38 +0530401 return -ENOMEM;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530402 }
403 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
404 req = nonemb_cmd.va;
Jayamohan Kallickalf98c96b2010-02-11 05:11:15 +0530405 memset(req, 0, sizeof(*req));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530406 spin_lock(&ctrl->mbox_lock);
407 memset(wrb, 0, sizeof(*wrb));
408 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
409 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
410 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
411 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
412 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
413 sge->len = cpu_to_le32(nonemb_cmd.size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530414 status = be_mbox_notify(ctrl);
415 if (!status) {
416 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530417 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
418 "BG_%d : Firmware Version of CMD : %s\n"
419 "Firmware Version is : %s\n"
420 "Developer Build, not performing version check...\n",
421 resp->params.hba_attribs
422 .flashrom_version_string,
423 resp->params.hba_attribs.
424 firmware_version_string);
425
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530426 phba->fw_config.iscsi_features =
427 resp->params.hba_attribs.iscsi_features;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530428 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
429 "BM_%d : phba->fw_config.iscsi_features = %d\n",
430 phba->fw_config.iscsi_features);
Jayamohan Kallickal22661e22013-04-05 20:38:28 -0700431 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
432 firmware_version_string, BEISCSI_VER_STRLEN);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530433 } else
John Soni Jose99bc5d52012-08-20 23:00:18 +0530434 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
435 "BG_%d : Failed in mgmt_check_supported_fw\n");
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530436 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530437 if (nonemb_cmd.va)
438 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
439 nonemb_cmd.va, nonemb_cmd.dma);
440
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530441 return status;
442}
443
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500444unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
445 struct beiscsi_hba *phba,
446 struct bsg_job *job,
447 struct be_dma_mem *nonemb_cmd)
448{
449 struct be_cmd_resp_hdr *resp;
450 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
451 struct be_sge *mcc_sge = nonembedded_sgl(wrb);
452 unsigned int tag = 0;
453 struct iscsi_bsg_request *bsg_req = job->request;
454 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
455 unsigned short region, sector_size, sector, offset;
456
457 nonemb_cmd->size = job->request_payload.payload_len;
458 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
459 resp = nonemb_cmd->va;
460 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
461 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
462 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
463 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
464 req->region = region;
465 req->sector = sector;
466 req->offset = offset;
467 spin_lock(&ctrl->mbox_lock);
468 memset(wrb, 0, sizeof(*wrb));
469
470 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
471 case BEISCSI_WRITE_FLASH:
472 offset = sector * sector_size + offset;
473 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
474 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
475 sg_copy_to_buffer(job->request_payload.sg_list,
476 job->request_payload.sg_cnt,
477 nonemb_cmd->va + offset, job->request_len);
478 break;
479 case BEISCSI_READ_FLASH:
480 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
481 OPCODE_COMMON_READ_FLASH, sizeof(*req));
482 break;
483 default:
John Soni Jose99bc5d52012-08-20 23:00:18 +0530484 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
485 "BG_%d : Unsupported cmd = 0x%x\n\n",
486 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
487
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500488 spin_unlock(&ctrl->mbox_lock);
489 return -ENOSYS;
490 }
491
492 tag = alloc_mcc_tag(phba);
493 if (!tag) {
494 spin_unlock(&ctrl->mbox_lock);
495 return tag;
496 }
497
498 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
499 job->request_payload.sg_cnt);
500 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
501 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
502 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
503 wrb->tag0 |= tag;
504
505 be_mcc_notify(phba);
506
507 spin_unlock(&ctrl->mbox_lock);
508 return tag;
509}
510
Jayamohan Kallickalbd41c2b2013-09-28 15:35:51 -0700511/**
512 * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
513 * @phba: pointer to dev priv structure
514 * @ulp_num: ULP number.
515 *
516 * return
517 * Success: 0
518 * Failure: Non-Zero Value
519 **/
520int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530521{
522 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530523 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530524 struct iscsi_cleanup_req *req = embedded_payload(wrb);
525 int status = 0;
526
527 spin_lock(&ctrl->mbox_lock);
528 memset(wrb, 0, sizeof(*wrb));
529
530 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
531 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
532 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
533
Jayamohan Kallickalbd41c2b2013-09-28 15:35:51 -0700534 req->chute = (1 << ulp_num);
535 req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
536 req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530537
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530538 status = be_mcc_notify_wait(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530539 if (status)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530540 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
541 "BG_%d : mgmt_epfw_cleanup , FAILED\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530542 spin_unlock(&ctrl->mbox_lock);
543 return status;
544}
545
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530546unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530547 struct invalidate_command_table *inv_tbl,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530548 unsigned int num_invalidate, unsigned int cid,
549 struct be_dma_mem *nonemb_cmd)
550
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530551{
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530552 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530553 struct be_mcc_wrb *wrb;
554 struct be_sge *sge;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530555 struct invalidate_commands_params_in *req;
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530556 unsigned int i, tag = 0;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530557
558 spin_lock(&ctrl->mbox_lock);
559 tag = alloc_mcc_tag(phba);
560 if (!tag) {
561 spin_unlock(&ctrl->mbox_lock);
562 return tag;
563 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530564
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530565 req = nonemb_cmd->va;
Jayamohan Kallickalf98c96b2010-02-11 05:11:15 +0530566 memset(req, 0, sizeof(*req));
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530567 wrb = wrb_from_mccq(phba);
568 sge = nonembedded_sgl(wrb);
569 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530570
571 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
572 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
573 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
574 sizeof(*req));
575 req->ref_handle = 0;
576 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530577 for (i = 0; i < num_invalidate; i++) {
578 req->table[i].icd = inv_tbl->icd;
579 req->table[i].cid = inv_tbl->cid;
580 req->icd_count++;
581 inv_tbl++;
582 }
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530583 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
584 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
585 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530586
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530587 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530588 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530589 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530590}
591
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530592unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530593 struct beiscsi_endpoint *beiscsi_ep,
594 unsigned short cid,
595 unsigned short issue_reset,
596 unsigned short savecfg_flag)
597{
598 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530599 struct be_mcc_wrb *wrb;
600 struct iscsi_invalidate_connection_params_in *req;
601 unsigned int tag = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530602
603 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530604 tag = alloc_mcc_tag(phba);
605 if (!tag) {
606 spin_unlock(&ctrl->mbox_lock);
607 return tag;
608 }
609 wrb = wrb_from_mccq(phba);
610 wrb->tag0 |= tag;
611 req = embedded_payload(wrb);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530612
613 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
614 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
615 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
616 sizeof(*req));
617 req->session_handle = beiscsi_ep->fw_handle;
618 req->cid = cid;
619 if (issue_reset)
620 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
621 else
622 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
623 req->save_cfg = savecfg_flag;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530624 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530625 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530626 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530627}
628
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530629unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530630 unsigned short cid, unsigned int upload_flag)
631{
632 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530633 struct be_mcc_wrb *wrb;
634 struct tcp_upload_params_in *req;
635 unsigned int tag = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530636
637 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530638 tag = alloc_mcc_tag(phba);
639 if (!tag) {
640 spin_unlock(&ctrl->mbox_lock);
641 return tag;
642 }
643 wrb = wrb_from_mccq(phba);
644 req = embedded_payload(wrb);
645 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530646
647 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
648 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
649 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
650 req->id = (unsigned short)cid;
651 req->upload_type = (unsigned char)upload_flag;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530652 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530653 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530654 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530655}
656
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700657/**
658 * mgmt_open_connection()- Establish a TCP CXN
659 * @dst_addr: Destination Address
660 * @beiscsi_ep: ptr to device endpoint struct
661 * @nonemb_cmd: ptr to memory allocated for command
662 *
663 * return
664 * Success: Tag number of the MBX Command issued
665 * Failure: Error code
666 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530667int mgmt_open_connection(struct beiscsi_hba *phba,
668 struct sockaddr *dst_addr,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530669 struct beiscsi_endpoint *beiscsi_ep,
670 struct be_dma_mem *nonemb_cmd)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530671{
672 struct hwi_controller *phwi_ctrlr;
673 struct hwi_context_memory *phwi_context;
674 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
675 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
676 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530677 struct be_mcc_wrb *wrb;
678 struct tcp_connect_and_offload_in *req;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530679 unsigned short def_hdr_id;
680 unsigned short def_data_id;
681 struct phys_addr template_address = { 0, 0 };
682 struct phys_addr *ptemplate_address;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530683 unsigned int tag = 0;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700684 unsigned int i, ulp_num;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530685 unsigned short cid = beiscsi_ep->ep_cid;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530686 struct be_sge *sge;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530687
688 phwi_ctrlr = phba->phwi_ctrlr;
689 phwi_context = phwi_ctrlr->phwi_ctxt;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700690
691 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
692
693 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
694 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530695
696 ptemplate_address = &template_address;
697 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
698 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530699 tag = alloc_mcc_tag(phba);
700 if (!tag) {
701 spin_unlock(&ctrl->mbox_lock);
702 return tag;
703 }
704 wrb = wrb_from_mccq(phba);
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530705 memset(wrb, 0, sizeof(*wrb));
706 sge = nonembedded_sgl(wrb);
707
708 req = nonemb_cmd->va;
709 memset(req, 0, sizeof(*req));
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530710 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530711
Jayamohan Kallickalb15d05b2010-08-12 23:36:06 +0530712 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530713 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
714 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
715 sizeof(*req));
716 if (dst_addr->sa_family == PF_INET) {
717 __be32 s_addr = daddr_in->sin_addr.s_addr;
718 req->ip_address.ip_type = BE2_IPV4;
Mike Christie0e438952012-04-03 23:41:51 -0500719 req->ip_address.addr[0] = s_addr & 0x000000ff;
720 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
721 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
722 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530723 req->tcp_port = ntohs(daddr_in->sin_port);
724 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
725 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
726 beiscsi_ep->ip_type = BE2_IPV4;
727 } else if (dst_addr->sa_family == PF_INET6) {
728 req->ip_address.ip_type = BE2_IPV6;
Mike Christie0e438952012-04-03 23:41:51 -0500729 memcpy(&req->ip_address.addr,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530730 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
731 req->tcp_port = ntohs(daddr_in6->sin6_port);
732 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
733 memcpy(&beiscsi_ep->dst6_addr,
734 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
735 beiscsi_ep->ip_type = BE2_IPV6;
736 } else{
John Soni Jose99bc5d52012-08-20 23:00:18 +0530737 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
738 "BG_%d : unknown addr family %d\n",
739 dst_addr->sa_family);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530740 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal5db3f332010-07-22 04:24:22 +0530741 free_mcc_tag(&phba->ctrl, tag);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530742 return -EINVAL;
743
744 }
745 req->cid = cid;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530746 i = phba->nxt_cqid++;
747 if (phba->nxt_cqid == phba->num_cpus)
748 phba->nxt_cqid = 0;
749 req->cq_id = phwi_context->be_cq[i].id;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530750 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
751 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530752 req->defq_id = def_hdr_id;
753 req->hdr_ring_id = def_hdr_id;
754 req->data_ring_id = def_data_id;
755 req->do_offload = 1;
756 req->dataout_template_pa.lo = ptemplate_address->lo;
757 req->dataout_template_pa.hi = ptemplate_address->hi;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530758 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
759 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
760 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530761 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530762 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530763 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530764}
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530765
Mike Christie0e438952012-04-03 23:41:51 -0500766unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530767{
768 struct be_ctrl_info *ctrl = &phba->ctrl;
Mike Christie0e438952012-04-03 23:41:51 -0500769 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
770 struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
771 struct be_cmd_get_all_if_id_req *pbe_allid = req;
772 int status = 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530773
Mike Christie0e438952012-04-03 23:41:51 -0500774 memset(wrb, 0, sizeof(*wrb));
775
776 spin_lock(&ctrl->mbox_lock);
777
778 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
779 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
780 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
781 sizeof(*req));
782 status = be_mbox_notify(ctrl);
783 if (!status)
784 phba->interface_handle = pbe_allid->if_hndl_list[0];
785 else {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530786 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
787 "BG_%d : Failed in mgmt_get_all_if_id\n");
Mike Christie0e438952012-04-03 23:41:51 -0500788 }
789 spin_unlock(&ctrl->mbox_lock);
790
791 return status;
792}
793
John Soni Josee175def2012-10-20 04:45:40 +0530794/*
795 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
796 * @phba: Driver priv structure
797 * @nonemb_cmd: Address of the MBX command issued
798 * @resp_buf: Buffer to copy the MBX cmd response
799 * @resp_buf_len: respone lenght to be copied
800 *
801 **/
Mike Christie0e438952012-04-03 23:41:51 -0500802static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
803 struct be_dma_mem *nonemb_cmd, void *resp_buf,
804 int resp_buf_len)
805{
806 struct be_ctrl_info *ctrl = &phba->ctrl;
807 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
Mike Christie0e438952012-04-03 23:41:51 -0500808 struct be_sge *sge;
809 unsigned int tag;
810 int rc = 0;
811
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530812 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530813 tag = alloc_mcc_tag(phba);
814 if (!tag) {
815 spin_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500816 rc = -ENOMEM;
817 goto free_cmd;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530818 }
Mike Christie0e438952012-04-03 23:41:51 -0500819 memset(wrb, 0, sizeof(*wrb));
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530820 wrb->tag0 |= tag;
Mike Christie0e438952012-04-03 23:41:51 -0500821 sge = nonembedded_sgl(wrb);
822
823 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
824 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
John Soni Josee175def2012-10-20 04:45:40 +0530825 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
Mike Christie0e438952012-04-03 23:41:51 -0500826 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530827
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530828 be_mcc_notify(phba);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530829 spin_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500830
John Soni Josee175def2012-10-20 04:45:40 +0530831 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
832 if (rc) {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700833 /* Check if the IOCTL needs to be re-issued */
834 if (rc == -EAGAIN)
835 return rc;
836
John Soni Jose99bc5d52012-08-20 23:00:18 +0530837 beiscsi_log(phba, KERN_ERR,
838 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
John Soni Josee175def2012-10-20 04:45:40 +0530839 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
840
John Soni Josee175def2012-10-20 04:45:40 +0530841 goto free_cmd;
Mike Christie0e438952012-04-03 23:41:51 -0500842 }
843
844 if (resp_buf)
845 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
846
Mike Christie0e438952012-04-03 23:41:51 -0500847free_cmd:
848 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
849 nonemb_cmd->va, nonemb_cmd->dma);
850 return rc;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530851}
852
Mike Christie0e438952012-04-03 23:41:51 -0500853static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
854 int iscsi_cmd, int size)
855{
Mike Christieb83d5432012-05-23 20:40:54 -0500856 cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
Mike Christie0e438952012-04-03 23:41:51 -0500857 if (!cmd->va) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530858 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
859 "BG_%d : Failed to allocate memory for if info\n");
Mike Christie0e438952012-04-03 23:41:51 -0500860 return -ENOMEM;
861 }
Mike Christieb83d5432012-05-23 20:40:54 -0500862 memset(cmd->va, 0, size);
Mike Christie0e438952012-04-03 23:41:51 -0500863 cmd->size = size;
864 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
865 return 0;
866}
867
868static int
869mgmt_static_ip_modify(struct beiscsi_hba *phba,
870 struct be_cmd_get_if_info_resp *if_info,
871 struct iscsi_iface_param_info *ip_param,
872 struct iscsi_iface_param_info *subnet_param,
873 uint32_t ip_action)
874{
875 struct be_cmd_set_ip_addr_req *req;
876 struct be_dma_mem nonemb_cmd;
877 uint32_t ip_type;
878 int rc;
879
880 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
881 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
882 sizeof(*req));
883 if (rc)
884 return rc;
885
886 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
887 BE2_IPV6 : BE2_IPV4 ;
888
889 req = nonemb_cmd.va;
890 req->ip_params.record_entry_count = 1;
891 req->ip_params.ip_record.action = ip_action;
892 req->ip_params.ip_record.interface_hndl =
893 phba->interface_handle;
894 req->ip_params.ip_record.ip_addr.size_of_structure =
895 sizeof(struct be_ip_addr_subnet_format);
896 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
897
898 if (ip_action == IP_ACTION_ADD) {
899 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
900 ip_param->len);
901
902 if (subnet_param)
903 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
904 subnet_param->value, subnet_param->len);
905 } else {
906 memcpy(req->ip_params.ip_record.ip_addr.addr,
907 if_info->ip_addr.addr, ip_param->len);
908
909 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
910 if_info->ip_addr.subnet_mask, ip_param->len);
911 }
912
913 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
914 if (rc < 0)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530915 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
916 "BG_%d : Failed to Modify existing IP Address\n");
Mike Christie0e438952012-04-03 23:41:51 -0500917 return rc;
918}
919
920static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
921 uint32_t gtway_action, uint32_t param_len)
922{
923 struct be_cmd_set_def_gateway_req *req;
924 struct be_dma_mem nonemb_cmd;
925 int rt_val;
926
927
928 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
929 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
930 sizeof(*req));
931 if (rt_val)
932 return rt_val;
933
934 req = nonemb_cmd.va;
935 req->action = gtway_action;
936 req->ip_addr.ip_type = BE2_IPV4;
937
938 memcpy(req->ip_addr.addr, gt_addr, param_len);
939
940 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
941}
942
943int mgmt_set_ip(struct beiscsi_hba *phba,
944 struct iscsi_iface_param_info *ip_param,
945 struct iscsi_iface_param_info *subnet_param,
946 uint32_t boot_proto)
947{
948 struct be_cmd_get_def_gateway_resp gtway_addr_set;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700949 struct be_cmd_get_if_info_resp *if_info;
Mike Christie0e438952012-04-03 23:41:51 -0500950 struct be_cmd_set_dhcp_req *dhcpreq;
951 struct be_cmd_rel_dhcp_req *reldhcp;
952 struct be_dma_mem nonemb_cmd;
953 uint8_t *gtway_addr;
954 uint32_t ip_type;
955 int rc;
956
957 if (mgmt_get_all_if_id(phba))
958 return -EIO;
959
Mike Christie0e438952012-04-03 23:41:51 -0500960 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
961 BE2_IPV6 : BE2_IPV4 ;
962
963 rc = mgmt_get_if_info(phba, ip_type, &if_info);
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700964 if (rc) {
965 kfree(if_info);
Mike Christie0e438952012-04-03 23:41:51 -0500966 return rc;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700967 }
Mike Christie0e438952012-04-03 23:41:51 -0500968
969 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700970 if (if_info->dhcp_state) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530971 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
972 "BG_%d : DHCP Already Enabled\n");
Mike Christie0e438952012-04-03 23:41:51 -0500973 return 0;
974 }
975 /* The ip_param->len is 1 in DHCP case. Setting
976 proper IP len as this it is used while
977 freeing the Static IP.
978 */
979 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
980 IP_V6_LEN : IP_V4_LEN;
981
982 } else {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700983 if (if_info->dhcp_state) {
Mike Christie0e438952012-04-03 23:41:51 -0500984
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700985 memset(if_info, 0, sizeof(*if_info));
Mike Christie0e438952012-04-03 23:41:51 -0500986 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
987 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
988 sizeof(*reldhcp));
989
990 if (rc)
991 return rc;
992
993 reldhcp = nonemb_cmd.va;
994 reldhcp->interface_hndl = phba->interface_handle;
995 reldhcp->ip_type = ip_type;
996
997 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
998 if (rc < 0) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530999 beiscsi_log(phba, KERN_WARNING,
1000 BEISCSI_LOG_CONFIG,
1001 "BG_%d : Failed to Delete existing dhcp\n");
Mike Christie0e438952012-04-03 23:41:51 -05001002 return rc;
1003 }
1004 }
1005 }
1006
1007 /* Delete the Static IP Set */
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001008 if (if_info->ip_addr.addr[0]) {
1009 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
Mike Christie0e438952012-04-03 23:41:51 -05001010 IP_ACTION_DEL);
1011 if (rc)
1012 return rc;
1013 }
1014
1015 /* Delete the Gateway settings if mode change is to DHCP */
1016 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1017 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1018 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1019 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301020 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1021 "BG_%d : Failed to Get Gateway Addr\n");
Mike Christie0e438952012-04-03 23:41:51 -05001022 return rc;
1023 }
1024
1025 if (gtway_addr_set.ip_addr.addr[0]) {
1026 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1027 rc = mgmt_modify_gateway(phba, gtway_addr,
1028 IP_ACTION_DEL, IP_V4_LEN);
1029
1030 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301031 beiscsi_log(phba, KERN_WARNING,
1032 BEISCSI_LOG_CONFIG,
1033 "BG_%d : Failed to clear Gateway Addr Set\n");
Mike Christie0e438952012-04-03 23:41:51 -05001034 return rc;
1035 }
1036 }
1037 }
1038
1039 /* Set Adapter to DHCP/Static Mode */
1040 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1041 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1042 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1043 sizeof(*dhcpreq));
1044 if (rc)
1045 return rc;
1046
1047 dhcpreq = nonemb_cmd.va;
1048 dhcpreq->flags = BLOCKING;
1049 dhcpreq->retry_count = 1;
1050 dhcpreq->interface_hndl = phba->interface_handle;
1051 dhcpreq->ip_type = BE2_DHCP_V4;
1052
1053 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1054 } else {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001055 return mgmt_static_ip_modify(phba, if_info, ip_param,
Mike Christie0e438952012-04-03 23:41:51 -05001056 subnet_param, IP_ACTION_ADD);
1057 }
1058
1059 return rc;
1060}
1061
1062int mgmt_set_gateway(struct beiscsi_hba *phba,
1063 struct iscsi_iface_param_info *gateway_param)
1064{
1065 struct be_cmd_get_def_gateway_resp gtway_addr_set;
1066 uint8_t *gtway_addr;
1067 int rt_val;
1068
1069 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1070 rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1071 if (rt_val) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301072 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1073 "BG_%d : Failed to Get Gateway Addr\n");
Mike Christie0e438952012-04-03 23:41:51 -05001074 return rt_val;
1075 }
1076
1077 if (gtway_addr_set.ip_addr.addr[0]) {
1078 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1079 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1080 gateway_param->len);
1081 if (rt_val) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301082 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1083 "BG_%d : Failed to clear Gateway Addr Set\n");
Mike Christie0e438952012-04-03 23:41:51 -05001084 return rt_val;
1085 }
1086 }
1087
1088 gtway_addr = (uint8_t *)&gateway_param->value;
1089 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1090 gateway_param->len);
1091
1092 if (rt_val)
John Soni Jose99bc5d52012-08-20 23:00:18 +05301093 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1094 "BG_%d : Failed to Set Gateway Addr\n");
Mike Christie0e438952012-04-03 23:41:51 -05001095
1096 return rt_val;
1097}
1098
1099int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1100 struct be_cmd_get_def_gateway_resp *gateway)
1101{
1102 struct be_cmd_get_def_gateway_req *req;
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_DEFAULT_GATEWAY,
1108 sizeof(*gateway));
1109 if (rc)
1110 return rc;
1111
1112 req = nonemb_cmd.va;
1113 req->ip_type = ip_type;
1114
1115 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1116 sizeof(*gateway));
1117}
1118
1119int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001120 struct be_cmd_get_if_info_resp **if_info)
Mike Christie0e438952012-04-03 23:41:51 -05001121{
1122 struct be_cmd_get_if_info_req *req;
1123 struct be_dma_mem nonemb_cmd;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001124 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
Mike Christie0e438952012-04-03 23:41:51 -05001125 int rc;
1126
1127 if (mgmt_get_all_if_id(phba))
1128 return -EIO;
1129
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001130 do {
1131 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1132 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1133 ioctl_size);
1134 if (rc)
1135 return rc;
Mike Christie0e438952012-04-03 23:41:51 -05001136
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001137 req = nonemb_cmd.va;
1138 req->interface_hndl = phba->interface_handle;
1139 req->ip_type = ip_type;
Mike Christie0e438952012-04-03 23:41:51 -05001140
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001141 /* Allocate memory for if_info */
1142 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1143 if (!*if_info) {
1144 beiscsi_log(phba, KERN_ERR,
1145 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1146 "BG_%d : Memory Allocation Failure\n");
1147
1148 /* Free the DMA memory for the IOCTL issuing */
1149 pci_free_consistent(phba->ctrl.pdev,
1150 nonemb_cmd.size,
1151 nonemb_cmd.va,
1152 nonemb_cmd.dma);
1153 return -ENOMEM;
1154 }
1155
1156 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1157 ioctl_size);
1158
1159 /* Check if the error is because of Insufficent_Buffer */
1160 if (rc == -EAGAIN) {
1161
1162 /* Get the new memory size */
1163 ioctl_size = ((struct be_cmd_resp_hdr *)
1164 nonemb_cmd.va)->actual_resp_len;
1165 ioctl_size += sizeof(struct be_cmd_req_hdr);
1166
1167 /* Free the previous allocated DMA memory */
1168 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1169 nonemb_cmd.va,
1170 nonemb_cmd.dma);
1171
1172 /* Free the virtual memory */
1173 kfree(*if_info);
1174 } else
1175 break;
1176 } while (true);
1177 return rc;
Mike Christie0e438952012-04-03 23:41:51 -05001178}
1179
1180int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1181 struct be_cmd_get_nic_conf_resp *nic)
1182{
1183 struct be_dma_mem nonemb_cmd;
1184 int rc;
1185
1186 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1187 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1188 sizeof(*nic));
1189 if (rc)
1190 return rc;
1191
1192 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1193}
1194
1195
1196
John Soni Jose21771992012-04-03 23:41:49 -05001197unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1198{
1199 unsigned int tag = 0;
1200 struct be_mcc_wrb *wrb;
1201 struct be_cmd_hba_name *req;
1202 struct be_ctrl_info *ctrl = &phba->ctrl;
1203
1204 spin_lock(&ctrl->mbox_lock);
1205 tag = alloc_mcc_tag(phba);
1206 if (!tag) {
1207 spin_unlock(&ctrl->mbox_lock);
1208 return tag;
1209 }
1210
1211 wrb = wrb_from_mccq(phba);
1212 req = embedded_payload(wrb);
1213 wrb->tag0 |= tag;
1214 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1215 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1216 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1217 sizeof(*req));
1218
1219 be_mcc_notify(phba);
1220 spin_unlock(&ctrl->mbox_lock);
1221 return tag;
1222}
John Soni Josec62eef02012-04-03 23:41:52 -05001223
1224unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1225{
1226 unsigned int tag = 0;
1227 struct be_mcc_wrb *wrb;
1228 struct be_cmd_ntwk_link_status_req *req;
1229 struct be_ctrl_info *ctrl = &phba->ctrl;
1230
1231 spin_lock(&ctrl->mbox_lock);
1232 tag = alloc_mcc_tag(phba);
1233 if (!tag) {
1234 spin_unlock(&ctrl->mbox_lock);
1235 return tag;
1236 }
1237
1238 wrb = wrb_from_mccq(phba);
1239 req = embedded_payload(wrb);
1240 wrb->tag0 |= tag;
1241 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1242 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1243 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1244 sizeof(*req));
1245
1246 be_mcc_notify(phba);
1247 spin_unlock(&ctrl->mbox_lock);
1248 return tag;
1249}
John Soni Jose9aef4202012-08-20 23:00:08 +05301250
1251/**
1252 * be_mgmt_get_boot_shandle()- Get the session handle
1253 * @phba: device priv structure instance
1254 * @s_handle: session handle returned for boot session.
1255 *
1256 * Get the boot target session handle. In case of
1257 * crashdump mode driver has to issue and MBX Cmd
1258 * for FW to login to boot target
1259 *
1260 * return
1261 * Success: 0
1262 * Failure: Non-Zero value
1263 *
1264 **/
1265int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1266 unsigned int *s_handle)
1267{
1268 struct be_cmd_get_boot_target_resp *boot_resp;
1269 struct be_mcc_wrb *wrb;
John Soni Josee175def2012-10-20 04:45:40 +05301270 unsigned int tag;
John Soni Jose9aef4202012-08-20 23:00:08 +05301271 uint8_t boot_retry = 3;
John Soni Josee175def2012-10-20 04:45:40 +05301272 int rc;
John Soni Jose9aef4202012-08-20 23:00:08 +05301273
1274 do {
1275 /* Get the Boot Target Session Handle and Count*/
1276 tag = mgmt_get_boot_target(phba);
1277 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301278 beiscsi_log(phba, KERN_ERR,
1279 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1280 "BG_%d : Getting Boot Target Info Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301281 return -EAGAIN;
John Soni Josee175def2012-10-20 04:45:40 +05301282 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301283
John Soni Josee175def2012-10-20 04:45:40 +05301284 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1285 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301286 beiscsi_log(phba, KERN_ERR,
1287 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
John Soni Josee175def2012-10-20 04:45:40 +05301288 "BG_%d : MBX CMD get_boot_target Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301289 return -EBUSY;
1290 }
John Soni Josee175def2012-10-20 04:45:40 +05301291
John Soni Jose9aef4202012-08-20 23:00:08 +05301292 boot_resp = embedded_payload(wrb);
1293
1294 /* Check if the there are any Boot targets configured */
1295 if (!boot_resp->boot_session_count) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301296 beiscsi_log(phba, KERN_INFO,
1297 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1298 "BG_%d ;No boot targets configured\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301299 return -ENXIO;
1300 }
1301
1302 /* FW returns the session handle of the boot session */
1303 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1304 *s_handle = boot_resp->boot_session_handle;
1305 return 0;
1306 }
1307
1308 /* Issue MBX Cmd to FW to login to the boot target */
1309 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1310 INVALID_SESS_HANDLE);
1311 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301312 beiscsi_log(phba, KERN_ERR,
1313 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1314 "BG_%d : mgmt_reopen_session Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301315 return -EAGAIN;
John Soni Josee175def2012-10-20 04:45:40 +05301316 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301317
John Soni Josee175def2012-10-20 04:45:40 +05301318 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1319 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301320 beiscsi_log(phba, KERN_ERR,
1321 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
John Soni Josee175def2012-10-20 04:45:40 +05301322 "BG_%d : mgmt_reopen_session Failed");
1323 return rc;
John Soni Jose9aef4202012-08-20 23:00:08 +05301324 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301325 } while (--boot_retry);
1326
1327 /* Couldn't log into the boot target */
John Soni Jose99bc5d52012-08-20 23:00:18 +05301328 beiscsi_log(phba, KERN_ERR,
1329 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1330 "BG_%d : Login to Boot Target Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301331 return -ENXIO;
1332}
John Soni Jose6f722382012-08-20 23:00:43 +05301333
1334/**
1335 * mgmt_set_vlan()- Issue and wait for CMD completion
1336 * @phba: device private structure instance
1337 * @vlan_tag: VLAN tag
1338 *
1339 * Issue the MBX Cmd and wait for the completion of the
1340 * command.
1341 *
1342 * returns
1343 * Success: 0
1344 * Failure: Non-Xero Value
1345 **/
1346int mgmt_set_vlan(struct beiscsi_hba *phba,
1347 uint16_t vlan_tag)
1348{
John Soni Josee175def2012-10-20 04:45:40 +05301349 int rc;
1350 unsigned int tag;
1351 struct be_mcc_wrb *wrb = NULL;
John Soni Jose6f722382012-08-20 23:00:43 +05301352
1353 tag = be_cmd_set_vlan(phba, vlan_tag);
1354 if (!tag) {
1355 beiscsi_log(phba, KERN_ERR,
1356 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1357 "BG_%d : VLAN Setting Failed\n");
1358 return -EBUSY;
John Soni Jose6f722382012-08-20 23:00:43 +05301359 }
1360
John Soni Josee175def2012-10-20 04:45:40 +05301361 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1362 if (rc) {
1363 beiscsi_log(phba, KERN_ERR,
1364 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1365 "BS_%d : VLAN MBX Cmd Failed\n");
1366 return rc;
1367 }
1368 return rc;
John Soni Jose6f722382012-08-20 23:00:43 +05301369}
John Soni Jose5cac7592012-10-20 04:42:25 +05301370
1371/**
1372 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1373 * @dev: ptr to device not used.
1374 * @attr: device attribute, not used.
1375 * @buf: contains formatted text driver name and version
1376 *
1377 * return
1378 * size of the formatted string
1379 **/
1380ssize_t
1381beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1382 char *buf)
1383{
1384 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1385}
John Soni Joseacb96932012-10-20 04:44:35 +05301386
John Soni Jose26000db2012-10-20 04:45:06 +05301387/**
Jayamohan Kallickal22661e22013-04-05 20:38:28 -07001388 * beiscsi_fw_ver_disp()- Display Firmware Version
1389 * @dev: ptr to device not used.
1390 * @attr: device attribute, not used.
1391 * @buf: contains formatted text Firmware version
1392 *
1393 * return
1394 * size of the formatted string
1395 **/
1396ssize_t
1397beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1398 char *buf)
1399{
1400 struct Scsi_Host *shost = class_to_shost(dev);
1401 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1402
1403 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1404}
1405
1406/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001407 * beiscsi_active_session_disp()- Display Sessions Active
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001408 * @dev: ptr to device not used.
1409 * @attr: device attribute, not used.
1410 * @buf: contains formatted text Session Count
1411 *
1412 * return
1413 * size of the formatted string
1414 **/
1415ssize_t
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001416beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001417 char *buf)
1418{
1419 struct Scsi_Host *shost = class_to_shost(dev);
1420 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001421 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001422
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001423 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1424 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1425 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1426 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1427 len += snprintf(buf+len, PAGE_SIZE - len,
1428 "ULP%d : %d\n", ulp_num,
1429 (total_cids - avlbl_cids));
1430 } else
1431 len += snprintf(buf+len, PAGE_SIZE - len,
1432 "ULP%d : %d\n", ulp_num, 0);
1433 }
1434
1435 return len;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001436}
1437
1438/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001439 * beiscsi_free_session_disp()- Display Avaliable Session
1440 * @dev: ptr to device not used.
1441 * @attr: device attribute, not used.
1442 * @buf: contains formatted text Session Count
1443 *
1444 * return
1445 * size of the formatted string
1446 **/
1447ssize_t
1448beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1449 char *buf)
1450{
1451 struct Scsi_Host *shost = class_to_shost(dev);
1452 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1453 uint16_t ulp_num, len = 0;
1454
1455 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1456 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1457 len += snprintf(buf+len, PAGE_SIZE - len,
1458 "ULP%d : %d\n", ulp_num,
1459 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1460 else
1461 len += snprintf(buf+len, PAGE_SIZE - len,
1462 "ULP%d : %d\n", ulp_num, 0);
1463 }
1464
1465 return len;
1466}
1467
1468/**
John Soni Jose26000db2012-10-20 04:45:06 +05301469 * beiscsi_adap_family_disp()- Display adapter family.
1470 * @dev: ptr to device to get priv structure
1471 * @attr: device attribute, not used.
1472 * @buf: contains formatted text driver name and version
1473 *
1474 * return
1475 * size of the formatted string
1476 **/
1477ssize_t
1478beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1479 char *buf)
1480{
1481 uint16_t dev_id = 0;
1482 struct Scsi_Host *shost = class_to_shost(dev);
1483 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1484
1485 dev_id = phba->pcidev->device;
1486 switch (dev_id) {
1487 case BE_DEVICE_ID1:
1488 case OC_DEVICE_ID1:
1489 case OC_DEVICE_ID2:
1490 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1491 break;
1492 case BE_DEVICE_ID2:
1493 case OC_DEVICE_ID3:
1494 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1495 break;
1496 case OC_SKH_ID1:
1497 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1498 break;
1499 default:
1500 return snprintf(buf, PAGE_SIZE,
Masanari Iidab23f7a02013-04-18 00:12:55 +09001501 "Unknown Adapter Family: 0x%x\n", dev_id);
John Soni Jose26000db2012-10-20 04:45:06 +05301502 break;
1503 }
1504}
1505
Jayamohan Kallickald3fea9a2013-09-28 15:35:53 -07001506/**
1507 * beiscsi_phys_port()- Display Physical Port Identifier
1508 * @dev: ptr to device not used.
1509 * @attr: device attribute, not used.
1510 * @buf: contains formatted text port identifier
1511 *
1512 * return
1513 * size of the formatted string
1514 **/
1515ssize_t
1516beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1517 char *buf)
1518{
1519 struct Scsi_Host *shost = class_to_shost(dev);
1520 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1521
1522 return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1523 phba->fw_config.phys_port);
1524}
John Soni Jose26000db2012-10-20 04:45:06 +05301525
John Soni Joseacb96932012-10-20 04:44:35 +05301526void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1527 struct wrb_handle *pwrb_handle,
1528 struct be_mem_descriptor *mem_descr)
1529{
1530 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1531
1532 memset(pwrb, 0, sizeof(*pwrb));
1533 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1534 max_send_data_segment_length, pwrb,
1535 params->dw[offsetof(struct amap_beiscsi_offload_params,
1536 max_send_data_segment_length) / 32]);
1537 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1538 BE_TGT_CTX_UPDT_CMD);
1539 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1540 first_burst_length,
1541 pwrb,
1542 params->dw[offsetof(struct amap_beiscsi_offload_params,
1543 first_burst_length) / 32]);
1544 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1545 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1546 erl) / 32] & OFFLD_PARAMS_ERL));
1547 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1548 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1549 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1550 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1551 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1552 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1553 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1554 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1555 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1556 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1557 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1558 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1559 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1560 pwrb,
1561 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1562 exp_statsn) / 32] + 1));
1563 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1564 pwrb, pwrb_handle->wrb_index);
1565
1566 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1567 max_burst_length, pwrb, params->dw[offsetof
1568 (struct amap_beiscsi_offload_params,
1569 max_burst_length) / 32]);
1570
1571 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1572 pwrb, pwrb_handle->nxt_wrb_index);
1573 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1574 session_state, pwrb, 0);
1575 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1576 pwrb, 1);
1577 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1578 pwrb, 0);
1579 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1580 0);
1581
1582 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1583 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1584 pad_buffer_addr_hi, pwrb,
1585 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1586 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1587 pad_buffer_addr_lo, pwrb,
1588 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1589}
1590
1591void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1592 struct wrb_handle *pwrb_handle)
1593{
1594 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1595
1596 memset(pwrb, 0, sizeof(*pwrb));
1597
John Soni Joseacb96932012-10-20 04:44:35 +05301598 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1599 max_burst_length, pwrb, params->dw[offsetof
1600 (struct amap_beiscsi_offload_params,
1601 max_burst_length) / 32]);
1602 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1603 type, pwrb,
1604 BE_TGT_CTX_UPDT_CMD);
1605 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1606 ptr2nextwrb,
1607 pwrb, pwrb_handle->nxt_wrb_index);
1608 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1609 pwrb, pwrb_handle->wrb_index);
1610 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1611 max_send_data_segment_length, pwrb,
1612 params->dw[offsetof(struct amap_beiscsi_offload_params,
1613 max_send_data_segment_length) / 32]);
1614 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1615 first_burst_length, pwrb,
1616 params->dw[offsetof(struct amap_beiscsi_offload_params,
1617 first_burst_length) / 32]);
1618 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
Jayamohan Kallickal73316132013-09-28 15:35:41 -07001619 max_recv_dataseg_len, pwrb,
1620 params->dw[offsetof(struct amap_beiscsi_offload_params,
1621 max_recv_data_segment_length) / 32]);
John Soni Joseacb96932012-10-20 04:44:35 +05301622 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1623 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1624 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1625 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1626 erl) / 32] & OFFLD_PARAMS_ERL));
1627 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1628 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1629 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1630 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1631 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1632 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1633 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1634 ir2t, pwrb,
1635 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1636 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1637 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1638 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1639 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1640 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1641 data_seq_inorder,
1642 pwrb,
1643 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1644 data_seq_inorder) / 32] &
1645 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1646 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1647 pdu_seq_inorder,
1648 pwrb,
1649 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1650 pdu_seq_inorder) / 32] &
1651 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1652 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1653 pwrb,
1654 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1655 max_r2t) / 32] &
1656 OFFLD_PARAMS_MAX_R2T) >> 8);
1657 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1658 pwrb,
1659 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1660 exp_statsn) / 32] + 1));
1661}