aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/enic/vnic_dev.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
committerLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
commitb2576e1d4408e134e2188c967b1f28af39cd79d4 (patch)
tree004f3c82faab760f304ce031d6d2f572e7746a50 /drivers/net/enic/vnic_dev.c
parent3cc8a5f4ba91f67bbdb81a43a99281a26aab8d77 (diff)
parent2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff)
Merge branch 'linus' into release
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r--drivers/net/enic/vnic_dev.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 4d104f5c30f9..11708579b6ce 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -43,6 +43,7 @@ struct vnic_dev {
43 struct vnic_devcmd_notify *notify; 43 struct vnic_devcmd_notify *notify;
44 struct vnic_devcmd_notify notify_copy; 44 struct vnic_devcmd_notify notify_copy;
45 dma_addr_t notify_pa; 45 dma_addr_t notify_pa;
46 u32 notify_sz;
46 u32 *linkstatus; 47 u32 *linkstatus;
47 dma_addr_t linkstatus_pa; 48 dma_addr_t linkstatus_pa;
48 struct vnic_stats *stats; 49 struct vnic_stats *stats;
@@ -235,14 +236,6 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
235 struct vnic_devcmd __iomem *devcmd = vdev->devcmd; 236 struct vnic_devcmd __iomem *devcmd = vdev->devcmd;
236 int delay; 237 int delay;
237 u32 status; 238 u32 status;
238 int dev_cmd_err[] = {
239 /* convert from fw's version of error.h to host's version */
240 0, /* ERR_SUCCESS */
241 EINVAL, /* ERR_EINVAL */
242 EFAULT, /* ERR_EFAULT */
243 EPERM, /* ERR_EPERM */
244 EBUSY, /* ERR_EBUSY */
245 };
246 int err; 239 int err;
247 240
248 status = ioread32(&devcmd->status); 241 status = ioread32(&devcmd->status);
@@ -270,10 +263,12 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
270 if (!(status & STAT_BUSY)) { 263 if (!(status & STAT_BUSY)) {
271 264
272 if (status & STAT_ERROR) { 265 if (status & STAT_ERROR) {
273 err = dev_cmd_err[(int)readq(&devcmd->args[0])]; 266 err = (int)readq(&devcmd->args[0]);
274 printk(KERN_ERR "Error %d devcmd %d\n", 267 if (err != ERR_ECMDUNKNOWN ||
275 err, _CMD_N(cmd)); 268 cmd != CMD_CAPABILITY)
276 return -err; 269 printk(KERN_ERR "Error %d devcmd %d\n",
270 err, _CMD_N(cmd));
271 return err;
277 } 272 }
278 273
279 if (_CMD_DIR(cmd) & _CMD_DIR_READ) { 274 if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
@@ -290,6 +285,17 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
290 return -ETIMEDOUT; 285 return -ETIMEDOUT;
291} 286}
292 287
288static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
289{
290 u64 a0 = (u32)cmd, a1 = 0;
291 int wait = 1000;
292 int err;
293
294 err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
295
296 return !(err || a0);
297}
298
293int vnic_dev_fw_info(struct vnic_dev *vdev, 299int vnic_dev_fw_info(struct vnic_dev *vdev,
294 struct vnic_devcmd_fw_info **fw_info) 300 struct vnic_devcmd_fw_info **fw_info)
295{ 301{
@@ -489,10 +495,7 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
489 495
490 err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); 496 err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
491 if (err) 497 if (err)
492 printk(KERN_ERR 498 printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
493 "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
494 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
495 err);
496} 499}
497 500
498void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) 501void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
@@ -507,16 +510,14 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
507 510
508 err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); 511 err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
509 if (err) 512 if (err)
510 printk(KERN_ERR 513 printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
511 "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
512 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
513 err);
514} 514}
515 515
516int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) 516int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
517{ 517{
518 u64 a0, a1; 518 u64 a0, a1;
519 int wait = 1000; 519 int wait = 1000;
520 int r;
520 521
521 if (!vdev->notify) { 522 if (!vdev->notify) {
522 vdev->notify = pci_alloc_consistent(vdev->pdev, 523 vdev->notify = pci_alloc_consistent(vdev->pdev,
@@ -524,13 +525,16 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
524 &vdev->notify_pa); 525 &vdev->notify_pa);
525 if (!vdev->notify) 526 if (!vdev->notify)
526 return -ENOMEM; 527 return -ENOMEM;
528 memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify));
527 } 529 }
528 530
529 a0 = vdev->notify_pa; 531 a0 = vdev->notify_pa;
530 a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; 532 a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
531 a1 += sizeof(struct vnic_devcmd_notify); 533 a1 += sizeof(struct vnic_devcmd_notify);
532 534
533 return vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); 535 r = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
536 vdev->notify_sz = (r == 0) ? (u32)a1 : 0;
537 return r;
534} 538}
535 539
536void vnic_dev_notify_unset(struct vnic_dev *vdev) 540void vnic_dev_notify_unset(struct vnic_dev *vdev)
@@ -543,22 +547,22 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev)
543 a1 += sizeof(struct vnic_devcmd_notify); 547 a1 += sizeof(struct vnic_devcmd_notify);
544 548
545 vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); 549 vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
550 vdev->notify_sz = 0;
546} 551}
547 552
548static int vnic_dev_notify_ready(struct vnic_dev *vdev) 553static int vnic_dev_notify_ready(struct vnic_dev *vdev)
549{ 554{
550 u32 *words; 555 u32 *words;
551 unsigned int nwords = sizeof(struct vnic_devcmd_notify) / 4; 556 unsigned int nwords = vdev->notify_sz / 4;
552 unsigned int i; 557 unsigned int i;
553 u32 csum; 558 u32 csum;
554 559
555 if (!vdev->notify) 560 if (!vdev->notify || !vdev->notify_sz)
556 return 0; 561 return 0;
557 562
558 do { 563 do {
559 csum = 0; 564 csum = 0;
560 memcpy(&vdev->notify_copy, vdev->notify, 565 memcpy(&vdev->notify_copy, vdev->notify, vdev->notify_sz);
561 sizeof(struct vnic_devcmd_notify));
562 words = (u32 *)&vdev->notify_copy; 566 words = (u32 *)&vdev->notify_copy;
563 for (i = 1; i < nwords; i++) 567 for (i = 1; i < nwords; i++)
564 csum += words[i]; 568 csum += words[i];
@@ -571,7 +575,20 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
571{ 575{
572 u64 a0 = (u32)arg, a1 = 0; 576 u64 a0 = (u32)arg, a1 = 0;
573 int wait = 1000; 577 int wait = 1000;
574 return vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); 578 int r = 0;
579
580 if (vnic_dev_capable(vdev, CMD_INIT))
581 r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
582 else {
583 vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
584 if (a0 & CMD_INITF_DEFAULT_MAC) {
585 // Emulate these for old CMD_INIT_v1 which
586 // didn't pass a0 so no CMD_INITF_*.
587 vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
588 vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
589 }
590 }
591 return r;
575} 592}
576 593
577int vnic_dev_link_status(struct vnic_dev *vdev) 594int vnic_dev_link_status(struct vnic_dev *vdev)
@@ -672,3 +689,4 @@ err_out:
672 return NULL; 689 return NULL;
673} 690}
674 691
692