diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
| commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
| tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/enic/vnic_dev.c | |
| parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
| parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) | |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
| -rw-r--r-- | drivers/net/enic/vnic_dev.c | 256 |
1 files changed, 85 insertions, 171 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 6a5b578a69e1..68f24ae860ae 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
| @@ -74,6 +74,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
| 74 | struct vnic_dev_bar *bar, unsigned int num_bars) | 74 | struct vnic_dev_bar *bar, unsigned int num_bars) |
| 75 | { | 75 | { |
| 76 | struct vnic_resource_header __iomem *rh; | 76 | struct vnic_resource_header __iomem *rh; |
| 77 | struct mgmt_barmap_hdr __iomem *mrh; | ||
| 77 | struct vnic_resource __iomem *r; | 78 | struct vnic_resource __iomem *r; |
| 78 | u8 type; | 79 | u8 type; |
| 79 | 80 | ||
| @@ -85,22 +86,32 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
| 85 | return -EINVAL; | 86 | return -EINVAL; |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | rh = bar->vaddr; | 89 | rh = bar->vaddr; |
| 90 | mrh = bar->vaddr; | ||
| 89 | if (!rh) { | 91 | if (!rh) { |
| 90 | pr_err("vNIC BAR0 res hdr not mem-mapped\n"); | 92 | pr_err("vNIC BAR0 res hdr not mem-mapped\n"); |
| 91 | return -EINVAL; | 93 | return -EINVAL; |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | if (ioread32(&rh->magic) != VNIC_RES_MAGIC || | 96 | /* Check for mgmt vnic in addition to normal vnic */ |
| 95 | ioread32(&rh->version) != VNIC_RES_VERSION) { | 97 | if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) || |
| 96 | pr_err("vNIC BAR0 res magic/version error " | 98 | (ioread32(&rh->version) != VNIC_RES_VERSION)) { |
| 97 | "exp (%lx/%lx) curr (%x/%x)\n", | 99 | if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) || |
| 100 | (ioread32(&mrh->version) != MGMTVNIC_VERSION)) { | ||
| 101 | pr_err("vNIC BAR0 res magic/version error " | ||
| 102 | "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n", | ||
| 98 | VNIC_RES_MAGIC, VNIC_RES_VERSION, | 103 | VNIC_RES_MAGIC, VNIC_RES_VERSION, |
| 104 | MGMTVNIC_MAGIC, MGMTVNIC_VERSION, | ||
| 99 | ioread32(&rh->magic), ioread32(&rh->version)); | 105 | ioread32(&rh->magic), ioread32(&rh->version)); |
| 100 | return -EINVAL; | 106 | return -EINVAL; |
| 107 | } | ||
| 101 | } | 108 | } |
| 102 | 109 | ||
| 103 | r = (struct vnic_resource __iomem *)(rh + 1); | 110 | if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC) |
| 111 | r = (struct vnic_resource __iomem *)(mrh + 1); | ||
| 112 | else | ||
| 113 | r = (struct vnic_resource __iomem *)(rh + 1); | ||
| 114 | |||
| 104 | 115 | ||
| 105 | while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { | 116 | while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { |
| 106 | 117 | ||
| @@ -175,22 +186,7 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | |||
| 175 | } | 186 | } |
| 176 | } | 187 | } |
| 177 | 188 | ||
| 178 | dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, | 189 | static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, |
| 179 | enum vnic_res_type type, unsigned int index) | ||
| 180 | { | ||
| 181 | switch (type) { | ||
| 182 | case RES_TYPE_WQ: | ||
| 183 | case RES_TYPE_RQ: | ||
| 184 | case RES_TYPE_CQ: | ||
| 185 | case RES_TYPE_INTR_CTRL: | ||
| 186 | return vdev->res[type].bus_addr + | ||
| 187 | index * VNIC_RES_STRIDE; | ||
| 188 | default: | ||
| 189 | return vdev->res[type].bus_addr; | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, | ||
| 194 | unsigned int desc_count, unsigned int desc_size) | 190 | unsigned int desc_count, unsigned int desc_size) |
| 195 | { | 191 | { |
| 196 | /* The base address of the desc rings must be 512 byte aligned. | 192 | /* The base address of the desc rings must be 512 byte aligned. |
| @@ -373,18 +369,6 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, | |||
| 373 | return err; | 369 | return err; |
| 374 | } | 370 | } |
| 375 | 371 | ||
| 376 | void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf) | ||
| 377 | { | ||
| 378 | vdev->proxy = PROXY_BY_BDF; | ||
| 379 | vdev->proxy_index = bdf; | ||
| 380 | } | ||
| 381 | |||
| 382 | void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) | ||
| 383 | { | ||
| 384 | vdev->proxy = PROXY_NONE; | ||
| 385 | vdev->proxy_index = 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | 372 | int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, |
| 389 | u64 *a0, u64 *a1, int wait) | 373 | u64 *a0, u64 *a1, int wait) |
| 390 | { | 374 | { |
| @@ -424,10 +408,17 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, | |||
| 424 | if (!vdev->fw_info) | 408 | if (!vdev->fw_info) |
| 425 | return -ENOMEM; | 409 | return -ENOMEM; |
| 426 | 410 | ||
| 411 | memset(vdev->fw_info, 0, sizeof(struct vnic_devcmd_fw_info)); | ||
| 412 | |||
| 427 | a0 = vdev->fw_info_pa; | 413 | a0 = vdev->fw_info_pa; |
| 414 | a1 = sizeof(struct vnic_devcmd_fw_info); | ||
| 428 | 415 | ||
| 429 | /* only get fw_info once and cache it */ | 416 | /* only get fw_info once and cache it */ |
| 430 | err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); | 417 | err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait); |
| 418 | if (err == ERR_ECMDUNKNOWN) { | ||
| 419 | err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD, | ||
| 420 | &a0, &a1, wait); | ||
| 421 | } | ||
| 431 | } | 422 | } |
| 432 | 423 | ||
| 433 | *fw_info = vdev->fw_info; | 424 | *fw_info = vdev->fw_info; |
| @@ -435,25 +426,6 @@ int vnic_dev_fw_info(struct vnic_dev *vdev, | |||
| 435 | return err; | 426 | return err; |
| 436 | } | 427 | } |
| 437 | 428 | ||
| 438 | int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver) | ||
| 439 | { | ||
| 440 | struct vnic_devcmd_fw_info *fw_info; | ||
| 441 | int err; | ||
| 442 | |||
| 443 | err = vnic_dev_fw_info(vdev, &fw_info); | ||
| 444 | if (err) | ||
| 445 | return err; | ||
| 446 | |||
| 447 | if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0) | ||
| 448 | *hw_ver = VNIC_DEV_HW_VER_A1; | ||
| 449 | else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0) | ||
| 450 | *hw_ver = VNIC_DEV_HW_VER_A2; | ||
| 451 | else | ||
| 452 | *hw_ver = VNIC_DEV_HW_VER_UNKNOWN; | ||
| 453 | |||
| 454 | return 0; | ||
| 455 | } | ||
| 456 | |||
| 457 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | 429 | int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, |
| 458 | void *value) | 430 | void *value) |
| 459 | { | 431 | { |
| @@ -477,13 +449,6 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, | |||
| 477 | return err; | 449 | return err; |
| 478 | } | 450 | } |
| 479 | 451 | ||
| 480 | int vnic_dev_stats_clear(struct vnic_dev *vdev) | ||
| 481 | { | ||
| 482 | u64 a0 = 0, a1 = 0; | ||
| 483 | int wait = 1000; | ||
| 484 | return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait); | ||
| 485 | } | ||
| 486 | |||
| 487 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) | 452 | int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) |
| 488 | { | 453 | { |
| 489 | u64 a0, a1; | 454 | u64 a0, a1; |
| @@ -510,13 +475,6 @@ int vnic_dev_close(struct vnic_dev *vdev) | |||
| 510 | return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); | 475 | return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); |
| 511 | } | 476 | } |
| 512 | 477 | ||
| 513 | int vnic_dev_enable(struct vnic_dev *vdev) | ||
| 514 | { | ||
| 515 | u64 a0 = 0, a1 = 0; | ||
| 516 | int wait = 1000; | ||
| 517 | return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); | ||
| 518 | } | ||
| 519 | |||
| 520 | int vnic_dev_enable_wait(struct vnic_dev *vdev) | 478 | int vnic_dev_enable_wait(struct vnic_dev *vdev) |
| 521 | { | 479 | { |
| 522 | u64 a0 = 0, a1 = 0; | 480 | u64 a0 = 0, a1 = 0; |
| @@ -561,14 +519,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done) | |||
| 561 | return 0; | 519 | return 0; |
| 562 | } | 520 | } |
| 563 | 521 | ||
| 564 | int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) | 522 | static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) |
| 565 | { | 523 | { |
| 566 | u64 a0 = (u32)arg, a1 = 0; | 524 | u64 a0 = (u32)arg, a1 = 0; |
| 567 | int wait = 1000; | 525 | int wait = 1000; |
| 568 | return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait); | 526 | return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait); |
| 569 | } | 527 | } |
| 570 | 528 | ||
| 571 | int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) | 529 | static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) |
| 572 | { | 530 | { |
| 573 | u64 a0 = 0, a1 = 0; | 531 | u64 a0 = 0, a1 = 0; |
| 574 | int wait = 1000; | 532 | int wait = 1000; |
| @@ -669,26 +627,6 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, | |||
| 669 | return err; | 627 | return err; |
| 670 | } | 628 | } |
| 671 | 629 | ||
| 672 | int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, | ||
| 673 | int multicast, int broadcast, int promisc, int allmulti) | ||
| 674 | { | ||
| 675 | u64 a0, a1 = 0; | ||
| 676 | int wait = 1000; | ||
| 677 | int err; | ||
| 678 | |||
| 679 | a0 = (directed ? CMD_PFILTER_DIRECTED : 0) | | ||
| 680 | (multicast ? CMD_PFILTER_MULTICAST : 0) | | ||
| 681 | (broadcast ? CMD_PFILTER_BROADCAST : 0) | | ||
| 682 | (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | | ||
| 683 | (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); | ||
| 684 | |||
| 685 | err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); | ||
| 686 | if (err) | ||
| 687 | pr_err("Can't set packet filter\n"); | ||
| 688 | |||
| 689 | return err; | ||
| 690 | } | ||
| 691 | |||
| 692 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) | 630 | int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) |
| 693 | { | 631 | { |
| 694 | u64 a0 = 0, a1 = 0; | 632 | u64 a0 = 0, a1 = 0; |
| @@ -737,20 +675,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, | |||
| 737 | return err; | 675 | return err; |
| 738 | } | 676 | } |
| 739 | 677 | ||
| 740 | int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) | 678 | static int vnic_dev_notify_setcmd(struct vnic_dev *vdev, |
| 741 | { | ||
| 742 | u64 a0 = intr, a1 = 0; | ||
| 743 | int wait = 1000; | ||
| 744 | int err; | ||
| 745 | |||
| 746 | err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait); | ||
| 747 | if (err) | ||
| 748 | pr_err("Failed to raise INTR[%d], err %d\n", intr, err); | ||
| 749 | |||
| 750 | return err; | ||
| 751 | } | ||
| 752 | |||
| 753 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, | ||
| 754 | void *notify_addr, dma_addr_t notify_pa, u16 intr) | 679 | void *notify_addr, dma_addr_t notify_pa, u16 intr) |
| 755 | { | 680 | { |
| 756 | u64 a0, a1; | 681 | u64 a0, a1; |
| @@ -789,7 +714,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
| 789 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); | 714 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); |
| 790 | } | 715 | } |
| 791 | 716 | ||
| 792 | int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) | 717 | static int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) |
| 793 | { | 718 | { |
| 794 | u64 a0, a1; | 719 | u64 a0, a1; |
| 795 | int wait = 1000; | 720 | int wait = 1000; |
| @@ -861,48 +786,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) | |||
| 861 | return r; | 786 | return r; |
| 862 | } | 787 | } |
| 863 | 788 | ||
| 864 | int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err) | ||
| 865 | { | ||
| 866 | u64 a0 = 0, a1 = 0; | ||
| 867 | int wait = 1000; | ||
| 868 | int ret; | ||
| 869 | |||
| 870 | *done = 0; | ||
| 871 | |||
| 872 | ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait); | ||
| 873 | if (ret) | ||
| 874 | return ret; | ||
| 875 | |||
| 876 | *done = (a0 == 0); | ||
| 877 | |||
| 878 | *err = (a0 == 0) ? (int)a1:0; | ||
| 879 | |||
| 880 | return 0; | ||
| 881 | } | ||
| 882 | |||
| 883 | int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len) | ||
| 884 | { | ||
| 885 | u64 a0, a1 = len; | ||
| 886 | int wait = 1000; | ||
| 887 | dma_addr_t prov_pa; | ||
| 888 | void *prov_buf; | ||
| 889 | int ret; | ||
| 890 | |||
| 891 | prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); | ||
| 892 | if (!prov_buf) | ||
| 893 | return -ENOMEM; | ||
| 894 | |||
| 895 | memcpy(prov_buf, buf, len); | ||
| 896 | |||
| 897 | a0 = prov_pa; | ||
| 898 | |||
| 899 | ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait); | ||
| 900 | |||
| 901 | pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); | ||
| 902 | |||
| 903 | return ret; | ||
| 904 | } | ||
| 905 | |||
| 906 | int vnic_dev_deinit(struct vnic_dev *vdev) | 789 | int vnic_dev_deinit(struct vnic_dev *vdev) |
| 907 | { | 790 | { |
| 908 | u64 a0 = 0, a1 = 0; | 791 | u64 a0 = 0, a1 = 0; |
| @@ -943,30 +826,6 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev) | |||
| 943 | return vdev->notify_copy.mtu; | 826 | return vdev->notify_copy.mtu; |
| 944 | } | 827 | } |
| 945 | 828 | ||
| 946 | u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev) | ||
| 947 | { | ||
| 948 | if (!vnic_dev_notify_ready(vdev)) | ||
| 949 | return 0; | ||
| 950 | |||
| 951 | return vdev->notify_copy.link_down_cnt; | ||
| 952 | } | ||
| 953 | |||
| 954 | u32 vnic_dev_notify_status(struct vnic_dev *vdev) | ||
| 955 | { | ||
| 956 | if (!vnic_dev_notify_ready(vdev)) | ||
| 957 | return 0; | ||
| 958 | |||
| 959 | return vdev->notify_copy.status; | ||
| 960 | } | ||
| 961 | |||
| 962 | u32 vnic_dev_uif(struct vnic_dev *vdev) | ||
| 963 | { | ||
| 964 | if (!vnic_dev_notify_ready(vdev)) | ||
| 965 | return 0; | ||
| 966 | |||
| 967 | return vdev->notify_copy.uif; | ||
| 968 | } | ||
| 969 | |||
| 970 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, | 829 | void vnic_dev_set_intr_mode(struct vnic_dev *vdev, |
| 971 | enum vnic_dev_intr_mode intr_mode) | 830 | enum vnic_dev_intr_mode intr_mode) |
| 972 | { | 831 | { |
| @@ -1026,4 +885,59 @@ err_out: | |||
| 1026 | return NULL; | 885 | return NULL; |
| 1027 | } | 886 | } |
| 1028 | 887 | ||
| 888 | int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len) | ||
| 889 | { | ||
| 890 | u64 a0, a1 = len; | ||
| 891 | int wait = 1000; | ||
| 892 | dma_addr_t prov_pa; | ||
| 893 | void *prov_buf; | ||
| 894 | int ret; | ||
| 895 | |||
| 896 | prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); | ||
| 897 | if (!prov_buf) | ||
| 898 | return -ENOMEM; | ||
| 899 | |||
| 900 | memcpy(prov_buf, buf, len); | ||
| 901 | |||
| 902 | a0 = prov_pa; | ||
| 903 | |||
| 904 | ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO2, &a0, &a1, wait); | ||
| 905 | |||
| 906 | pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); | ||
| 907 | |||
| 908 | return ret; | ||
| 909 | } | ||
| 1029 | 910 | ||
| 911 | int vnic_dev_enable2(struct vnic_dev *vdev, int active) | ||
| 912 | { | ||
| 913 | u64 a0, a1 = 0; | ||
| 914 | int wait = 1000; | ||
| 915 | |||
| 916 | a0 = (active ? CMD_ENABLE2_ACTIVE : 0); | ||
| 917 | |||
| 918 | return vnic_dev_cmd(vdev, CMD_ENABLE2, &a0, &a1, wait); | ||
| 919 | } | ||
| 920 | |||
| 921 | static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | ||
| 922 | int *status) | ||
| 923 | { | ||
| 924 | u64 a0 = cmd, a1 = 0; | ||
| 925 | int wait = 1000; | ||
| 926 | int ret; | ||
| 927 | |||
| 928 | ret = vnic_dev_cmd(vdev, CMD_STATUS, &a0, &a1, wait); | ||
| 929 | if (!ret) | ||
| 930 | *status = (int)a0; | ||
| 931 | |||
| 932 | return ret; | ||
| 933 | } | ||
| 934 | |||
| 935 | int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status) | ||
| 936 | { | ||
| 937 | return vnic_dev_cmd_status(vdev, CMD_ENABLE2, status); | ||
| 938 | } | ||
| 939 | |||
| 940 | int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status) | ||
| 941 | { | ||
| 942 | return vnic_dev_cmd_status(vdev, CMD_DEINIT, status); | ||
| 943 | } | ||
