blob: a3e56487616c2b5ea37c25010fd6c9d58d12da19 [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
Jayamohan Kallickal73af08e2014-05-05 21:41:26 -0400158int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
159 struct be_set_eqd *set_eqd, int num)
160{
161 struct be_ctrl_info *ctrl = &phba->ctrl;
162 struct be_mcc_wrb *wrb;
163 struct be_cmd_req_modify_eq_delay *req;
164 unsigned int tag = 0;
165 int i;
166
167 spin_lock(&ctrl->mbox_lock);
168 tag = alloc_mcc_tag(phba);
169 if (!tag) {
170 spin_unlock(&ctrl->mbox_lock);
171 return tag;
172 }
173
174 wrb = wrb_from_mccq(phba);
175 req = embedded_payload(wrb);
176
177 wrb->tag0 |= tag;
178 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
179 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
180 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
181
182 req->num_eq = cpu_to_le32(num);
183 for (i = 0; i < num; i++) {
184 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
185 req->delay[i].phase = 0;
186 req->delay[i].delay_multiplier =
187 cpu_to_le32(set_eqd[i].delay_multiplier);
188 }
189
190 be_mcc_notify(phba);
191 spin_unlock(&ctrl->mbox_lock);
192 return tag;
193}
194
John Soni Jose9aef4202012-08-20 23:00:08 +0530195/**
196 * mgmt_reopen_session()- Reopen a session based on reopen_type
197 * @phba: Device priv structure instance
198 * @reopen_type: Type of reopen_session FW should do.
199 * @sess_handle: Session Handle of the session to be re-opened
200 *
201 * return
202 * the TAG used for MBOX Command
203 *
204 **/
205unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
206 unsigned int reopen_type,
207 unsigned int sess_handle)
208{
209 struct be_ctrl_info *ctrl = &phba->ctrl;
210 struct be_mcc_wrb *wrb;
211 struct be_cmd_reopen_session_req *req;
212 unsigned int tag = 0;
213
John Soni Jose99bc5d52012-08-20 23:00:18 +0530214 beiscsi_log(phba, KERN_INFO,
215 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
216 "BG_%d : In bescsi_get_boot_target\n");
217
John Soni Jose9aef4202012-08-20 23:00:08 +0530218 spin_lock(&ctrl->mbox_lock);
219 tag = alloc_mcc_tag(phba);
220 if (!tag) {
221 spin_unlock(&ctrl->mbox_lock);
222 return tag;
223 }
224
225 wrb = wrb_from_mccq(phba);
226 req = embedded_payload(wrb);
227 wrb->tag0 |= tag;
228 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
229 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
230 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
231 sizeof(struct be_cmd_reopen_session_resp));
232
233 /* set the reopen_type,sess_handle */
234 req->reopen_type = reopen_type;
235 req->session_handle = sess_handle;
236
237 be_mcc_notify(phba);
238 spin_unlock(&ctrl->mbox_lock);
239 return tag;
240}
241
Mike Christie0e438952012-04-03 23:41:51 -0500242unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530243{
244 struct be_ctrl_info *ctrl = &phba->ctrl;
245 struct be_mcc_wrb *wrb;
Mike Christie0e438952012-04-03 23:41:51 -0500246 struct be_cmd_get_boot_target_req *req;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530247 unsigned int tag = 0;
248
John Soni Jose99bc5d52012-08-20 23:00:18 +0530249 beiscsi_log(phba, KERN_INFO,
250 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
251 "BG_%d : In bescsi_get_boot_target\n");
252
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530253 spin_lock(&ctrl->mbox_lock);
254 tag = alloc_mcc_tag(phba);
255 if (!tag) {
256 spin_unlock(&ctrl->mbox_lock);
257 return tag;
258 }
259
260 wrb = wrb_from_mccq(phba);
261 req = embedded_payload(wrb);
262 wrb->tag0 |= tag;
263 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
264 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
265 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
Mike Christie0e438952012-04-03 23:41:51 -0500266 sizeof(struct be_cmd_get_boot_target_resp));
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530267
268 be_mcc_notify(phba);
269 spin_unlock(&ctrl->mbox_lock);
270 return tag;
271}
272
Mike Christie0e438952012-04-03 23:41:51 -0500273unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
274 u32 boot_session_handle,
275 struct be_dma_mem *nonemb_cmd)
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530276{
277 struct be_ctrl_info *ctrl = &phba->ctrl;
278 struct be_mcc_wrb *wrb;
279 unsigned int tag = 0;
Mike Christie0e438952012-04-03 23:41:51 -0500280 struct be_cmd_get_session_req *req;
281 struct be_cmd_get_session_resp *resp;
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530282 struct be_sge *sge;
283
John Soni Jose99bc5d52012-08-20 23:00:18 +0530284 beiscsi_log(phba, KERN_INFO,
285 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
286 "BG_%d : In beiscsi_get_session_info\n");
287
Jayamohan Kallickalc7acc5b2010-07-22 04:29:18 +0530288 spin_lock(&ctrl->mbox_lock);
289 tag = alloc_mcc_tag(phba);
290 if (!tag) {
291 spin_unlock(&ctrl->mbox_lock);
292 return tag;
293 }
294
295 nonemb_cmd->size = sizeof(*resp);
296 req = nonemb_cmd->va;
297 memset(req, 0, sizeof(*req));
298 wrb = wrb_from_mccq(phba);
299 sge = nonembedded_sgl(wrb);
300 wrb->tag0 |= tag;
301
302
303 wrb->tag0 |= tag;
304 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
305 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
306 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
307 sizeof(*resp));
308 req->session_handle = boot_session_handle;
309 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
310 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
311 sge->len = cpu_to_le32(nonemb_cmd->size);
312
313 be_mcc_notify(phba);
314 spin_unlock(&ctrl->mbox_lock);
315 return tag;
316}
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530317
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700318/**
319 * mgmt_get_fw_config()- Get the FW config for the function
320 * @ctrl: ptr to Ctrl Info
321 * @phba: ptr to the dev priv structure
322 *
323 * Get the FW config and resources available for the function.
324 * The resources are created based on the count received here.
325 *
326 * return
327 * Success: 0
328 * Failure: Non-Zero Value
329 **/
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530330int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530331 struct beiscsi_hba *phba)
332{
333 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
334 struct be_fw_cfg *req = embedded_payload(wrb);
335 int status = 0;
336
337 spin_lock(&ctrl->mbox_lock);
338 memset(wrb, 0, sizeof(*wrb));
339
340 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
341
342 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700343 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
344 EMBED_MBX_MAX_PAYLOAD_SIZE);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530345 status = be_mbox_notify(ctrl);
346 if (!status) {
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700347 uint8_t ulp_num = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530348 struct be_fw_cfg *pfw_cfg;
349 pfw_cfg = req;
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700350
Jayamohan Kallickal68c26a32013-09-28 15:35:54 -0700351 if (!is_chip_be2_be3r(phba)) {
352 phba->fw_config.eqid_count = pfw_cfg->eqid_count;
353 phba->fw_config.cqid_count = pfw_cfg->cqid_count;
354
355 beiscsi_log(phba, KERN_INFO,
356 BEISCSI_LOG_INIT,
357 "BG_%d : EQ_Count : %d CQ_Count : %d\n",
358 phba->fw_config.eqid_count,
359 phba->fw_config.cqid_count);
360 }
361
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700362 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++)
363 if (pfw_cfg->ulp[ulp_num].ulp_mode &
364 BEISCSI_ULP_ISCSI_INI_MODE)
365 set_bit(ulp_num,
Jayamohan Kallickal8a86e832013-09-28 15:35:45 -0700366 &phba->fw_config.ulp_supported);
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700367
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530368 phba->fw_config.phys_port = pfw_cfg->phys_port;
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700369 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
370 if (test_bit(ulp_num, &phba->fw_config.ulp_supported)) {
371
372 phba->fw_config.iscsi_cid_start[ulp_num] =
373 pfw_cfg->ulp[ulp_num].sq_base;
374 phba->fw_config.iscsi_cid_count[ulp_num] =
375 pfw_cfg->ulp[ulp_num].sq_count;
376
377 phba->fw_config.iscsi_icd_start[ulp_num] =
378 pfw_cfg->ulp[ulp_num].icd_base;
379 phba->fw_config.iscsi_icd_count[ulp_num] =
380 pfw_cfg->ulp[ulp_num].icd_count;
381
382 phba->fw_config.iscsi_chain_start[ulp_num] =
383 pfw_cfg->chain_icd[ulp_num].chain_base;
384 phba->fw_config.iscsi_chain_count[ulp_num] =
385 pfw_cfg->chain_icd[ulp_num].chain_count;
386
387 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
388 "BG_%d : Function loaded on ULP : %d\n"
389 "\tiscsi_cid_count : %d\n"
Jayamohan Kallickalcf987b72013-09-28 15:35:59 -0700390 "\tiscsi_cid_start : %d\n"
391 "\t iscsi_icd_count : %d\n"
392 "\t iscsi_icd_start : %d\n",
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700393 ulp_num,
394 phba->fw_config.
395 iscsi_cid_count[ulp_num],
396 phba->fw_config.
Jayamohan Kallickalcf987b72013-09-28 15:35:59 -0700397 iscsi_cid_start[ulp_num],
398 phba->fw_config.
399 iscsi_icd_count[ulp_num],
400 phba->fw_config.
401 iscsi_icd_start[ulp_num]);
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700402 }
Jayamohan Kallickal7da50872010-01-05 05:04:12 +0530403 }
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700404
405 phba->fw_config.dual_ulp_aware = (pfw_cfg->function_mode &
406 BEISCSI_FUNC_DUA_MODE);
407
408 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
409 "BG_%d : DUA Mode : 0x%x\n",
410 phba->fw_config.dual_ulp_aware);
411
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530412 } else {
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700413 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
John Soni Jose99bc5d52012-08-20 23:00:18 +0530414 "BG_%d : Failed in mgmt_get_fw_config\n");
Jayamohan Kallickal843ae752013-09-28 15:35:44 -0700415 status = -EINVAL;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530416 }
417
418 spin_unlock(&ctrl->mbox_lock);
419 return status;
420}
421
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530422int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530423 struct beiscsi_hba *phba)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530424{
425 struct be_dma_mem nonemb_cmd;
426 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
427 struct be_mgmt_controller_attributes *req;
428 struct be_sge *sge = nonembedded_sgl(wrb);
429 int status = 0;
430
431 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
432 sizeof(struct be_mgmt_controller_attributes),
433 &nonemb_cmd.dma);
434 if (nonemb_cmd.va == NULL) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530435 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
436 "BG_%d : Failed to allocate memory for "
437 "mgmt_check_supported_fw\n");
Jayamohan Kallickald3ad2bb2010-07-22 04:16:38 +0530438 return -ENOMEM;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530439 }
440 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
441 req = nonemb_cmd.va;
Jayamohan Kallickalf98c96b2010-02-11 05:11:15 +0530442 memset(req, 0, sizeof(*req));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530443 spin_lock(&ctrl->mbox_lock);
444 memset(wrb, 0, sizeof(*wrb));
445 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
446 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
447 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
448 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
449 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
450 sge->len = cpu_to_le32(nonemb_cmd.size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530451 status = be_mbox_notify(ctrl);
452 if (!status) {
453 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530454 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
455 "BG_%d : Firmware Version of CMD : %s\n"
456 "Firmware Version is : %s\n"
457 "Developer Build, not performing version check...\n",
458 resp->params.hba_attribs
459 .flashrom_version_string,
460 resp->params.hba_attribs.
461 firmware_version_string);
462
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530463 phba->fw_config.iscsi_features =
464 resp->params.hba_attribs.iscsi_features;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530465 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
466 "BM_%d : phba->fw_config.iscsi_features = %d\n",
467 phba->fw_config.iscsi_features);
Jayamohan Kallickal22661e22013-04-05 20:38:28 -0700468 memcpy(phba->fw_ver_str, resp->params.hba_attribs.
469 firmware_version_string, BEISCSI_VER_STRLEN);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530470 } else
John Soni Jose99bc5d52012-08-20 23:00:18 +0530471 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
472 "BG_%d : Failed in mgmt_check_supported_fw\n");
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530473 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530474 if (nonemb_cmd.va)
475 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
476 nonemb_cmd.va, nonemb_cmd.dma);
477
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530478 return status;
479}
480
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500481unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
482 struct beiscsi_hba *phba,
483 struct bsg_job *job,
484 struct be_dma_mem *nonemb_cmd)
485{
486 struct be_cmd_resp_hdr *resp;
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400487 struct be_mcc_wrb *wrb;
488 struct be_sge *mcc_sge;
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500489 unsigned int tag = 0;
490 struct iscsi_bsg_request *bsg_req = job->request;
491 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
492 unsigned short region, sector_size, sector, offset;
493
494 nonemb_cmd->size = job->request_payload.payload_len;
495 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
496 resp = nonemb_cmd->va;
497 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
498 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
499 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
500 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
501 req->region = region;
502 req->sector = sector;
503 req->offset = offset;
504 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500505
506 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
507 case BEISCSI_WRITE_FLASH:
508 offset = sector * sector_size + offset;
509 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
510 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
511 sg_copy_to_buffer(job->request_payload.sg_list,
512 job->request_payload.sg_cnt,
513 nonemb_cmd->va + offset, job->request_len);
514 break;
515 case BEISCSI_READ_FLASH:
516 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
517 OPCODE_COMMON_READ_FLASH, sizeof(*req));
518 break;
519 default:
John Soni Jose99bc5d52012-08-20 23:00:18 +0530520 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
521 "BG_%d : Unsupported cmd = 0x%x\n\n",
522 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
523
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500524 spin_unlock(&ctrl->mbox_lock);
525 return -ENOSYS;
526 }
527
528 tag = alloc_mcc_tag(phba);
529 if (!tag) {
530 spin_unlock(&ctrl->mbox_lock);
531 return tag;
532 }
533
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400534 wrb = wrb_from_mccq(phba);
535 mcc_sge = nonembedded_sgl(wrb);
Jayamohan Kallickalffce3e22012-04-03 23:41:50 -0500536 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
537 job->request_payload.sg_cnt);
538 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
539 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
540 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
541 wrb->tag0 |= tag;
542
543 be_mcc_notify(phba);
544
545 spin_unlock(&ctrl->mbox_lock);
546 return tag;
547}
548
Jayamohan Kallickalbd41c2b2013-09-28 15:35:51 -0700549/**
550 * mgmt_epfw_cleanup()- Inform FW to cleanup data structures.
551 * @phba: pointer to dev priv structure
552 * @ulp_num: ULP number.
553 *
554 * return
555 * Success: 0
556 * Failure: Non-Zero Value
557 **/
558int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short ulp_num)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530559{
560 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530561 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530562 struct iscsi_cleanup_req *req = embedded_payload(wrb);
563 int status = 0;
564
565 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530566
567 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
568 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
569 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
570
Jayamohan Kallickalbd41c2b2013-09-28 15:35:51 -0700571 req->chute = (1 << ulp_num);
572 req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba, ulp_num));
573 req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba, ulp_num));
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530574
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530575 status = be_mcc_notify_wait(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530576 if (status)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530577 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_INIT,
578 "BG_%d : mgmt_epfw_cleanup , FAILED\n");
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530579 spin_unlock(&ctrl->mbox_lock);
580 return status;
581}
582
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530583unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530584 struct invalidate_command_table *inv_tbl,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530585 unsigned int num_invalidate, unsigned int cid,
586 struct be_dma_mem *nonemb_cmd)
587
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530588{
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530589 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530590 struct be_mcc_wrb *wrb;
591 struct be_sge *sge;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530592 struct invalidate_commands_params_in *req;
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530593 unsigned int i, tag = 0;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530594
595 spin_lock(&ctrl->mbox_lock);
596 tag = alloc_mcc_tag(phba);
597 if (!tag) {
598 spin_unlock(&ctrl->mbox_lock);
599 return tag;
600 }
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530601
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530602 req = nonemb_cmd->va;
Jayamohan Kallickalf98c96b2010-02-11 05:11:15 +0530603 memset(req, 0, sizeof(*req));
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530604 wrb = wrb_from_mccq(phba);
605 sge = nonembedded_sgl(wrb);
606 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530607
608 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
609 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
610 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
611 sizeof(*req));
612 req->ref_handle = 0;
613 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
Jayamohan Kallickal41831222010-02-20 08:02:39 +0530614 for (i = 0; i < num_invalidate; i++) {
615 req->table[i].icd = inv_tbl->icd;
616 req->table[i].cid = inv_tbl->cid;
617 req->icd_count++;
618 inv_tbl++;
619 }
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530620 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
621 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
622 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530623
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_invalidate_connection(struct beiscsi_hba *phba,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530630 struct beiscsi_endpoint *beiscsi_ep,
631 unsigned short cid,
632 unsigned short issue_reset,
633 unsigned short savecfg_flag)
634{
635 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530636 struct be_mcc_wrb *wrb;
637 struct iscsi_invalidate_connection_params_in *req;
638 unsigned int tag = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530639
640 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530641 tag = alloc_mcc_tag(phba);
642 if (!tag) {
643 spin_unlock(&ctrl->mbox_lock);
644 return tag;
645 }
646 wrb = wrb_from_mccq(phba);
647 wrb->tag0 |= tag;
648 req = embedded_payload(wrb);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530649
650 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
651 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
652 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
653 sizeof(*req));
654 req->session_handle = beiscsi_ep->fw_handle;
655 req->cid = cid;
656 if (issue_reset)
657 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
658 else
659 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
660 req->save_cfg = savecfg_flag;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530661 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530662 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530663 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530664}
665
Jayamohan Kallickal03a12312010-07-22 04:17:16 +0530666unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530667 unsigned short cid, unsigned int upload_flag)
668{
669 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530670 struct be_mcc_wrb *wrb;
671 struct tcp_upload_params_in *req;
672 unsigned int tag = 0;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530673
674 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530675 tag = alloc_mcc_tag(phba);
676 if (!tag) {
677 spin_unlock(&ctrl->mbox_lock);
678 return tag;
679 }
680 wrb = wrb_from_mccq(phba);
681 req = embedded_payload(wrb);
682 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530683
684 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
685 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
686 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
687 req->id = (unsigned short)cid;
688 req->upload_type = (unsigned char)upload_flag;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530689 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530690 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530691 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530692}
693
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700694/**
695 * mgmt_open_connection()- Establish a TCP CXN
696 * @dst_addr: Destination Address
697 * @beiscsi_ep: ptr to device endpoint struct
698 * @nonemb_cmd: ptr to memory allocated for command
699 *
700 * return
701 * Success: Tag number of the MBX Command issued
702 * Failure: Error code
703 **/
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530704int mgmt_open_connection(struct beiscsi_hba *phba,
705 struct sockaddr *dst_addr,
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530706 struct beiscsi_endpoint *beiscsi_ep,
707 struct be_dma_mem *nonemb_cmd)
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530708{
709 struct hwi_controller *phwi_ctrlr;
710 struct hwi_context_memory *phwi_context;
711 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
712 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
713 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530714 struct be_mcc_wrb *wrb;
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400715 struct tcp_connect_and_offload_in_v1 *req;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530716 unsigned short def_hdr_id;
717 unsigned short def_data_id;
718 struct phys_addr template_address = { 0, 0 };
719 struct phys_addr *ptemplate_address;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530720 unsigned int tag = 0;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700721 unsigned int i, ulp_num;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530722 unsigned short cid = beiscsi_ep->ep_cid;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530723 struct be_sge *sge;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530724
725 phwi_ctrlr = phba->phwi_ctrlr;
726 phwi_context = phwi_ctrlr->phwi_ctxt;
Jayamohan Kallickal1e4be6f2013-09-28 15:35:50 -0700727
728 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
729
730 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
731 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530732
733 ptemplate_address = &template_address;
734 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
735 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530736 tag = alloc_mcc_tag(phba);
737 if (!tag) {
738 spin_unlock(&ctrl->mbox_lock);
739 return tag;
740 }
741 wrb = wrb_from_mccq(phba);
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530742 sge = nonembedded_sgl(wrb);
743
744 req = nonemb_cmd->va;
745 memset(req, 0, sizeof(*req));
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530746 wrb->tag0 |= tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530747
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400748 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530749 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
750 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400751 nonemb_cmd->size);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530752 if (dst_addr->sa_family == PF_INET) {
753 __be32 s_addr = daddr_in->sin_addr.s_addr;
754 req->ip_address.ip_type = BE2_IPV4;
Mike Christie0e438952012-04-03 23:41:51 -0500755 req->ip_address.addr[0] = s_addr & 0x000000ff;
756 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
757 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
758 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530759 req->tcp_port = ntohs(daddr_in->sin_port);
760 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
761 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
762 beiscsi_ep->ip_type = BE2_IPV4;
763 } else if (dst_addr->sa_family == PF_INET6) {
764 req->ip_address.ip_type = BE2_IPV6;
Mike Christie0e438952012-04-03 23:41:51 -0500765 memcpy(&req->ip_address.addr,
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530766 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
767 req->tcp_port = ntohs(daddr_in6->sin6_port);
768 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
769 memcpy(&beiscsi_ep->dst6_addr,
770 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
771 beiscsi_ep->ip_type = BE2_IPV6;
772 } else{
John Soni Jose99bc5d52012-08-20 23:00:18 +0530773 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
774 "BG_%d : unknown addr family %d\n",
775 dst_addr->sa_family);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530776 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal5db3f332010-07-22 04:24:22 +0530777 free_mcc_tag(&phba->ctrl, tag);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530778 return -EINVAL;
779
780 }
781 req->cid = cid;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530782 i = phba->nxt_cqid++;
783 if (phba->nxt_cqid == phba->num_cpus)
784 phba->nxt_cqid = 0;
785 req->cq_id = phwi_context->be_cq[i].id;
John Soni Jose99bc5d52012-08-20 23:00:18 +0530786 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
787 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530788 req->defq_id = def_hdr_id;
789 req->hdr_ring_id = def_hdr_id;
790 req->data_ring_id = def_data_id;
791 req->do_offload = 1;
792 req->dataout_template_pa.lo = ptemplate_address->lo;
793 req->dataout_template_pa.hi = ptemplate_address->hi;
Jayamohan Kallickal3cbb7a72010-07-22 04:27:47 +0530794 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
795 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
796 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalb3c202d2014-05-05 21:41:27 -0400797
798 if (!is_chip_be2_be3r(phba)) {
799 req->hdr.version = MBX_CMD_VER1;
800 req->tcp_window_size = 0;
801 req->tcp_window_scale_count = 2;
802 }
803
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530804 be_mcc_notify(phba);
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530805 spin_unlock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530806 return tag;
Jayamohan Kallickal6733b392009-09-05 07:36:35 +0530807}
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530808
Mike Christie0e438952012-04-03 23:41:51 -0500809unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530810{
811 struct be_ctrl_info *ctrl = &phba->ctrl;
Mike Christie0e438952012-04-03 23:41:51 -0500812 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
813 struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
814 struct be_cmd_get_all_if_id_req *pbe_allid = req;
815 int status = 0;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530816
Mike Christie0e438952012-04-03 23:41:51 -0500817 memset(wrb, 0, sizeof(*wrb));
818
819 spin_lock(&ctrl->mbox_lock);
820
821 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
822 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
823 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
824 sizeof(*req));
825 status = be_mbox_notify(ctrl);
826 if (!status)
827 phba->interface_handle = pbe_allid->if_hndl_list[0];
828 else {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530829 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
830 "BG_%d : Failed in mgmt_get_all_if_id\n");
Mike Christie0e438952012-04-03 23:41:51 -0500831 }
832 spin_unlock(&ctrl->mbox_lock);
833
834 return status;
835}
836
John Soni Josee175def2012-10-20 04:45:40 +0530837/*
838 * mgmt_exec_nonemb_cmd()- Execute Non Embedded MBX Cmd
839 * @phba: Driver priv structure
840 * @nonemb_cmd: Address of the MBX command issued
841 * @resp_buf: Buffer to copy the MBX cmd response
842 * @resp_buf_len: respone lenght to be copied
843 *
844 **/
Mike Christie0e438952012-04-03 23:41:51 -0500845static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
846 struct be_dma_mem *nonemb_cmd, void *resp_buf,
847 int resp_buf_len)
848{
849 struct be_ctrl_info *ctrl = &phba->ctrl;
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400850 struct be_mcc_wrb *wrb;
Mike Christie0e438952012-04-03 23:41:51 -0500851 struct be_sge *sge;
852 unsigned int tag;
853 int rc = 0;
854
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530855 spin_lock(&ctrl->mbox_lock);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530856 tag = alloc_mcc_tag(phba);
857 if (!tag) {
858 spin_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500859 rc = -ENOMEM;
860 goto free_cmd;
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530861 }
Jayamohan Kallickaldaa8dc02014-05-05 21:41:24 -0400862
863 wrb = wrb_from_mccq(phba);
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530864 wrb->tag0 |= tag;
Mike Christie0e438952012-04-03 23:41:51 -0500865 sge = nonembedded_sgl(wrb);
866
867 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
868 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
John Soni Josee175def2012-10-20 04:45:40 +0530869 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
Mike Christie0e438952012-04-03 23:41:51 -0500870 sge->len = cpu_to_le32(nonemb_cmd->size);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530871
Jayamohan Kallickal756d29c2010-01-05 05:10:46 +0530872 be_mcc_notify(phba);
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530873 spin_unlock(&ctrl->mbox_lock);
Mike Christie0e438952012-04-03 23:41:51 -0500874
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500875 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd);
Mike Christie0e438952012-04-03 23:41:51 -0500876
877 if (resp_buf)
878 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
879
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -0500880 if (rc) {
881 /* Check if the MBX Cmd needs to be re-issued */
882 if (rc == -EAGAIN)
883 return rc;
884
885 beiscsi_log(phba, KERN_WARNING,
886 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
887 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
888
889 if (rc != -EBUSY)
890 goto free_cmd;
891 else
892 return rc;
893 }
Mike Christie0e438952012-04-03 23:41:51 -0500894free_cmd:
895 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
896 nonemb_cmd->va, nonemb_cmd->dma);
897 return rc;
Jayamohan Kallickalbfead3b2009-10-23 11:52:33 +0530898}
899
Mike Christie0e438952012-04-03 23:41:51 -0500900static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
901 int iscsi_cmd, int size)
902{
Mike Christieb83d5432012-05-23 20:40:54 -0500903 cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
Mike Christie0e438952012-04-03 23:41:51 -0500904 if (!cmd->va) {
John Soni Jose99bc5d52012-08-20 23:00:18 +0530905 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
906 "BG_%d : Failed to allocate memory for if info\n");
Mike Christie0e438952012-04-03 23:41:51 -0500907 return -ENOMEM;
908 }
Mike Christieb83d5432012-05-23 20:40:54 -0500909 memset(cmd->va, 0, size);
Mike Christie0e438952012-04-03 23:41:51 -0500910 cmd->size = size;
911 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
912 return 0;
913}
914
915static int
916mgmt_static_ip_modify(struct beiscsi_hba *phba,
917 struct be_cmd_get_if_info_resp *if_info,
918 struct iscsi_iface_param_info *ip_param,
919 struct iscsi_iface_param_info *subnet_param,
920 uint32_t ip_action)
921{
922 struct be_cmd_set_ip_addr_req *req;
923 struct be_dma_mem nonemb_cmd;
924 uint32_t ip_type;
925 int rc;
926
927 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
928 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
929 sizeof(*req));
930 if (rc)
931 return rc;
932
933 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
934 BE2_IPV6 : BE2_IPV4 ;
935
936 req = nonemb_cmd.va;
937 req->ip_params.record_entry_count = 1;
938 req->ip_params.ip_record.action = ip_action;
939 req->ip_params.ip_record.interface_hndl =
940 phba->interface_handle;
941 req->ip_params.ip_record.ip_addr.size_of_structure =
942 sizeof(struct be_ip_addr_subnet_format);
943 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
944
945 if (ip_action == IP_ACTION_ADD) {
946 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
947 ip_param->len);
948
949 if (subnet_param)
950 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
951 subnet_param->value, subnet_param->len);
952 } else {
953 memcpy(req->ip_params.ip_record.ip_addr.addr,
954 if_info->ip_addr.addr, ip_param->len);
955
956 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
957 if_info->ip_addr.subnet_mask, ip_param->len);
958 }
959
960 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
961 if (rc < 0)
John Soni Jose99bc5d52012-08-20 23:00:18 +0530962 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
963 "BG_%d : Failed to Modify existing IP Address\n");
Mike Christie0e438952012-04-03 23:41:51 -0500964 return rc;
965}
966
967static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
968 uint32_t gtway_action, uint32_t param_len)
969{
970 struct be_cmd_set_def_gateway_req *req;
971 struct be_dma_mem nonemb_cmd;
972 int rt_val;
973
974
975 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
976 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
977 sizeof(*req));
978 if (rt_val)
979 return rt_val;
980
981 req = nonemb_cmd.va;
982 req->action = gtway_action;
983 req->ip_addr.ip_type = BE2_IPV4;
984
985 memcpy(req->ip_addr.addr, gt_addr, param_len);
986
987 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
988}
989
990int mgmt_set_ip(struct beiscsi_hba *phba,
991 struct iscsi_iface_param_info *ip_param,
992 struct iscsi_iface_param_info *subnet_param,
993 uint32_t boot_proto)
994{
995 struct be_cmd_get_def_gateway_resp gtway_addr_set;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -0700996 struct be_cmd_get_if_info_resp *if_info;
Mike Christie0e438952012-04-03 23:41:51 -0500997 struct be_cmd_set_dhcp_req *dhcpreq;
998 struct be_cmd_rel_dhcp_req *reldhcp;
999 struct be_dma_mem nonemb_cmd;
1000 uint8_t *gtway_addr;
1001 uint32_t ip_type;
1002 int rc;
1003
1004 if (mgmt_get_all_if_id(phba))
1005 return -EIO;
1006
Mike Christie0e438952012-04-03 23:41:51 -05001007 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1008 BE2_IPV6 : BE2_IPV4 ;
1009
1010 rc = mgmt_get_if_info(phba, ip_type, &if_info);
Tomas Henzlbeff6542014-06-06 14:22:44 +02001011 if (rc)
Mike Christie0e438952012-04-03 23:41:51 -05001012 return rc;
1013
1014 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001015 if (if_info->dhcp_state) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301016 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1017 "BG_%d : DHCP Already Enabled\n");
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001018 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001019 }
1020 /* The ip_param->len is 1 in DHCP case. Setting
1021 proper IP len as this it is used while
1022 freeing the Static IP.
1023 */
1024 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
1025 IP_V6_LEN : IP_V4_LEN;
1026
1027 } else {
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001028 if (if_info->dhcp_state) {
Mike Christie0e438952012-04-03 23:41:51 -05001029
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001030 memset(if_info, 0, sizeof(*if_info));
Mike Christie0e438952012-04-03 23:41:51 -05001031 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1032 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
1033 sizeof(*reldhcp));
1034
1035 if (rc)
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001036 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001037
1038 reldhcp = nonemb_cmd.va;
1039 reldhcp->interface_hndl = phba->interface_handle;
1040 reldhcp->ip_type = ip_type;
1041
1042 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1043 if (rc < 0) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301044 beiscsi_log(phba, KERN_WARNING,
1045 BEISCSI_LOG_CONFIG,
1046 "BG_%d : Failed to Delete existing dhcp\n");
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001047 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001048 }
1049 }
1050 }
1051
1052 /* Delete the Static IP Set */
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001053 if (if_info->ip_addr.addr[0]) {
1054 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
Mike Christie0e438952012-04-03 23:41:51 -05001055 IP_ACTION_DEL);
1056 if (rc)
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001057 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001058 }
1059
1060 /* Delete the Gateway settings if mode change is to DHCP */
1061 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1062 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1063 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1064 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301065 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1066 "BG_%d : Failed to Get Gateway Addr\n");
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001067 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001068 }
1069
1070 if (gtway_addr_set.ip_addr.addr[0]) {
1071 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1072 rc = mgmt_modify_gateway(phba, gtway_addr,
1073 IP_ACTION_DEL, IP_V4_LEN);
1074
1075 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301076 beiscsi_log(phba, KERN_WARNING,
1077 BEISCSI_LOG_CONFIG,
1078 "BG_%d : Failed to clear Gateway Addr Set\n");
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001079 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001080 }
1081 }
1082 }
1083
1084 /* Set Adapter to DHCP/Static Mode */
1085 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
1086 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1087 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
1088 sizeof(*dhcpreq));
1089 if (rc)
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001090 goto exit;
Mike Christie0e438952012-04-03 23:41:51 -05001091
1092 dhcpreq = nonemb_cmd.va;
1093 dhcpreq->flags = BLOCKING;
1094 dhcpreq->retry_count = 1;
1095 dhcpreq->interface_hndl = phba->interface_handle;
1096 dhcpreq->ip_type = BE2_DHCP_V4;
1097
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001098 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
Mike Christie0e438952012-04-03 23:41:51 -05001099 } else {
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001100 rc = mgmt_static_ip_modify(phba, if_info, ip_param,
Mike Christie0e438952012-04-03 23:41:51 -05001101 subnet_param, IP_ACTION_ADD);
1102 }
1103
Maurizio Lombardi6d677262014-06-27 14:55:20 +02001104exit:
1105 kfree(if_info);
Mike Christie0e438952012-04-03 23:41:51 -05001106 return rc;
1107}
1108
1109int mgmt_set_gateway(struct beiscsi_hba *phba,
1110 struct iscsi_iface_param_info *gateway_param)
1111{
1112 struct be_cmd_get_def_gateway_resp gtway_addr_set;
1113 uint8_t *gtway_addr;
1114 int rt_val;
1115
1116 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
1117 rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
1118 if (rt_val) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301119 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1120 "BG_%d : Failed to Get Gateway Addr\n");
Mike Christie0e438952012-04-03 23:41:51 -05001121 return rt_val;
1122 }
1123
1124 if (gtway_addr_set.ip_addr.addr[0]) {
1125 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
1126 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
1127 gateway_param->len);
1128 if (rt_val) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301129 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1130 "BG_%d : Failed to clear Gateway Addr Set\n");
Mike Christie0e438952012-04-03 23:41:51 -05001131 return rt_val;
1132 }
1133 }
1134
1135 gtway_addr = (uint8_t *)&gateway_param->value;
1136 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
1137 gateway_param->len);
1138
1139 if (rt_val)
John Soni Jose99bc5d52012-08-20 23:00:18 +05301140 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1141 "BG_%d : Failed to Set Gateway Addr\n");
Mike Christie0e438952012-04-03 23:41:51 -05001142
1143 return rt_val;
1144}
1145
1146int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1147 struct be_cmd_get_def_gateway_resp *gateway)
1148{
1149 struct be_cmd_get_def_gateway_req *req;
1150 struct be_dma_mem nonemb_cmd;
1151 int rc;
1152
1153 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1154 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
1155 sizeof(*gateway));
1156 if (rc)
1157 return rc;
1158
1159 req = nonemb_cmd.va;
1160 req->ip_type = ip_type;
1161
1162 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
1163 sizeof(*gateway));
1164}
1165
1166int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001167 struct be_cmd_get_if_info_resp **if_info)
Mike Christie0e438952012-04-03 23:41:51 -05001168{
1169 struct be_cmd_get_if_info_req *req;
1170 struct be_dma_mem nonemb_cmd;
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001171 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
Mike Christie0e438952012-04-03 23:41:51 -05001172 int rc;
1173
1174 if (mgmt_get_all_if_id(phba))
1175 return -EIO;
1176
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001177 do {
1178 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1179 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1180 ioctl_size);
1181 if (rc)
1182 return rc;
Mike Christie0e438952012-04-03 23:41:51 -05001183
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001184 req = nonemb_cmd.va;
1185 req->interface_hndl = phba->interface_handle;
1186 req->ip_type = ip_type;
Mike Christie0e438952012-04-03 23:41:51 -05001187
Jayamohan Kallickal1f536d42013-09-28 15:35:56 -07001188 /* Allocate memory for if_info */
1189 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1190 if (!*if_info) {
1191 beiscsi_log(phba, KERN_ERR,
1192 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1193 "BG_%d : Memory Allocation Failure\n");
1194
1195 /* Free the DMA memory for the IOCTL issuing */
1196 pci_free_consistent(phba->ctrl.pdev,
1197 nonemb_cmd.size,
1198 nonemb_cmd.va,
1199 nonemb_cmd.dma);
1200 return -ENOMEM;
1201 }
1202
1203 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1204 ioctl_size);
1205
1206 /* Check if the error is because of Insufficent_Buffer */
1207 if (rc == -EAGAIN) {
1208
1209 /* Get the new memory size */
1210 ioctl_size = ((struct be_cmd_resp_hdr *)
1211 nonemb_cmd.va)->actual_resp_len;
1212 ioctl_size += sizeof(struct be_cmd_req_hdr);
1213
1214 /* Free the previous allocated DMA memory */
1215 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1216 nonemb_cmd.va,
1217 nonemb_cmd.dma);
1218
1219 /* Free the virtual memory */
1220 kfree(*if_info);
1221 } else
1222 break;
1223 } while (true);
1224 return rc;
Mike Christie0e438952012-04-03 23:41:51 -05001225}
1226
1227int mgmt_get_nic_conf(struct beiscsi_hba *phba,
1228 struct be_cmd_get_nic_conf_resp *nic)
1229{
1230 struct be_dma_mem nonemb_cmd;
1231 int rc;
1232
1233 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1234 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
1235 sizeof(*nic));
1236 if (rc)
1237 return rc;
1238
1239 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
1240}
1241
1242
1243
John Soni Jose21771992012-04-03 23:41:49 -05001244unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
1245{
1246 unsigned int tag = 0;
1247 struct be_mcc_wrb *wrb;
1248 struct be_cmd_hba_name *req;
1249 struct be_ctrl_info *ctrl = &phba->ctrl;
1250
1251 spin_lock(&ctrl->mbox_lock);
1252 tag = alloc_mcc_tag(phba);
1253 if (!tag) {
1254 spin_unlock(&ctrl->mbox_lock);
1255 return tag;
1256 }
1257
1258 wrb = wrb_from_mccq(phba);
1259 req = embedded_payload(wrb);
1260 wrb->tag0 |= tag;
1261 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1262 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1263 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME,
1264 sizeof(*req));
1265
1266 be_mcc_notify(phba);
1267 spin_unlock(&ctrl->mbox_lock);
1268 return tag;
1269}
John Soni Josec62eef02012-04-03 23:41:52 -05001270
1271unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
1272{
1273 unsigned int tag = 0;
1274 struct be_mcc_wrb *wrb;
1275 struct be_cmd_ntwk_link_status_req *req;
1276 struct be_ctrl_info *ctrl = &phba->ctrl;
1277
1278 spin_lock(&ctrl->mbox_lock);
1279 tag = alloc_mcc_tag(phba);
1280 if (!tag) {
1281 spin_unlock(&ctrl->mbox_lock);
1282 return tag;
1283 }
1284
1285 wrb = wrb_from_mccq(phba);
1286 req = embedded_payload(wrb);
1287 wrb->tag0 |= tag;
1288 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1289 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1290 OPCODE_COMMON_NTWK_LINK_STATUS_QUERY,
1291 sizeof(*req));
1292
1293 be_mcc_notify(phba);
1294 spin_unlock(&ctrl->mbox_lock);
1295 return tag;
1296}
John Soni Jose9aef4202012-08-20 23:00:08 +05301297
1298/**
1299 * be_mgmt_get_boot_shandle()- Get the session handle
1300 * @phba: device priv structure instance
1301 * @s_handle: session handle returned for boot session.
1302 *
1303 * Get the boot target session handle. In case of
1304 * crashdump mode driver has to issue and MBX Cmd
1305 * for FW to login to boot target
1306 *
1307 * return
1308 * Success: 0
1309 * Failure: Non-Zero value
1310 *
1311 **/
1312int be_mgmt_get_boot_shandle(struct beiscsi_hba *phba,
1313 unsigned int *s_handle)
1314{
1315 struct be_cmd_get_boot_target_resp *boot_resp;
1316 struct be_mcc_wrb *wrb;
John Soni Josee175def2012-10-20 04:45:40 +05301317 unsigned int tag;
John Soni Jose9aef4202012-08-20 23:00:08 +05301318 uint8_t boot_retry = 3;
John Soni Josee175def2012-10-20 04:45:40 +05301319 int rc;
John Soni Jose9aef4202012-08-20 23:00:08 +05301320
1321 do {
1322 /* Get the Boot Target Session Handle and Count*/
1323 tag = mgmt_get_boot_target(phba);
1324 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301325 beiscsi_log(phba, KERN_ERR,
1326 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1327 "BG_%d : Getting Boot Target Info Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301328 return -EAGAIN;
John Soni Josee175def2012-10-20 04:45:40 +05301329 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301330
John Soni Josee175def2012-10-20 04:45:40 +05301331 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL);
1332 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301333 beiscsi_log(phba, KERN_ERR,
1334 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
John Soni Josee175def2012-10-20 04:45:40 +05301335 "BG_%d : MBX CMD get_boot_target Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301336 return -EBUSY;
1337 }
John Soni Josee175def2012-10-20 04:45:40 +05301338
John Soni Jose9aef4202012-08-20 23:00:08 +05301339 boot_resp = embedded_payload(wrb);
1340
1341 /* Check if the there are any Boot targets configured */
1342 if (!boot_resp->boot_session_count) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301343 beiscsi_log(phba, KERN_INFO,
1344 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1345 "BG_%d ;No boot targets configured\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301346 return -ENXIO;
1347 }
1348
1349 /* FW returns the session handle of the boot session */
1350 if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1351 *s_handle = boot_resp->boot_session_handle;
1352 return 0;
1353 }
1354
1355 /* Issue MBX Cmd to FW to login to the boot target */
1356 tag = mgmt_reopen_session(phba, BE_REOPEN_BOOT_SESSIONS,
1357 INVALID_SESS_HANDLE);
1358 if (!tag) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301359 beiscsi_log(phba, KERN_ERR,
1360 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1361 "BG_%d : mgmt_reopen_session Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301362 return -EAGAIN;
John Soni Josee175def2012-10-20 04:45:40 +05301363 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301364
John Soni Josee175def2012-10-20 04:45:40 +05301365 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
1366 if (rc) {
John Soni Jose99bc5d52012-08-20 23:00:18 +05301367 beiscsi_log(phba, KERN_ERR,
1368 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
John Soni Josee175def2012-10-20 04:45:40 +05301369 "BG_%d : mgmt_reopen_session Failed");
1370 return rc;
John Soni Jose9aef4202012-08-20 23:00:08 +05301371 }
John Soni Jose9aef4202012-08-20 23:00:08 +05301372 } while (--boot_retry);
1373
1374 /* Couldn't log into the boot target */
John Soni Jose99bc5d52012-08-20 23:00:18 +05301375 beiscsi_log(phba, KERN_ERR,
1376 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1377 "BG_%d : Login to Boot Target Failed\n");
John Soni Jose9aef4202012-08-20 23:00:08 +05301378 return -ENXIO;
1379}
John Soni Jose6f722382012-08-20 23:00:43 +05301380
1381/**
1382 * mgmt_set_vlan()- Issue and wait for CMD completion
1383 * @phba: device private structure instance
1384 * @vlan_tag: VLAN tag
1385 *
1386 * Issue the MBX Cmd and wait for the completion of the
1387 * command.
1388 *
1389 * returns
1390 * Success: 0
1391 * Failure: Non-Xero Value
1392 **/
1393int mgmt_set_vlan(struct beiscsi_hba *phba,
1394 uint16_t vlan_tag)
1395{
John Soni Josee175def2012-10-20 04:45:40 +05301396 int rc;
1397 unsigned int tag;
John Soni Jose6f722382012-08-20 23:00:43 +05301398
1399 tag = be_cmd_set_vlan(phba, vlan_tag);
1400 if (!tag) {
1401 beiscsi_log(phba, KERN_ERR,
1402 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1403 "BG_%d : VLAN Setting Failed\n");
1404 return -EBUSY;
John Soni Jose6f722382012-08-20 23:00:43 +05301405 }
1406
Jayamohan Kallickal1957aa72014-01-29 02:16:39 -05001407 rc = beiscsi_mccq_compl(phba, tag, NULL, NULL);
John Soni Josee175def2012-10-20 04:45:40 +05301408 if (rc) {
1409 beiscsi_log(phba, KERN_ERR,
1410 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
1411 "BS_%d : VLAN MBX Cmd Failed\n");
1412 return rc;
1413 }
1414 return rc;
John Soni Jose6f722382012-08-20 23:00:43 +05301415}
John Soni Jose5cac7592012-10-20 04:42:25 +05301416
1417/**
1418 * beiscsi_drvr_ver_disp()- Display the driver Name and Version
1419 * @dev: ptr to device not used.
1420 * @attr: device attribute, not used.
1421 * @buf: contains formatted text driver name and version
1422 *
1423 * return
1424 * size of the formatted string
1425 **/
1426ssize_t
1427beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1428 char *buf)
1429{
1430 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1431}
John Soni Joseacb96932012-10-20 04:44:35 +05301432
John Soni Jose26000db2012-10-20 04:45:06 +05301433/**
Jayamohan Kallickal22661e22013-04-05 20:38:28 -07001434 * beiscsi_fw_ver_disp()- Display Firmware Version
1435 * @dev: ptr to device not used.
1436 * @attr: device attribute, not used.
1437 * @buf: contains formatted text Firmware version
1438 *
1439 * return
1440 * size of the formatted string
1441 **/
1442ssize_t
1443beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1444 char *buf)
1445{
1446 struct Scsi_Host *shost = class_to_shost(dev);
1447 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1448
1449 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1450}
1451
1452/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001453 * beiscsi_active_session_disp()- Display Sessions Active
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001454 * @dev: ptr to device not used.
1455 * @attr: device attribute, not used.
1456 * @buf: contains formatted text Session Count
1457 *
1458 * return
1459 * size of the formatted string
1460 **/
1461ssize_t
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001462beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001463 char *buf)
1464{
1465 struct Scsi_Host *shost = class_to_shost(dev);
1466 struct beiscsi_hba *phba = iscsi_host_priv(shost);
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001467 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001468
Jayamohan Kallickal0a3db7c2013-09-28 15:35:49 -07001469 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1470 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1471 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1472 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1473 len += snprintf(buf+len, PAGE_SIZE - len,
1474 "ULP%d : %d\n", ulp_num,
1475 (total_cids - avlbl_cids));
1476 } else
1477 len += snprintf(buf+len, PAGE_SIZE - len,
1478 "ULP%d : %d\n", ulp_num, 0);
1479 }
1480
1481 return len;
Jayamohan Kallickal7ad4dfe2013-04-05 20:38:29 -07001482}
1483
1484/**
Jayamohan Kallickal6103c1f2013-09-28 15:35:52 -07001485 * beiscsi_free_session_disp()- Display Avaliable Session
1486 * @dev: ptr to device not used.
1487 * @attr: device attribute, not used.
1488 * @buf: contains formatted text Session Count
1489 *
1490 * return
1491 * size of the formatted string
1492 **/
1493ssize_t
1494beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1495 char *buf)
1496{
1497 struct Scsi_Host *shost = class_to_shost(dev);
1498 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1499 uint16_t ulp_num, len = 0;
1500
1501 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1502 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1503 len += snprintf(buf+len, PAGE_SIZE - len,
1504 "ULP%d : %d\n", ulp_num,
1505 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1506 else
1507 len += snprintf(buf+len, PAGE_SIZE - len,
1508 "ULP%d : %d\n", ulp_num, 0);
1509 }
1510
1511 return len;
1512}
1513
1514/**
John Soni Jose26000db2012-10-20 04:45:06 +05301515 * beiscsi_adap_family_disp()- Display adapter family.
1516 * @dev: ptr to device to get priv structure
1517 * @attr: device attribute, not used.
1518 * @buf: contains formatted text driver name and version
1519 *
1520 * return
1521 * size of the formatted string
1522 **/
1523ssize_t
1524beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1525 char *buf)
1526{
1527 uint16_t dev_id = 0;
1528 struct Scsi_Host *shost = class_to_shost(dev);
1529 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1530
1531 dev_id = phba->pcidev->device;
1532 switch (dev_id) {
1533 case BE_DEVICE_ID1:
1534 case OC_DEVICE_ID1:
1535 case OC_DEVICE_ID2:
1536 return snprintf(buf, PAGE_SIZE, "BE2 Adapter Family\n");
1537 break;
1538 case BE_DEVICE_ID2:
1539 case OC_DEVICE_ID3:
1540 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1541 break;
1542 case OC_SKH_ID1:
1543 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1544 break;
1545 default:
1546 return snprintf(buf, PAGE_SIZE,
Masanari Iidab23f7a02013-04-18 00:12:55 +09001547 "Unknown Adapter Family: 0x%x\n", dev_id);
John Soni Jose26000db2012-10-20 04:45:06 +05301548 break;
1549 }
1550}
1551
Jayamohan Kallickald3fea9a2013-09-28 15:35:53 -07001552/**
1553 * beiscsi_phys_port()- Display Physical Port Identifier
1554 * @dev: ptr to device not used.
1555 * @attr: device attribute, not used.
1556 * @buf: contains formatted text port identifier
1557 *
1558 * return
1559 * size of the formatted string
1560 **/
1561ssize_t
1562beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1563 char *buf)
1564{
1565 struct Scsi_Host *shost = class_to_shost(dev);
1566 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1567
1568 return snprintf(buf, PAGE_SIZE, "Port Identifier : %d\n",
1569 phba->fw_config.phys_port);
1570}
John Soni Jose26000db2012-10-20 04:45:06 +05301571
John Soni Joseacb96932012-10-20 04:44:35 +05301572void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1573 struct wrb_handle *pwrb_handle,
1574 struct be_mem_descriptor *mem_descr)
1575{
1576 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1577
1578 memset(pwrb, 0, sizeof(*pwrb));
1579 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1580 max_send_data_segment_length, pwrb,
1581 params->dw[offsetof(struct amap_beiscsi_offload_params,
1582 max_send_data_segment_length) / 32]);
1583 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1584 BE_TGT_CTX_UPDT_CMD);
1585 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1586 first_burst_length,
1587 pwrb,
1588 params->dw[offsetof(struct amap_beiscsi_offload_params,
1589 first_burst_length) / 32]);
1590 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1591 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1592 erl) / 32] & OFFLD_PARAMS_ERL));
1593 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1594 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1595 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1596 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1597 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1598 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1599 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1600 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1601 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1602 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1603 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1604 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1605 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1606 pwrb,
1607 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1608 exp_statsn) / 32] + 1));
1609 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1610 pwrb, pwrb_handle->wrb_index);
1611
1612 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1613 max_burst_length, pwrb, params->dw[offsetof
1614 (struct amap_beiscsi_offload_params,
1615 max_burst_length) / 32]);
1616
1617 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1618 pwrb, pwrb_handle->nxt_wrb_index);
1619 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1620 session_state, pwrb, 0);
1621 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1622 pwrb, 1);
1623 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1624 pwrb, 0);
1625 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1626 0);
1627
1628 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1629 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1630 pad_buffer_addr_hi, pwrb,
1631 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1632 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1633 pad_buffer_addr_lo, pwrb,
1634 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1635}
1636
1637void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1638 struct wrb_handle *pwrb_handle)
1639{
1640 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1641
1642 memset(pwrb, 0, sizeof(*pwrb));
1643
John Soni Joseacb96932012-10-20 04:44:35 +05301644 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1645 max_burst_length, pwrb, params->dw[offsetof
1646 (struct amap_beiscsi_offload_params,
1647 max_burst_length) / 32]);
1648 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1649 type, pwrb,
1650 BE_TGT_CTX_UPDT_CMD);
1651 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1652 ptr2nextwrb,
1653 pwrb, pwrb_handle->nxt_wrb_index);
1654 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1655 pwrb, pwrb_handle->wrb_index);
1656 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1657 max_send_data_segment_length, pwrb,
1658 params->dw[offsetof(struct amap_beiscsi_offload_params,
1659 max_send_data_segment_length) / 32]);
1660 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1661 first_burst_length, pwrb,
1662 params->dw[offsetof(struct amap_beiscsi_offload_params,
1663 first_burst_length) / 32]);
1664 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
Jayamohan Kallickal73316132013-09-28 15:35:41 -07001665 max_recv_dataseg_len, pwrb,
1666 params->dw[offsetof(struct amap_beiscsi_offload_params,
1667 max_recv_data_segment_length) / 32]);
John Soni Joseacb96932012-10-20 04:44:35 +05301668 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1669 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1670 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1671 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1672 erl) / 32] & OFFLD_PARAMS_ERL));
1673 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1674 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1675 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1676 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1677 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1678 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1679 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1680 ir2t, pwrb,
1681 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1682 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1683 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1684 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1685 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1686 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1687 data_seq_inorder,
1688 pwrb,
1689 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1690 data_seq_inorder) / 32] &
1691 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1692 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1693 pdu_seq_inorder,
1694 pwrb,
1695 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1696 pdu_seq_inorder) / 32] &
1697 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1698 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1699 pwrb,
1700 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1701 max_r2t) / 32] &
1702 OFFLD_PARAMS_MAX_R2T) >> 8);
1703 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1704 pwrb,
1705 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1706 exp_statsn) / 32] + 1));
1707}