1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/bsg-lib.h>
16#include <scsi/scsi_transport_iscsi.h>
17#include <scsi/scsi_bsg_iscsi.h>
18#include "be_mgmt.h"
19#include "be_iscsi.h"
20#include "be_main.h"
21
22unsigned int mgmt_vendor_specific_fw_cmd(struct be_ctrl_info *ctrl,
23 struct beiscsi_hba *phba,
24 struct bsg_job *job,
25 struct be_dma_mem *nonemb_cmd)
26{
27 struct be_mcc_wrb *wrb;
28 struct be_sge *mcc_sge;
29 unsigned int tag = 0;
30 struct iscsi_bsg_request *bsg_req = job->request;
31 struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
32 unsigned short region, sector_size, sector, offset;
33
34 nonemb_cmd->size = job->request_payload.payload_len;
35 memset(nonemb_cmd->va, 0, nonemb_cmd->size);
36 region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
37 sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
38 sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
39 offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
40 req->region = region;
41 req->sector = sector;
42 req->offset = offset;
43
44 if (mutex_lock_interruptible(&ctrl->mbox_lock))
45 return 0;
46 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
47 case BEISCSI_WRITE_FLASH:
48 offset = sector * sector_size + offset;
49 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
50 OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
51 sg_copy_to_buffer(job->request_payload.sg_list,
52 job->request_payload.sg_cnt,
53 nonemb_cmd->va + offset, job->request_len);
54 break;
55 case BEISCSI_READ_FLASH:
56 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
57 OPCODE_COMMON_READ_FLASH, sizeof(*req));
58 break;
59 default:
60 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
61 "BG_%d : Unsupported cmd = 0x%x\n\n",
62 bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
63
64 mutex_unlock(&ctrl->mbox_lock);
65 return -EPERM;
66 }
67
68 wrb = alloc_mcc_wrb(phba, &tag);
69 if (!wrb) {
70 mutex_unlock(&ctrl->mbox_lock);
71 return 0;
72 }
73
74 mcc_sge = nonembedded_sgl(wrb);
75 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
76 job->request_payload.sg_cnt);
77 mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
78 mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
79 mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
80
81 be_mcc_notify(phba, tag);
82
83 mutex_unlock(&ctrl->mbox_lock);
84 return tag;
85}
86
87
88
89
90
91
92
93
94
95
96
97int mgmt_open_connection(struct beiscsi_hba *phba,
98 struct sockaddr *dst_addr,
99 struct beiscsi_endpoint *beiscsi_ep,
100 struct be_dma_mem *nonemb_cmd)
101{
102 struct hwi_controller *phwi_ctrlr;
103 struct hwi_context_memory *phwi_context;
104 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
105 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
106 struct be_ctrl_info *ctrl = &phba->ctrl;
107 struct be_mcc_wrb *wrb;
108 struct tcp_connect_and_offload_in_v1 *req;
109 unsigned short def_hdr_id;
110 unsigned short def_data_id;
111 struct phys_addr template_address = { 0, 0 };
112 struct phys_addr *ptemplate_address;
113 unsigned int tag = 0;
114 unsigned int i, ulp_num;
115 unsigned short cid = beiscsi_ep->ep_cid;
116 struct be_sge *sge;
117
118 if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
119 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
120 "BG_%d : unknown addr family %d\n",
121 dst_addr->sa_family);
122 return 0;
123 }
124
125 phwi_ctrlr = phba->phwi_ctrlr;
126 phwi_context = phwi_ctrlr->phwi_ctxt;
127
128 ulp_num = phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID(cid)].ulp_num;
129
130 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba, ulp_num);
131 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba, ulp_num);
132
133 ptemplate_address = &template_address;
134 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
135 if (mutex_lock_interruptible(&ctrl->mbox_lock))
136 return 0;
137 wrb = alloc_mcc_wrb(phba, &tag);
138 if (!wrb) {
139 mutex_unlock(&ctrl->mbox_lock);
140 return 0;
141 }
142
143 sge = nonembedded_sgl(wrb);
144 req = nonemb_cmd->va;
145 memset(req, 0, sizeof(*req));
146
147 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
148 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
149 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
150 nonemb_cmd->size);
151 if (dst_addr->sa_family == PF_INET) {
152 __be32 s_addr = daddr_in->sin_addr.s_addr;
153 req->ip_address.ip_type = BEISCSI_IP_TYPE_V4;
154 req->ip_address.addr[0] = s_addr & 0x000000ff;
155 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
156 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
157 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
158 req->tcp_port = ntohs(daddr_in->sin_port);
159 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
160 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
161 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V4;
162 } else {
163
164 req->ip_address.ip_type = BEISCSI_IP_TYPE_V6;
165 memcpy(&req->ip_address.addr,
166 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
167 req->tcp_port = ntohs(daddr_in6->sin6_port);
168 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
169 memcpy(&beiscsi_ep->dst6_addr,
170 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
171 beiscsi_ep->ip_type = BEISCSI_IP_TYPE_V6;
172 }
173 req->cid = cid;
174 i = phba->nxt_cqid++;
175 if (phba->nxt_cqid == phba->num_cpus)
176 phba->nxt_cqid = 0;
177 req->cq_id = phwi_context->be_cq[i].id;
178 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
179 "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
180 req->defq_id = def_hdr_id;
181 req->hdr_ring_id = def_hdr_id;
182 req->data_ring_id = def_data_id;
183 req->do_offload = 1;
184 req->dataout_template_pa.lo = ptemplate_address->lo;
185 req->dataout_template_pa.hi = ptemplate_address->hi;
186 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
187 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
188 sge->len = cpu_to_le32(nonemb_cmd->size);
189
190 if (!is_chip_be2_be3r(phba)) {
191 req->hdr.version = MBX_CMD_VER1;
192 req->tcp_window_size = 0x8000;
193 req->tcp_window_scale_count = 2;
194 }
195
196 be_mcc_notify(phba, tag);
197 mutex_unlock(&ctrl->mbox_lock);
198 return tag;
199}
200
201
202
203
204
205
206
207
208
209
210static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba,
211 struct be_dma_mem *nonemb_cmd,
212 void (*cbfn)(struct beiscsi_hba *,
213 unsigned int),
214 void *resp_buf, u32 resp_buf_len)
215{
216 struct be_ctrl_info *ctrl = &phba->ctrl;
217 struct be_mcc_wrb *wrb;
218 struct be_sge *sge;
219 unsigned int tag;
220 int rc = 0;
221
222 mutex_lock(&ctrl->mbox_lock);
223 wrb = alloc_mcc_wrb(phba, &tag);
224 if (!wrb) {
225 mutex_unlock(&ctrl->mbox_lock);
226 rc = -ENOMEM;
227 goto free_cmd;
228 }
229
230 sge = nonembedded_sgl(wrb);
231 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
232 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
233 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd->dma));
234 sge->len = cpu_to_le32(nonemb_cmd->size);
235
236 if (cbfn) {
237 struct be_dma_mem *tag_mem;
238
239 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
240 ctrl->ptag_state[tag].cbfn = cbfn;
241 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
242
243
244 tag_mem->size = nonemb_cmd->size;
245 tag_mem->va = nonemb_cmd->va;
246 tag_mem->dma = nonemb_cmd->dma;
247 }
248 be_mcc_notify(phba, tag);
249 mutex_unlock(&ctrl->mbox_lock);
250
251
252 if (cbfn)
253 return 0;
254
255 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, nonemb_cmd);
256
257
258 if (resp_buf)
259 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
260
261
262
263
264
265 if (rc == -EAGAIN)
266 return rc;
267
268
269
270
271
272 if (rc == -EBUSY)
273 return rc;
274
275free_cmd:
276 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
277 nonemb_cmd->va, nonemb_cmd->dma);
278 return rc;
279}
280
281static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba,
282 struct be_dma_mem *cmd,
283 u8 subsystem, u8 opcode, u32 size)
284{
285 cmd->va = pci_zalloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
286 if (!cmd->va) {
287 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
288 "BG_%d : Failed to allocate memory for if info\n");
289 return -ENOMEM;
290 }
291 cmd->size = size;
292 be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
293 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
294 "BG_%d : subsystem %u cmd %u size %u\n",
295 subsystem, opcode, size);
296 return 0;
297}
298
299static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
300{
301 struct be_dma_mem *tag_mem;
302
303
304 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
305 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
306 if (tag_mem->size) {
307 pci_free_consistent(phba->pcidev, tag_mem->size,
308 tag_mem->va, tag_mem->dma);
309 tag_mem->size = 0;
310 }
311}
312
313int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
314 struct be_set_eqd *set_eqd, int num)
315{
316 struct be_cmd_req_modify_eq_delay *req;
317 struct be_dma_mem nonemb_cmd;
318 int i, rc;
319
320 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
321 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
322 if (rc)
323 return rc;
324
325 req = nonemb_cmd.va;
326 req->num_eq = cpu_to_le32(num);
327 for (i = 0; i < num; i++) {
328 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
329 req->delay[i].phase = 0;
330 req->delay[i].delay_multiplier =
331 cpu_to_le32(set_eqd[i].delay_multiplier);
332 }
333
334 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd,
335 __beiscsi_eq_delay_compl, NULL, 0);
336}
337
338
339
340
341
342
343
344
345int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
346{
347 struct be_dma_mem nonemb_cmd;
348 struct be_cmd_hba_name resp;
349 struct be_cmd_hba_name *req;
350 int rc;
351
352 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
353 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
354 if (rc)
355 return rc;
356
357 req = nonemb_cmd.va;
358 if (cfg)
359 req->hdr.version = 1;
360 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
361 &resp, sizeof(resp));
362 if (rc) {
363 beiscsi_log(phba, KERN_ERR,
364 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
365 "BS_%d : Initiator Name MBX Failed\n");
366 return rc;
367 }
368 rc = sprintf(name, "%s\n", resp.initiator_name);
369 return rc;
370}
371
372unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
373{
374 struct be_ctrl_info *ctrl = &phba->ctrl;
375 struct be_mcc_wrb *wrb;
376 struct be_cmd_get_all_if_id_req *req;
377 struct be_cmd_get_all_if_id_req *pbe_allid;
378 unsigned int tag;
379 int status = 0;
380
381 if (mutex_lock_interruptible(&ctrl->mbox_lock))
382 return -EINTR;
383 wrb = alloc_mcc_wrb(phba, &tag);
384 if (!wrb) {
385 mutex_unlock(&ctrl->mbox_lock);
386 return -ENOMEM;
387 }
388
389 req = embedded_payload(wrb);
390 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
391 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
392 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
393 sizeof(*req));
394 be_mcc_notify(phba, tag);
395 mutex_unlock(&ctrl->mbox_lock);
396
397 status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
398 if (status) {
399 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
400 "BG_%d : %s failed: %d\n", __func__, status);
401 return -EBUSY;
402 }
403
404 pbe_allid = embedded_payload(wrb);
405
406 phba->interface_handle = pbe_allid->if_hndl_list[0];
407
408 return status;
409}
410
411static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
412{
413 u32 len;
414
415 len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
416 while (len && !ip[len - 1])
417 len--;
418 return (len == 0);
419}
420
421static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
422 u32 action, u32 ip_type, u8 *gw)
423{
424 struct be_cmd_set_def_gateway_req *req;
425 struct be_dma_mem nonemb_cmd;
426 int rt_val;
427
428 rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
429 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
430 sizeof(*req));
431 if (rt_val)
432 return rt_val;
433
434 req = nonemb_cmd.va;
435 req->action = action;
436 req->ip_addr.ip_type = ip_type;
437 memcpy(req->ip_addr.addr, gw,
438 (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
439 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
440}
441
442int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
443{
444 struct be_cmd_get_def_gateway_resp gw_resp;
445 int rt_val;
446
447 memset(&gw_resp, 0, sizeof(gw_resp));
448 rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
449 if (rt_val) {
450 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
451 "BG_%d : Failed to Get Gateway Addr\n");
452 return rt_val;
453 }
454
455 if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
456 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
457 gw_resp.ip_addr.addr);
458 if (rt_val) {
459 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
460 "BG_%d : Failed to clear Gateway Addr Set\n");
461 return rt_val;
462 }
463 }
464
465 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
466 if (rt_val)
467 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
468 "BG_%d : Failed to Set Gateway Addr\n");
469
470 return rt_val;
471}
472
473int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
474 struct be_cmd_get_def_gateway_resp *resp)
475{
476 struct be_cmd_get_def_gateway_req *req;
477 struct be_dma_mem nonemb_cmd;
478 int rc;
479
480 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
481 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
482 sizeof(*resp));
483 if (rc)
484 return rc;
485
486 req = nonemb_cmd.va;
487 req->ip_type = ip_type;
488
489 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
490 resp, sizeof(*resp));
491}
492
493static int
494beiscsi_if_clr_ip(struct beiscsi_hba *phba,
495 struct be_cmd_get_if_info_resp *if_info)
496{
497 struct be_cmd_set_ip_addr_req *req;
498 struct be_dma_mem nonemb_cmd;
499 int rc;
500
501 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
502 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
503 sizeof(*req));
504 if (rc)
505 return rc;
506
507 req = nonemb_cmd.va;
508 req->ip_params.record_entry_count = 1;
509 req->ip_params.ip_record.action = IP_ACTION_DEL;
510 req->ip_params.ip_record.interface_hndl =
511 phba->interface_handle;
512 req->ip_params.ip_record.ip_addr.size_of_structure =
513 sizeof(struct be_ip_addr_subnet_format);
514 req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
515 memcpy(req->ip_params.ip_record.ip_addr.addr,
516 if_info->ip_addr.addr,
517 sizeof(if_info->ip_addr.addr));
518 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
519 if_info->ip_addr.subnet_mask,
520 sizeof(if_info->ip_addr.subnet_mask));
521 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
522 if (rc < 0 || req->ip_params.ip_record.status) {
523 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
524 "BG_%d : failed to clear IP: rc %d status %d\n",
525 rc, req->ip_params.ip_record.status);
526 }
527 return rc;
528}
529
530static int
531beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
532 u8 *subnet, u32 ip_type)
533{
534 struct be_cmd_set_ip_addr_req *req;
535 struct be_dma_mem nonemb_cmd;
536 uint32_t ip_len;
537 int rc;
538
539 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
540 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
541 sizeof(*req));
542 if (rc)
543 return rc;
544
545 req = nonemb_cmd.va;
546 req->ip_params.record_entry_count = 1;
547 req->ip_params.ip_record.action = IP_ACTION_ADD;
548 req->ip_params.ip_record.interface_hndl =
549 phba->interface_handle;
550 req->ip_params.ip_record.ip_addr.size_of_structure =
551 sizeof(struct be_ip_addr_subnet_format);
552 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
553 ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
554 memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
555 if (subnet)
556 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
557 subnet, ip_len);
558
559 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
560
561
562
563
564 if (rc < 0 || req->ip_params.ip_record.status) {
565 __beiscsi_log(phba, KERN_ERR,
566 "BG_%d : failed to set IP: rc %d status %d\n",
567 rc, req->ip_params.ip_record.status);
568 if (req->ip_params.ip_record.status)
569 rc = -EINVAL;
570 }
571 return rc;
572}
573
574int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
575 u8 *ip, u8 *subnet)
576{
577 struct be_cmd_get_if_info_resp *if_info;
578 struct be_cmd_rel_dhcp_req *reldhcp;
579 struct be_dma_mem nonemb_cmd;
580 int rc;
581
582 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
583 if (rc)
584 return rc;
585
586 if (if_info->dhcp_state) {
587 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
588 CMD_SUBSYSTEM_ISCSI,
589 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
590 sizeof(*reldhcp));
591 if (rc)
592 goto exit;
593
594 reldhcp = nonemb_cmd.va;
595 reldhcp->interface_hndl = phba->interface_handle;
596 reldhcp->ip_type = ip_type;
597 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
598 if (rc < 0) {
599 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
600 "BG_%d : failed to release existing DHCP: %d\n",
601 rc);
602 goto exit;
603 }
604 }
605
606
607 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
608 rc = beiscsi_if_clr_ip(phba, if_info);
609 if (rc)
610 goto exit;
611 }
612
613
614 if (ip)
615 rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
616exit:
617 kfree(if_info);
618 return rc;
619}
620
621int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
622{
623 struct be_cmd_get_def_gateway_resp gw_resp;
624 struct be_cmd_get_if_info_resp *if_info;
625 struct be_cmd_set_dhcp_req *dhcpreq;
626 struct be_dma_mem nonemb_cmd;
627 u8 *gw;
628 int rc;
629
630 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
631 if (rc)
632 return rc;
633
634 if (if_info->dhcp_state) {
635 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
636 "BG_%d : DHCP Already Enabled\n");
637 goto exit;
638 }
639
640
641 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
642 rc = beiscsi_if_clr_ip(phba, if_info);
643 if (rc)
644 goto exit;
645 }
646
647
648 memset(&gw_resp, 0, sizeof(gw_resp));
649
650 rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
651 if (rc) {
652 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
653 "BG_%d : Failed to Get Gateway Addr\n");
654 goto exit;
655 }
656 gw = (u8 *)&gw_resp.ip_addr.addr;
657 if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
658 rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
659 if_info->ip_addr.ip_type, gw);
660 if (rc) {
661 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
662 "BG_%d : Failed to clear Gateway Addr Set\n");
663 goto exit;
664 }
665 }
666
667 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
668 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
669 sizeof(*dhcpreq));
670 if (rc)
671 goto exit;
672
673 dhcpreq = nonemb_cmd.va;
674 dhcpreq->flags = 1;
675 dhcpreq->retry_count = 1;
676 dhcpreq->interface_hndl = phba->interface_handle;
677 dhcpreq->ip_type = ip_type;
678 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
679
680exit:
681 kfree(if_info);
682 return rc;
683}
684
685
686
687
688
689
690
691
692
693
694
695
696
697int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
698{
699 int rc;
700 unsigned int tag;
701
702 tag = be_cmd_set_vlan(phba, vlan_tag);
703 if (!tag) {
704 beiscsi_log(phba, KERN_ERR,
705 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
706 "BG_%d : VLAN Setting Failed\n");
707 return -EBUSY;
708 }
709
710 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
711 if (rc) {
712 beiscsi_log(phba, KERN_ERR,
713 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
714 "BS_%d : VLAN MBX Cmd Failed\n");
715 return rc;
716 }
717 return rc;
718}
719
720
721int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
722 struct be_cmd_get_if_info_resp **if_info)
723{
724 struct be_cmd_get_if_info_req *req;
725 struct be_dma_mem nonemb_cmd;
726 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
727 int rc;
728
729 rc = beiscsi_if_get_handle(phba);
730 if (rc)
731 return rc;
732
733 do {
734 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
735 CMD_SUBSYSTEM_ISCSI,
736 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
737 ioctl_size);
738 if (rc)
739 return rc;
740
741 req = nonemb_cmd.va;
742 req->interface_hndl = phba->interface_handle;
743 req->ip_type = ip_type;
744
745
746 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
747 if (!*if_info) {
748 beiscsi_log(phba, KERN_ERR,
749 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
750 "BG_%d : Memory Allocation Failure\n");
751
752
753 pci_free_consistent(phba->ctrl.pdev,
754 nonemb_cmd.size,
755 nonemb_cmd.va,
756 nonemb_cmd.dma);
757 return -ENOMEM;
758 }
759
760 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
761 ioctl_size);
762
763
764 if (rc == -EAGAIN) {
765
766
767 ioctl_size = ((struct be_cmd_resp_hdr *)
768 nonemb_cmd.va)->actual_resp_len;
769 ioctl_size += sizeof(struct be_cmd_req_hdr);
770
771
772 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
773 nonemb_cmd.va,
774 nonemb_cmd.dma);
775
776
777 kfree(*if_info);
778 } else
779 break;
780 } while (true);
781 return rc;
782}
783
784int mgmt_get_nic_conf(struct beiscsi_hba *phba,
785 struct be_cmd_get_nic_conf_resp *nic)
786{
787 struct be_dma_mem nonemb_cmd;
788 int rc;
789
790 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
791 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
792 sizeof(*nic));
793 if (rc)
794 return rc;
795
796 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
797 nic, sizeof(*nic));
798}
799
800static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
801 unsigned int tag)
802{
803 struct be_cmd_get_boot_target_resp *boot_resp;
804 struct be_cmd_resp_logout_fw_sess *logo_resp;
805 struct be_cmd_get_session_resp *sess_resp;
806 struct be_mcc_wrb *wrb;
807 struct boot_struct *bs;
808 int boot_work, status;
809
810 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
811 __beiscsi_log(phba, KERN_ERR,
812 "BG_%d : %s no boot work %lx\n",
813 __func__, phba->state);
814 return;
815 }
816
817 if (phba->boot_struct.tag != tag) {
818 __beiscsi_log(phba, KERN_ERR,
819 "BG_%d : %s tag mismatch %d:%d\n",
820 __func__, tag, phba->boot_struct.tag);
821 return;
822 }
823 bs = &phba->boot_struct;
824 boot_work = 1;
825 status = 0;
826 switch (bs->action) {
827 case BEISCSI_BOOT_REOPEN_SESS:
828 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
829 if (!status)
830 bs->action = BEISCSI_BOOT_GET_SHANDLE;
831 else
832 bs->retry--;
833 break;
834 case BEISCSI_BOOT_GET_SHANDLE:
835 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
836 if (!status) {
837 boot_resp = embedded_payload(wrb);
838 bs->s_handle = boot_resp->boot_session_handle;
839 }
840 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
841 bs->action = BEISCSI_BOOT_REOPEN_SESS;
842 bs->retry--;
843 } else {
844 bs->action = BEISCSI_BOOT_GET_SINFO;
845 }
846 break;
847 case BEISCSI_BOOT_GET_SINFO:
848 status = __beiscsi_mcc_compl_status(phba, tag, NULL,
849 &bs->nonemb_cmd);
850 if (!status) {
851 sess_resp = bs->nonemb_cmd.va;
852 memcpy(&bs->boot_sess, &sess_resp->session_info,
853 sizeof(struct mgmt_session_info));
854 bs->action = BEISCSI_BOOT_LOGOUT_SESS;
855 } else {
856 __beiscsi_log(phba, KERN_ERR,
857 "BG_%d : get boot session info error : 0x%x\n",
858 status);
859 boot_work = 0;
860 }
861 pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
862 bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
863 bs->nonemb_cmd.va = NULL;
864 break;
865 case BEISCSI_BOOT_LOGOUT_SESS:
866 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
867 if (!status) {
868 logo_resp = embedded_payload(wrb);
869 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
870 __beiscsi_log(phba, KERN_ERR,
871 "BG_%d : FW boot session logout error : 0x%x\n",
872 logo_resp->session_status);
873 }
874 }
875
876 bs->action = BEISCSI_BOOT_CREATE_KSET;
877 break;
878 default:
879 break;
880 }
881
882
883 bs->tag = 0;
884 if (!bs->retry) {
885 boot_work = 0;
886 __beiscsi_log(phba, KERN_ERR,
887 "BG_%d : failed to setup boot target: status %d action %d\n",
888 status, bs->action);
889 }
890 if (!boot_work) {
891
892 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
893 return;
894 }
895 schedule_work(&phba->boot_work);
896}
897
898
899
900
901
902
903
904
905
906unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
907{
908 struct be_ctrl_info *ctrl = &phba->ctrl;
909 struct be_mcc_wrb *wrb;
910 struct be_cmd_req_logout_fw_sess *req;
911 unsigned int tag;
912
913 mutex_lock(&ctrl->mbox_lock);
914 wrb = alloc_mcc_wrb(phba, &tag);
915 if (!wrb) {
916 mutex_unlock(&ctrl->mbox_lock);
917 return 0;
918 }
919
920 req = embedded_payload(wrb);
921 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
922 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
923 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
924 sizeof(struct be_cmd_req_logout_fw_sess));
925
926 req->session_handle = phba->boot_struct.boot_sess.session_handle;
927
928 phba->boot_struct.tag = tag;
929 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
930 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
931
932 be_mcc_notify(phba, tag);
933 mutex_unlock(&ctrl->mbox_lock);
934
935 return tag;
936}
937
938
939
940
941
942
943
944
945unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
946{
947 struct be_ctrl_info *ctrl = &phba->ctrl;
948 struct be_mcc_wrb *wrb;
949 struct be_cmd_reopen_session_req *req;
950 unsigned int tag;
951
952 mutex_lock(&ctrl->mbox_lock);
953 wrb = alloc_mcc_wrb(phba, &tag);
954 if (!wrb) {
955 mutex_unlock(&ctrl->mbox_lock);
956 return 0;
957 }
958
959 req = embedded_payload(wrb);
960 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
961 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
962 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
963 sizeof(struct be_cmd_reopen_session_resp));
964 req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
965 req->session_handle = BE_BOOT_INVALID_SHANDLE;
966
967 phba->boot_struct.tag = tag;
968 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
969 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
970
971 be_mcc_notify(phba, tag);
972 mutex_unlock(&ctrl->mbox_lock);
973 return tag;
974}
975
976
977
978
979
980
981
982
983
984
985
986unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
987{
988 struct be_ctrl_info *ctrl = &phba->ctrl;
989 struct be_cmd_get_session_req *req;
990 struct be_dma_mem *nonemb_cmd;
991 struct be_mcc_wrb *wrb;
992 struct be_sge *sge;
993 unsigned int tag;
994
995 mutex_lock(&ctrl->mbox_lock);
996 wrb = alloc_mcc_wrb(phba, &tag);
997 if (!wrb) {
998 mutex_unlock(&ctrl->mbox_lock);
999 return 0;
1000 }
1001
1002 nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1003 nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
1004 nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
1005 nonemb_cmd->size,
1006 &nonemb_cmd->dma);
1007 if (!nonemb_cmd->va) {
1008 mutex_unlock(&ctrl->mbox_lock);
1009 return 0;
1010 }
1011
1012 req = nonemb_cmd->va;
1013 memset(req, 0, sizeof(*req));
1014 sge = nonembedded_sgl(wrb);
1015 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1016 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1017 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1018 sizeof(struct be_cmd_get_session_resp));
1019 req->session_handle = phba->boot_struct.s_handle;
1020 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1021 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1022 sge->len = cpu_to_le32(nonemb_cmd->size);
1023
1024 phba->boot_struct.tag = tag;
1025 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1026 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1027
1028 be_mcc_notify(phba, tag);
1029 mutex_unlock(&ctrl->mbox_lock);
1030 return tag;
1031}
1032
1033unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1034{
1035 struct be_ctrl_info *ctrl = &phba->ctrl;
1036 struct be_mcc_wrb *wrb;
1037 struct be_cmd_get_boot_target_req *req;
1038 unsigned int tag;
1039
1040 mutex_lock(&ctrl->mbox_lock);
1041 wrb = alloc_mcc_wrb(phba, &tag);
1042 if (!wrb) {
1043 mutex_unlock(&ctrl->mbox_lock);
1044 return 0;
1045 }
1046
1047 req = embedded_payload(wrb);
1048 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1049 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1050 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1051 sizeof(struct be_cmd_get_boot_target_resp));
1052
1053 if (async) {
1054 phba->boot_struct.tag = tag;
1055 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1056 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1057 }
1058
1059 be_mcc_notify(phba, tag);
1060 mutex_unlock(&ctrl->mbox_lock);
1061 return tag;
1062}
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1075{
1076 struct be_cmd_get_boot_target_resp *boot_resp;
1077 struct be_mcc_wrb *wrb;
1078 unsigned int tag;
1079 int rc;
1080
1081 *s_handle = BE_BOOT_INVALID_SHANDLE;
1082
1083 tag = __beiscsi_boot_get_shandle(phba, 0);
1084 if (!tag) {
1085 beiscsi_log(phba, KERN_ERR,
1086 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1087 "BG_%d : Getting Boot Target Info Failed\n");
1088 return -EAGAIN;
1089 }
1090
1091 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1092 if (rc) {
1093 beiscsi_log(phba, KERN_ERR,
1094 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1095 "BG_%d : MBX CMD get_boot_target Failed\n");
1096 return -EBUSY;
1097 }
1098
1099 boot_resp = embedded_payload(wrb);
1100
1101 if (!boot_resp->boot_session_count) {
1102 __beiscsi_log(phba, KERN_INFO,
1103 "BG_%d : No boot targets configured\n");
1104 return -ENXIO;
1105 }
1106
1107
1108 *s_handle = boot_resp->boot_session_handle;
1109 return 1;
1110}
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121ssize_t
1122beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1123 char *buf)
1124{
1125 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1126}
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137ssize_t
1138beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1139 char *buf)
1140{
1141 struct Scsi_Host *shost = class_to_shost(dev);
1142 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1143
1144 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1145}
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156ssize_t
1157beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1158 char *buf)
1159{
1160 struct Scsi_Host *shost = class_to_shost(dev);
1161 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1162 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1163
1164 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1165 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1166 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1167 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1168 len += snprintf(buf+len, PAGE_SIZE - len,
1169 "ULP%d : %d\n", ulp_num,
1170 (total_cids - avlbl_cids));
1171 } else
1172 len += snprintf(buf+len, PAGE_SIZE - len,
1173 "ULP%d : %d\n", ulp_num, 0);
1174 }
1175
1176 return len;
1177}
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188ssize_t
1189beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1190 char *buf)
1191{
1192 struct Scsi_Host *shost = class_to_shost(dev);
1193 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1194 uint16_t ulp_num, len = 0;
1195
1196 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1197 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1198 len += snprintf(buf+len, PAGE_SIZE - len,
1199 "ULP%d : %d\n", ulp_num,
1200 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1201 else
1202 len += snprintf(buf+len, PAGE_SIZE - len,
1203 "ULP%d : %d\n", ulp_num, 0);
1204 }
1205
1206 return len;
1207}
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218ssize_t
1219beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1220 char *buf)
1221{
1222 uint16_t dev_id = 0;
1223 struct Scsi_Host *shost = class_to_shost(dev);
1224 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1225
1226 dev_id = phba->pcidev->device;
1227 switch (dev_id) {
1228 case BE_DEVICE_ID1:
1229 case OC_DEVICE_ID1:
1230 case OC_DEVICE_ID2:
1231 return snprintf(buf, PAGE_SIZE,
1232 "Obsolete/Unsupported BE2 Adapter Family\n");
1233 break;
1234 case BE_DEVICE_ID2:
1235 case OC_DEVICE_ID3:
1236 return snprintf(buf, PAGE_SIZE, "BE3-R Adapter Family\n");
1237 break;
1238 case OC_SKH_ID1:
1239 return snprintf(buf, PAGE_SIZE, "Skyhawk-R Adapter Family\n");
1240 break;
1241 default:
1242 return snprintf(buf, PAGE_SIZE,
1243 "Unknown Adapter Family: 0x%x\n", dev_id);
1244 break;
1245 }
1246}
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257ssize_t
1258beiscsi_phys_port_disp(struct device *dev, struct device_attribute *attr,
1259 char *buf)
1260{
1261 struct Scsi_Host *shost = class_to_shost(dev);
1262 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1263
1264 return snprintf(buf, PAGE_SIZE, "Port Identifier : %u\n",
1265 phba->fw_config.phys_port);
1266}
1267
1268void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
1269 struct wrb_handle *pwrb_handle,
1270 struct be_mem_descriptor *mem_descr,
1271 struct hwi_wrb_context *pwrb_context)
1272{
1273 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1274
1275 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1276 max_send_data_segment_length, pwrb,
1277 params->dw[offsetof(struct amap_beiscsi_offload_params,
1278 max_send_data_segment_length) / 32]);
1279 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
1280 BE_TGT_CTX_UPDT_CMD);
1281 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1282 first_burst_length,
1283 pwrb,
1284 params->dw[offsetof(struct amap_beiscsi_offload_params,
1285 first_burst_length) / 32]);
1286 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
1287 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1288 erl) / 32] & OFFLD_PARAMS_ERL));
1289 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
1290 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1291 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1292 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
1293 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1294 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1295 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
1296 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1297 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1298 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
1299 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1300 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1301 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
1302 pwrb,
1303 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1304 exp_statsn) / 32] + 1));
1305 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
1306 pwrb, pwrb_handle->wrb_index);
1307
1308 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1309 max_burst_length, pwrb, params->dw[offsetof
1310 (struct amap_beiscsi_offload_params,
1311 max_burst_length) / 32]);
1312
1313 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
1314 pwrb, pwrb_handle->wrb_index);
1315 if (pwrb_context->plast_wrb)
1316 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1317 ptr2nextwrb,
1318 pwrb_context->plast_wrb,
1319 pwrb_handle->wrb_index);
1320 pwrb_context->plast_wrb = pwrb;
1321
1322 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1323 session_state, pwrb, 0);
1324 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
1325 pwrb, 1);
1326 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
1327 pwrb, 0);
1328 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
1329 0);
1330
1331 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1332 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1333 pad_buffer_addr_hi, pwrb,
1334 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
1335 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
1336 pad_buffer_addr_lo, pwrb,
1337 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
1338}
1339
1340void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
1341 struct wrb_handle *pwrb_handle,
1342 struct hwi_wrb_context *pwrb_context)
1343{
1344 struct iscsi_wrb *pwrb = pwrb_handle->pwrb;
1345
1346 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1347 max_burst_length, pwrb, params->dw[offsetof
1348 (struct amap_beiscsi_offload_params,
1349 max_burst_length) / 32]);
1350 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1351 type, pwrb,
1352 BE_TGT_CTX_UPDT_CMD);
1353 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1354 ptr2nextwrb,
1355 pwrb, pwrb_handle->wrb_index);
1356 if (pwrb_context->plast_wrb)
1357 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1358 ptr2nextwrb,
1359 pwrb_context->plast_wrb,
1360 pwrb_handle->wrb_index);
1361 pwrb_context->plast_wrb = pwrb;
1362
1363 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, wrb_idx,
1364 pwrb, pwrb_handle->wrb_index);
1365 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1366 max_send_data_segment_length, pwrb,
1367 params->dw[offsetof(struct amap_beiscsi_offload_params,
1368 max_send_data_segment_length) / 32]);
1369 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1370 first_burst_length, pwrb,
1371 params->dw[offsetof(struct amap_beiscsi_offload_params,
1372 first_burst_length) / 32]);
1373 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1374 max_recv_dataseg_len, pwrb,
1375 params->dw[offsetof(struct amap_beiscsi_offload_params,
1376 max_recv_data_segment_length) / 32]);
1377 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1378 max_cxns, pwrb, BEISCSI_MAX_CXNS);
1379 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, erl, pwrb,
1380 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1381 erl) / 32] & OFFLD_PARAMS_ERL));
1382 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, dde, pwrb,
1383 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1384 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
1385 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, hde, pwrb,
1386 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1387 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
1388 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1389 ir2t, pwrb,
1390 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1391 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
1392 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, imd, pwrb,
1393 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1394 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
1395 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1396 data_seq_inorder,
1397 pwrb,
1398 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1399 data_seq_inorder) / 32] &
1400 OFFLD_PARAMS_DATA_SEQ_INORDER) >> 6);
1401 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2,
1402 pdu_seq_inorder,
1403 pwrb,
1404 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1405 pdu_seq_inorder) / 32] &
1406 OFFLD_PARAMS_PDU_SEQ_INORDER) >> 7);
1407 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, max_r2t,
1408 pwrb,
1409 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1410 max_r2t) / 32] &
1411 OFFLD_PARAMS_MAX_R2T) >> 8);
1412 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb_v2, stat_sn,
1413 pwrb,
1414 (params->dw[offsetof(struct amap_beiscsi_offload_params,
1415 exp_statsn) / 32] + 1));
1416}
1417
1418unsigned int beiscsi_invalidate_cxn(struct beiscsi_hba *phba,
1419 struct beiscsi_endpoint *beiscsi_ep)
1420{
1421 struct be_invalidate_connection_params_in *req;
1422 struct be_ctrl_info *ctrl = &phba->ctrl;
1423 struct be_mcc_wrb *wrb;
1424 unsigned int tag = 0;
1425
1426 mutex_lock(&ctrl->mbox_lock);
1427 wrb = alloc_mcc_wrb(phba, &tag);
1428 if (!wrb) {
1429 mutex_unlock(&ctrl->mbox_lock);
1430 return 0;
1431 }
1432
1433 req = embedded_payload(wrb);
1434 be_wrb_hdr_prepare(wrb, sizeof(union be_invalidate_connection_params),
1435 true, 0);
1436 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1437 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
1438 sizeof(*req));
1439 req->session_handle = beiscsi_ep->fw_handle;
1440 req->cid = beiscsi_ep->ep_cid;
1441 if (beiscsi_ep->conn)
1442 req->cleanup_type = BE_CLEANUP_TYPE_INVALIDATE;
1443 else
1444 req->cleanup_type = BE_CLEANUP_TYPE_ISSUE_TCP_RST;
1445
1446
1447
1448
1449 req->save_cfg = 0;
1450 be_mcc_notify(phba, tag);
1451 mutex_unlock(&ctrl->mbox_lock);
1452 return tag;
1453}
1454
1455unsigned int beiscsi_upload_cxn(struct beiscsi_hba *phba,
1456 struct beiscsi_endpoint *beiscsi_ep)
1457{
1458 struct be_ctrl_info *ctrl = &phba->ctrl;
1459 struct be_mcc_wrb *wrb;
1460 struct be_tcp_upload_params_in *req;
1461 unsigned int tag;
1462
1463 mutex_lock(&ctrl->mbox_lock);
1464 wrb = alloc_mcc_wrb(phba, &tag);
1465 if (!wrb) {
1466 mutex_unlock(&ctrl->mbox_lock);
1467 return 0;
1468 }
1469
1470 req = embedded_payload(wrb);
1471 be_wrb_hdr_prepare(wrb, sizeof(union be_tcp_upload_params), true, 0);
1472 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
1473 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
1474 req->id = beiscsi_ep->ep_cid;
1475 if (beiscsi_ep->conn)
1476 req->upload_type = BE_UPLOAD_TYPE_GRACEFUL;
1477 else
1478 req->upload_type = BE_UPLOAD_TYPE_ABORT;
1479 be_mcc_notify(phba, tag);
1480 mutex_unlock(&ctrl->mbox_lock);
1481 return tag;
1482}
1483
1484int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba,
1485 struct invldt_cmd_tbl *inv_tbl,
1486 unsigned int nents)
1487{
1488 struct be_ctrl_info *ctrl = &phba->ctrl;
1489 struct invldt_cmds_params_in *req;
1490 struct be_dma_mem nonemb_cmd;
1491 struct be_mcc_wrb *wrb;
1492 unsigned int i, tag;
1493 struct be_sge *sge;
1494 int rc;
1495
1496 if (!nents || nents > BE_INVLDT_CMD_TBL_SZ)
1497 return -EINVAL;
1498
1499 nonemb_cmd.size = sizeof(union be_invldt_cmds_params);
1500 nonemb_cmd.va = pci_zalloc_consistent(phba->ctrl.pdev,
1501 nonemb_cmd.size,
1502 &nonemb_cmd.dma);
1503 if (!nonemb_cmd.va) {
1504 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH,
1505 "BM_%d : invldt_cmds_params alloc failed\n");
1506 return -ENOMEM;
1507 }
1508
1509 mutex_lock(&ctrl->mbox_lock);
1510 wrb = alloc_mcc_wrb(phba, &tag);
1511 if (!wrb) {
1512 mutex_unlock(&ctrl->mbox_lock);
1513 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1514 nonemb_cmd.va, nonemb_cmd.dma);
1515 return -ENOMEM;
1516 }
1517
1518 req = nonemb_cmd.va;
1519 be_wrb_hdr_prepare(wrb, nonemb_cmd.size, false, 1);
1520 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
1521 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
1522 sizeof(*req));
1523 req->ref_handle = 0;
1524 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
1525 for (i = 0; i < nents; i++) {
1526 req->table[i].icd = inv_tbl[i].icd;
1527 req->table[i].cid = inv_tbl[i].cid;
1528 req->icd_count++;
1529 }
1530 sge = nonembedded_sgl(wrb);
1531 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
1532 sge->pa_lo = cpu_to_le32(lower_32_bits(nonemb_cmd.dma));
1533 sge->len = cpu_to_le32(nonemb_cmd.size);
1534
1535 be_mcc_notify(phba, tag);
1536 mutex_unlock(&ctrl->mbox_lock);
1537
1538 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
1539 if (rc != -EBUSY)
1540 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1541 nonemb_cmd.va, nonemb_cmd.dma);
1542 return rc;
1543}
1544