diff options
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r-- | drivers/net/enic/vnic_dev.c | 110 |
1 files changed, 97 insertions, 13 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index cf22de71014e..2b3e16db5c82 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
@@ -530,7 +530,7 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | |||
530 | printk(KERN_ERR "Can't set packet filter\n"); | 530 | printk(KERN_ERR "Can't set packet filter\n"); |
531 | } | 531 | } |
532 | 532 | ||
533 | void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | 533 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) |
534 | { | 534 | { |
535 | u64 a0 = 0, a1 = 0; | 535 | u64 a0 = 0, a1 = 0; |
536 | int wait = 1000; | 536 | int wait = 1000; |
@@ -543,9 +543,11 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | |||
543 | err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); | 543 | err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); |
544 | if (err) | 544 | if (err) |
545 | printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err); | 545 | printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err); |
546 | |||
547 | return err; | ||
546 | } | 548 | } |
547 | 549 | ||
548 | void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) | 550 | int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) |
549 | { | 551 | { |
550 | u64 a0 = 0, a1 = 0; | 552 | u64 a0 = 0, a1 = 0; |
551 | int wait = 1000; | 553 | int wait = 1000; |
@@ -558,6 +560,8 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) | |||
558 | err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); | 560 | err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); |
559 | if (err) | 561 | if (err) |
560 | printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err); | 562 | printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err); |
563 | |||
564 | return err; | ||
561 | } | 565 | } |
562 | 566 | ||
563 | int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) | 567 | int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) |
@@ -574,22 +578,18 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) | |||
574 | return err; | 578 | return err; |
575 | } | 579 | } |
576 | 580 | ||
577 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | 581 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, |
582 | void *notify_addr, dma_addr_t notify_pa, u16 intr) | ||
578 | { | 583 | { |
579 | u64 a0, a1; | 584 | u64 a0, a1; |
580 | int wait = 1000; | 585 | int wait = 1000; |
581 | int r; | 586 | int r; |
582 | 587 | ||
583 | if (!vdev->notify) { | 588 | memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify)); |
584 | vdev->notify = pci_alloc_consistent(vdev->pdev, | 589 | vdev->notify = notify_addr; |
585 | sizeof(struct vnic_devcmd_notify), | 590 | vdev->notify_pa = notify_pa; |
586 | &vdev->notify_pa); | ||
587 | if (!vdev->notify) | ||
588 | return -ENOMEM; | ||
589 | memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify)); | ||
590 | } | ||
591 | 591 | ||
592 | a0 = vdev->notify_pa; | 592 | a0 = (u64)notify_pa; |
593 | a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; | 593 | a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; |
594 | a1 += sizeof(struct vnic_devcmd_notify); | 594 | a1 += sizeof(struct vnic_devcmd_notify); |
595 | 595 | ||
@@ -598,7 +598,27 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
598 | return r; | 598 | return r; |
599 | } | 599 | } |
600 | 600 | ||
601 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | 601 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) |
602 | { | ||
603 | void *notify_addr; | ||
604 | dma_addr_t notify_pa; | ||
605 | |||
606 | if (vdev->notify || vdev->notify_pa) { | ||
607 | printk(KERN_ERR "notify block %p still allocated", | ||
608 | vdev->notify); | ||
609 | return -EINVAL; | ||
610 | } | ||
611 | |||
612 | notify_addr = pci_alloc_consistent(vdev->pdev, | ||
613 | sizeof(struct vnic_devcmd_notify), | ||
614 | ¬ify_pa); | ||
615 | if (!notify_addr) | ||
616 | return -ENOMEM; | ||
617 | |||
618 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); | ||
619 | } | ||
620 | |||
621 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) | ||
602 | { | 622 | { |
603 | u64 a0, a1; | 623 | u64 a0, a1; |
604 | int wait = 1000; | 624 | int wait = 1000; |
@@ -608,9 +628,23 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev) | |||
608 | a1 += sizeof(struct vnic_devcmd_notify); | 628 | a1 += sizeof(struct vnic_devcmd_notify); |
609 | 629 | ||
610 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | 630 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); |
631 | vdev->notify = NULL; | ||
632 | vdev->notify_pa = 0; | ||
611 | vdev->notify_sz = 0; | 633 | vdev->notify_sz = 0; |
612 | } | 634 | } |
613 | 635 | ||
636 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | ||
637 | { | ||
638 | if (vdev->notify) { | ||
639 | pci_free_consistent(vdev->pdev, | ||
640 | sizeof(struct vnic_devcmd_notify), | ||
641 | vdev->notify, | ||
642 | vdev->notify_pa); | ||
643 | } | ||
644 | |||
645 | vnic_dev_notify_unsetcmd(vdev); | ||
646 | } | ||
647 | |||
614 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) | 648 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) |
615 | { | 649 | { |
616 | u32 *words; | 650 | u32 *words; |
@@ -652,6 +686,56 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) | |||
652 | return r; | 686 | return r; |
653 | } | 687 | } |
654 | 688 | ||
689 | int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err) | ||
690 | { | ||
691 | u64 a0 = 0, a1 = 0; | ||
692 | int wait = 1000; | ||
693 | int ret; | ||
694 | |||
695 | *done = 0; | ||
696 | |||
697 | ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait); | ||
698 | if (ret) | ||
699 | return ret; | ||
700 | |||
701 | *done = (a0 == 0); | ||
702 | |||
703 | *err = (a0 == 0) ? a1 : 0; | ||
704 | |||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len) | ||
709 | { | ||
710 | u64 a0, a1 = len; | ||
711 | int wait = 1000; | ||
712 | u64 prov_pa; | ||
713 | void *prov_buf; | ||
714 | int ret; | ||
715 | |||
716 | prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); | ||
717 | if (!prov_buf) | ||
718 | return -ENOMEM; | ||
719 | |||
720 | memcpy(prov_buf, buf, len); | ||
721 | |||
722 | a0 = prov_pa; | ||
723 | |||
724 | ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait); | ||
725 | |||
726 | pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); | ||
727 | |||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | int vnic_dev_deinit(struct vnic_dev *vdev) | ||
732 | { | ||
733 | u64 a0 = 0, a1 = 0; | ||
734 | int wait = 1000; | ||
735 | |||
736 | return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait); | ||
737 | } | ||
738 | |||
655 | int vnic_dev_link_status(struct vnic_dev *vdev) | 739 | int vnic_dev_link_status(struct vnic_dev *vdev) |
656 | { | 740 | { |
657 | if (vdev->linkstatus) | 741 | if (vdev->linkstatus) |