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_alloc_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 memset(cmd->va, 0, size);
292 cmd->size = size;
293 be_cmd_hdr_prepare(cmd->va, subsystem, opcode, size);
294 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
295 "BG_%d : subsystem %u cmd %u size %u\n",
296 subsystem, opcode, size);
297 return 0;
298}
299
300static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag)
301{
302 struct be_dma_mem *tag_mem;
303
304
305 __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
306 tag_mem = &phba->ctrl.ptag_state[tag].tag_mem_state;
307 if (tag_mem->size) {
308 pci_free_consistent(phba->pcidev, tag_mem->size,
309 tag_mem->va, tag_mem->dma);
310 tag_mem->size = 0;
311 }
312}
313
314int beiscsi_modify_eq_delay(struct beiscsi_hba *phba,
315 struct be_set_eqd *set_eqd, int num)
316{
317 struct be_cmd_req_modify_eq_delay *req;
318 struct be_dma_mem nonemb_cmd;
319 int i, rc;
320
321 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_COMMON,
322 OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));
323 if (rc)
324 return rc;
325
326 req = nonemb_cmd.va;
327 req->num_eq = cpu_to_le32(num);
328 for (i = 0; i < num; i++) {
329 req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
330 req->delay[i].phase = 0;
331 req->delay[i].delay_multiplier =
332 cpu_to_le32(set_eqd[i].delay_multiplier);
333 }
334
335 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd,
336 __beiscsi_eq_delay_compl, NULL, 0);
337}
338
339
340
341
342
343
344
345
346int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg)
347{
348 struct be_dma_mem nonemb_cmd;
349 struct be_cmd_hba_name resp;
350 struct be_cmd_hba_name *req;
351 int rc;
352
353 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI,
354 OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp));
355 if (rc)
356 return rc;
357
358 req = nonemb_cmd.va;
359 if (cfg)
360 req->hdr.version = 1;
361 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
362 &resp, sizeof(resp));
363 if (rc) {
364 beiscsi_log(phba, KERN_ERR,
365 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
366 "BS_%d : Initiator Name MBX Failed\n");
367 return rc;
368 }
369 rc = sprintf(name, "%s\n", resp.initiator_name);
370 return rc;
371}
372
373unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba)
374{
375 struct be_ctrl_info *ctrl = &phba->ctrl;
376 struct be_mcc_wrb *wrb;
377 struct be_cmd_get_all_if_id_req *req;
378 struct be_cmd_get_all_if_id_req *pbe_allid;
379 unsigned int tag;
380 int status = 0;
381
382 if (mutex_lock_interruptible(&ctrl->mbox_lock))
383 return -EINTR;
384 wrb = alloc_mcc_wrb(phba, &tag);
385 if (!wrb) {
386 mutex_unlock(&ctrl->mbox_lock);
387 return -ENOMEM;
388 }
389
390 req = embedded_payload(wrb);
391 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
392 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
393 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
394 sizeof(*req));
395 be_mcc_notify(phba, tag);
396 mutex_unlock(&ctrl->mbox_lock);
397
398 status = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
399 if (status) {
400 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
401 "BG_%d : %s failed: %d\n", __func__, status);
402 return -EBUSY;
403 }
404
405 pbe_allid = embedded_payload(wrb);
406
407 phba->interface_handle = pbe_allid->if_hndl_list[0];
408
409 return status;
410}
411
412static inline bool beiscsi_if_zero_ip(u8 *ip, u32 ip_type)
413{
414 u32 len;
415
416 len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
417 while (len && !ip[len - 1])
418 len--;
419 return (len == 0);
420}
421
422static int beiscsi_if_mod_gw(struct beiscsi_hba *phba,
423 u32 action, u32 ip_type, u8 *gw)
424{
425 struct be_cmd_set_def_gateway_req *req;
426 struct be_dma_mem nonemb_cmd;
427 int rt_val;
428
429 rt_val = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
430 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
431 sizeof(*req));
432 if (rt_val)
433 return rt_val;
434
435 req = nonemb_cmd.va;
436 req->action = action;
437 req->ip_addr.ip_type = ip_type;
438 memcpy(req->ip_addr.addr, gw,
439 (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN);
440 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
441}
442
443int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw)
444{
445 struct be_cmd_get_def_gateway_resp gw_resp;
446 int rt_val;
447
448 memset(&gw_resp, 0, sizeof(gw_resp));
449 rt_val = beiscsi_if_get_gw(phba, ip_type, &gw_resp);
450 if (rt_val) {
451 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
452 "BG_%d : Failed to Get Gateway Addr\n");
453 return rt_val;
454 }
455
456 if (!beiscsi_if_zero_ip(gw_resp.ip_addr.addr, ip_type)) {
457 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_DEL, ip_type,
458 gw_resp.ip_addr.addr);
459 if (rt_val) {
460 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
461 "BG_%d : Failed to clear Gateway Addr Set\n");
462 return rt_val;
463 }
464 }
465
466 rt_val = beiscsi_if_mod_gw(phba, IP_ACTION_ADD, ip_type, gw);
467 if (rt_val)
468 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
469 "BG_%d : Failed to Set Gateway Addr\n");
470
471 return rt_val;
472}
473
474int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type,
475 struct be_cmd_get_def_gateway_resp *resp)
476{
477 struct be_cmd_get_def_gateway_req *req;
478 struct be_dma_mem nonemb_cmd;
479 int rc;
480
481 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
482 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
483 sizeof(*resp));
484 if (rc)
485 return rc;
486
487 req = nonemb_cmd.va;
488 req->ip_type = ip_type;
489
490 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
491 resp, sizeof(*resp));
492}
493
494static int
495beiscsi_if_clr_ip(struct beiscsi_hba *phba,
496 struct be_cmd_get_if_info_resp *if_info)
497{
498 struct be_cmd_set_ip_addr_req *req;
499 struct be_dma_mem nonemb_cmd;
500 int rc;
501
502 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
503 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
504 sizeof(*req));
505 if (rc)
506 return rc;
507
508 req = nonemb_cmd.va;
509 req->ip_params.record_entry_count = 1;
510 req->ip_params.ip_record.action = IP_ACTION_DEL;
511 req->ip_params.ip_record.interface_hndl =
512 phba->interface_handle;
513 req->ip_params.ip_record.ip_addr.size_of_structure =
514 sizeof(struct be_ip_addr_subnet_format);
515 req->ip_params.ip_record.ip_addr.ip_type = if_info->ip_addr.ip_type;
516 memcpy(req->ip_params.ip_record.ip_addr.addr,
517 if_info->ip_addr.addr,
518 sizeof(if_info->ip_addr.addr));
519 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
520 if_info->ip_addr.subnet_mask,
521 sizeof(if_info->ip_addr.subnet_mask));
522 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
523 if (rc < 0 || req->ip_params.ip_record.status) {
524 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
525 "BG_%d : failed to clear IP: rc %d status %d\n",
526 rc, req->ip_params.ip_record.status);
527 }
528 return rc;
529}
530
531static int
532beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip,
533 u8 *subnet, u32 ip_type)
534{
535 struct be_cmd_set_ip_addr_req *req;
536 struct be_dma_mem nonemb_cmd;
537 uint32_t ip_len;
538 int rc;
539
540 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
541 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
542 sizeof(*req));
543 if (rc)
544 return rc;
545
546 req = nonemb_cmd.va;
547 req->ip_params.record_entry_count = 1;
548 req->ip_params.ip_record.action = IP_ACTION_ADD;
549 req->ip_params.ip_record.interface_hndl =
550 phba->interface_handle;
551 req->ip_params.ip_record.ip_addr.size_of_structure =
552 sizeof(struct be_ip_addr_subnet_format);
553 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
554 ip_len = (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN;
555 memcpy(req->ip_params.ip_record.ip_addr.addr, ip, ip_len);
556 if (subnet)
557 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
558 subnet, ip_len);
559
560 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
561
562
563
564
565 if (rc < 0 || req->ip_params.ip_record.status) {
566 __beiscsi_log(phba, KERN_ERR,
567 "BG_%d : failed to set IP: rc %d status %d\n",
568 rc, req->ip_params.ip_record.status);
569 if (req->ip_params.ip_record.status)
570 rc = -EINVAL;
571 }
572 return rc;
573}
574
575int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type,
576 u8 *ip, u8 *subnet)
577{
578 struct be_cmd_get_if_info_resp *if_info;
579 struct be_cmd_rel_dhcp_req *reldhcp;
580 struct be_dma_mem nonemb_cmd;
581 int rc;
582
583 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
584 if (rc)
585 return rc;
586
587 if (if_info->dhcp_state) {
588 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
589 CMD_SUBSYSTEM_ISCSI,
590 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
591 sizeof(*reldhcp));
592 if (rc)
593 goto exit;
594
595 reldhcp = nonemb_cmd.va;
596 reldhcp->interface_hndl = phba->interface_handle;
597 reldhcp->ip_type = ip_type;
598 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
599 if (rc < 0) {
600 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
601 "BG_%d : failed to release existing DHCP: %d\n",
602 rc);
603 goto exit;
604 }
605 }
606
607
608 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
609 rc = beiscsi_if_clr_ip(phba, if_info);
610 if (rc)
611 goto exit;
612 }
613
614
615 if (ip)
616 rc = beiscsi_if_set_ip(phba, ip, subnet, ip_type);
617exit:
618 kfree(if_info);
619 return rc;
620}
621
622int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type)
623{
624 struct be_cmd_get_def_gateway_resp gw_resp;
625 struct be_cmd_get_if_info_resp *if_info;
626 struct be_cmd_set_dhcp_req *dhcpreq;
627 struct be_dma_mem nonemb_cmd;
628 u8 *gw;
629 int rc;
630
631 rc = beiscsi_if_get_info(phba, ip_type, &if_info);
632 if (rc)
633 return rc;
634
635 if (if_info->dhcp_state) {
636 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
637 "BG_%d : DHCP Already Enabled\n");
638 goto exit;
639 }
640
641
642 if (!beiscsi_if_zero_ip(if_info->ip_addr.addr, ip_type)) {
643 rc = beiscsi_if_clr_ip(phba, if_info);
644 if (rc)
645 goto exit;
646 }
647
648
649 memset(&gw_resp, 0, sizeof(gw_resp));
650
651 rc = beiscsi_if_get_gw(phba, if_info->ip_addr.ip_type, &gw_resp);
652 if (rc) {
653 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
654 "BG_%d : Failed to Get Gateway Addr\n");
655 goto exit;
656 }
657 gw = (u8 *)&gw_resp.ip_addr.addr;
658 if (!beiscsi_if_zero_ip(gw, if_info->ip_addr.ip_type)) {
659 rc = beiscsi_if_mod_gw(phba, IP_ACTION_DEL,
660 if_info->ip_addr.ip_type, gw);
661 if (rc) {
662 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
663 "BG_%d : Failed to clear Gateway Addr Set\n");
664 goto exit;
665 }
666 }
667
668 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
669 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
670 sizeof(*dhcpreq));
671 if (rc)
672 goto exit;
673
674 dhcpreq = nonemb_cmd.va;
675 dhcpreq->flags = 1;
676 dhcpreq->retry_count = 1;
677 dhcpreq->interface_hndl = phba->interface_handle;
678 dhcpreq->ip_type = ip_type;
679 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0);
680
681exit:
682 kfree(if_info);
683 return rc;
684}
685
686
687
688
689
690
691
692
693
694
695
696
697
698int beiscsi_if_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag)
699{
700 int rc;
701 unsigned int tag;
702
703 tag = be_cmd_set_vlan(phba, vlan_tag);
704 if (!tag) {
705 beiscsi_log(phba, KERN_ERR,
706 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
707 "BG_%d : VLAN Setting Failed\n");
708 return -EBUSY;
709 }
710
711 rc = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
712 if (rc) {
713 beiscsi_log(phba, KERN_ERR,
714 (BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX),
715 "BS_%d : VLAN MBX Cmd Failed\n");
716 return rc;
717 }
718 return rc;
719}
720
721
722int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type,
723 struct be_cmd_get_if_info_resp **if_info)
724{
725 struct be_cmd_get_if_info_req *req;
726 struct be_dma_mem nonemb_cmd;
727 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
728 int rc;
729
730 rc = beiscsi_if_get_handle(phba);
731 if (rc)
732 return rc;
733
734 do {
735 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd,
736 CMD_SUBSYSTEM_ISCSI,
737 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
738 ioctl_size);
739 if (rc)
740 return rc;
741
742 req = nonemb_cmd.va;
743 req->interface_hndl = phba->interface_handle;
744 req->ip_type = ip_type;
745
746
747 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
748 if (!*if_info) {
749 beiscsi_log(phba, KERN_ERR,
750 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
751 "BG_%d : Memory Allocation Failure\n");
752
753
754 pci_free_consistent(phba->ctrl.pdev,
755 nonemb_cmd.size,
756 nonemb_cmd.va,
757 nonemb_cmd.dma);
758 return -ENOMEM;
759 }
760
761 rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, *if_info,
762 ioctl_size);
763
764
765 if (rc == -EAGAIN) {
766
767
768 ioctl_size = ((struct be_cmd_resp_hdr *)
769 nonemb_cmd.va)->actual_resp_len;
770 ioctl_size += sizeof(struct be_cmd_req_hdr);
771
772
773 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
774 nonemb_cmd.va,
775 nonemb_cmd.dma);
776
777
778 kfree(*if_info);
779 } else
780 break;
781 } while (true);
782 return rc;
783}
784
785int mgmt_get_nic_conf(struct beiscsi_hba *phba,
786 struct be_cmd_get_nic_conf_resp *nic)
787{
788 struct be_dma_mem nonemb_cmd;
789 int rc;
790
791 rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI,
792 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
793 sizeof(*nic));
794 if (rc)
795 return rc;
796
797 return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL,
798 nic, sizeof(*nic));
799}
800
801static void beiscsi_boot_process_compl(struct beiscsi_hba *phba,
802 unsigned int tag)
803{
804 struct be_cmd_get_boot_target_resp *boot_resp;
805 struct be_cmd_resp_logout_fw_sess *logo_resp;
806 struct be_cmd_get_session_resp *sess_resp;
807 struct be_mcc_wrb *wrb;
808 struct boot_struct *bs;
809 int boot_work, status;
810
811 if (!test_bit(BEISCSI_HBA_BOOT_WORK, &phba->state)) {
812 __beiscsi_log(phba, KERN_ERR,
813 "BG_%d : %s no boot work %lx\n",
814 __func__, phba->state);
815 return;
816 }
817
818 if (phba->boot_struct.tag != tag) {
819 __beiscsi_log(phba, KERN_ERR,
820 "BG_%d : %s tag mismatch %d:%d\n",
821 __func__, tag, phba->boot_struct.tag);
822 return;
823 }
824 bs = &phba->boot_struct;
825 boot_work = 1;
826 status = 0;
827 switch (bs->action) {
828 case BEISCSI_BOOT_REOPEN_SESS:
829 status = __beiscsi_mcc_compl_status(phba, tag, NULL, NULL);
830 if (!status)
831 bs->action = BEISCSI_BOOT_GET_SHANDLE;
832 else
833 bs->retry--;
834 break;
835 case BEISCSI_BOOT_GET_SHANDLE:
836 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
837 if (!status) {
838 boot_resp = embedded_payload(wrb);
839 bs->s_handle = boot_resp->boot_session_handle;
840 }
841 if (bs->s_handle == BE_BOOT_INVALID_SHANDLE) {
842 bs->action = BEISCSI_BOOT_REOPEN_SESS;
843 bs->retry--;
844 } else {
845 bs->action = BEISCSI_BOOT_GET_SINFO;
846 }
847 break;
848 case BEISCSI_BOOT_GET_SINFO:
849 status = __beiscsi_mcc_compl_status(phba, tag, NULL,
850 &bs->nonemb_cmd);
851 if (!status) {
852 sess_resp = bs->nonemb_cmd.va;
853 memcpy(&bs->boot_sess, &sess_resp->session_info,
854 sizeof(struct mgmt_session_info));
855 bs->action = BEISCSI_BOOT_LOGOUT_SESS;
856 } else {
857 __beiscsi_log(phba, KERN_ERR,
858 "BG_%d : get boot session info error : 0x%x\n",
859 status);
860 boot_work = 0;
861 }
862 pci_free_consistent(phba->ctrl.pdev, bs->nonemb_cmd.size,
863 bs->nonemb_cmd.va, bs->nonemb_cmd.dma);
864 bs->nonemb_cmd.va = NULL;
865 break;
866 case BEISCSI_BOOT_LOGOUT_SESS:
867 status = __beiscsi_mcc_compl_status(phba, tag, &wrb, NULL);
868 if (!status) {
869 logo_resp = embedded_payload(wrb);
870 if (logo_resp->session_status != BE_SESS_STATUS_CLOSE) {
871 __beiscsi_log(phba, KERN_ERR,
872 "BG_%d : FW boot session logout error : 0x%x\n",
873 logo_resp->session_status);
874 }
875 }
876
877 bs->action = BEISCSI_BOOT_CREATE_KSET;
878 break;
879 default:
880 break;
881 }
882
883
884 bs->tag = 0;
885 if (!bs->retry) {
886 boot_work = 0;
887 __beiscsi_log(phba, KERN_ERR,
888 "BG_%d : failed to setup boot target: status %d action %d\n",
889 status, bs->action);
890 }
891 if (!boot_work) {
892
893 clear_bit(BEISCSI_HBA_BOOT_WORK, &phba->state);
894 return;
895 }
896 schedule_work(&phba->boot_work);
897}
898
899
900
901
902
903
904
905
906
907unsigned int beiscsi_boot_logout_sess(struct beiscsi_hba *phba)
908{
909 struct be_ctrl_info *ctrl = &phba->ctrl;
910 struct be_mcc_wrb *wrb;
911 struct be_cmd_req_logout_fw_sess *req;
912 unsigned int tag;
913
914 mutex_lock(&ctrl->mbox_lock);
915 wrb = alloc_mcc_wrb(phba, &tag);
916 if (!wrb) {
917 mutex_unlock(&ctrl->mbox_lock);
918 return 0;
919 }
920
921 req = embedded_payload(wrb);
922 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
923 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
924 OPCODE_ISCSI_INI_SESSION_LOGOUT_TARGET,
925 sizeof(struct be_cmd_req_logout_fw_sess));
926
927 req->session_handle = phba->boot_struct.boot_sess.session_handle;
928
929 phba->boot_struct.tag = tag;
930 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
931 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
932
933 be_mcc_notify(phba, tag);
934 mutex_unlock(&ctrl->mbox_lock);
935
936 return tag;
937}
938
939
940
941
942
943
944
945
946unsigned int beiscsi_boot_reopen_sess(struct beiscsi_hba *phba)
947{
948 struct be_ctrl_info *ctrl = &phba->ctrl;
949 struct be_mcc_wrb *wrb;
950 struct be_cmd_reopen_session_req *req;
951 unsigned int tag;
952
953 mutex_lock(&ctrl->mbox_lock);
954 wrb = alloc_mcc_wrb(phba, &tag);
955 if (!wrb) {
956 mutex_unlock(&ctrl->mbox_lock);
957 return 0;
958 }
959
960 req = embedded_payload(wrb);
961 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
962 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
963 OPCODE_ISCSI_INI_DRIVER_REOPEN_ALL_SESSIONS,
964 sizeof(struct be_cmd_reopen_session_resp));
965 req->reopen_type = BE_REOPEN_BOOT_SESSIONS;
966 req->session_handle = BE_BOOT_INVALID_SHANDLE;
967
968 phba->boot_struct.tag = tag;
969 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
970 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
971
972 be_mcc_notify(phba, tag);
973 mutex_unlock(&ctrl->mbox_lock);
974 return tag;
975}
976
977
978
979
980
981
982
983
984
985
986
987unsigned int beiscsi_boot_get_sinfo(struct beiscsi_hba *phba)
988{
989 struct be_ctrl_info *ctrl = &phba->ctrl;
990 struct be_cmd_get_session_req *req;
991 struct be_dma_mem *nonemb_cmd;
992 struct be_mcc_wrb *wrb;
993 struct be_sge *sge;
994 unsigned int tag;
995
996 mutex_lock(&ctrl->mbox_lock);
997 wrb = alloc_mcc_wrb(phba, &tag);
998 if (!wrb) {
999 mutex_unlock(&ctrl->mbox_lock);
1000 return 0;
1001 }
1002
1003 nonemb_cmd = &phba->boot_struct.nonemb_cmd;
1004 nonemb_cmd->size = sizeof(struct be_cmd_get_session_resp);
1005 nonemb_cmd->va = pci_alloc_consistent(phba->ctrl.pdev,
1006 nonemb_cmd->size,
1007 &nonemb_cmd->dma);
1008 if (!nonemb_cmd->va) {
1009 mutex_unlock(&ctrl->mbox_lock);
1010 return 0;
1011 }
1012
1013 req = nonemb_cmd->va;
1014 memset(req, 0, sizeof(*req));
1015 sge = nonembedded_sgl(wrb);
1016 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1017 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1018 OPCODE_ISCSI_INI_SESSION_GET_A_SESSION,
1019 sizeof(struct be_cmd_get_session_resp));
1020 req->session_handle = phba->boot_struct.s_handle;
1021 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
1022 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
1023 sge->len = cpu_to_le32(nonemb_cmd->size);
1024
1025 phba->boot_struct.tag = tag;
1026 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1027 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1028
1029 be_mcc_notify(phba, tag);
1030 mutex_unlock(&ctrl->mbox_lock);
1031 return tag;
1032}
1033
1034unsigned int __beiscsi_boot_get_shandle(struct beiscsi_hba *phba, int async)
1035{
1036 struct be_ctrl_info *ctrl = &phba->ctrl;
1037 struct be_mcc_wrb *wrb;
1038 struct be_cmd_get_boot_target_req *req;
1039 unsigned int tag;
1040
1041 mutex_lock(&ctrl->mbox_lock);
1042 wrb = alloc_mcc_wrb(phba, &tag);
1043 if (!wrb) {
1044 mutex_unlock(&ctrl->mbox_lock);
1045 return 0;
1046 }
1047
1048 req = embedded_payload(wrb);
1049 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
1050 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
1051 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
1052 sizeof(struct be_cmd_get_boot_target_resp));
1053
1054 if (async) {
1055 phba->boot_struct.tag = tag;
1056 set_bit(MCC_TAG_STATE_ASYNC, &ctrl->ptag_state[tag].tag_state);
1057 ctrl->ptag_state[tag].cbfn = beiscsi_boot_process_compl;
1058 }
1059
1060 be_mcc_notify(phba, tag);
1061 mutex_unlock(&ctrl->mbox_lock);
1062 return tag;
1063}
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075int beiscsi_boot_get_shandle(struct beiscsi_hba *phba, unsigned int *s_handle)
1076{
1077 struct be_cmd_get_boot_target_resp *boot_resp;
1078 struct be_mcc_wrb *wrb;
1079 unsigned int tag;
1080 int rc;
1081
1082 *s_handle = BE_BOOT_INVALID_SHANDLE;
1083
1084 tag = __beiscsi_boot_get_shandle(phba, 0);
1085 if (!tag) {
1086 beiscsi_log(phba, KERN_ERR,
1087 BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
1088 "BG_%d : Getting Boot Target Info Failed\n");
1089 return -EAGAIN;
1090 }
1091
1092 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL);
1093 if (rc) {
1094 beiscsi_log(phba, KERN_ERR,
1095 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1096 "BG_%d : MBX CMD get_boot_target Failed\n");
1097 return -EBUSY;
1098 }
1099
1100 boot_resp = embedded_payload(wrb);
1101
1102 if (!boot_resp->boot_session_count) {
1103 __beiscsi_log(phba, KERN_INFO,
1104 "BG_%d : No boot targets configured\n");
1105 return -ENXIO;
1106 }
1107
1108
1109 *s_handle = boot_resp->boot_session_handle;
1110 return 1;
1111}
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122ssize_t
1123beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr,
1124 char *buf)
1125{
1126 return snprintf(buf, PAGE_SIZE, BE_NAME "\n");
1127}
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138ssize_t
1139beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr,
1140 char *buf)
1141{
1142 struct Scsi_Host *shost = class_to_shost(dev);
1143 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1144
1145 return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str);
1146}
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157ssize_t
1158beiscsi_active_session_disp(struct device *dev, struct device_attribute *attr,
1159 char *buf)
1160{
1161 struct Scsi_Host *shost = class_to_shost(dev);
1162 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1163 uint16_t avlbl_cids = 0, ulp_num, len = 0, total_cids = 0;
1164
1165 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1166 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) {
1167 avlbl_cids = BEISCSI_ULP_AVLBL_CID(phba, ulp_num);
1168 total_cids = BEISCSI_GET_CID_COUNT(phba, ulp_num);
1169 len += snprintf(buf+len, PAGE_SIZE - len,
1170 "ULP%d : %d\n", ulp_num,
1171 (total_cids - avlbl_cids));
1172 } else
1173 len += snprintf(buf+len, PAGE_SIZE - len,
1174 "ULP%d : %d\n", ulp_num, 0);
1175 }
1176
1177 return len;
1178}
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189ssize_t
1190beiscsi_free_session_disp(struct device *dev, struct device_attribute *attr,
1191 char *buf)
1192{
1193 struct Scsi_Host *shost = class_to_shost(dev);
1194 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1195 uint16_t ulp_num, len = 0;
1196
1197 for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) {
1198 if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported))
1199 len += snprintf(buf+len, PAGE_SIZE - len,
1200 "ULP%d : %d\n", ulp_num,
1201 BEISCSI_ULP_AVLBL_CID(phba, ulp_num));
1202 else
1203 len += snprintf(buf+len, PAGE_SIZE - len,
1204 "ULP%d : %d\n", ulp_num, 0);
1205 }
1206
1207 return len;
1208}
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219ssize_t
1220beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr,
1221 char *buf)
1222{
1223 uint16_t dev_id = 0;
1224 struct Scsi_Host *shost = class_to_shost(dev);
1225 struct beiscsi_hba *phba = iscsi_host_priv(shost);
1226
1227 dev_id = phba->pcidev->device;
1228 switch (dev_id) {
1229 case BE_DEVICE_ID1:
1230 case OC_DEVICE_ID1:
1231 case OC_DEVICE_ID2:
1232 return snprintf(buf, PAGE_SIZE, "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