diff options
Diffstat (limited to 'drivers/atm/he.c')
-rw-r--r-- | drivers/atm/he.c | 147 |
1 files changed, 16 insertions, 131 deletions
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 56c2e99e458f..c725494e0d41 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
@@ -780,59 +780,18 @@ he_init_group(struct he_dev *he_dev, int group) | |||
780 | { | 780 | { |
781 | int i; | 781 | int i; |
782 | 782 | ||
783 | /* small buffer pool */ | 783 | he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32)); |
784 | he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev, | 784 | he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32)); |
785 | CONFIG_RBPS_BUFSIZE, 8, 0); | 785 | he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32)); |
786 | if (he_dev->rbps_pool == NULL) { | 786 | he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), |
787 | hprintk("unable to create rbps pages\n"); | 787 | G0_RBPS_BS + (group * 32)); |
788 | return -ENOMEM; | ||
789 | } | ||
790 | |||
791 | he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev, | ||
792 | CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys); | ||
793 | if (he_dev->rbps_base == NULL) { | ||
794 | hprintk("failed to alloc rbps_base\n"); | ||
795 | goto out_destroy_rbps_pool; | ||
796 | } | ||
797 | memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp)); | ||
798 | he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL); | ||
799 | if (he_dev->rbps_virt == NULL) { | ||
800 | hprintk("failed to alloc rbps_virt\n"); | ||
801 | goto out_free_rbps_base; | ||
802 | } | ||
803 | |||
804 | for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { | ||
805 | dma_addr_t dma_handle; | ||
806 | void *cpuaddr; | ||
807 | |||
808 | cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle); | ||
809 | if (cpuaddr == NULL) | ||
810 | goto out_free_rbps_virt; | ||
811 | |||
812 | he_dev->rbps_virt[i].virt = cpuaddr; | ||
813 | he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF); | ||
814 | he_dev->rbps_base[i].phys = dma_handle; | ||
815 | |||
816 | } | ||
817 | he_dev->rbps_tail = &he_dev->rbps_base[CONFIG_RBPS_SIZE - 1]; | ||
818 | |||
819 | he_writel(he_dev, he_dev->rbps_phys, G0_RBPS_S + (group * 32)); | ||
820 | he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), | ||
821 | G0_RBPS_T + (group * 32)); | ||
822 | he_writel(he_dev, CONFIG_RBPS_BUFSIZE/4, | ||
823 | G0_RBPS_BS + (group * 32)); | ||
824 | he_writel(he_dev, | ||
825 | RBP_THRESH(CONFIG_RBPS_THRESH) | | ||
826 | RBP_QSIZE(CONFIG_RBPS_SIZE - 1) | | ||
827 | RBP_INT_ENB, | ||
828 | G0_RBPS_QI + (group * 32)); | ||
829 | 788 | ||
830 | /* large buffer pool */ | 789 | /* large buffer pool */ |
831 | he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, | 790 | he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, |
832 | CONFIG_RBPL_BUFSIZE, 8, 0); | 791 | CONFIG_RBPL_BUFSIZE, 8, 0); |
833 | if (he_dev->rbpl_pool == NULL) { | 792 | if (he_dev->rbpl_pool == NULL) { |
834 | hprintk("unable to create rbpl pool\n"); | 793 | hprintk("unable to create rbpl pool\n"); |
835 | goto out_free_rbps_virt; | 794 | return -ENOMEM; |
836 | } | 795 | } |
837 | 796 | ||
838 | he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, | 797 | he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, |
@@ -934,19 +893,6 @@ out_free_rbpl_base: | |||
934 | out_destroy_rbpl_pool: | 893 | out_destroy_rbpl_pool: |
935 | pci_pool_destroy(he_dev->rbpl_pool); | 894 | pci_pool_destroy(he_dev->rbpl_pool); |
936 | 895 | ||
937 | i = CONFIG_RBPS_SIZE; | ||
938 | out_free_rbps_virt: | ||
939 | while (i--) | ||
940 | pci_pool_free(he_dev->rbps_pool, he_dev->rbps_virt[i].virt, | ||
941 | he_dev->rbps_base[i].phys); | ||
942 | kfree(he_dev->rbps_virt); | ||
943 | |||
944 | out_free_rbps_base: | ||
945 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE * | ||
946 | sizeof(struct he_rbp), he_dev->rbps_base, | ||
947 | he_dev->rbps_phys); | ||
948 | out_destroy_rbps_pool: | ||
949 | pci_pool_destroy(he_dev->rbps_pool); | ||
950 | return -ENOMEM; | 896 | return -ENOMEM; |
951 | } | 897 | } |
952 | 898 | ||
@@ -1634,22 +1580,6 @@ he_stop(struct he_dev *he_dev) | |||
1634 | if (he_dev->rbpl_pool) | 1580 | if (he_dev->rbpl_pool) |
1635 | pci_pool_destroy(he_dev->rbpl_pool); | 1581 | pci_pool_destroy(he_dev->rbpl_pool); |
1636 | 1582 | ||
1637 | if (he_dev->rbps_base) { | ||
1638 | int i; | ||
1639 | |||
1640 | for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { | ||
1641 | void *cpuaddr = he_dev->rbps_virt[i].virt; | ||
1642 | dma_addr_t dma_handle = he_dev->rbps_base[i].phys; | ||
1643 | |||
1644 | pci_pool_free(he_dev->rbps_pool, cpuaddr, dma_handle); | ||
1645 | } | ||
1646 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE | ||
1647 | * sizeof(struct he_rbp), he_dev->rbps_base, he_dev->rbps_phys); | ||
1648 | } | ||
1649 | |||
1650 | if (he_dev->rbps_pool) | ||
1651 | pci_pool_destroy(he_dev->rbps_pool); | ||
1652 | |||
1653 | if (he_dev->rbrq_base) | 1583 | if (he_dev->rbrq_base) |
1654 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), | 1584 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), |
1655 | he_dev->rbrq_base, he_dev->rbrq_phys); | 1585 | he_dev->rbrq_base, he_dev->rbrq_phys); |
@@ -1740,10 +1670,7 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1740 | RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", | 1670 | RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", |
1741 | RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); | 1671 | RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); |
1742 | 1672 | ||
1743 | if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF) | 1673 | rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; |
1744 | rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; | ||
1745 | else | ||
1746 | rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; | ||
1747 | 1674 | ||
1748 | buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; | 1675 | buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; |
1749 | cid = RBRQ_CID(he_dev->rbrq_head); | 1676 | cid = RBRQ_CID(he_dev->rbrq_head); |
@@ -1819,15 +1746,9 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1819 | 1746 | ||
1820 | __net_timestamp(skb); | 1747 | __net_timestamp(skb); |
1821 | 1748 | ||
1822 | for (iov = he_vcc->iov_head; | 1749 | for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) |
1823 | iov < he_vcc->iov_tail; ++iov) { | 1750 | memcpy(skb_put(skb, iov->iov_len), |
1824 | if (iov->iov_base & RBP_SMALLBUF) | 1751 | he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); |
1825 | memcpy(skb_put(skb, iov->iov_len), | ||
1826 | he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); | ||
1827 | else | ||
1828 | memcpy(skb_put(skb, iov->iov_len), | ||
1829 | he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); | ||
1830 | } | ||
1831 | 1752 | ||
1832 | switch (vcc->qos.aal) { | 1753 | switch (vcc->qos.aal) { |
1833 | case ATM_AAL0: | 1754 | case ATM_AAL0: |
@@ -1867,13 +1788,8 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1867 | return_host_buffers: | 1788 | return_host_buffers: |
1868 | ++pdus_assembled; | 1789 | ++pdus_assembled; |
1869 | 1790 | ||
1870 | for (iov = he_vcc->iov_head; | 1791 | for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) { |
1871 | iov < he_vcc->iov_tail; ++iov) { | 1792 | rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)]; |
1872 | if (iov->iov_base & RBP_SMALLBUF) | ||
1873 | rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)]; | ||
1874 | else | ||
1875 | rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)]; | ||
1876 | |||
1877 | rbp->status &= ~RBP_LOANED; | 1793 | rbp->status &= ~RBP_LOANED; |
1878 | } | 1794 | } |
1879 | 1795 | ||
@@ -1978,7 +1894,6 @@ next_tbrq_entry: | |||
1978 | } | 1894 | } |
1979 | } | 1895 | } |
1980 | 1896 | ||
1981 | |||
1982 | static void | 1897 | static void |
1983 | he_service_rbpl(struct he_dev *he_dev, int group) | 1898 | he_service_rbpl(struct he_dev *he_dev, int group) |
1984 | { | 1899 | { |
@@ -2007,33 +1922,6 @@ he_service_rbpl(struct he_dev *he_dev, int group) | |||
2007 | } | 1922 | } |
2008 | 1923 | ||
2009 | static void | 1924 | static void |
2010 | he_service_rbps(struct he_dev *he_dev, int group) | ||
2011 | { | ||
2012 | struct he_rbp *newtail; | ||
2013 | struct he_rbp *rbps_head; | ||
2014 | int moved = 0; | ||
2015 | |||
2016 | rbps_head = (struct he_rbp *) ((unsigned long)he_dev->rbps_base | | ||
2017 | RBPS_MASK(he_readl(he_dev, G0_RBPS_S))); | ||
2018 | |||
2019 | for (;;) { | ||
2020 | newtail = (struct he_rbp *) ((unsigned long)he_dev->rbps_base | | ||
2021 | RBPS_MASK(he_dev->rbps_tail+1)); | ||
2022 | |||
2023 | /* table 3.42 -- rbps_tail should never be set to rbps_head */ | ||
2024 | if ((newtail == rbps_head) || (newtail->status & RBP_LOANED)) | ||
2025 | break; | ||
2026 | |||
2027 | newtail->status |= RBP_LOANED; | ||
2028 | he_dev->rbps_tail = newtail; | ||
2029 | ++moved; | ||
2030 | } | ||
2031 | |||
2032 | if (moved) | ||
2033 | he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T); | ||
2034 | } | ||
2035 | |||
2036 | static void | ||
2037 | he_tasklet(unsigned long data) | 1925 | he_tasklet(unsigned long data) |
2038 | { | 1926 | { |
2039 | unsigned long flags; | 1927 | unsigned long flags; |
@@ -2055,10 +1943,8 @@ he_tasklet(unsigned long data) | |||
2055 | HPRINTK("rbrq%d threshold\n", group); | 1943 | HPRINTK("rbrq%d threshold\n", group); |
2056 | /* fall through */ | 1944 | /* fall through */ |
2057 | case ITYPE_RBRQ_TIMER: | 1945 | case ITYPE_RBRQ_TIMER: |
2058 | if (he_service_rbrq(he_dev, group)) { | 1946 | if (he_service_rbrq(he_dev, group)) |
2059 | he_service_rbpl(he_dev, group); | 1947 | he_service_rbpl(he_dev, group); |
2060 | he_service_rbps(he_dev, group); | ||
2061 | } | ||
2062 | break; | 1948 | break; |
2063 | case ITYPE_TBRQ_THRESH: | 1949 | case ITYPE_TBRQ_THRESH: |
2064 | HPRINTK("tbrq%d threshold\n", group); | 1950 | HPRINTK("tbrq%d threshold\n", group); |
@@ -2070,7 +1956,7 @@ he_tasklet(unsigned long data) | |||
2070 | he_service_rbpl(he_dev, group); | 1956 | he_service_rbpl(he_dev, group); |
2071 | break; | 1957 | break; |
2072 | case ITYPE_RBPS_THRESH: | 1958 | case ITYPE_RBPS_THRESH: |
2073 | he_service_rbps(he_dev, group); | 1959 | /* shouldn't happen unless small buffers enabled */ |
2074 | break; | 1960 | break; |
2075 | case ITYPE_PHY: | 1961 | case ITYPE_PHY: |
2076 | HPRINTK("phy interrupt\n"); | 1962 | HPRINTK("phy interrupt\n"); |
@@ -2098,7 +1984,6 @@ he_tasklet(unsigned long data) | |||
2098 | 1984 | ||
2099 | he_service_rbrq(he_dev, 0); | 1985 | he_service_rbrq(he_dev, 0); |
2100 | he_service_rbpl(he_dev, 0); | 1986 | he_service_rbpl(he_dev, 0); |
2101 | he_service_rbps(he_dev, 0); | ||
2102 | he_service_tbrq(he_dev, 0); | 1987 | he_service_tbrq(he_dev, 0); |
2103 | break; | 1988 | break; |
2104 | default: | 1989 | default: |
@@ -2406,8 +2291,8 @@ he_open(struct atm_vcc *vcc) | |||
2406 | goto open_failed; | 2291 | goto open_failed; |
2407 | } | 2292 | } |
2408 | 2293 | ||
2409 | rsr1 = RSR1_GROUP(0); | 2294 | rsr1 = RSR1_GROUP(0) | RSR1_RBPL_ONLY; |
2410 | rsr4 = RSR4_GROUP(0); | 2295 | rsr4 = RSR4_GROUP(0) | RSR4_RBPL_ONLY; |
2411 | rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? | 2296 | rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? |
2412 | (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; | 2297 | (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; |
2413 | 2298 | ||