- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.git] / drivers / net / enic / vnic_dev.c
index cf22de7..2b3e16d 100644 (file)
@@ -530,7 +530,7 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
                printk(KERN_ERR "Can't set packet filter\n");
 }
 
-void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
+int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
 {
        u64 a0 = 0, a1 = 0;
        int wait = 1000;
@@ -543,9 +543,11 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
        err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
        if (err)
                printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
+
+       return err;
 }
 
-void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
 {
        u64 a0 = 0, a1 = 0;
        int wait = 1000;
@@ -558,6 +560,8 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
        err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
        if (err)
                printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
+
+       return err;
 }
 
 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)
        return err;
 }
 
-int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
+int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
+       void *notify_addr, dma_addr_t notify_pa, u16 intr)
 {
        u64 a0, a1;
        int wait = 1000;
        int r;
 
-       if (!vdev->notify) {
-               vdev->notify = pci_alloc_consistent(vdev->pdev,
-                       sizeof(struct vnic_devcmd_notify),
-                       &vdev->notify_pa);
-               if (!vdev->notify)
-                       return -ENOMEM;
-               memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify));
-       }
+       memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
+       vdev->notify = notify_addr;
+       vdev->notify_pa = notify_pa;
 
-       a0 = vdev->notify_pa;
+       a0 = (u64)notify_pa;
        a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
        a1 += sizeof(struct vnic_devcmd_notify);
 
@@ -598,7 +598,27 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
        return r;
 }
 
-void vnic_dev_notify_unset(struct vnic_dev *vdev)
+int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
+{
+       void *notify_addr;
+       dma_addr_t notify_pa;
+
+       if (vdev->notify || vdev->notify_pa) {
+               printk(KERN_ERR "notify block %p still allocated",
+                       vdev->notify);
+               return -EINVAL;
+       }
+
+       notify_addr = pci_alloc_consistent(vdev->pdev,
+                       sizeof(struct vnic_devcmd_notify),
+                       &notify_pa);
+       if (!notify_addr)
+               return -ENOMEM;
+
+       return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
+}
+
+void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
 {
        u64 a0, a1;
        int wait = 1000;
@@ -608,9 +628,23 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev)
        a1 += sizeof(struct vnic_devcmd_notify);
 
        vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
+       vdev->notify = NULL;
+       vdev->notify_pa = 0;
        vdev->notify_sz = 0;
 }
 
+void vnic_dev_notify_unset(struct vnic_dev *vdev)
+{
+       if (vdev->notify) {
+               pci_free_consistent(vdev->pdev,
+                       sizeof(struct vnic_devcmd_notify),
+                       vdev->notify,
+                       vdev->notify_pa);
+       }
+
+       vnic_dev_notify_unsetcmd(vdev);
+}
+
 static int vnic_dev_notify_ready(struct vnic_dev *vdev)
 {
        u32 *words;
@@ -652,6 +686,56 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
        return r;
 }
 
+int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
+{
+       u64 a0 = 0, a1 = 0;
+       int wait = 1000;
+       int ret;
+
+       *done = 0;
+
+       ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait);
+       if (ret)
+               return ret;
+
+       *done = (a0 == 0);
+
+       *err = (a0 == 0) ? a1 : 0;
+
+       return 0;
+}
+
+int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
+{
+       u64 a0, a1 = len;
+       int wait = 1000;
+       u64 prov_pa;
+       void *prov_buf;
+       int ret;
+
+       prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
+       if (!prov_buf)
+               return -ENOMEM;
+
+       memcpy(prov_buf, buf, len);
+
+       a0 = prov_pa;
+
+       ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait);
+
+       pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
+
+       return ret;
+}
+
+int vnic_dev_deinit(struct vnic_dev *vdev)
+{
+       u64 a0 = 0, a1 = 0;
+       int wait = 1000;
+
+       return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait);
+}
+
 int vnic_dev_link_status(struct vnic_dev *vdev)
 {
        if (vdev->linkstatus)