aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic/vnic_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r--drivers/net/enic/vnic_dev.c110
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
533void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) 533int 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
548void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) 550int 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
563int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) 567int 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
577int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) 581int 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
601void vnic_dev_notify_unset(struct vnic_dev *vdev) 601int 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 &notify_pa);
615 if (!notify_addr)
616 return -ENOMEM;
617
618 return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
619}
620
621void 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
636void 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
614static int vnic_dev_notify_ready(struct vnic_dev *vdev) 648static 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
689int 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
708int 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
731int 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
655int vnic_dev_link_status(struct vnic_dev *vdev) 739int vnic_dev_link_status(struct vnic_dev *vdev)
656{ 740{
657 if (vdev->linkstatus) 741 if (vdev->linkstatus)