Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
be_mgmt.c
Go to the documentation of this file.
1 
20 #include <linux/bsg-lib.h>
22 #include <scsi/scsi_bsg_iscsi.h>
23 #include "be_mgmt.h"
24 #include "be_iscsi.h"
25 
36 unsigned int mgmt_reopen_session(struct beiscsi_hba *phba,
37  unsigned int reopen_type,
38  unsigned int sess_handle)
39 {
40  struct be_ctrl_info *ctrl = &phba->ctrl;
41  struct be_mcc_wrb *wrb;
43  unsigned int tag = 0;
44 
45  beiscsi_log(phba, KERN_INFO,
47  "BG_%d : In bescsi_get_boot_target\n");
48 
49  spin_lock(&ctrl->mbox_lock);
50  tag = alloc_mcc_tag(phba);
51  if (!tag) {
52  spin_unlock(&ctrl->mbox_lock);
53  return tag;
54  }
55 
56  wrb = wrb_from_mccq(phba);
57  req = embedded_payload(wrb);
58  wrb->tag0 |= tag;
59  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
62  sizeof(struct be_cmd_reopen_session_resp));
63 
64  /* set the reopen_type,sess_handle */
65  req->reopen_type = reopen_type;
66  req->session_handle = sess_handle;
67 
68  be_mcc_notify(phba);
69  spin_unlock(&ctrl->mbox_lock);
70  return tag;
71 }
72 
73 unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
74 {
75  struct be_ctrl_info *ctrl = &phba->ctrl;
76  struct be_mcc_wrb *wrb;
78  unsigned int tag = 0;
79 
80  beiscsi_log(phba, KERN_INFO,
82  "BG_%d : In bescsi_get_boot_target\n");
83 
84  spin_lock(&ctrl->mbox_lock);
85  tag = alloc_mcc_tag(phba);
86  if (!tag) {
87  spin_unlock(&ctrl->mbox_lock);
88  return tag;
89  }
90 
91  wrb = wrb_from_mccq(phba);
92  req = embedded_payload(wrb);
93  wrb->tag0 |= tag;
94  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
97  sizeof(struct be_cmd_get_boot_target_resp));
98 
99  be_mcc_notify(phba);
100  spin_unlock(&ctrl->mbox_lock);
101  return tag;
102 }
103 
104 unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
105  u32 boot_session_handle,
106  struct be_dma_mem *nonemb_cmd)
107 {
108  struct be_ctrl_info *ctrl = &phba->ctrl;
109  struct be_mcc_wrb *wrb;
110  unsigned int tag = 0;
111  struct be_cmd_get_session_req *req;
113  struct be_sge *sge;
114 
115  beiscsi_log(phba, KERN_INFO,
117  "BG_%d : In beiscsi_get_session_info\n");
118 
119  spin_lock(&ctrl->mbox_lock);
120  tag = alloc_mcc_tag(phba);
121  if (!tag) {
122  spin_unlock(&ctrl->mbox_lock);
123  return tag;
124  }
125 
126  nonemb_cmd->size = sizeof(*resp);
127  req = nonemb_cmd->va;
128  memset(req, 0, sizeof(*req));
129  wrb = wrb_from_mccq(phba);
130  sge = nonembedded_sgl(wrb);
131  wrb->tag0 |= tag;
132 
133 
134  wrb->tag0 |= tag;
135  be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
138  sizeof(*resp));
139  req->session_handle = boot_session_handle;
140  sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
141  sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
142  sge->len = cpu_to_le32(nonemb_cmd->size);
143 
144  be_mcc_notify(phba);
145  spin_unlock(&ctrl->mbox_lock);
146  return tag;
147 }
148 
150  struct beiscsi_hba *phba)
151 {
152  struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
153  struct be_fw_cfg *req = embedded_payload(wrb);
154  int status = 0;
155 
156  spin_lock(&ctrl->mbox_lock);
157  memset(wrb, 0, sizeof(*wrb));
158 
159  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
160 
163  status = be_mbox_notify(ctrl);
164  if (!status) {
165  struct be_fw_cfg *pfw_cfg;
166  pfw_cfg = req;
167  phba->fw_config.phys_port = pfw_cfg->phys_port;
168  phba->fw_config.iscsi_icd_start =
169  pfw_cfg->ulp[0].icd_base;
170  phba->fw_config.iscsi_icd_count =
171  pfw_cfg->ulp[0].icd_count;
172  phba->fw_config.iscsi_cid_start =
173  pfw_cfg->ulp[0].sq_base;
174  phba->fw_config.iscsi_cid_count =
175  pfw_cfg->ulp[0].sq_count;
176  if (phba->fw_config.iscsi_cid_count > (BE2_MAX_SESSIONS / 2)) {
178  "BG_%d : FW reported MAX CXNS as %d\t"
179  "Max Supported = %d.\n",
180  phba->fw_config.iscsi_cid_count,
182  phba->fw_config.iscsi_cid_count = BE2_MAX_SESSIONS / 2;
183  }
184  } else {
186  "BG_%d : Failed in mgmt_get_fw_config\n");
187  }
188 
189  spin_unlock(&ctrl->mbox_lock);
190  return status;
191 }
192 
194  struct beiscsi_hba *phba)
195 {
196  struct be_dma_mem nonemb_cmd;
197  struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
199  struct be_sge *sge = nonembedded_sgl(wrb);
200  int status = 0;
201 
202  nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
203  sizeof(struct be_mgmt_controller_attributes),
204  &nonemb_cmd.dma);
205  if (nonemb_cmd.va == NULL) {
207  "BG_%d : Failed to allocate memory for "
208  "mgmt_check_supported_fw\n");
209  return -ENOMEM;
210  }
211  nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
212  req = nonemb_cmd.va;
213  memset(req, 0, sizeof(*req));
214  spin_lock(&ctrl->mbox_lock);
215  memset(wrb, 0, sizeof(*wrb));
216  be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
218  OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
219  sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
220  sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
221  sge->len = cpu_to_le32(nonemb_cmd.size);
222  status = be_mbox_notify(ctrl);
223  if (!status) {
224  struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
226  "BG_%d : Firmware Version of CMD : %s\n"
227  "Firmware Version is : %s\n"
228  "Developer Build, not performing version check...\n",
229  resp->params.hba_attribs
230  .flashrom_version_string,
231  resp->params.hba_attribs.
232  firmware_version_string);
233 
234  phba->fw_config.iscsi_features =
235  resp->params.hba_attribs.iscsi_features;
237  "BM_%d : phba->fw_config.iscsi_features = %d\n",
238  phba->fw_config.iscsi_features);
239  } else
241  "BG_%d : Failed in mgmt_check_supported_fw\n");
242  spin_unlock(&ctrl->mbox_lock);
243  if (nonemb_cmd.va)
244  pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
245  nonemb_cmd.va, nonemb_cmd.dma);
246 
247  return status;
248 }
249 
251  struct beiscsi_hba *phba,
252  struct bsg_job *job,
253  struct be_dma_mem *nonemb_cmd)
254 {
255  struct be_cmd_resp_hdr *resp;
256  struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
257  struct be_sge *mcc_sge = nonembedded_sgl(wrb);
258  unsigned int tag = 0;
259  struct iscsi_bsg_request *bsg_req = job->request;
260  struct be_bsg_vendor_cmd *req = nonemb_cmd->va;
261  unsigned short region, sector_size, sector, offset;
262 
263  nonemb_cmd->size = job->request_payload.payload_len;
264  memset(nonemb_cmd->va, 0, nonemb_cmd->size);
265  resp = nonemb_cmd->va;
266  region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
267  sector_size = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
268  sector = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
269  offset = bsg_req->rqst_data.h_vendor.vendor_cmd[4];
270  req->region = region;
271  req->sector = sector;
272  req->offset = offset;
273  spin_lock(&ctrl->mbox_lock);
274  memset(wrb, 0, sizeof(*wrb));
275 
276  switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
277  case BEISCSI_WRITE_FLASH:
278  offset = sector * sector_size + offset;
280  OPCODE_COMMON_WRITE_FLASH, sizeof(*req));
281  sg_copy_to_buffer(job->request_payload.sg_list,
282  job->request_payload.sg_cnt,
283  nonemb_cmd->va + offset, job->request_len);
284  break;
285  case BEISCSI_READ_FLASH:
287  OPCODE_COMMON_READ_FLASH, sizeof(*req));
288  break;
289  default:
291  "BG_%d : Unsupported cmd = 0x%x\n\n",
292  bsg_req->rqst_data.h_vendor.vendor_cmd[0]);
293 
294  spin_unlock(&ctrl->mbox_lock);
295  return -ENOSYS;
296  }
297 
298  tag = alloc_mcc_tag(phba);
299  if (!tag) {
300  spin_unlock(&ctrl->mbox_lock);
301  return tag;
302  }
303 
304  be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false,
305  job->request_payload.sg_cnt);
306  mcc_sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
307  mcc_sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
308  mcc_sge->len = cpu_to_le32(nonemb_cmd->size);
309  wrb->tag0 |= tag;
310 
311  be_mcc_notify(phba);
312 
313  spin_unlock(&ctrl->mbox_lock);
314  return tag;
315 }
316 
317 int mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
318 {
319  struct be_ctrl_info *ctrl = &phba->ctrl;
320  struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
321  struct iscsi_cleanup_req *req = embedded_payload(wrb);
322  int status = 0;
323 
324  spin_lock(&ctrl->mbox_lock);
325  memset(wrb, 0, sizeof(*wrb));
326 
327  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
329  OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
330 
331  req->chute = chute;
334 
335  status = be_mcc_notify_wait(phba);
336  if (status)
338  "BG_%d : mgmt_epfw_cleanup , FAILED\n");
339  spin_unlock(&ctrl->mbox_lock);
340  return status;
341 }
342 
343 unsigned int mgmt_invalidate_icds(struct beiscsi_hba *phba,
344  struct invalidate_command_table *inv_tbl,
345  unsigned int num_invalidate, unsigned int cid,
346  struct be_dma_mem *nonemb_cmd)
347 
348 {
349  struct be_ctrl_info *ctrl = &phba->ctrl;
350  struct be_mcc_wrb *wrb;
351  struct be_sge *sge;
353  unsigned int i, tag = 0;
354 
355  spin_lock(&ctrl->mbox_lock);
356  tag = alloc_mcc_tag(phba);
357  if (!tag) {
358  spin_unlock(&ctrl->mbox_lock);
359  return tag;
360  }
361 
362  req = nonemb_cmd->va;
363  memset(req, 0, sizeof(*req));
364  wrb = wrb_from_mccq(phba);
365  sge = nonembedded_sgl(wrb);
366  wrb->tag0 |= tag;
367 
368  be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
371  sizeof(*req));
372  req->ref_handle = 0;
374  for (i = 0; i < num_invalidate; i++) {
375  req->table[i].icd = inv_tbl->icd;
376  req->table[i].cid = inv_tbl->cid;
377  req->icd_count++;
378  inv_tbl++;
379  }
380  sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
381  sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
382  sge->len = cpu_to_le32(nonemb_cmd->size);
383 
384  be_mcc_notify(phba);
385  spin_unlock(&ctrl->mbox_lock);
386  return tag;
387 }
388 
389 unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
390  struct beiscsi_endpoint *beiscsi_ep,
391  unsigned short cid,
392  unsigned short issue_reset,
393  unsigned short savecfg_flag)
394 {
395  struct be_ctrl_info *ctrl = &phba->ctrl;
396  struct be_mcc_wrb *wrb;
398  unsigned int tag = 0;
399 
400  spin_lock(&ctrl->mbox_lock);
401  tag = alloc_mcc_tag(phba);
402  if (!tag) {
403  spin_unlock(&ctrl->mbox_lock);
404  return tag;
405  }
406  wrb = wrb_from_mccq(phba);
407  wrb->tag0 |= tag;
408  req = embedded_payload(wrb);
409 
410  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
413  sizeof(*req));
414  req->session_handle = beiscsi_ep->fw_handle;
415  req->cid = cid;
416  if (issue_reset)
418  else
420  req->save_cfg = savecfg_flag;
421  be_mcc_notify(phba);
422  spin_unlock(&ctrl->mbox_lock);
423  return tag;
424 }
425 
426 unsigned int mgmt_upload_connection(struct beiscsi_hba *phba,
427  unsigned short cid, unsigned int upload_flag)
428 {
429  struct be_ctrl_info *ctrl = &phba->ctrl;
430  struct be_mcc_wrb *wrb;
431  struct tcp_upload_params_in *req;
432  unsigned int tag = 0;
433 
434  spin_lock(&ctrl->mbox_lock);
435  tag = alloc_mcc_tag(phba);
436  if (!tag) {
437  spin_unlock(&ctrl->mbox_lock);
438  return tag;
439  }
440  wrb = wrb_from_mccq(phba);
441  req = embedded_payload(wrb);
442  wrb->tag0 |= tag;
443 
444  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
446  OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
447  req->id = (unsigned short)cid;
448  req->upload_type = (unsigned char)upload_flag;
449  be_mcc_notify(phba);
450  spin_unlock(&ctrl->mbox_lock);
451  return tag;
452 }
453 
455  struct sockaddr *dst_addr,
456  struct beiscsi_endpoint *beiscsi_ep,
457  struct be_dma_mem *nonemb_cmd)
458 {
459  struct hwi_controller *phwi_ctrlr;
460  struct hwi_context_memory *phwi_context;
461  struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
462  struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
463  struct be_ctrl_info *ctrl = &phba->ctrl;
464  struct be_mcc_wrb *wrb;
466  unsigned short def_hdr_id;
467  unsigned short def_data_id;
468  struct phys_addr template_address = { 0, 0 };
469  struct phys_addr *ptemplate_address;
470  unsigned int tag = 0;
471  unsigned int i;
472  unsigned short cid = beiscsi_ep->ep_cid;
473  struct be_sge *sge;
474 
475  phwi_ctrlr = phba->phwi_ctrlr;
476  phwi_context = phwi_ctrlr->phwi_ctxt;
477  def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba);
478  def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba);
479 
480  ptemplate_address = &template_address;
481  ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
482  spin_lock(&ctrl->mbox_lock);
483  tag = alloc_mcc_tag(phba);
484  if (!tag) {
485  spin_unlock(&ctrl->mbox_lock);
486  return tag;
487  }
488  wrb = wrb_from_mccq(phba);
489  memset(wrb, 0, sizeof(*wrb));
490  sge = nonembedded_sgl(wrb);
491 
492  req = nonemb_cmd->va;
493  memset(req, 0, sizeof(*req));
494  wrb->tag0 |= tag;
495 
496  be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
499  sizeof(*req));
500  if (dst_addr->sa_family == PF_INET) {
501  __be32 s_addr = daddr_in->sin_addr.s_addr;
502  req->ip_address.ip_type = BE2_IPV4;
503  req->ip_address.addr[0] = s_addr & 0x000000ff;
504  req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
505  req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
506  req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
507  req->tcp_port = ntohs(daddr_in->sin_port);
508  beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
509  beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
510  beiscsi_ep->ip_type = BE2_IPV4;
511  } else if (dst_addr->sa_family == PF_INET6) {
512  req->ip_address.ip_type = BE2_IPV6;
513  memcpy(&req->ip_address.addr,
514  &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
515  req->tcp_port = ntohs(daddr_in6->sin6_port);
516  beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
517  memcpy(&beiscsi_ep->dst6_addr,
518  &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
519  beiscsi_ep->ip_type = BE2_IPV6;
520  } else{
522  "BG_%d : unknown addr family %d\n",
523  dst_addr->sa_family);
524  spin_unlock(&ctrl->mbox_lock);
525  free_mcc_tag(&phba->ctrl, tag);
526  return -EINVAL;
527 
528  }
529  req->cid = cid;
530  i = phba->nxt_cqid++;
531  if (phba->nxt_cqid == phba->num_cpus)
532  phba->nxt_cqid = 0;
533  req->cq_id = phwi_context->be_cq[i].id;
535  "BG_%d : i=%d cq_id=%d\n", i, req->cq_id);
536  req->defq_id = def_hdr_id;
537  req->hdr_ring_id = def_hdr_id;
538  req->data_ring_id = def_data_id;
539  req->do_offload = 1;
540  req->dataout_template_pa.lo = ptemplate_address->lo;
541  req->dataout_template_pa.hi = ptemplate_address->hi;
542  sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
543  sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
544  sge->len = cpu_to_le32(nonemb_cmd->size);
545  be_mcc_notify(phba);
546  spin_unlock(&ctrl->mbox_lock);
547  return tag;
548 }
549 
550 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
551 {
552  struct be_ctrl_info *ctrl = &phba->ctrl;
553  struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
554  struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
555  struct be_cmd_get_all_if_id_req *pbe_allid = req;
556  int status = 0;
557 
558  memset(wrb, 0, sizeof(*wrb));
559 
560  spin_lock(&ctrl->mbox_lock);
561 
562  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
565  sizeof(*req));
566  status = be_mbox_notify(ctrl);
567  if (!status)
568  phba->interface_handle = pbe_allid->if_hndl_list[0];
569  else {
571  "BG_%d : Failed in mgmt_get_all_if_id\n");
572  }
573  spin_unlock(&ctrl->mbox_lock);
574 
575  return status;
576 }
577 
578 static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
579  struct be_dma_mem *nonemb_cmd, void *resp_buf,
580  int resp_buf_len)
581 {
582  struct be_ctrl_info *ctrl = &phba->ctrl;
583  struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
584  unsigned short status, extd_status;
585  struct be_sge *sge;
586  unsigned int tag;
587  int rc = 0;
588 
589  spin_lock(&ctrl->mbox_lock);
590  tag = alloc_mcc_tag(phba);
591  if (!tag) {
592  spin_unlock(&ctrl->mbox_lock);
593  rc = -ENOMEM;
594  goto free_cmd;
595  }
596  memset(wrb, 0, sizeof(*wrb));
597  wrb->tag0 |= tag;
598  sge = nonembedded_sgl(wrb);
599 
600  be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
601  sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
602  sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
603  sge->len = cpu_to_le32(nonemb_cmd->size);
604 
605  be_mcc_notify(phba);
606  spin_unlock(&ctrl->mbox_lock);
607 
608  wait_event_interruptible(phba->ctrl.mcc_wait[tag],
609  phba->ctrl.mcc_numtag[tag]);
610 
611  extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
612  status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
613  if (status || extd_status) {
614  beiscsi_log(phba, KERN_ERR,
616  "BG_%d : mgmt_exec_nonemb_cmd Failed status = %d"
617  "extd_status = %d\n", status, extd_status);
618  rc = -EIO;
619  goto free_tag;
620  }
621 
622  if (resp_buf)
623  memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
624 
625 free_tag:
626  free_mcc_tag(&phba->ctrl, tag);
627 free_cmd:
628  pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
629  nonemb_cmd->va, nonemb_cmd->dma);
630  return rc;
631 }
632 
633 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
634  int iscsi_cmd, int size)
635 {
636  cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma);
637  if (!cmd->va) {
639  "BG_%d : Failed to allocate memory for if info\n");
640  return -ENOMEM;
641  }
642  memset(cmd->va, 0, size);
643  cmd->size = size;
644  be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
645  return 0;
646 }
647 
648 static int
649 mgmt_static_ip_modify(struct beiscsi_hba *phba,
650  struct be_cmd_get_if_info_resp *if_info,
651  struct iscsi_iface_param_info *ip_param,
652  struct iscsi_iface_param_info *subnet_param,
653  uint32_t ip_action)
654 {
655  struct be_cmd_set_ip_addr_req *req;
656  struct be_dma_mem nonemb_cmd;
657  uint32_t ip_type;
658  int rc;
659 
660  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
662  sizeof(*req));
663  if (rc)
664  return rc;
665 
666  ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
667  BE2_IPV6 : BE2_IPV4 ;
668 
669  req = nonemb_cmd.va;
670  req->ip_params.record_entry_count = 1;
671  req->ip_params.ip_record.action = ip_action;
672  req->ip_params.ip_record.interface_hndl =
673  phba->interface_handle;
674  req->ip_params.ip_record.ip_addr.size_of_structure =
675  sizeof(struct be_ip_addr_subnet_format);
676  req->ip_params.ip_record.ip_addr.ip_type = ip_type;
677 
678  if (ip_action == IP_ACTION_ADD) {
679  memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
680  ip_param->len);
681 
682  if (subnet_param)
683  memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
684  subnet_param->value, subnet_param->len);
685  } else {
686  memcpy(req->ip_params.ip_record.ip_addr.addr,
687  if_info->ip_addr.addr, ip_param->len);
688 
689  memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
690  if_info->ip_addr.subnet_mask, ip_param->len);
691  }
692 
693  rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
694  if (rc < 0)
696  "BG_%d : Failed to Modify existing IP Address\n");
697  return rc;
698 }
699 
700 static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
701  uint32_t gtway_action, uint32_t param_len)
702 {
704  struct be_dma_mem nonemb_cmd;
705  int rt_val;
706 
707 
708  rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
710  sizeof(*req));
711  if (rt_val)
712  return rt_val;
713 
714  req = nonemb_cmd.va;
715  req->action = gtway_action;
716  req->ip_addr.ip_type = BE2_IPV4;
717 
718  memcpy(req->ip_addr.addr, gt_addr, param_len);
719 
720  return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
721 }
722 
723 int mgmt_set_ip(struct beiscsi_hba *phba,
724  struct iscsi_iface_param_info *ip_param,
725  struct iscsi_iface_param_info *subnet_param,
726  uint32_t boot_proto)
727 {
728  struct be_cmd_get_def_gateway_resp gtway_addr_set;
729  struct be_cmd_get_if_info_resp if_info;
730  struct be_cmd_set_dhcp_req *dhcpreq;
731  struct be_cmd_rel_dhcp_req *reldhcp;
732  struct be_dma_mem nonemb_cmd;
733  uint8_t *gtway_addr;
734  uint32_t ip_type;
735  int rc;
736 
737  if (mgmt_get_all_if_id(phba))
738  return -EIO;
739 
740  memset(&if_info, 0, sizeof(if_info));
741  ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
742  BE2_IPV6 : BE2_IPV4 ;
743 
744  rc = mgmt_get_if_info(phba, ip_type, &if_info);
745  if (rc)
746  return rc;
747 
748  if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
749  if (if_info.dhcp_state) {
751  "BG_%d : DHCP Already Enabled\n");
752  return 0;
753  }
754  /* The ip_param->len is 1 in DHCP case. Setting
755  proper IP len as this it is used while
756  freeing the Static IP.
757  */
758  ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
760 
761  } else {
762  if (if_info.dhcp_state) {
763 
764  memset(&if_info, 0, sizeof(if_info));
765  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
767  sizeof(*reldhcp));
768 
769  if (rc)
770  return rc;
771 
772  reldhcp = nonemb_cmd.va;
773  reldhcp->interface_hndl = phba->interface_handle;
774  reldhcp->ip_type = ip_type;
775 
776  rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
777  if (rc < 0) {
780  "BG_%d : Failed to Delete existing dhcp\n");
781  return rc;
782  }
783  }
784  }
785 
786  /* Delete the Static IP Set */
787  if (if_info.ip_addr.addr[0]) {
788  rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL,
789  IP_ACTION_DEL);
790  if (rc)
791  return rc;
792  }
793 
794  /* Delete the Gateway settings if mode change is to DHCP */
795  if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
796  memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
797  rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
798  if (rc) {
800  "BG_%d : Failed to Get Gateway Addr\n");
801  return rc;
802  }
803 
804  if (gtway_addr_set.ip_addr.addr[0]) {
805  gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
806  rc = mgmt_modify_gateway(phba, gtway_addr,
808 
809  if (rc) {
812  "BG_%d : Failed to clear Gateway Addr Set\n");
813  return rc;
814  }
815  }
816  }
817 
818  /* Set Adapter to DHCP/Static Mode */
819  if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
820  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
822  sizeof(*dhcpreq));
823  if (rc)
824  return rc;
825 
826  dhcpreq = nonemb_cmd.va;
827  dhcpreq->flags = BLOCKING;
828  dhcpreq->retry_count = 1;
829  dhcpreq->interface_hndl = phba->interface_handle;
830  dhcpreq->ip_type = BE2_DHCP_V4;
831 
832  return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
833  } else {
834  return mgmt_static_ip_modify(phba, &if_info, ip_param,
835  subnet_param, IP_ACTION_ADD);
836  }
837 
838  return rc;
839 }
840 
841 int mgmt_set_gateway(struct beiscsi_hba *phba,
842  struct iscsi_iface_param_info *gateway_param)
843 {
844  struct be_cmd_get_def_gateway_resp gtway_addr_set;
845  uint8_t *gtway_addr;
846  int rt_val;
847 
848  memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
849  rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
850  if (rt_val) {
852  "BG_%d : Failed to Get Gateway Addr\n");
853  return rt_val;
854  }
855 
856  if (gtway_addr_set.ip_addr.addr[0]) {
857  gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
858  rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
859  gateway_param->len);
860  if (rt_val) {
862  "BG_%d : Failed to clear Gateway Addr Set\n");
863  return rt_val;
864  }
865  }
866 
867  gtway_addr = (uint8_t *)&gateway_param->value;
868  rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
869  gateway_param->len);
870 
871  if (rt_val)
873  "BG_%d : Failed to Set Gateway Addr\n");
874 
875  return rt_val;
876 }
877 
878 int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
880 {
882  struct be_dma_mem nonemb_cmd;
883  int rc;
884 
885  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
887  sizeof(*gateway));
888  if (rc)
889  return rc;
890 
891  req = nonemb_cmd.va;
892  req->ip_type = ip_type;
893 
894  return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
895  sizeof(*gateway));
896 }
897 
898 int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
899  struct be_cmd_get_if_info_resp *if_info)
900 {
901  struct be_cmd_get_if_info_req *req;
902  struct be_dma_mem nonemb_cmd;
903  int rc;
904 
905  if (mgmt_get_all_if_id(phba))
906  return -EIO;
907 
908  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
910  sizeof(*if_info));
911  if (rc)
912  return rc;
913 
914  req = nonemb_cmd.va;
915  req->interface_hndl = phba->interface_handle;
916  req->ip_type = ip_type;
917 
918  return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info,
919  sizeof(*if_info));
920 }
921 
923  struct be_cmd_get_nic_conf_resp *nic)
924 {
925  struct be_dma_mem nonemb_cmd;
926  int rc;
927 
928  rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
930  sizeof(*nic));
931  if (rc)
932  return rc;
933 
934  return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
935 }
936 
937 
938 
939 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
940 {
941  unsigned int tag = 0;
942  struct be_mcc_wrb *wrb;
943  struct be_cmd_hba_name *req;
944  struct be_ctrl_info *ctrl = &phba->ctrl;
945 
946  spin_lock(&ctrl->mbox_lock);
947  tag = alloc_mcc_tag(phba);
948  if (!tag) {
949  spin_unlock(&ctrl->mbox_lock);
950  return tag;
951  }
952 
953  wrb = wrb_from_mccq(phba);
954  req = embedded_payload(wrb);
955  wrb->tag0 |= tag;
956  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
959  sizeof(*req));
960 
961  be_mcc_notify(phba);
962  spin_unlock(&ctrl->mbox_lock);
963  return tag;
964 }
965 
966 unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba)
967 {
968  unsigned int tag = 0;
969  struct be_mcc_wrb *wrb;
971  struct be_ctrl_info *ctrl = &phba->ctrl;
972 
973  spin_lock(&ctrl->mbox_lock);
974  tag = alloc_mcc_tag(phba);
975  if (!tag) {
976  spin_unlock(&ctrl->mbox_lock);
977  return tag;
978  }
979 
980  wrb = wrb_from_mccq(phba);
981  req = embedded_payload(wrb);
982  wrb->tag0 |= tag;
983  be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
986  sizeof(*req));
987 
988  be_mcc_notify(phba);
989  spin_unlock(&ctrl->mbox_lock);
990  return tag;
991 }
992 
1008  unsigned int *s_handle)
1009 {
1010  struct be_cmd_get_boot_target_resp *boot_resp;
1011  struct be_mcc_wrb *wrb;
1012  unsigned int tag, wrb_num;
1013  uint8_t boot_retry = 3;
1014  unsigned short status, extd_status;
1015  struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
1016 
1017  do {
1018  /* Get the Boot Target Session Handle and Count*/
1019  tag = mgmt_get_boot_target(phba);
1020  if (!tag) {
1021  beiscsi_log(phba, KERN_ERR,
1023  "BG_%d : Getting Boot Target Info Failed\n");
1024  return -EAGAIN;
1025  } else
1026  wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1027  phba->ctrl.mcc_numtag[tag]);
1028 
1029  wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
1030  extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
1031  status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
1032  if (status || extd_status) {
1033  beiscsi_log(phba, KERN_ERR,
1035  "BG_%d : mgmt_get_boot_target Failed"
1036  " status = %d extd_status = %d\n",
1037  status, extd_status);
1038  free_mcc_tag(&phba->ctrl, tag);
1039  return -EBUSY;
1040  }
1041  wrb = queue_get_wrb(mccq, wrb_num);
1042  free_mcc_tag(&phba->ctrl, tag);
1043  boot_resp = embedded_payload(wrb);
1044 
1045  /* Check if the there are any Boot targets configured */
1046  if (!boot_resp->boot_session_count) {
1047  beiscsi_log(phba, KERN_INFO,
1049  "BG_%d ;No boot targets configured\n");
1050  return -ENXIO;
1051  }
1052 
1053  /* FW returns the session handle of the boot session */
1054  if (boot_resp->boot_session_handle != INVALID_SESS_HANDLE) {
1055  *s_handle = boot_resp->boot_session_handle;
1056  return 0;
1057  }
1058 
1059  /* Issue MBX Cmd to FW to login to the boot target */
1062  if (!tag) {
1063  beiscsi_log(phba, KERN_ERR,
1065  "BG_%d : mgmt_reopen_session Failed\n");
1066  return -EAGAIN;
1067  } else
1068  wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1069  phba->ctrl.mcc_numtag[tag]);
1070 
1071  wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
1072  extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
1073  status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
1074  if (status || extd_status) {
1075  beiscsi_log(phba, KERN_ERR,
1077  "BG_%d : mgmt_reopen_session Failed"
1078  " status = %d extd_status = %d\n",
1079  status, extd_status);
1080  free_mcc_tag(&phba->ctrl, tag);
1081  return -EBUSY;
1082  }
1083  free_mcc_tag(&phba->ctrl, tag);
1084 
1085  } while (--boot_retry);
1086 
1087  /* Couldn't log into the boot target */
1088  beiscsi_log(phba, KERN_ERR,
1090  "BG_%d : Login to Boot Target Failed\n");
1091  return -ENXIO;
1092 }
1093 
1106 int mgmt_set_vlan(struct beiscsi_hba *phba,
1107  uint16_t vlan_tag)
1108 {
1109  unsigned int tag, wrb_num;
1110  unsigned short status, extd_status;
1111 
1112  tag = be_cmd_set_vlan(phba, vlan_tag);
1113  if (!tag) {
1114  beiscsi_log(phba, KERN_ERR,
1116  "BG_%d : VLAN Setting Failed\n");
1117  return -EBUSY;
1118  } else
1119  wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1120  phba->ctrl.mcc_numtag[tag]);
1121 
1122  wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
1123  extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
1124  status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
1125 
1126  if (status || extd_status) {
1127  beiscsi_log(phba, KERN_ERR,
1129  "BS_%d : status : %d extd_status : %d\n",
1130  status, extd_status);
1131 
1132  free_mcc_tag(&phba->ctrl, tag);
1133  return -EAGAIN;
1134  }
1135 
1136  free_mcc_tag(&phba->ctrl, tag);
1137  return 0;
1138 }