diff options
Diffstat (limited to 'drivers/scsi/be2iscsi/be_iscsi.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 493 |
1 files changed, 457 insertions, 36 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 33c8f09c7ac1..43f35034585d 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <scsi/scsi_cmnd.h> | 23 | #include <scsi/scsi_cmnd.h> |
24 | #include <scsi/scsi_device.h> | 24 | #include <scsi/scsi_device.h> |
25 | #include <scsi/scsi_host.h> | 25 | #include <scsi/scsi_host.h> |
26 | #include <scsi/scsi_netlink.h> | ||
27 | #include <net/netlink.h> | ||
26 | #include <scsi/scsi.h> | 28 | #include <scsi/scsi.h> |
27 | 29 | ||
28 | #include "be_iscsi.h" | 30 | #include "be_iscsi.h" |
@@ -207,6 +209,301 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
207 | return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); | 209 | return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); |
208 | } | 210 | } |
209 | 211 | ||
212 | static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba) | ||
213 | { | ||
214 | if (phba->ipv4_iface) | ||
215 | return 0; | ||
216 | |||
217 | phba->ipv4_iface = iscsi_create_iface(phba->shost, | ||
218 | &beiscsi_iscsi_transport, | ||
219 | ISCSI_IFACE_TYPE_IPV4, | ||
220 | 0, 0); | ||
221 | if (!phba->ipv4_iface) { | ||
222 | shost_printk(KERN_ERR, phba->shost, "Could not " | ||
223 | "create default IPv4 address.\n"); | ||
224 | return -ENODEV; | ||
225 | } | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba) | ||
231 | { | ||
232 | if (phba->ipv6_iface) | ||
233 | return 0; | ||
234 | |||
235 | phba->ipv6_iface = iscsi_create_iface(phba->shost, | ||
236 | &beiscsi_iscsi_transport, | ||
237 | ISCSI_IFACE_TYPE_IPV6, | ||
238 | 0, 0); | ||
239 | if (!phba->ipv6_iface) { | ||
240 | shost_printk(KERN_ERR, phba->shost, "Could not " | ||
241 | "create default IPv6 address.\n"); | ||
242 | return -ENODEV; | ||
243 | } | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) | ||
249 | { | ||
250 | struct be_cmd_get_if_info_resp if_info; | ||
251 | |||
252 | if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) | ||
253 | beiscsi_create_ipv4_iface(phba); | ||
254 | |||
255 | if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) | ||
256 | beiscsi_create_ipv6_iface(phba); | ||
257 | } | ||
258 | |||
259 | void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) | ||
260 | { | ||
261 | if (phba->ipv6_iface) | ||
262 | iscsi_destroy_iface(phba->ipv6_iface); | ||
263 | if (phba->ipv4_iface) | ||
264 | iscsi_destroy_iface(phba->ipv4_iface); | ||
265 | } | ||
266 | |||
267 | static int | ||
268 | beiscsi_set_static_ip(struct Scsi_Host *shost, | ||
269 | struct iscsi_iface_param_info *iface_param, | ||
270 | void *data, uint32_t dt_len) | ||
271 | { | ||
272 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
273 | struct iscsi_iface_param_info *iface_ip = NULL; | ||
274 | struct iscsi_iface_param_info *iface_subnet = NULL; | ||
275 | struct nlattr *nla; | ||
276 | int ret; | ||
277 | |||
278 | |||
279 | switch (iface_param->param) { | ||
280 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | ||
281 | nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); | ||
282 | if (nla) | ||
283 | iface_ip = nla_data(nla); | ||
284 | |||
285 | nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); | ||
286 | if (nla) | ||
287 | iface_subnet = nla_data(nla); | ||
288 | break; | ||
289 | case ISCSI_NET_PARAM_IPV4_ADDR: | ||
290 | iface_ip = iface_param; | ||
291 | nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); | ||
292 | if (nla) | ||
293 | iface_subnet = nla_data(nla); | ||
294 | break; | ||
295 | case ISCSI_NET_PARAM_IPV4_SUBNET: | ||
296 | iface_subnet = iface_param; | ||
297 | nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); | ||
298 | if (nla) | ||
299 | iface_ip = nla_data(nla); | ||
300 | break; | ||
301 | default: | ||
302 | shost_printk(KERN_ERR, shost, "Unsupported param %d\n", | ||
303 | iface_param->param); | ||
304 | } | ||
305 | |||
306 | if (!iface_ip || !iface_subnet) { | ||
307 | shost_printk(KERN_ERR, shost, "IP and Subnet Mask required\n"); | ||
308 | return -EINVAL; | ||
309 | } | ||
310 | |||
311 | ret = mgmt_set_ip(phba, iface_ip, iface_subnet, | ||
312 | ISCSI_BOOTPROTO_STATIC); | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static int | ||
318 | beiscsi_set_ipv4(struct Scsi_Host *shost, | ||
319 | struct iscsi_iface_param_info *iface_param, | ||
320 | void *data, uint32_t dt_len) | ||
321 | { | ||
322 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
323 | int ret = 0; | ||
324 | |||
325 | /* Check the param */ | ||
326 | switch (iface_param->param) { | ||
327 | case ISCSI_NET_PARAM_IPV4_GW: | ||
328 | ret = mgmt_set_gateway(phba, iface_param); | ||
329 | break; | ||
330 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | ||
331 | if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP) | ||
332 | ret = mgmt_set_ip(phba, iface_param, | ||
333 | NULL, ISCSI_BOOTPROTO_DHCP); | ||
334 | else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC) | ||
335 | ret = beiscsi_set_static_ip(shost, iface_param, | ||
336 | data, dt_len); | ||
337 | else | ||
338 | shost_printk(KERN_ERR, shost, "Invalid BOOTPROTO: %d\n", | ||
339 | iface_param->value[0]); | ||
340 | break; | ||
341 | case ISCSI_NET_PARAM_IFACE_ENABLE: | ||
342 | if (iface_param->value[0] == ISCSI_IFACE_ENABLE) | ||
343 | ret = beiscsi_create_ipv4_iface(phba); | ||
344 | else | ||
345 | iscsi_destroy_iface(phba->ipv4_iface); | ||
346 | break; | ||
347 | case ISCSI_NET_PARAM_IPV4_SUBNET: | ||
348 | case ISCSI_NET_PARAM_IPV4_ADDR: | ||
349 | ret = beiscsi_set_static_ip(shost, iface_param, | ||
350 | data, dt_len); | ||
351 | break; | ||
352 | default: | ||
353 | shost_printk(KERN_ERR, shost, "Param %d not supported\n", | ||
354 | iface_param->param); | ||
355 | } | ||
356 | |||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | static int | ||
361 | beiscsi_set_ipv6(struct Scsi_Host *shost, | ||
362 | struct iscsi_iface_param_info *iface_param, | ||
363 | void *data, uint32_t dt_len) | ||
364 | { | ||
365 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
366 | int ret = 0; | ||
367 | |||
368 | switch (iface_param->param) { | ||
369 | case ISCSI_NET_PARAM_IFACE_ENABLE: | ||
370 | if (iface_param->value[0] == ISCSI_IFACE_ENABLE) | ||
371 | ret = beiscsi_create_ipv6_iface(phba); | ||
372 | else { | ||
373 | iscsi_destroy_iface(phba->ipv6_iface); | ||
374 | ret = 0; | ||
375 | } | ||
376 | break; | ||
377 | case ISCSI_NET_PARAM_IPV6_ADDR: | ||
378 | ret = mgmt_set_ip(phba, iface_param, NULL, | ||
379 | ISCSI_BOOTPROTO_STATIC); | ||
380 | break; | ||
381 | default: | ||
382 | shost_printk(KERN_ERR, shost, "Param %d not supported\n", | ||
383 | iface_param->param); | ||
384 | } | ||
385 | |||
386 | return ret; | ||
387 | } | ||
388 | |||
389 | int be2iscsi_iface_set_param(struct Scsi_Host *shost, | ||
390 | void *data, uint32_t dt_len) | ||
391 | { | ||
392 | struct iscsi_iface_param_info *iface_param = NULL; | ||
393 | struct nlattr *attrib; | ||
394 | uint32_t rm_len = dt_len; | ||
395 | int ret = 0 ; | ||
396 | |||
397 | nla_for_each_attr(attrib, data, dt_len, rm_len) { | ||
398 | iface_param = nla_data(attrib); | ||
399 | |||
400 | if (iface_param->param_type != ISCSI_NET_PARAM) | ||
401 | continue; | ||
402 | |||
403 | /* | ||
404 | * BE2ISCSI only supports 1 interface | ||
405 | */ | ||
406 | if (iface_param->iface_num) { | ||
407 | shost_printk(KERN_ERR, shost, "Invalid iface_num %d." | ||
408 | "Only iface_num 0 is supported.\n", | ||
409 | iface_param->iface_num); | ||
410 | return -EINVAL; | ||
411 | } | ||
412 | |||
413 | switch (iface_param->iface_type) { | ||
414 | case ISCSI_IFACE_TYPE_IPV4: | ||
415 | ret = beiscsi_set_ipv4(shost, iface_param, | ||
416 | data, dt_len); | ||
417 | break; | ||
418 | case ISCSI_IFACE_TYPE_IPV6: | ||
419 | ret = beiscsi_set_ipv6(shost, iface_param, | ||
420 | data, dt_len); | ||
421 | break; | ||
422 | default: | ||
423 | shost_printk(KERN_ERR, shost, | ||
424 | "Invalid iface type :%d passed\n", | ||
425 | iface_param->iface_type); | ||
426 | break; | ||
427 | } | ||
428 | |||
429 | if (ret) | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | static int be2iscsi_get_if_param(struct beiscsi_hba *phba, | ||
437 | struct iscsi_iface *iface, int param, | ||
438 | char *buf) | ||
439 | { | ||
440 | struct be_cmd_get_if_info_resp if_info; | ||
441 | int len, ip_type = BE2_IPV4; | ||
442 | |||
443 | memset(&if_info, 0, sizeof(if_info)); | ||
444 | |||
445 | if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) | ||
446 | ip_type = BE2_IPV6; | ||
447 | |||
448 | len = mgmt_get_if_info(phba, ip_type, &if_info); | ||
449 | if (len) | ||
450 | return len; | ||
451 | |||
452 | switch (param) { | ||
453 | case ISCSI_NET_PARAM_IPV4_ADDR: | ||
454 | len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr); | ||
455 | break; | ||
456 | case ISCSI_NET_PARAM_IPV6_ADDR: | ||
457 | len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr); | ||
458 | break; | ||
459 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | ||
460 | if (!if_info.dhcp_state) | ||
461 | len = sprintf(buf, "static"); | ||
462 | else | ||
463 | len = sprintf(buf, "dhcp"); | ||
464 | break; | ||
465 | case ISCSI_NET_PARAM_IPV4_SUBNET: | ||
466 | len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask); | ||
467 | break; | ||
468 | default: | ||
469 | WARN_ON(1); | ||
470 | } | ||
471 | |||
472 | return len; | ||
473 | } | ||
474 | |||
475 | int be2iscsi_iface_get_param(struct iscsi_iface *iface, | ||
476 | enum iscsi_param_type param_type, | ||
477 | int param, char *buf) | ||
478 | { | ||
479 | struct Scsi_Host *shost = iscsi_iface_to_shost(iface); | ||
480 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
481 | struct be_cmd_get_def_gateway_resp gateway; | ||
482 | int len = -ENOSYS; | ||
483 | |||
484 | switch (param) { | ||
485 | case ISCSI_NET_PARAM_IPV4_ADDR: | ||
486 | case ISCSI_NET_PARAM_IPV4_SUBNET: | ||
487 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | ||
488 | case ISCSI_NET_PARAM_IPV6_ADDR: | ||
489 | len = be2iscsi_get_if_param(phba, iface, param, buf); | ||
490 | break; | ||
491 | case ISCSI_NET_PARAM_IFACE_ENABLE: | ||
492 | len = sprintf(buf, "enabled"); | ||
493 | break; | ||
494 | case ISCSI_NET_PARAM_IPV4_GW: | ||
495 | memset(&gateway, 0, sizeof(gateway)); | ||
496 | len = mgmt_get_gateway(phba, BE2_IPV4, &gateway); | ||
497 | if (!len) | ||
498 | len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); | ||
499 | break; | ||
500 | default: | ||
501 | len = -ENOSYS; | ||
502 | } | ||
503 | |||
504 | return len; | ||
505 | } | ||
506 | |||
210 | /** | 507 | /** |
211 | * beiscsi_ep_get_param - get the iscsi parameter | 508 | * beiscsi_ep_get_param - get the iscsi parameter |
212 | * @ep: pointer to iscsi ep | 509 | * @ep: pointer to iscsi ep |
@@ -221,7 +518,7 @@ int beiscsi_ep_get_param(struct iscsi_endpoint *ep, | |||
221 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; | 518 | struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; |
222 | int len = 0; | 519 | int len = 0; |
223 | 520 | ||
224 | SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_param, param= %d\n", param); | 521 | SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_get_param, param= %d\n", param); |
225 | 522 | ||
226 | switch (param) { | 523 | switch (param) { |
227 | case ISCSI_PARAM_CONN_PORT: | 524 | case ISCSI_PARAM_CONN_PORT: |
@@ -279,6 +576,121 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
279 | } | 576 | } |
280 | 577 | ||
281 | /** | 578 | /** |
579 | * beiscsi_get_initname - Read Initiator Name from flash | ||
580 | * @buf: buffer bointer | ||
581 | * @phba: The device priv structure instance | ||
582 | * | ||
583 | * returns number of bytes | ||
584 | */ | ||
585 | static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) | ||
586 | { | ||
587 | int rc; | ||
588 | unsigned int tag, wrb_num; | ||
589 | unsigned short status, extd_status; | ||
590 | struct be_mcc_wrb *wrb; | ||
591 | struct be_cmd_hba_name *resp; | ||
592 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
593 | |||
594 | tag = be_cmd_get_initname(phba); | ||
595 | if (!tag) { | ||
596 | SE_DEBUG(DBG_LVL_1, "Getting Initiator Name Failed\n"); | ||
597 | return -EBUSY; | ||
598 | } else | ||
599 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
600 | phba->ctrl.mcc_numtag[tag]); | ||
601 | |||
602 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
603 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
604 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
605 | |||
606 | if (status || extd_status) { | ||
607 | SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with " | ||
608 | "status = %d extd_status = %d\n", | ||
609 | status, extd_status); | ||
610 | free_mcc_tag(&phba->ctrl, tag); | ||
611 | return -EAGAIN; | ||
612 | } | ||
613 | wrb = queue_get_wrb(mccq, wrb_num); | ||
614 | free_mcc_tag(&phba->ctrl, tag); | ||
615 | resp = embedded_payload(wrb); | ||
616 | rc = sprintf(buf, "%s\n", resp->initiator_name); | ||
617 | return rc; | ||
618 | } | ||
619 | |||
620 | /** | ||
621 | * beiscsi_get_port_state - Get the Port State | ||
622 | * @shost : pointer to scsi_host structure | ||
623 | * | ||
624 | * returns number of bytes | ||
625 | */ | ||
626 | static void beiscsi_get_port_state(struct Scsi_Host *shost) | ||
627 | { | ||
628 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
629 | struct iscsi_cls_host *ihost = shost->shost_data; | ||
630 | |||
631 | ihost->port_state = (phba->state == BE_ADAPTER_UP) ? | ||
632 | ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * beiscsi_get_port_speed - Get the Port Speed from Adapter | ||
637 | * @shost : pointer to scsi_host structure | ||
638 | * | ||
639 | * returns Success/Failure | ||
640 | */ | ||
641 | static int beiscsi_get_port_speed(struct Scsi_Host *shost) | ||
642 | { | ||
643 | unsigned int tag, wrb_num; | ||
644 | unsigned short status, extd_status; | ||
645 | struct be_mcc_wrb *wrb; | ||
646 | struct be_cmd_ntwk_link_status_resp *resp; | ||
647 | struct beiscsi_hba *phba = iscsi_host_priv(shost); | ||
648 | struct iscsi_cls_host *ihost = shost->shost_data; | ||
649 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
650 | |||
651 | tag = be_cmd_get_port_speed(phba); | ||
652 | if (!tag) { | ||
653 | SE_DEBUG(DBG_LVL_1, "Getting Port Speed Failed\n"); | ||
654 | return -EBUSY; | ||
655 | } else | ||
656 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
657 | phba->ctrl.mcc_numtag[tag]); | ||
658 | |||
659 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
660 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
661 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
662 | |||
663 | if (status || extd_status) { | ||
664 | SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with " | ||
665 | "status = %d extd_status = %d\n", | ||
666 | status, extd_status); | ||
667 | free_mcc_tag(&phba->ctrl, tag); | ||
668 | return -EAGAIN; | ||
669 | } | ||
670 | wrb = queue_get_wrb(mccq, wrb_num); | ||
671 | free_mcc_tag(&phba->ctrl, tag); | ||
672 | resp = embedded_payload(wrb); | ||
673 | |||
674 | switch (resp->mac_speed) { | ||
675 | case BE2ISCSI_LINK_SPEED_10MBPS: | ||
676 | ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; | ||
677 | break; | ||
678 | case BE2ISCSI_LINK_SPEED_100MBPS: | ||
679 | ihost->port_speed = BE2ISCSI_LINK_SPEED_100MBPS; | ||
680 | break; | ||
681 | case BE2ISCSI_LINK_SPEED_1GBPS: | ||
682 | ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; | ||
683 | break; | ||
684 | case BE2ISCSI_LINK_SPEED_10GBPS: | ||
685 | ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; | ||
686 | break; | ||
687 | default: | ||
688 | ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; | ||
689 | } | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | /** | ||
282 | * beiscsi_get_host_param - get the iscsi parameter | 694 | * beiscsi_get_host_param - get the iscsi parameter |
283 | * @shost: pointer to scsi_host structure | 695 | * @shost: pointer to scsi_host structure |
284 | * @param: parameter type identifier | 696 | * @param: parameter type identifier |
@@ -301,6 +713,27 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
301 | return status; | 713 | return status; |
302 | } | 714 | } |
303 | break; | 715 | break; |
716 | case ISCSI_HOST_PARAM_INITIATOR_NAME: | ||
717 | status = beiscsi_get_initname(buf, phba); | ||
718 | if (status < 0) { | ||
719 | SE_DEBUG(DBG_LVL_1, | ||
720 | "Retreiving Initiator Name Failed\n"); | ||
721 | return status; | ||
722 | } | ||
723 | break; | ||
724 | case ISCSI_HOST_PARAM_PORT_STATE: | ||
725 | beiscsi_get_port_state(shost); | ||
726 | status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); | ||
727 | break; | ||
728 | case ISCSI_HOST_PARAM_PORT_SPEED: | ||
729 | status = beiscsi_get_port_speed(shost); | ||
730 | if (status) { | ||
731 | SE_DEBUG(DBG_LVL_1, | ||
732 | "Retreiving Port Speed Failed\n"); | ||
733 | return status; | ||
734 | } | ||
735 | status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); | ||
736 | break; | ||
304 | default: | 737 | default: |
305 | return iscsi_host_get_param(shost, param, buf); | 738 | return iscsi_host_get_param(shost, param, buf); |
306 | } | 739 | } |
@@ -309,46 +742,21 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
309 | 742 | ||
310 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) | 743 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) |
311 | { | 744 | { |
312 | struct be_cmd_resp_get_mac_addr *resp; | 745 | struct be_cmd_get_nic_conf_resp resp; |
313 | struct be_mcc_wrb *wrb; | ||
314 | unsigned int tag, wrb_num; | ||
315 | unsigned short status, extd_status; | ||
316 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
317 | int rc; | 746 | int rc; |
318 | 747 | ||
319 | if (phba->read_mac_address) | 748 | if (strlen(phba->mac_address)) |
320 | return sysfs_format_mac(buf, phba->mac_address, | 749 | return strlcpy(buf, phba->mac_address, PAGE_SIZE); |
321 | ETH_ALEN); | ||
322 | 750 | ||
323 | tag = be_cmd_get_mac_addr(phba); | 751 | memset(&resp, 0, sizeof(resp)); |
324 | if (!tag) { | 752 | rc = mgmt_get_nic_conf(phba, &resp); |
325 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); | 753 | if (rc) |
326 | return -EBUSY; | 754 | return rc; |
327 | } else | ||
328 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
329 | phba->ctrl.mcc_numtag[tag]); | ||
330 | 755 | ||
331 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | 756 | memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); |
332 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | 757 | return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); |
333 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
334 | if (status || extd_status) { | ||
335 | SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr" | ||
336 | " status = %d extd_status = %d\n", | ||
337 | status, extd_status); | ||
338 | free_mcc_tag(&phba->ctrl, tag); | ||
339 | return -EAGAIN; | ||
340 | } | ||
341 | wrb = queue_get_wrb(mccq, wrb_num); | ||
342 | free_mcc_tag(&phba->ctrl, tag); | ||
343 | resp = embedded_payload(wrb); | ||
344 | memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); | ||
345 | rc = sysfs_format_mac(buf, phba->mac_address, | ||
346 | ETH_ALEN); | ||
347 | phba->read_mac_address = 1; | ||
348 | return rc; | ||
349 | } | 758 | } |
350 | 759 | ||
351 | |||
352 | /** | 760 | /** |
353 | * beiscsi_conn_get_stats - get the iscsi stats | 761 | * beiscsi_conn_get_stats - get the iscsi stats |
354 | * @cls_conn: pointer to iscsi cls conn | 762 | * @cls_conn: pointer to iscsi cls conn |
@@ -736,11 +1144,24 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) | |||
736 | umode_t be2iscsi_attr_is_visible(int param_type, int param) | 1144 | umode_t be2iscsi_attr_is_visible(int param_type, int param) |
737 | { | 1145 | { |
738 | switch (param_type) { | 1146 | switch (param_type) { |
1147 | case ISCSI_NET_PARAM: | ||
1148 | switch (param) { | ||
1149 | case ISCSI_NET_PARAM_IFACE_ENABLE: | ||
1150 | case ISCSI_NET_PARAM_IPV4_ADDR: | ||
1151 | case ISCSI_NET_PARAM_IPV4_SUBNET: | ||
1152 | case ISCSI_NET_PARAM_IPV4_BOOTPROTO: | ||
1153 | case ISCSI_NET_PARAM_IPV4_GW: | ||
1154 | case ISCSI_NET_PARAM_IPV6_ADDR: | ||
1155 | return S_IRUGO; | ||
1156 | default: | ||
1157 | return 0; | ||
1158 | } | ||
739 | case ISCSI_HOST_PARAM: | 1159 | case ISCSI_HOST_PARAM: |
740 | switch (param) { | 1160 | switch (param) { |
741 | case ISCSI_HOST_PARAM_HWADDRESS: | 1161 | case ISCSI_HOST_PARAM_HWADDRESS: |
742 | case ISCSI_HOST_PARAM_IPADDRESS: | ||
743 | case ISCSI_HOST_PARAM_INITIATOR_NAME: | 1162 | case ISCSI_HOST_PARAM_INITIATOR_NAME: |
1163 | case ISCSI_HOST_PARAM_PORT_STATE: | ||
1164 | case ISCSI_HOST_PARAM_PORT_SPEED: | ||
744 | return S_IRUGO; | 1165 | return S_IRUGO; |
745 | default: | 1166 | default: |
746 | return 0; | 1167 | return 0; |