2 * Copyright (C) 2005 - 2011 Emulex
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.
10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
12 * Contact Information:
13 * linux-drivers@emulex.com
17 * Costa Mesa, CA 92626
22 #include <scsi/scsi_transport_iscsi.h>
24 unsigned int beiscsi_get_boot_target(struct beiscsi_hba
*phba
)
26 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
27 struct be_mcc_wrb
*wrb
;
28 struct be_cmd_req_get_mac_addr
*req
;
31 SE_DEBUG(DBG_LVL_8
, "In bescsi_get_boot_target\n");
32 spin_lock(&ctrl
->mbox_lock
);
33 tag
= alloc_mcc_tag(phba
);
35 spin_unlock(&ctrl
->mbox_lock
);
39 wrb
= wrb_from_mccq(phba
);
40 req
= embedded_payload(wrb
);
42 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
43 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI_INI
,
44 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET
,
48 spin_unlock(&ctrl
->mbox_lock
);
52 unsigned int beiscsi_get_session_info(struct beiscsi_hba
*phba
,
53 u32 boot_session_handle
,
54 struct be_dma_mem
*nonemb_cmd
)
56 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
57 struct be_mcc_wrb
*wrb
;
59 struct be_cmd_req_get_session
*req
;
60 struct be_cmd_resp_get_session
*resp
;
63 SE_DEBUG(DBG_LVL_8
, "In beiscsi_get_session_info\n");
64 spin_lock(&ctrl
->mbox_lock
);
65 tag
= alloc_mcc_tag(phba
);
67 spin_unlock(&ctrl
->mbox_lock
);
71 nonemb_cmd
->size
= sizeof(*resp
);
73 memset(req
, 0, sizeof(*req
));
74 wrb
= wrb_from_mccq(phba
);
75 sge
= nonembedded_sgl(wrb
);
80 be_wrb_hdr_prepare(wrb
, sizeof(*req
), false, 1);
81 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI_INI
,
82 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION
,
84 req
->session_handle
= boot_session_handle
;
85 sge
->pa_hi
= cpu_to_le32(upper_32_bits(nonemb_cmd
->dma
));
86 sge
->pa_lo
= cpu_to_le32(nonemb_cmd
->dma
& 0xFFFFFFFF);
87 sge
->len
= cpu_to_le32(nonemb_cmd
->size
);
90 spin_unlock(&ctrl
->mbox_lock
);
94 int mgmt_get_fw_config(struct be_ctrl_info
*ctrl
,
95 struct beiscsi_hba
*phba
)
97 struct be_mcc_wrb
*wrb
= wrb_from_mbox(&ctrl
->mbox_mem
);
98 struct be_fw_cfg
*req
= embedded_payload(wrb
);
101 spin_lock(&ctrl
->mbox_lock
);
102 memset(wrb
, 0, sizeof(*wrb
));
104 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
106 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_COMMON
,
107 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG
, sizeof(*req
));
108 status
= be_mbox_notify(ctrl
);
110 struct be_fw_cfg
*pfw_cfg
;
112 phba
->fw_config
.phys_port
= pfw_cfg
->phys_port
;
113 phba
->fw_config
.iscsi_icd_start
=
114 pfw_cfg
->ulp
[0].icd_base
;
115 phba
->fw_config
.iscsi_icd_count
=
116 pfw_cfg
->ulp
[0].icd_count
;
117 phba
->fw_config
.iscsi_cid_start
=
118 pfw_cfg
->ulp
[0].sq_base
;
119 phba
->fw_config
.iscsi_cid_count
=
120 pfw_cfg
->ulp
[0].sq_count
;
121 if (phba
->fw_config
.iscsi_cid_count
> (BE2_MAX_SESSIONS
/ 2)) {
123 "FW reported MAX CXNS as %d\t"
124 "Max Supported = %d.\n",
125 phba
->fw_config
.iscsi_cid_count
,
127 phba
->fw_config
.iscsi_cid_count
= BE2_MAX_SESSIONS
/ 2;
130 shost_printk(KERN_WARNING
, phba
->shost
,
131 "Failed in mgmt_get_fw_config\n");
134 spin_unlock(&ctrl
->mbox_lock
);
138 int mgmt_check_supported_fw(struct be_ctrl_info
*ctrl
,
139 struct beiscsi_hba
*phba
)
141 struct be_dma_mem nonemb_cmd
;
142 struct be_mcc_wrb
*wrb
= wrb_from_mbox(&ctrl
->mbox_mem
);
143 struct be_mgmt_controller_attributes
*req
;
144 struct be_sge
*sge
= nonembedded_sgl(wrb
);
147 nonemb_cmd
.va
= pci_alloc_consistent(ctrl
->pdev
,
148 sizeof(struct be_mgmt_controller_attributes
),
150 if (nonemb_cmd
.va
== NULL
) {
152 "Failed to allocate memory for mgmt_check_supported_fw"
156 nonemb_cmd
.size
= sizeof(struct be_mgmt_controller_attributes
);
158 memset(req
, 0, sizeof(*req
));
159 spin_lock(&ctrl
->mbox_lock
);
160 memset(wrb
, 0, sizeof(*wrb
));
161 be_wrb_hdr_prepare(wrb
, sizeof(*req
), false, 1);
162 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_COMMON
,
163 OPCODE_COMMON_GET_CNTL_ATTRIBUTES
, sizeof(*req
));
164 sge
->pa_hi
= cpu_to_le32(upper_32_bits(nonemb_cmd
.dma
));
165 sge
->pa_lo
= cpu_to_le32(nonemb_cmd
.dma
& 0xFFFFFFFF);
166 sge
->len
= cpu_to_le32(nonemb_cmd
.size
);
167 status
= be_mbox_notify(ctrl
);
169 struct be_mgmt_controller_attributes_resp
*resp
= nonemb_cmd
.va
;
170 SE_DEBUG(DBG_LVL_8
, "Firmware version of CMD: %s\n",
171 resp
->params
.hba_attribs
.flashrom_version_string
);
172 SE_DEBUG(DBG_LVL_8
, "Firmware version is : %s\n",
173 resp
->params
.hba_attribs
.firmware_version_string
);
175 "Developer Build, not performing version check...\n");
176 phba
->fw_config
.iscsi_features
=
177 resp
->params
.hba_attribs
.iscsi_features
;
178 SE_DEBUG(DBG_LVL_8
, " phba->fw_config.iscsi_features = %d\n",
179 phba
->fw_config
.iscsi_features
);
181 SE_DEBUG(DBG_LVL_1
, " Failed in mgmt_check_supported_fw\n");
182 spin_unlock(&ctrl
->mbox_lock
);
184 pci_free_consistent(ctrl
->pdev
, nonemb_cmd
.size
,
185 nonemb_cmd
.va
, nonemb_cmd
.dma
);
190 int mgmt_epfw_cleanup(struct beiscsi_hba
*phba
, unsigned short chute
)
192 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
193 struct be_mcc_wrb
*wrb
= wrb_from_mccq(phba
);
194 struct iscsi_cleanup_req
*req
= embedded_payload(wrb
);
197 spin_lock(&ctrl
->mbox_lock
);
198 memset(wrb
, 0, sizeof(*wrb
));
200 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
201 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI
,
202 OPCODE_COMMON_ISCSI_CLEANUP
, sizeof(*req
));
205 req
->hdr_ring_id
= cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba
));
206 req
->data_ring_id
= cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba
));
208 status
= be_mcc_notify_wait(phba
);
210 shost_printk(KERN_WARNING
, phba
->shost
,
211 " mgmt_epfw_cleanup , FAILED\n");
212 spin_unlock(&ctrl
->mbox_lock
);
216 unsigned int mgmt_invalidate_icds(struct beiscsi_hba
*phba
,
217 struct invalidate_command_table
*inv_tbl
,
218 unsigned int num_invalidate
, unsigned int cid
,
219 struct be_dma_mem
*nonemb_cmd
)
222 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
223 struct be_mcc_wrb
*wrb
;
225 struct invalidate_commands_params_in
*req
;
226 unsigned int i
, tag
= 0;
228 spin_lock(&ctrl
->mbox_lock
);
229 tag
= alloc_mcc_tag(phba
);
231 spin_unlock(&ctrl
->mbox_lock
);
235 req
= nonemb_cmd
->va
;
236 memset(req
, 0, sizeof(*req
));
237 wrb
= wrb_from_mccq(phba
);
238 sge
= nonembedded_sgl(wrb
);
241 be_wrb_hdr_prepare(wrb
, sizeof(*req
), false, 1);
242 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI
,
243 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS
,
246 req
->cleanup_type
= CMD_ISCSI_COMMAND_INVALIDATE
;
247 for (i
= 0; i
< num_invalidate
; i
++) {
248 req
->table
[i
].icd
= inv_tbl
->icd
;
249 req
->table
[i
].cid
= inv_tbl
->cid
;
253 sge
->pa_hi
= cpu_to_le32(upper_32_bits(nonemb_cmd
->dma
));
254 sge
->pa_lo
= cpu_to_le32(nonemb_cmd
->dma
& 0xFFFFFFFF);
255 sge
->len
= cpu_to_le32(nonemb_cmd
->size
);
258 spin_unlock(&ctrl
->mbox_lock
);
262 unsigned int mgmt_invalidate_connection(struct beiscsi_hba
*phba
,
263 struct beiscsi_endpoint
*beiscsi_ep
,
265 unsigned short issue_reset
,
266 unsigned short savecfg_flag
)
268 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
269 struct be_mcc_wrb
*wrb
;
270 struct iscsi_invalidate_connection_params_in
*req
;
271 unsigned int tag
= 0;
273 spin_lock(&ctrl
->mbox_lock
);
274 tag
= alloc_mcc_tag(phba
);
276 spin_unlock(&ctrl
->mbox_lock
);
279 wrb
= wrb_from_mccq(phba
);
281 req
= embedded_payload(wrb
);
283 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
284 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI_INI
,
285 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION
,
287 req
->session_handle
= beiscsi_ep
->fw_handle
;
290 req
->cleanup_type
= CMD_ISCSI_CONNECTION_ISSUE_TCP_RST
;
292 req
->cleanup_type
= CMD_ISCSI_CONNECTION_INVALIDATE
;
293 req
->save_cfg
= savecfg_flag
;
295 spin_unlock(&ctrl
->mbox_lock
);
299 unsigned int mgmt_upload_connection(struct beiscsi_hba
*phba
,
300 unsigned short cid
, unsigned int upload_flag
)
302 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
303 struct be_mcc_wrb
*wrb
;
304 struct tcp_upload_params_in
*req
;
305 unsigned int tag
= 0;
307 spin_lock(&ctrl
->mbox_lock
);
308 tag
= alloc_mcc_tag(phba
);
310 spin_unlock(&ctrl
->mbox_lock
);
313 wrb
= wrb_from_mccq(phba
);
314 req
= embedded_payload(wrb
);
317 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
318 be_cmd_hdr_prepare(&req
->hdr
, CMD_COMMON_TCP_UPLOAD
,
319 OPCODE_COMMON_TCP_UPLOAD
, sizeof(*req
));
320 req
->id
= (unsigned short)cid
;
321 req
->upload_type
= (unsigned char)upload_flag
;
323 spin_unlock(&ctrl
->mbox_lock
);
327 int mgmt_open_connection(struct beiscsi_hba
*phba
,
328 struct sockaddr
*dst_addr
,
329 struct beiscsi_endpoint
*beiscsi_ep
,
330 struct be_dma_mem
*nonemb_cmd
)
333 struct hwi_controller
*phwi_ctrlr
;
334 struct hwi_context_memory
*phwi_context
;
335 struct sockaddr_in
*daddr_in
= (struct sockaddr_in
*)dst_addr
;
336 struct sockaddr_in6
*daddr_in6
= (struct sockaddr_in6
*)dst_addr
;
337 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
338 struct be_mcc_wrb
*wrb
;
339 struct tcp_connect_and_offload_in
*req
;
340 unsigned short def_hdr_id
;
341 unsigned short def_data_id
;
342 struct phys_addr template_address
= { 0, 0 };
343 struct phys_addr
*ptemplate_address
;
344 unsigned int tag
= 0;
346 unsigned short cid
= beiscsi_ep
->ep_cid
;
349 phwi_ctrlr
= phba
->phwi_ctrlr
;
350 phwi_context
= phwi_ctrlr
->phwi_ctxt
;
351 def_hdr_id
= (unsigned short)HWI_GET_DEF_HDRQ_ID(phba
);
352 def_data_id
= (unsigned short)HWI_GET_DEF_BUFQ_ID(phba
);
354 ptemplate_address
= &template_address
;
355 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba
, ptemplate_address
);
356 spin_lock(&ctrl
->mbox_lock
);
357 tag
= alloc_mcc_tag(phba
);
359 spin_unlock(&ctrl
->mbox_lock
);
362 wrb
= wrb_from_mccq(phba
);
363 memset(wrb
, 0, sizeof(*wrb
));
364 sge
= nonembedded_sgl(wrb
);
366 req
= nonemb_cmd
->va
;
367 memset(req
, 0, sizeof(*req
));
370 be_wrb_hdr_prepare(wrb
, sizeof(*req
), false, 1);
371 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI
,
372 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD
,
374 if (dst_addr
->sa_family
== PF_INET
) {
375 __be32 s_addr
= daddr_in
->sin_addr
.s_addr
;
376 req
->ip_address
.ip_type
= BE2_IPV4
;
377 req
->ip_address
.ip_address
[0] = s_addr
& 0x000000ff;
378 req
->ip_address
.ip_address
[1] = (s_addr
& 0x0000ff00) >> 8;
379 req
->ip_address
.ip_address
[2] = (s_addr
& 0x00ff0000) >> 16;
380 req
->ip_address
.ip_address
[3] = (s_addr
& 0xff000000) >> 24;
381 req
->tcp_port
= ntohs(daddr_in
->sin_port
);
382 beiscsi_ep
->dst_addr
= daddr_in
->sin_addr
.s_addr
;
383 beiscsi_ep
->dst_tcpport
= ntohs(daddr_in
->sin_port
);
384 beiscsi_ep
->ip_type
= BE2_IPV4
;
385 } else if (dst_addr
->sa_family
== PF_INET6
) {
386 req
->ip_address
.ip_type
= BE2_IPV6
;
387 memcpy(&req
->ip_address
.ip_address
,
388 &daddr_in6
->sin6_addr
.in6_u
.u6_addr8
, 16);
389 req
->tcp_port
= ntohs(daddr_in6
->sin6_port
);
390 beiscsi_ep
->dst_tcpport
= ntohs(daddr_in6
->sin6_port
);
391 memcpy(&beiscsi_ep
->dst6_addr
,
392 &daddr_in6
->sin6_addr
.in6_u
.u6_addr8
, 16);
393 beiscsi_ep
->ip_type
= BE2_IPV6
;
395 shost_printk(KERN_ERR
, phba
->shost
, "unknown addr family %d\n",
396 dst_addr
->sa_family
);
397 spin_unlock(&ctrl
->mbox_lock
);
398 free_mcc_tag(&phba
->ctrl
, tag
);
403 i
= phba
->nxt_cqid
++;
404 if (phba
->nxt_cqid
== phba
->num_cpus
)
406 req
->cq_id
= phwi_context
->be_cq
[i
].id
;
407 SE_DEBUG(DBG_LVL_8
, "i=%d cq_id=%d\n", i
, req
->cq_id
);
408 req
->defq_id
= def_hdr_id
;
409 req
->hdr_ring_id
= def_hdr_id
;
410 req
->data_ring_id
= def_data_id
;
412 req
->dataout_template_pa
.lo
= ptemplate_address
->lo
;
413 req
->dataout_template_pa
.hi
= ptemplate_address
->hi
;
414 sge
->pa_hi
= cpu_to_le32(upper_32_bits(nonemb_cmd
->dma
));
415 sge
->pa_lo
= cpu_to_le32(nonemb_cmd
->dma
& 0xFFFFFFFF);
416 sge
->len
= cpu_to_le32(nonemb_cmd
->size
);
418 spin_unlock(&ctrl
->mbox_lock
);
422 unsigned int be_cmd_get_mac_addr(struct beiscsi_hba
*phba
)
424 struct be_ctrl_info
*ctrl
= &phba
->ctrl
;
425 struct be_mcc_wrb
*wrb
;
426 struct be_cmd_req_get_mac_addr
*req
;
427 unsigned int tag
= 0;
429 SE_DEBUG(DBG_LVL_8
, "In be_cmd_get_mac_addr\n");
430 spin_lock(&ctrl
->mbox_lock
);
431 tag
= alloc_mcc_tag(phba
);
433 spin_unlock(&ctrl
->mbox_lock
);
437 wrb
= wrb_from_mccq(phba
);
438 req
= embedded_payload(wrb
);
440 be_wrb_hdr_prepare(wrb
, sizeof(*req
), true, 0);
441 be_cmd_hdr_prepare(&req
->hdr
, CMD_SUBSYSTEM_ISCSI
,
442 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG
,
446 spin_unlock(&ctrl
->mbox_lock
);