diff options
Diffstat (limited to 'drivers/atm')
-rw-r--r-- | drivers/atm/Kconfig | 2 | ||||
-rw-r--r-- | drivers/atm/adummy.c | 39 | ||||
-rw-r--r-- | drivers/atm/ambassador.c | 6 | ||||
-rw-r--r-- | drivers/atm/eni.c | 6 | ||||
-rw-r--r-- | drivers/atm/firestream.c | 6 | ||||
-rw-r--r-- | drivers/atm/fore200e.c | 8 | ||||
-rw-r--r-- | drivers/atm/he.c | 310 | ||||
-rw-r--r-- | drivers/atm/he.h | 65 | ||||
-rw-r--r-- | drivers/atm/idt77105.c | 11 | ||||
-rw-r--r-- | drivers/atm/idt77252.c | 5 | ||||
-rw-r--r-- | drivers/atm/nicstar.c | 5196 | ||||
-rw-r--r-- | drivers/atm/nicstar.h | 602 | ||||
-rw-r--r-- | drivers/atm/nicstarmac.c | 364 | ||||
-rw-r--r-- | drivers/atm/solos-pci.c | 6 | ||||
-rw-r--r-- | drivers/atm/suni.c | 5 | ||||
-rw-r--r-- | drivers/atm/zatm.c | 6 |
16 files changed, 3164 insertions, 3473 deletions
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index f1a0a00b3b07..be7461c9a87e 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig | |||
@@ -177,7 +177,7 @@ config ATM_ZATM_DEBUG | |||
177 | 177 | ||
178 | config ATM_NICSTAR | 178 | config ATM_NICSTAR |
179 | tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" | 179 | tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" |
180 | depends on PCI && !64BIT && VIRT_TO_BUS | 180 | depends on PCI |
181 | help | 181 | help |
182 | The NICStAR chipset family is used in a large number of ATM NICs for | 182 | The NICStAR chipset family is used in a large number of ATM NICs for |
183 | 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE | 183 | 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE |
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 6d44f07b69f8..46b94762125b 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c | |||
@@ -40,6 +40,42 @@ struct adummy_dev { | |||
40 | 40 | ||
41 | static LIST_HEAD(adummy_devs); | 41 | static LIST_HEAD(adummy_devs); |
42 | 42 | ||
43 | static ssize_t __set_signal(struct device *dev, | ||
44 | struct device_attribute *attr, | ||
45 | const char *buf, size_t len) | ||
46 | { | ||
47 | struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); | ||
48 | int signal; | ||
49 | |||
50 | if (sscanf(buf, "%d", &signal) == 1) { | ||
51 | |||
52 | if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND) | ||
53 | signal = ATM_PHY_SIG_UNKNOWN; | ||
54 | |||
55 | atm_dev_signal_change(atm_dev, signal); | ||
56 | return 1; | ||
57 | } | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | static ssize_t __show_signal(struct device *dev, | ||
62 | struct device_attribute *attr, char *buf) | ||
63 | { | ||
64 | struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev); | ||
65 | return sprintf(buf, "%d\n", atm_dev->signal); | ||
66 | } | ||
67 | static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal); | ||
68 | |||
69 | static struct attribute *adummy_attrs[] = { | ||
70 | &dev_attr_signal.attr, | ||
71 | NULL | ||
72 | }; | ||
73 | |||
74 | static struct attribute_group adummy_group_attrs = { | ||
75 | .name = NULL, /* We want them in dev's root folder */ | ||
76 | .attrs = adummy_attrs | ||
77 | }; | ||
78 | |||
43 | static int __init | 79 | static int __init |
44 | adummy_start(struct atm_dev *dev) | 80 | adummy_start(struct atm_dev *dev) |
45 | { | 81 | { |
@@ -128,6 +164,9 @@ static int __init adummy_init(void) | |||
128 | adummy_dev->atm_dev = atm_dev; | 164 | adummy_dev->atm_dev = atm_dev; |
129 | atm_dev->dev_data = adummy_dev; | 165 | atm_dev->dev_data = adummy_dev; |
130 | 166 | ||
167 | if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs)) | ||
168 | dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n"); | ||
169 | |||
131 | if (adummy_start(atm_dev)) { | 170 | if (adummy_start(atm_dev)) { |
132 | printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n"); | 171 | printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n"); |
133 | err = -ENODEV; | 172 | err = -ENODEV; |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 9d18644c897e..a33896a482e6 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2371,10 +2371,8 @@ MODULE_PARM_DESC(pci_lat, "PCI latency in bus cycles"); | |||
2371 | /********** module entry **********/ | 2371 | /********** module entry **********/ |
2372 | 2372 | ||
2373 | static struct pci_device_id amb_pci_tbl[] = { | 2373 | static struct pci_device_id amb_pci_tbl[] = { |
2374 | { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR, PCI_ANY_ID, PCI_ANY_ID, | 2374 | { PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR), 0 }, |
2375 | 0, 0, 0 }, | 2375 | { PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD), 0 }, |
2376 | { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD, PCI_ANY_ID, PCI_ANY_ID, | ||
2377 | 0, 0, 0 }, | ||
2378 | { 0, } | 2376 | { 0, } |
2379 | }; | 2377 | }; |
2380 | 2378 | ||
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 90a5a7cac740..80f9f3659e4d 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
@@ -2269,10 +2269,8 @@ out0: | |||
2269 | 2269 | ||
2270 | 2270 | ||
2271 | static struct pci_device_id eni_pci_tbl[] = { | 2271 | static struct pci_device_id eni_pci_tbl[] = { |
2272 | { PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_FPGA, PCI_ANY_ID, PCI_ANY_ID, | 2272 | { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ }, |
2273 | 0, 0, 0 /* FPGA */ }, | 2273 | { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ }, |
2274 | { PCI_VENDOR_ID_EF, PCI_DEVICE_ID_EF_ATM_ASIC, PCI_ANY_ID, PCI_ANY_ID, | ||
2275 | 0, 0, 1 /* ASIC */ }, | ||
2276 | { 0, } | 2274 | { 0, } |
2277 | }; | 2275 | }; |
2278 | MODULE_DEVICE_TABLE(pci,eni_pci_tbl); | 2276 | MODULE_DEVICE_TABLE(pci,eni_pci_tbl); |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 6e600afd06ae..8717809787fb 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -2027,10 +2027,8 @@ static void __devexit firestream_remove_one (struct pci_dev *pdev) | |||
2027 | } | 2027 | } |
2028 | 2028 | ||
2029 | static struct pci_device_id firestream_pci_tbl[] = { | 2029 | static struct pci_device_id firestream_pci_tbl[] = { |
2030 | { PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50, | 2030 | { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50), FS_IS50}, |
2031 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS50}, | 2031 | { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155), FS_IS155}, |
2032 | { PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155, | ||
2033 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS155}, | ||
2034 | { 0, } | 2032 | { 0, } |
2035 | }; | 2033 | }; |
2036 | 2034 | ||
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index da8f176c051e..b7385e077717 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -2657,7 +2657,7 @@ static int __devinit fore200e_sba_probe(struct of_device *op, | |||
2657 | 2657 | ||
2658 | fore200e->bus = bus; | 2658 | fore200e->bus = bus; |
2659 | fore200e->bus_dev = op; | 2659 | fore200e->bus_dev = op; |
2660 | fore200e->irq = op->irqs[0]; | 2660 | fore200e->irq = op->archdata.irqs[0]; |
2661 | fore200e->phys_base = op->resource[0].start; | 2661 | fore200e->phys_base = op->resource[0].start; |
2662 | 2662 | ||
2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
@@ -2795,7 +2795,7 @@ static int __init fore200e_module_init(void) | |||
2795 | printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); | 2795 | printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n"); |
2796 | 2796 | ||
2797 | #ifdef CONFIG_SBUS | 2797 | #ifdef CONFIG_SBUS |
2798 | err = of_register_driver(&fore200e_sba_driver, &of_bus_type); | 2798 | err = of_register_platform_driver(&fore200e_sba_driver); |
2799 | if (err) | 2799 | if (err) |
2800 | return err; | 2800 | return err; |
2801 | #endif | 2801 | #endif |
@@ -2806,7 +2806,7 @@ static int __init fore200e_module_init(void) | |||
2806 | 2806 | ||
2807 | #ifdef CONFIG_SBUS | 2807 | #ifdef CONFIG_SBUS |
2808 | if (err) | 2808 | if (err) |
2809 | of_unregister_driver(&fore200e_sba_driver); | 2809 | of_unregister_platform_driver(&fore200e_sba_driver); |
2810 | #endif | 2810 | #endif |
2811 | 2811 | ||
2812 | return err; | 2812 | return err; |
@@ -2818,7 +2818,7 @@ static void __exit fore200e_module_cleanup(void) | |||
2818 | pci_unregister_driver(&fore200e_pca_driver); | 2818 | pci_unregister_driver(&fore200e_pca_driver); |
2819 | #endif | 2819 | #endif |
2820 | #ifdef CONFIG_SBUS | 2820 | #ifdef CONFIG_SBUS |
2821 | of_unregister_driver(&fore200e_sba_driver); | 2821 | of_unregister_platform_driver(&fore200e_sba_driver); |
2822 | #endif | 2822 | #endif |
2823 | } | 2823 | } |
2824 | 2824 | ||
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 56c2e99e458f..801e8b6e9d1f 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <linux/timer.h> | 67 | #include <linux/timer.h> |
68 | #include <linux/interrupt.h> | 68 | #include <linux/interrupt.h> |
69 | #include <linux/dma-mapping.h> | 69 | #include <linux/dma-mapping.h> |
70 | #include <linux/bitmap.h> | ||
70 | #include <linux/slab.h> | 71 | #include <linux/slab.h> |
71 | #include <asm/io.h> | 72 | #include <asm/io.h> |
72 | #include <asm/byteorder.h> | 73 | #include <asm/byteorder.h> |
@@ -778,61 +779,39 @@ he_init_cs_block_rcm(struct he_dev *he_dev) | |||
778 | static int __devinit | 779 | static int __devinit |
779 | he_init_group(struct he_dev *he_dev, int group) | 780 | he_init_group(struct he_dev *he_dev, int group) |
780 | { | 781 | { |
782 | struct he_buff *heb, *next; | ||
783 | dma_addr_t mapping; | ||
781 | int i; | 784 | int i; |
782 | 785 | ||
783 | /* small buffer pool */ | 786 | he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32)); |
784 | he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev, | 787 | he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32)); |
785 | CONFIG_RBPS_BUFSIZE, 8, 0); | 788 | he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32)); |
786 | if (he_dev->rbps_pool == NULL) { | 789 | he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), |
787 | hprintk("unable to create rbps pages\n"); | 790 | G0_RBPS_BS + (group * 32)); |
791 | |||
792 | /* bitmap table */ | ||
793 | he_dev->rbpl_table = kmalloc(BITS_TO_LONGS(RBPL_TABLE_SIZE) | ||
794 | * sizeof(unsigned long), GFP_KERNEL); | ||
795 | if (!he_dev->rbpl_table) { | ||
796 | hprintk("unable to allocate rbpl bitmap table\n"); | ||
788 | return -ENOMEM; | 797 | return -ENOMEM; |
789 | } | 798 | } |
799 | bitmap_zero(he_dev->rbpl_table, RBPL_TABLE_SIZE); | ||
790 | 800 | ||
791 | he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev, | 801 | /* rbpl_virt 64-bit pointers */ |
792 | CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys); | 802 | he_dev->rbpl_virt = kmalloc(RBPL_TABLE_SIZE |
793 | if (he_dev->rbps_base == NULL) { | 803 | * sizeof(struct he_buff *), GFP_KERNEL); |
794 | hprintk("failed to alloc rbps_base\n"); | 804 | if (!he_dev->rbpl_virt) { |
795 | goto out_destroy_rbps_pool; | 805 | hprintk("unable to allocate rbpl virt table\n"); |
806 | goto out_free_rbpl_table; | ||
796 | } | 807 | } |
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 | 808 | ||
830 | /* large buffer pool */ | 809 | /* large buffer pool */ |
831 | he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, | 810 | he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, |
832 | CONFIG_RBPL_BUFSIZE, 8, 0); | 811 | CONFIG_RBPL_BUFSIZE, 64, 0); |
833 | if (he_dev->rbpl_pool == NULL) { | 812 | if (he_dev->rbpl_pool == NULL) { |
834 | hprintk("unable to create rbpl pool\n"); | 813 | hprintk("unable to create rbpl pool\n"); |
835 | goto out_free_rbps_virt; | 814 | goto out_free_rbpl_virt; |
836 | } | 815 | } |
837 | 816 | ||
838 | he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, | 817 | he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, |
@@ -842,30 +821,29 @@ he_init_group(struct he_dev *he_dev, int group) | |||
842 | goto out_destroy_rbpl_pool; | 821 | goto out_destroy_rbpl_pool; |
843 | } | 822 | } |
844 | memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp)); | 823 | memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp)); |
845 | he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL); | 824 | |
846 | if (he_dev->rbpl_virt == NULL) { | 825 | INIT_LIST_HEAD(&he_dev->rbpl_outstanding); |
847 | hprintk("failed to alloc rbpl_virt\n"); | ||
848 | goto out_free_rbpl_base; | ||
849 | } | ||
850 | 826 | ||
851 | for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { | 827 | for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { |
852 | dma_addr_t dma_handle; | ||
853 | void *cpuaddr; | ||
854 | 828 | ||
855 | cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle); | 829 | heb = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &mapping); |
856 | if (cpuaddr == NULL) | 830 | if (!heb) |
857 | goto out_free_rbpl_virt; | 831 | goto out_free_rbpl; |
832 | heb->mapping = mapping; | ||
833 | list_add(&heb->entry, &he_dev->rbpl_outstanding); | ||
858 | 834 | ||
859 | he_dev->rbpl_virt[i].virt = cpuaddr; | 835 | set_bit(i, he_dev->rbpl_table); |
860 | he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF); | 836 | he_dev->rbpl_virt[i] = heb; |
861 | he_dev->rbpl_base[i].phys = dma_handle; | 837 | he_dev->rbpl_hint = i + 1; |
838 | he_dev->rbpl_base[i].idx = i << RBP_IDX_OFFSET; | ||
839 | he_dev->rbpl_base[i].phys = mapping + offsetof(struct he_buff, data); | ||
862 | } | 840 | } |
863 | he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1]; | 841 | he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1]; |
864 | 842 | ||
865 | he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32)); | 843 | he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32)); |
866 | he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), | 844 | he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), |
867 | G0_RBPL_T + (group * 32)); | 845 | G0_RBPL_T + (group * 32)); |
868 | he_writel(he_dev, CONFIG_RBPL_BUFSIZE/4, | 846 | he_writel(he_dev, (CONFIG_RBPL_BUFSIZE - sizeof(struct he_buff))/4, |
869 | G0_RBPL_BS + (group * 32)); | 847 | G0_RBPL_BS + (group * 32)); |
870 | he_writel(he_dev, | 848 | he_writel(he_dev, |
871 | RBP_THRESH(CONFIG_RBPL_THRESH) | | 849 | RBP_THRESH(CONFIG_RBPL_THRESH) | |
@@ -879,7 +857,7 @@ he_init_group(struct he_dev *he_dev, int group) | |||
879 | CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys); | 857 | CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys); |
880 | if (he_dev->rbrq_base == NULL) { | 858 | if (he_dev->rbrq_base == NULL) { |
881 | hprintk("failed to allocate rbrq\n"); | 859 | hprintk("failed to allocate rbrq\n"); |
882 | goto out_free_rbpl_virt; | 860 | goto out_free_rbpl; |
883 | } | 861 | } |
884 | memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq)); | 862 | memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq)); |
885 | 863 | ||
@@ -920,33 +898,20 @@ out_free_rbpq_base: | |||
920 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * | 898 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * |
921 | sizeof(struct he_rbrq), he_dev->rbrq_base, | 899 | sizeof(struct he_rbrq), he_dev->rbrq_base, |
922 | he_dev->rbrq_phys); | 900 | he_dev->rbrq_phys); |
923 | i = CONFIG_RBPL_SIZE; | 901 | out_free_rbpl: |
924 | out_free_rbpl_virt: | 902 | list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry) |
925 | while (i--) | 903 | pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping); |
926 | pci_pool_free(he_dev->rbpl_pool, he_dev->rbpl_virt[i].virt, | ||
927 | he_dev->rbpl_base[i].phys); | ||
928 | kfree(he_dev->rbpl_virt); | ||
929 | 904 | ||
930 | out_free_rbpl_base: | ||
931 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * | 905 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * |
932 | sizeof(struct he_rbp), he_dev->rbpl_base, | 906 | sizeof(struct he_rbp), he_dev->rbpl_base, |
933 | he_dev->rbpl_phys); | 907 | he_dev->rbpl_phys); |
934 | out_destroy_rbpl_pool: | 908 | out_destroy_rbpl_pool: |
935 | pci_pool_destroy(he_dev->rbpl_pool); | 909 | pci_pool_destroy(he_dev->rbpl_pool); |
910 | out_free_rbpl_virt: | ||
911 | kfree(he_dev->rbpl_virt); | ||
912 | out_free_rbpl_table: | ||
913 | kfree(he_dev->rbpl_table); | ||
936 | 914 | ||
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; | 915 | return -ENOMEM; |
951 | } | 916 | } |
952 | 917 | ||
@@ -1002,7 +967,8 @@ he_init_irq(struct he_dev *he_dev) | |||
1002 | he_writel(he_dev, 0x0, GRP_54_MAP); | 967 | he_writel(he_dev, 0x0, GRP_54_MAP); |
1003 | he_writel(he_dev, 0x0, GRP_76_MAP); | 968 | he_writel(he_dev, 0x0, GRP_76_MAP); |
1004 | 969 | ||
1005 | if (request_irq(he_dev->pci_dev->irq, he_irq_handler, IRQF_DISABLED|IRQF_SHARED, DEV_LABEL, he_dev)) { | 970 | if (request_irq(he_dev->pci_dev->irq, |
971 | he_irq_handler, IRQF_SHARED, DEV_LABEL, he_dev)) { | ||
1006 | hprintk("irq %d already in use\n", he_dev->pci_dev->irq); | 972 | hprintk("irq %d already in use\n", he_dev->pci_dev->irq); |
1007 | return -EINVAL; | 973 | return -EINVAL; |
1008 | } | 974 | } |
@@ -1576,9 +1542,10 @@ he_start(struct atm_dev *dev) | |||
1576 | static void | 1542 | static void |
1577 | he_stop(struct he_dev *he_dev) | 1543 | he_stop(struct he_dev *he_dev) |
1578 | { | 1544 | { |
1579 | u16 command; | 1545 | struct he_buff *heb, *next; |
1580 | u32 gen_cntl_0, reg; | ||
1581 | struct pci_dev *pci_dev; | 1546 | struct pci_dev *pci_dev; |
1547 | u32 gen_cntl_0, reg; | ||
1548 | u16 command; | ||
1582 | 1549 | ||
1583 | pci_dev = he_dev->pci_dev; | 1550 | pci_dev = he_dev->pci_dev; |
1584 | 1551 | ||
@@ -1619,37 +1586,19 @@ he_stop(struct he_dev *he_dev) | |||
1619 | he_dev->hsp, he_dev->hsp_phys); | 1586 | he_dev->hsp, he_dev->hsp_phys); |
1620 | 1587 | ||
1621 | if (he_dev->rbpl_base) { | 1588 | if (he_dev->rbpl_base) { |
1622 | int i; | 1589 | list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry) |
1623 | 1590 | pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping); | |
1624 | for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { | ||
1625 | void *cpuaddr = he_dev->rbpl_virt[i].virt; | ||
1626 | dma_addr_t dma_handle = he_dev->rbpl_base[i].phys; | ||
1627 | 1591 | ||
1628 | pci_pool_free(he_dev->rbpl_pool, cpuaddr, dma_handle); | ||
1629 | } | ||
1630 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE | 1592 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE |
1631 | * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys); | 1593 | * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys); |
1632 | } | 1594 | } |
1633 | 1595 | ||
1596 | kfree(he_dev->rbpl_virt); | ||
1597 | kfree(he_dev->rbpl_table); | ||
1598 | |||
1634 | if (he_dev->rbpl_pool) | 1599 | if (he_dev->rbpl_pool) |
1635 | pci_pool_destroy(he_dev->rbpl_pool); | 1600 | pci_pool_destroy(he_dev->rbpl_pool); |
1636 | 1601 | ||
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) | 1602 | if (he_dev->rbrq_base) |
1654 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), | 1603 | pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), |
1655 | he_dev->rbrq_base, he_dev->rbrq_phys); | 1604 | he_dev->rbrq_base, he_dev->rbrq_phys); |
@@ -1679,13 +1628,13 @@ static struct he_tpd * | |||
1679 | __alloc_tpd(struct he_dev *he_dev) | 1628 | __alloc_tpd(struct he_dev *he_dev) |
1680 | { | 1629 | { |
1681 | struct he_tpd *tpd; | 1630 | struct he_tpd *tpd; |
1682 | dma_addr_t dma_handle; | 1631 | dma_addr_t mapping; |
1683 | 1632 | ||
1684 | tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &dma_handle); | 1633 | tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &mapping); |
1685 | if (tpd == NULL) | 1634 | if (tpd == NULL) |
1686 | return NULL; | 1635 | return NULL; |
1687 | 1636 | ||
1688 | tpd->status = TPD_ADDR(dma_handle); | 1637 | tpd->status = TPD_ADDR(mapping); |
1689 | tpd->reserved = 0; | 1638 | tpd->reserved = 0; |
1690 | tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0; | 1639 | tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0; |
1691 | tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0; | 1640 | tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0; |
@@ -1714,13 +1663,12 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1714 | struct he_rbrq *rbrq_tail = (struct he_rbrq *) | 1663 | struct he_rbrq *rbrq_tail = (struct he_rbrq *) |
1715 | ((unsigned long)he_dev->rbrq_base | | 1664 | ((unsigned long)he_dev->rbrq_base | |
1716 | he_dev->hsp->group[group].rbrq_tail); | 1665 | he_dev->hsp->group[group].rbrq_tail); |
1717 | struct he_rbp *rbp = NULL; | ||
1718 | unsigned cid, lastcid = -1; | 1666 | unsigned cid, lastcid = -1; |
1719 | unsigned buf_len = 0; | ||
1720 | struct sk_buff *skb; | 1667 | struct sk_buff *skb; |
1721 | struct atm_vcc *vcc = NULL; | 1668 | struct atm_vcc *vcc = NULL; |
1722 | struct he_vcc *he_vcc; | 1669 | struct he_vcc *he_vcc; |
1723 | struct he_iovec *iov; | 1670 | struct he_buff *heb, *next; |
1671 | int i; | ||
1724 | int pdus_assembled = 0; | 1672 | int pdus_assembled = 0; |
1725 | int updated = 0; | 1673 | int updated = 0; |
1726 | 1674 | ||
@@ -1740,44 +1688,35 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1740 | RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", | 1688 | RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", |
1741 | RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); | 1689 | RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); |
1742 | 1690 | ||
1743 | if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF) | 1691 | i = RBRQ_ADDR(he_dev->rbrq_head) >> RBP_IDX_OFFSET; |
1744 | rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; | 1692 | heb = he_dev->rbpl_virt[i]; |
1745 | else | ||
1746 | rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; | ||
1747 | |||
1748 | buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; | ||
1749 | cid = RBRQ_CID(he_dev->rbrq_head); | ||
1750 | 1693 | ||
1694 | cid = RBRQ_CID(he_dev->rbrq_head); | ||
1751 | if (cid != lastcid) | 1695 | if (cid != lastcid) |
1752 | vcc = __find_vcc(he_dev, cid); | 1696 | vcc = __find_vcc(he_dev, cid); |
1753 | lastcid = cid; | 1697 | lastcid = cid; |
1754 | 1698 | ||
1755 | if (vcc == NULL) { | 1699 | if (vcc == NULL || (he_vcc = HE_VCC(vcc)) == NULL) { |
1756 | hprintk("vcc == NULL (cid 0x%x)\n", cid); | 1700 | hprintk("vcc/he_vcc == NULL (cid 0x%x)\n", cid); |
1757 | if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) | 1701 | if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) { |
1758 | rbp->status &= ~RBP_LOANED; | 1702 | clear_bit(i, he_dev->rbpl_table); |
1703 | list_del(&heb->entry); | ||
1704 | pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping); | ||
1705 | } | ||
1759 | 1706 | ||
1760 | goto next_rbrq_entry; | 1707 | goto next_rbrq_entry; |
1761 | } | 1708 | } |
1762 | 1709 | ||
1763 | he_vcc = HE_VCC(vcc); | ||
1764 | if (he_vcc == NULL) { | ||
1765 | hprintk("he_vcc == NULL (cid 0x%x)\n", cid); | ||
1766 | if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) | ||
1767 | rbp->status &= ~RBP_LOANED; | ||
1768 | goto next_rbrq_entry; | ||
1769 | } | ||
1770 | |||
1771 | if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) { | 1710 | if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) { |
1772 | hprintk("HBUF_ERR! (cid 0x%x)\n", cid); | 1711 | hprintk("HBUF_ERR! (cid 0x%x)\n", cid); |
1773 | atomic_inc(&vcc->stats->rx_drop); | 1712 | atomic_inc(&vcc->stats->rx_drop); |
1774 | goto return_host_buffers; | 1713 | goto return_host_buffers; |
1775 | } | 1714 | } |
1776 | 1715 | ||
1777 | he_vcc->iov_tail->iov_base = RBRQ_ADDR(he_dev->rbrq_head); | 1716 | heb->len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; |
1778 | he_vcc->iov_tail->iov_len = buf_len; | 1717 | clear_bit(i, he_dev->rbpl_table); |
1779 | he_vcc->pdu_len += buf_len; | 1718 | list_move_tail(&heb->entry, &he_vcc->buffers); |
1780 | ++he_vcc->iov_tail; | 1719 | he_vcc->pdu_len += heb->len; |
1781 | 1720 | ||
1782 | if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) { | 1721 | if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) { |
1783 | lastcid = -1; | 1722 | lastcid = -1; |
@@ -1786,12 +1725,6 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1786 | goto return_host_buffers; | 1725 | goto return_host_buffers; |
1787 | } | 1726 | } |
1788 | 1727 | ||
1789 | #ifdef notdef | ||
1790 | if ((he_vcc->iov_tail - he_vcc->iov_head) > HE_MAXIOV) { | ||
1791 | hprintk("iovec full! cid 0x%x\n", cid); | ||
1792 | goto return_host_buffers; | ||
1793 | } | ||
1794 | #endif | ||
1795 | if (!RBRQ_END_PDU(he_dev->rbrq_head)) | 1728 | if (!RBRQ_END_PDU(he_dev->rbrq_head)) |
1796 | goto next_rbrq_entry; | 1729 | goto next_rbrq_entry; |
1797 | 1730 | ||
@@ -1819,15 +1752,8 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1819 | 1752 | ||
1820 | __net_timestamp(skb); | 1753 | __net_timestamp(skb); |
1821 | 1754 | ||
1822 | for (iov = he_vcc->iov_head; | 1755 | list_for_each_entry(heb, &he_vcc->buffers, entry) |
1823 | iov < he_vcc->iov_tail; ++iov) { | 1756 | memcpy(skb_put(skb, heb->len), &heb->data, heb->len); |
1824 | if (iov->iov_base & RBP_SMALLBUF) | ||
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 | 1757 | ||
1832 | switch (vcc->qos.aal) { | 1758 | switch (vcc->qos.aal) { |
1833 | case ATM_AAL0: | 1759 | case ATM_AAL0: |
@@ -1867,17 +1793,9 @@ he_service_rbrq(struct he_dev *he_dev, int group) | |||
1867 | return_host_buffers: | 1793 | return_host_buffers: |
1868 | ++pdus_assembled; | 1794 | ++pdus_assembled; |
1869 | 1795 | ||
1870 | for (iov = he_vcc->iov_head; | 1796 | list_for_each_entry_safe(heb, next, &he_vcc->buffers, entry) |
1871 | iov < he_vcc->iov_tail; ++iov) { | 1797 | pci_pool_free(he_dev->rbpl_pool, heb, heb->mapping); |
1872 | if (iov->iov_base & RBP_SMALLBUF) | 1798 | INIT_LIST_HEAD(&he_vcc->buffers); |
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; | ||
1878 | } | ||
1879 | |||
1880 | he_vcc->iov_tail = he_vcc->iov_head; | ||
1881 | he_vcc->pdu_len = 0; | 1799 | he_vcc->pdu_len = 0; |
1882 | 1800 | ||
1883 | next_rbrq_entry: | 1801 | next_rbrq_entry: |
@@ -1978,59 +1896,51 @@ next_tbrq_entry: | |||
1978 | } | 1896 | } |
1979 | } | 1897 | } |
1980 | 1898 | ||
1981 | |||
1982 | static void | 1899 | static void |
1983 | he_service_rbpl(struct he_dev *he_dev, int group) | 1900 | he_service_rbpl(struct he_dev *he_dev, int group) |
1984 | { | 1901 | { |
1985 | struct he_rbp *newtail; | 1902 | struct he_rbp *new_tail; |
1986 | struct he_rbp *rbpl_head; | 1903 | struct he_rbp *rbpl_head; |
1904 | struct he_buff *heb; | ||
1905 | dma_addr_t mapping; | ||
1906 | int i; | ||
1987 | int moved = 0; | 1907 | int moved = 0; |
1988 | 1908 | ||
1989 | rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | | 1909 | rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | |
1990 | RBPL_MASK(he_readl(he_dev, G0_RBPL_S))); | 1910 | RBPL_MASK(he_readl(he_dev, G0_RBPL_S))); |
1991 | 1911 | ||
1992 | for (;;) { | 1912 | for (;;) { |
1993 | newtail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | | 1913 | new_tail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base | |
1994 | RBPL_MASK(he_dev->rbpl_tail+1)); | 1914 | RBPL_MASK(he_dev->rbpl_tail+1)); |
1995 | 1915 | ||
1996 | /* table 3.42 -- rbpl_tail should never be set to rbpl_head */ | 1916 | /* table 3.42 -- rbpl_tail should never be set to rbpl_head */ |
1997 | if ((newtail == rbpl_head) || (newtail->status & RBP_LOANED)) | 1917 | if (new_tail == rbpl_head) |
1998 | break; | 1918 | break; |
1999 | 1919 | ||
2000 | newtail->status |= RBP_LOANED; | 1920 | i = find_next_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE, he_dev->rbpl_hint); |
2001 | he_dev->rbpl_tail = newtail; | 1921 | if (i > (RBPL_TABLE_SIZE - 1)) { |
2002 | ++moved; | 1922 | i = find_first_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE); |
2003 | } | 1923 | if (i > (RBPL_TABLE_SIZE - 1)) |
2004 | 1924 | break; | |
2005 | if (moved) | 1925 | } |
2006 | he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T); | 1926 | he_dev->rbpl_hint = i + 1; |
2007 | } | ||
2008 | |||
2009 | 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 | 1927 | ||
2023 | /* table 3.42 -- rbps_tail should never be set to rbps_head */ | 1928 | heb = pci_pool_alloc(he_dev->rbpl_pool, GFP_ATOMIC|GFP_DMA, &mapping); |
2024 | if ((newtail == rbps_head) || (newtail->status & RBP_LOANED)) | 1929 | if (!heb) |
2025 | break; | 1930 | break; |
2026 | 1931 | heb->mapping = mapping; | |
2027 | newtail->status |= RBP_LOANED; | 1932 | list_add(&heb->entry, &he_dev->rbpl_outstanding); |
2028 | he_dev->rbps_tail = newtail; | 1933 | he_dev->rbpl_virt[i] = heb; |
1934 | set_bit(i, he_dev->rbpl_table); | ||
1935 | new_tail->idx = i << RBP_IDX_OFFSET; | ||
1936 | new_tail->phys = mapping + offsetof(struct he_buff, data); | ||
1937 | |||
1938 | he_dev->rbpl_tail = new_tail; | ||
2029 | ++moved; | 1939 | ++moved; |
2030 | } | 1940 | } |
2031 | 1941 | ||
2032 | if (moved) | 1942 | if (moved) |
2033 | he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T); | 1943 | he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T); |
2034 | } | 1944 | } |
2035 | 1945 | ||
2036 | static void | 1946 | static void |
@@ -2055,10 +1965,8 @@ he_tasklet(unsigned long data) | |||
2055 | HPRINTK("rbrq%d threshold\n", group); | 1965 | HPRINTK("rbrq%d threshold\n", group); |
2056 | /* fall through */ | 1966 | /* fall through */ |
2057 | case ITYPE_RBRQ_TIMER: | 1967 | case ITYPE_RBRQ_TIMER: |
2058 | if (he_service_rbrq(he_dev, group)) { | 1968 | if (he_service_rbrq(he_dev, group)) |
2059 | he_service_rbpl(he_dev, group); | 1969 | he_service_rbpl(he_dev, group); |
2060 | he_service_rbps(he_dev, group); | ||
2061 | } | ||
2062 | break; | 1970 | break; |
2063 | case ITYPE_TBRQ_THRESH: | 1971 | case ITYPE_TBRQ_THRESH: |
2064 | HPRINTK("tbrq%d threshold\n", group); | 1972 | HPRINTK("tbrq%d threshold\n", group); |
@@ -2070,7 +1978,7 @@ he_tasklet(unsigned long data) | |||
2070 | he_service_rbpl(he_dev, group); | 1978 | he_service_rbpl(he_dev, group); |
2071 | break; | 1979 | break; |
2072 | case ITYPE_RBPS_THRESH: | 1980 | case ITYPE_RBPS_THRESH: |
2073 | he_service_rbps(he_dev, group); | 1981 | /* shouldn't happen unless small buffers enabled */ |
2074 | break; | 1982 | break; |
2075 | case ITYPE_PHY: | 1983 | case ITYPE_PHY: |
2076 | HPRINTK("phy interrupt\n"); | 1984 | HPRINTK("phy interrupt\n"); |
@@ -2098,7 +2006,6 @@ he_tasklet(unsigned long data) | |||
2098 | 2006 | ||
2099 | he_service_rbrq(he_dev, 0); | 2007 | he_service_rbrq(he_dev, 0); |
2100 | he_service_rbpl(he_dev, 0); | 2008 | he_service_rbpl(he_dev, 0); |
2101 | he_service_rbps(he_dev, 0); | ||
2102 | he_service_tbrq(he_dev, 0); | 2009 | he_service_tbrq(he_dev, 0); |
2103 | break; | 2010 | break; |
2104 | default: | 2011 | default: |
@@ -2252,7 +2159,7 @@ he_open(struct atm_vcc *vcc) | |||
2252 | return -ENOMEM; | 2159 | return -ENOMEM; |
2253 | } | 2160 | } |
2254 | 2161 | ||
2255 | he_vcc->iov_tail = he_vcc->iov_head; | 2162 | INIT_LIST_HEAD(&he_vcc->buffers); |
2256 | he_vcc->pdu_len = 0; | 2163 | he_vcc->pdu_len = 0; |
2257 | he_vcc->rc_index = -1; | 2164 | he_vcc->rc_index = -1; |
2258 | 2165 | ||
@@ -2406,8 +2313,8 @@ he_open(struct atm_vcc *vcc) | |||
2406 | goto open_failed; | 2313 | goto open_failed; |
2407 | } | 2314 | } |
2408 | 2315 | ||
2409 | rsr1 = RSR1_GROUP(0); | 2316 | rsr1 = RSR1_GROUP(0) | RSR1_RBPL_ONLY; |
2410 | rsr4 = RSR4_GROUP(0); | 2317 | rsr4 = RSR4_GROUP(0) | RSR4_RBPL_ONLY; |
2411 | rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? | 2318 | rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? |
2412 | (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; | 2319 | (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; |
2413 | 2320 | ||
@@ -2963,8 +2870,7 @@ module_param(sdh, bool, 0); | |||
2963 | MODULE_PARM_DESC(sdh, "use SDH framing (default 0)"); | 2870 | MODULE_PARM_DESC(sdh, "use SDH framing (default 0)"); |
2964 | 2871 | ||
2965 | static struct pci_device_id he_pci_tbl[] = { | 2872 | static struct pci_device_id he_pci_tbl[] = { |
2966 | { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_HE, PCI_ANY_ID, PCI_ANY_ID, | 2873 | { PCI_VDEVICE(FORE, PCI_DEVICE_ID_FORE_HE), 0 }, |
2967 | 0, 0, 0 }, | ||
2968 | { 0, } | 2874 | { 0, } |
2969 | }; | 2875 | }; |
2970 | 2876 | ||
diff --git a/drivers/atm/he.h b/drivers/atm/he.h index c2983e0d4ec1..110a27d2ecfc 100644 --- a/drivers/atm/he.h +++ b/drivers/atm/he.h | |||
@@ -67,11 +67,6 @@ | |||
67 | #define CONFIG_RBPL_BUFSIZE 4096 | 67 | #define CONFIG_RBPL_BUFSIZE 4096 |
68 | #define RBPL_MASK(x) (((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1)) | 68 | #define RBPL_MASK(x) (((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1)) |
69 | 69 | ||
70 | #define CONFIG_RBPS_SIZE 1024 | ||
71 | #define CONFIG_RBPS_THRESH 64 | ||
72 | #define CONFIG_RBPS_BUFSIZE 128 | ||
73 | #define RBPS_MASK(x) (((unsigned long)(x))&((CONFIG_RBPS_SIZE<<3)-1)) | ||
74 | |||
75 | /* 5.1.3 initialize connection memory */ | 70 | /* 5.1.3 initialize connection memory */ |
76 | 71 | ||
77 | #define CONFIG_RSRA 0x00000 | 72 | #define CONFIG_RSRA 0x00000 |
@@ -203,36 +198,37 @@ struct he_hsp { | |||
203 | } group[HE_NUM_GROUPS]; | 198 | } group[HE_NUM_GROUPS]; |
204 | }; | 199 | }; |
205 | 200 | ||
206 | /* figure 2.9 receive buffer pools */ | 201 | /* |
202 | * figure 2.9 receive buffer pools | ||
203 | * | ||
204 | * since a virtual address might be more than 32 bits, we store an index | ||
205 | * in the virt member of he_rbp. NOTE: the lower six bits in the rbrq | ||
206 | * addr member are used for buffer status further limiting us to 26 bits. | ||
207 | */ | ||
207 | 208 | ||
208 | struct he_rbp { | 209 | struct he_rbp { |
209 | volatile u32 phys; | 210 | volatile u32 phys; |
210 | volatile u32 status; | 211 | volatile u32 idx; /* virt */ |
211 | }; | 212 | }; |
212 | 213 | ||
213 | /* NOTE: it is suggested that virt be the virtual address of the host | 214 | #define RBP_IDX_OFFSET 6 |
214 | buffer. on a 64-bit machine, this would not work. Instead, we | ||
215 | store the real virtual address in another list, and store an index | ||
216 | (and buffer status) in the virt member. | ||
217 | */ | ||
218 | 215 | ||
219 | #define RBP_INDEX_OFF 6 | 216 | /* |
220 | #define RBP_INDEX(x) (((long)(x) >> RBP_INDEX_OFF) & 0xffff) | 217 | * the he dma engine will try to hold an extra 16 buffers in its local |
221 | #define RBP_LOANED 0x80000000 | 218 | * caches. and add a couple buffers for safety. |
222 | #define RBP_SMALLBUF 0x40000000 | 219 | */ |
223 | 220 | ||
224 | struct he_virt { | 221 | #define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2) |
225 | void *virt; | ||
226 | }; | ||
227 | 222 | ||
228 | #define RBPL_ALIGNMENT CONFIG_RBPL_SIZE | 223 | struct he_buff { |
229 | #define RBPS_ALIGNMENT CONFIG_RBPS_SIZE | 224 | struct list_head entry; |
225 | dma_addr_t mapping; | ||
226 | unsigned long len; | ||
227 | u8 data[]; | ||
228 | }; | ||
230 | 229 | ||
231 | #ifdef notyet | 230 | #ifdef notyet |
232 | struct he_group { | 231 | struct he_group { |
233 | u32 rpbs_size, rpbs_qsize; | ||
234 | struct he_rbp rbps_ba; | ||
235 | |||
236 | u32 rpbl_size, rpbl_qsize; | 232 | u32 rpbl_size, rpbl_qsize; |
237 | struct he_rpb_entry *rbpl_ba; | 233 | struct he_rpb_entry *rbpl_ba; |
238 | }; | 234 | }; |
@@ -297,18 +293,15 @@ struct he_dev { | |||
297 | struct he_rbrq *rbrq_base, *rbrq_head; | 293 | struct he_rbrq *rbrq_base, *rbrq_head; |
298 | int rbrq_peak; | 294 | int rbrq_peak; |
299 | 295 | ||
296 | struct he_buff **rbpl_virt; | ||
297 | unsigned long *rbpl_table; | ||
298 | unsigned long rbpl_hint; | ||
300 | struct pci_pool *rbpl_pool; | 299 | struct pci_pool *rbpl_pool; |
301 | dma_addr_t rbpl_phys; | 300 | dma_addr_t rbpl_phys; |
302 | struct he_rbp *rbpl_base, *rbpl_tail; | 301 | struct he_rbp *rbpl_base, *rbpl_tail; |
303 | struct he_virt *rbpl_virt; | 302 | struct list_head rbpl_outstanding; |
304 | int rbpl_peak; | 303 | int rbpl_peak; |
305 | 304 | ||
306 | struct pci_pool *rbps_pool; | ||
307 | dma_addr_t rbps_phys; | ||
308 | struct he_rbp *rbps_base, *rbps_tail; | ||
309 | struct he_virt *rbps_virt; | ||
310 | int rbps_peak; | ||
311 | |||
312 | dma_addr_t tbrq_phys; | 305 | dma_addr_t tbrq_phys; |
313 | struct he_tbrq *tbrq_base, *tbrq_head; | 306 | struct he_tbrq *tbrq_base, *tbrq_head; |
314 | int tbrq_peak; | 307 | int tbrq_peak; |
@@ -321,20 +314,12 @@ struct he_dev { | |||
321 | struct he_dev *next; | 314 | struct he_dev *next; |
322 | }; | 315 | }; |
323 | 316 | ||
324 | struct he_iovec | ||
325 | { | ||
326 | u32 iov_base; | ||
327 | u32 iov_len; | ||
328 | }; | ||
329 | |||
330 | #define HE_MAXIOV 20 | 317 | #define HE_MAXIOV 20 |
331 | 318 | ||
332 | struct he_vcc | 319 | struct he_vcc |
333 | { | 320 | { |
334 | struct he_iovec iov_head[HE_MAXIOV]; | 321 | struct list_head buffers; |
335 | struct he_iovec *iov_tail; | ||
336 | int pdu_len; | 322 | int pdu_len; |
337 | |||
338 | int rc_index; | 323 | int rc_index; |
339 | 324 | ||
340 | wait_queue_head_t rx_waitq; | 325 | wait_queue_head_t rx_waitq; |
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index dab5cf5274fb..bca9cb89a118 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c | |||
@@ -126,7 +126,7 @@ static void idt77105_restart_timer_func(unsigned long dummy) | |||
126 | istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ | 126 | istat = GET(ISTAT); /* side effect: clears all interrupt status bits */ |
127 | if (istat & IDT77105_ISTAT_GOODSIG) { | 127 | if (istat & IDT77105_ISTAT_GOODSIG) { |
128 | /* Found signal again */ | 128 | /* Found signal again */ |
129 | dev->signal = ATM_PHY_SIG_FOUND; | 129 | atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); |
130 | printk(KERN_NOTICE "%s(itf %d): signal detected again\n", | 130 | printk(KERN_NOTICE "%s(itf %d): signal detected again\n", |
131 | dev->type,dev->number); | 131 | dev->type,dev->number); |
132 | /* flush the receive FIFO */ | 132 | /* flush the receive FIFO */ |
@@ -222,7 +222,7 @@ static void idt77105_int(struct atm_dev *dev) | |||
222 | /* Rx Signal Condition Change - line went up or down */ | 222 | /* Rx Signal Condition Change - line went up or down */ |
223 | if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */ | 223 | if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */ |
224 | /* This should not happen (restart timer does it) but JIC */ | 224 | /* This should not happen (restart timer does it) but JIC */ |
225 | dev->signal = ATM_PHY_SIG_FOUND; | 225 | atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND); |
226 | } else { /* signal lost */ | 226 | } else { /* signal lost */ |
227 | /* | 227 | /* |
228 | * Disable interrupts and stop all transmission and | 228 | * Disable interrupts and stop all transmission and |
@@ -235,7 +235,7 @@ static void idt77105_int(struct atm_dev *dev) | |||
235 | IDT77105_MCR_DRIC| | 235 | IDT77105_MCR_DRIC| |
236 | IDT77105_MCR_HALTTX | 236 | IDT77105_MCR_HALTTX |
237 | ) & ~IDT77105_MCR_EIP, MCR); | 237 | ) & ~IDT77105_MCR_EIP, MCR); |
238 | dev->signal = ATM_PHY_SIG_LOST; | 238 | atm_dev_signal_change(dev, ATM_PHY_SIG_LOST); |
239 | printk(KERN_NOTICE "%s(itf %d): signal lost\n", | 239 | printk(KERN_NOTICE "%s(itf %d): signal lost\n", |
240 | dev->type,dev->number); | 240 | dev->type,dev->number); |
241 | } | 241 | } |
@@ -272,8 +272,9 @@ static int idt77105_start(struct atm_dev *dev) | |||
272 | memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); | 272 | memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats)); |
273 | 273 | ||
274 | /* initialise dev->signal from Good Signal Bit */ | 274 | /* initialise dev->signal from Good Signal Bit */ |
275 | dev->signal = GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? ATM_PHY_SIG_FOUND : | 275 | atm_dev_signal_change(dev, |
276 | ATM_PHY_SIG_LOST; | 276 | GET(ISTAT) & IDT77105_ISTAT_GOODSIG ? |
277 | ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST); | ||
277 | if (dev->signal == ATM_PHY_SIG_LOST) | 278 | if (dev->signal == ATM_PHY_SIG_LOST) |
278 | printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, | 279 | printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type, |
279 | dev->number); | 280 | dev->number); |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 98657a6a330d..1679cbf0c584 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -3364,7 +3364,7 @@ init_card(struct atm_dev *dev) | |||
3364 | writel(SAR_STAT_TMROF, SAR_REG_STAT); | 3364 | writel(SAR_STAT_TMROF, SAR_REG_STAT); |
3365 | } | 3365 | } |
3366 | IPRINTK("%s: Request IRQ ... ", card->name); | 3366 | IPRINTK("%s: Request IRQ ... ", card->name); |
3367 | if (request_irq(pcidev->irq, idt77252_interrupt, IRQF_DISABLED|IRQF_SHARED, | 3367 | if (request_irq(pcidev->irq, idt77252_interrupt, IRQF_SHARED, |
3368 | card->name, card) != 0) { | 3368 | card->name, card) != 0) { |
3369 | printk("%s: can't allocate IRQ.\n", card->name); | 3369 | printk("%s: can't allocate IRQ.\n", card->name); |
3370 | deinit_card(card); | 3370 | deinit_card(card); |
@@ -3779,8 +3779,7 @@ err_out_disable_pdev: | |||
3779 | 3779 | ||
3780 | static struct pci_device_id idt77252_pci_tbl[] = | 3780 | static struct pci_device_id idt77252_pci_tbl[] = |
3781 | { | 3781 | { |
3782 | { PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77252, | 3782 | { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 }, |
3783 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
3784 | { 0, } | 3783 | { 0, } |
3785 | }; | 3784 | }; |
3786 | 3785 | ||
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index b7473a6110a7..2f3516b7f118 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | * | ||
3 | * nicstar.c | 2 | * nicstar.c |
4 | * | 3 | * |
5 | * Device driver supporting CBR for IDT 77201/77211 "NICStAR" based cards. | 4 | * Device driver supporting CBR for IDT 77201/77211 "NICStAR" based cards. |
@@ -16,12 +15,10 @@ | |||
16 | * | 15 | * |
17 | * | 16 | * |
18 | * (C) INESC 1999 | 17 | * (C) INESC 1999 |
19 | * | 18 | */ |
20 | * | ||
21 | ******************************************************************************/ | ||
22 | |||
23 | 19 | ||
24 | /**** IMPORTANT INFORMATION *************************************************** | 20 | /* |
21 | * IMPORTANT INFORMATION | ||
25 | * | 22 | * |
26 | * There are currently three types of spinlocks: | 23 | * There are currently three types of spinlocks: |
27 | * | 24 | * |
@@ -31,9 +28,9 @@ | |||
31 | * | 28 | * |
32 | * These must NEVER be grabbed in reverse order. | 29 | * These must NEVER be grabbed in reverse order. |
33 | * | 30 | * |
34 | ******************************************************************************/ | 31 | */ |
35 | 32 | ||
36 | /* Header files ***************************************************************/ | 33 | /* Header files */ |
37 | 34 | ||
38 | #include <linux/module.h> | 35 | #include <linux/module.h> |
39 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -41,6 +38,7 @@ | |||
41 | #include <linux/atmdev.h> | 38 | #include <linux/atmdev.h> |
42 | #include <linux/atm.h> | 39 | #include <linux/atm.h> |
43 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/dma-mapping.h> | ||
44 | #include <linux/types.h> | 42 | #include <linux/types.h> |
45 | #include <linux/string.h> | 43 | #include <linux/string.h> |
46 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
@@ -50,6 +48,7 @@ | |||
50 | #include <linux/interrupt.h> | 48 | #include <linux/interrupt.h> |
51 | #include <linux/bitops.h> | 49 | #include <linux/bitops.h> |
52 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
51 | #include <linux/idr.h> | ||
53 | #include <asm/io.h> | 52 | #include <asm/io.h> |
54 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
55 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
@@ -61,16 +60,11 @@ | |||
61 | #include "idt77105.h" | 60 | #include "idt77105.h" |
62 | #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ | 61 | #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ |
63 | 62 | ||
64 | #if BITS_PER_LONG != 32 | 63 | /* Additional code */ |
65 | # error FIXME: this driver requires a 32-bit platform | ||
66 | #endif | ||
67 | |||
68 | /* Additional code ************************************************************/ | ||
69 | 64 | ||
70 | #include "nicstarmac.c" | 65 | #include "nicstarmac.c" |
71 | 66 | ||
72 | 67 | /* Configurable parameters */ | |
73 | /* Configurable parameters ****************************************************/ | ||
74 | 68 | ||
75 | #undef PHY_LOOPBACK | 69 | #undef PHY_LOOPBACK |
76 | #undef TX_DEBUG | 70 | #undef TX_DEBUG |
@@ -78,11 +72,10 @@ | |||
78 | #undef GENERAL_DEBUG | 72 | #undef GENERAL_DEBUG |
79 | #undef EXTRA_DEBUG | 73 | #undef EXTRA_DEBUG |
80 | 74 | ||
81 | #undef NS_USE_DESTRUCTORS /* For now keep this undefined unless you know | 75 | #undef NS_USE_DESTRUCTORS /* For now keep this undefined unless you know |
82 | you're going to use only raw ATM */ | 76 | you're going to use only raw ATM */ |
83 | 77 | ||
84 | 78 | /* Do not touch these */ | |
85 | /* Do not touch these *********************************************************/ | ||
86 | 79 | ||
87 | #ifdef TX_DEBUG | 80 | #ifdef TX_DEBUG |
88 | #define TXPRINTK(args...) printk(args) | 81 | #define TXPRINTK(args...) printk(args) |
@@ -108,2908 +101,2773 @@ | |||
108 | #define XPRINTK(args...) | 101 | #define XPRINTK(args...) |
109 | #endif /* EXTRA_DEBUG */ | 102 | #endif /* EXTRA_DEBUG */ |
110 | 103 | ||
111 | 104 | /* Macros */ | |
112 | /* Macros *********************************************************************/ | ||
113 | 105 | ||
114 | #define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ) | 106 | #define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ) |
115 | 107 | ||
116 | #define NS_DELAY mdelay(1) | 108 | #define NS_DELAY mdelay(1) |
117 | 109 | ||
118 | #define ALIGN_BUS_ADDR(addr, alignment) \ | 110 | #define PTR_DIFF(a, b) ((u32)((unsigned long)(a) - (unsigned long)(b))) |
119 | ((((u32) (addr)) + (((u32) (alignment)) - 1)) & ~(((u32) (alignment)) - 1)) | ||
120 | #define ALIGN_ADDRESS(addr, alignment) \ | ||
121 | bus_to_virt(ALIGN_BUS_ADDR(virt_to_bus(addr), alignment)) | ||
122 | |||
123 | #undef CEIL | ||
124 | 111 | ||
125 | #ifndef ATM_SKB | 112 | #ifndef ATM_SKB |
126 | #define ATM_SKB(s) (&(s)->atm) | 113 | #define ATM_SKB(s) (&(s)->atm) |
127 | #endif | 114 | #endif |
128 | 115 | ||
116 | #define scq_virt_to_bus(scq, p) \ | ||
117 | (scq->dma + ((unsigned long)(p) - (unsigned long)(scq)->org)) | ||
129 | 118 | ||
130 | /* Function declarations ******************************************************/ | 119 | /* Function declarations */ |
131 | 120 | ||
132 | static u32 ns_read_sram(ns_dev *card, u32 sram_address); | 121 | static u32 ns_read_sram(ns_dev * card, u32 sram_address); |
133 | static void ns_write_sram(ns_dev *card, u32 sram_address, u32 *value, int count); | 122 | static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value, |
123 | int count); | ||
134 | static int __devinit ns_init_card(int i, struct pci_dev *pcidev); | 124 | static int __devinit ns_init_card(int i, struct pci_dev *pcidev); |
135 | static void __devinit ns_init_card_error(ns_dev *card, int error); | 125 | static void __devinit ns_init_card_error(ns_dev * card, int error); |
136 | static scq_info *get_scq(int size, u32 scd); | 126 | static scq_info *get_scq(ns_dev *card, int size, u32 scd); |
137 | static void free_scq(scq_info *scq, struct atm_vcc *vcc); | 127 | static void free_scq(ns_dev *card, scq_info * scq, struct atm_vcc *vcc); |
138 | static void push_rxbufs(ns_dev *, struct sk_buff *); | 128 | static void push_rxbufs(ns_dev *, struct sk_buff *); |
139 | static irqreturn_t ns_irq_handler(int irq, void *dev_id); | 129 | static irqreturn_t ns_irq_handler(int irq, void *dev_id); |
140 | static int ns_open(struct atm_vcc *vcc); | 130 | static int ns_open(struct atm_vcc *vcc); |
141 | static void ns_close(struct atm_vcc *vcc); | 131 | static void ns_close(struct atm_vcc *vcc); |
142 | static void fill_tst(ns_dev *card, int n, vc_map *vc); | 132 | static void fill_tst(ns_dev * card, int n, vc_map * vc); |
143 | static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb); | 133 | static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb); |
144 | static int push_scqe(ns_dev *card, vc_map *vc, scq_info *scq, ns_scqe *tbd, | 134 | static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd, |
145 | struct sk_buff *skb); | 135 | struct sk_buff *skb); |
146 | static void process_tsq(ns_dev *card); | 136 | static void process_tsq(ns_dev * card); |
147 | static void drain_scq(ns_dev *card, scq_info *scq, int pos); | 137 | static void drain_scq(ns_dev * card, scq_info * scq, int pos); |
148 | static void process_rsq(ns_dev *card); | 138 | static void process_rsq(ns_dev * card); |
149 | static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe); | 139 | static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe); |
150 | #ifdef NS_USE_DESTRUCTORS | 140 | #ifdef NS_USE_DESTRUCTORS |
151 | static void ns_sb_destructor(struct sk_buff *sb); | 141 | static void ns_sb_destructor(struct sk_buff *sb); |
152 | static void ns_lb_destructor(struct sk_buff *lb); | 142 | static void ns_lb_destructor(struct sk_buff *lb); |
153 | static void ns_hb_destructor(struct sk_buff *hb); | 143 | static void ns_hb_destructor(struct sk_buff *hb); |
154 | #endif /* NS_USE_DESTRUCTORS */ | 144 | #endif /* NS_USE_DESTRUCTORS */ |
155 | static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb); | 145 | static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb); |
156 | static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count); | 146 | static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count); |
157 | static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb); | 147 | static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb); |
158 | static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb); | 148 | static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb); |
159 | static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb); | 149 | static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb); |
160 | static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page); | 150 | static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page); |
161 | static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg); | 151 | static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg); |
162 | static void which_list(ns_dev *card, struct sk_buff *skb); | 152 | #ifdef EXTRA_DEBUG |
153 | static void which_list(ns_dev * card, struct sk_buff *skb); | ||
154 | #endif | ||
163 | static void ns_poll(unsigned long arg); | 155 | static void ns_poll(unsigned long arg); |
164 | static int ns_parse_mac(char *mac, unsigned char *esi); | 156 | static int ns_parse_mac(char *mac, unsigned char *esi); |
165 | static short ns_h2i(char c); | ||
166 | static void ns_phy_put(struct atm_dev *dev, unsigned char value, | 157 | static void ns_phy_put(struct atm_dev *dev, unsigned char value, |
167 | unsigned long addr); | 158 | unsigned long addr); |
168 | static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr); | 159 | static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr); |
169 | 160 | ||
170 | 161 | /* Global variables */ | |
171 | |||
172 | /* Global variables ***********************************************************/ | ||
173 | 162 | ||
174 | static struct ns_dev *cards[NS_MAX_CARDS]; | 163 | static struct ns_dev *cards[NS_MAX_CARDS]; |
175 | static unsigned num_cards; | 164 | static unsigned num_cards; |
176 | static struct atmdev_ops atm_ops = | 165 | static struct atmdev_ops atm_ops = { |
177 | { | 166 | .open = ns_open, |
178 | .open = ns_open, | 167 | .close = ns_close, |
179 | .close = ns_close, | 168 | .ioctl = ns_ioctl, |
180 | .ioctl = ns_ioctl, | 169 | .send = ns_send, |
181 | .send = ns_send, | 170 | .phy_put = ns_phy_put, |
182 | .phy_put = ns_phy_put, | 171 | .phy_get = ns_phy_get, |
183 | .phy_get = ns_phy_get, | 172 | .proc_read = ns_proc_read, |
184 | .proc_read = ns_proc_read, | 173 | .owner = THIS_MODULE, |
185 | .owner = THIS_MODULE, | ||
186 | }; | 174 | }; |
175 | |||
187 | static struct timer_list ns_timer; | 176 | static struct timer_list ns_timer; |
188 | static char *mac[NS_MAX_CARDS]; | 177 | static char *mac[NS_MAX_CARDS]; |
189 | module_param_array(mac, charp, NULL, 0); | 178 | module_param_array(mac, charp, NULL, 0); |
190 | MODULE_LICENSE("GPL"); | 179 | MODULE_LICENSE("GPL"); |
191 | 180 | ||
192 | 181 | /* Functions */ | |
193 | /* Functions*******************************************************************/ | ||
194 | 182 | ||
195 | static int __devinit nicstar_init_one(struct pci_dev *pcidev, | 183 | static int __devinit nicstar_init_one(struct pci_dev *pcidev, |
196 | const struct pci_device_id *ent) | 184 | const struct pci_device_id *ent) |
197 | { | 185 | { |
198 | static int index = -1; | 186 | static int index = -1; |
199 | unsigned int error; | 187 | unsigned int error; |
200 | 188 | ||
201 | index++; | 189 | index++; |
202 | cards[index] = NULL; | 190 | cards[index] = NULL; |
203 | 191 | ||
204 | error = ns_init_card(index, pcidev); | 192 | error = ns_init_card(index, pcidev); |
205 | if (error) { | 193 | if (error) { |
206 | cards[index--] = NULL; /* don't increment index */ | 194 | cards[index--] = NULL; /* don't increment index */ |
207 | goto err_out; | 195 | goto err_out; |
208 | } | 196 | } |
209 | 197 | ||
210 | return 0; | 198 | return 0; |
211 | err_out: | 199 | err_out: |
212 | return -ENODEV; | 200 | return -ENODEV; |
213 | } | 201 | } |
214 | 202 | ||
215 | |||
216 | |||
217 | static void __devexit nicstar_remove_one(struct pci_dev *pcidev) | 203 | static void __devexit nicstar_remove_one(struct pci_dev *pcidev) |
218 | { | 204 | { |
219 | int i, j; | 205 | int i, j; |
220 | ns_dev *card = pci_get_drvdata(pcidev); | 206 | ns_dev *card = pci_get_drvdata(pcidev); |
221 | struct sk_buff *hb; | 207 | struct sk_buff *hb; |
222 | struct sk_buff *iovb; | 208 | struct sk_buff *iovb; |
223 | struct sk_buff *lb; | 209 | struct sk_buff *lb; |
224 | struct sk_buff *sb; | 210 | struct sk_buff *sb; |
225 | 211 | ||
226 | i = card->index; | 212 | i = card->index; |
227 | 213 | ||
228 | if (cards[i] == NULL) | 214 | if (cards[i] == NULL) |
229 | return; | 215 | return; |
230 | 216 | ||
231 | if (card->atmdev->phy && card->atmdev->phy->stop) | 217 | if (card->atmdev->phy && card->atmdev->phy->stop) |
232 | card->atmdev->phy->stop(card->atmdev); | 218 | card->atmdev->phy->stop(card->atmdev); |
233 | 219 | ||
234 | /* Stop everything */ | 220 | /* Stop everything */ |
235 | writel(0x00000000, card->membase + CFG); | 221 | writel(0x00000000, card->membase + CFG); |
236 | 222 | ||
237 | /* De-register device */ | 223 | /* De-register device */ |
238 | atm_dev_deregister(card->atmdev); | 224 | atm_dev_deregister(card->atmdev); |
239 | 225 | ||
240 | /* Disable PCI device */ | 226 | /* Disable PCI device */ |
241 | pci_disable_device(pcidev); | 227 | pci_disable_device(pcidev); |
242 | 228 | ||
243 | /* Free up resources */ | 229 | /* Free up resources */ |
244 | j = 0; | 230 | j = 0; |
245 | PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); | 231 | PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count); |
246 | while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) | 232 | while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) { |
247 | { | 233 | dev_kfree_skb_any(hb); |
248 | dev_kfree_skb_any(hb); | 234 | j++; |
249 | j++; | 235 | } |
250 | } | 236 | PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); |
251 | PRINTK("nicstar%d: %d huge buffers freed.\n", i, j); | 237 | j = 0; |
252 | j = 0; | 238 | PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, |
253 | PRINTK("nicstar%d: freeing %d iovec buffers.\n", i, card->iovpool.count); | 239 | card->iovpool.count); |
254 | while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) | 240 | while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) { |
255 | { | 241 | dev_kfree_skb_any(iovb); |
256 | dev_kfree_skb_any(iovb); | 242 | j++; |
257 | j++; | 243 | } |
258 | } | 244 | PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); |
259 | PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j); | 245 | while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) |
260 | while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) | 246 | dev_kfree_skb_any(lb); |
261 | dev_kfree_skb_any(lb); | 247 | while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) |
262 | while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) | 248 | dev_kfree_skb_any(sb); |
263 | dev_kfree_skb_any(sb); | 249 | free_scq(card, card->scq0, NULL); |
264 | free_scq(card->scq0, NULL); | 250 | for (j = 0; j < NS_FRSCD_NUM; j++) { |
265 | for (j = 0; j < NS_FRSCD_NUM; j++) | 251 | if (card->scd2vc[j] != NULL) |
266 | { | 252 | free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); |
267 | if (card->scd2vc[j] != NULL) | 253 | } |
268 | free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc); | 254 | idr_remove_all(&card->idr); |
269 | } | 255 | idr_destroy(&card->idr); |
270 | kfree(card->rsq.org); | 256 | pci_free_consistent(card->pcidev, NS_RSQSIZE + NS_RSQ_ALIGNMENT, |
271 | kfree(card->tsq.org); | 257 | card->rsq.org, card->rsq.dma); |
272 | free_irq(card->pcidev->irq, card); | 258 | pci_free_consistent(card->pcidev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, |
273 | iounmap(card->membase); | 259 | card->tsq.org, card->tsq.dma); |
274 | kfree(card); | 260 | free_irq(card->pcidev->irq, card); |
261 | iounmap(card->membase); | ||
262 | kfree(card); | ||
275 | } | 263 | } |
276 | 264 | ||
277 | 265 | static struct pci_device_id nicstar_pci_tbl[] __devinitdata = { | |
278 | 266 | { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 }, | |
279 | static struct pci_device_id nicstar_pci_tbl[] __devinitdata = | ||
280 | { | ||
281 | {PCI_VENDOR_ID_IDT, PCI_DEVICE_ID_IDT_IDT77201, | ||
282 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
283 | {0,} /* terminate list */ | 267 | {0,} /* terminate list */ |
284 | }; | 268 | }; |
285 | MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl); | ||
286 | |||
287 | 269 | ||
270 | MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl); | ||
288 | 271 | ||
289 | static struct pci_driver nicstar_driver = { | 272 | static struct pci_driver nicstar_driver = { |
290 | .name = "nicstar", | 273 | .name = "nicstar", |
291 | .id_table = nicstar_pci_tbl, | 274 | .id_table = nicstar_pci_tbl, |
292 | .probe = nicstar_init_one, | 275 | .probe = nicstar_init_one, |
293 | .remove = __devexit_p(nicstar_remove_one), | 276 | .remove = __devexit_p(nicstar_remove_one), |
294 | }; | 277 | }; |
295 | 278 | ||
296 | |||
297 | |||
298 | static int __init nicstar_init(void) | 279 | static int __init nicstar_init(void) |
299 | { | 280 | { |
300 | unsigned error = 0; /* Initialized to remove compile warning */ | 281 | unsigned error = 0; /* Initialized to remove compile warning */ |
282 | |||
283 | XPRINTK("nicstar: nicstar_init() called.\n"); | ||
301 | 284 | ||
302 | XPRINTK("nicstar: nicstar_init() called.\n"); | 285 | error = pci_register_driver(&nicstar_driver); |
303 | 286 | ||
304 | error = pci_register_driver(&nicstar_driver); | 287 | TXPRINTK("nicstar: TX debug enabled.\n"); |
305 | 288 | RXPRINTK("nicstar: RX debug enabled.\n"); | |
306 | TXPRINTK("nicstar: TX debug enabled.\n"); | 289 | PRINTK("nicstar: General debug enabled.\n"); |
307 | RXPRINTK("nicstar: RX debug enabled.\n"); | ||
308 | PRINTK("nicstar: General debug enabled.\n"); | ||
309 | #ifdef PHY_LOOPBACK | 290 | #ifdef PHY_LOOPBACK |
310 | printk("nicstar: using PHY loopback.\n"); | 291 | printk("nicstar: using PHY loopback.\n"); |
311 | #endif /* PHY_LOOPBACK */ | 292 | #endif /* PHY_LOOPBACK */ |
312 | XPRINTK("nicstar: nicstar_init() returned.\n"); | 293 | XPRINTK("nicstar: nicstar_init() returned.\n"); |
313 | |||
314 | if (!error) { | ||
315 | init_timer(&ns_timer); | ||
316 | ns_timer.expires = jiffies + NS_POLL_PERIOD; | ||
317 | ns_timer.data = 0UL; | ||
318 | ns_timer.function = ns_poll; | ||
319 | add_timer(&ns_timer); | ||
320 | } | ||
321 | |||
322 | return error; | ||
323 | } | ||
324 | 294 | ||
295 | if (!error) { | ||
296 | init_timer(&ns_timer); | ||
297 | ns_timer.expires = jiffies + NS_POLL_PERIOD; | ||
298 | ns_timer.data = 0UL; | ||
299 | ns_timer.function = ns_poll; | ||
300 | add_timer(&ns_timer); | ||
301 | } | ||
325 | 302 | ||
303 | return error; | ||
304 | } | ||
326 | 305 | ||
327 | static void __exit nicstar_cleanup(void) | 306 | static void __exit nicstar_cleanup(void) |
328 | { | 307 | { |
329 | XPRINTK("nicstar: nicstar_cleanup() called.\n"); | 308 | XPRINTK("nicstar: nicstar_cleanup() called.\n"); |
330 | 309 | ||
331 | del_timer(&ns_timer); | 310 | del_timer(&ns_timer); |
332 | 311 | ||
333 | pci_unregister_driver(&nicstar_driver); | 312 | pci_unregister_driver(&nicstar_driver); |
334 | 313 | ||
335 | XPRINTK("nicstar: nicstar_cleanup() returned.\n"); | 314 | XPRINTK("nicstar: nicstar_cleanup() returned.\n"); |
336 | } | 315 | } |
337 | 316 | ||
338 | 317 | static u32 ns_read_sram(ns_dev * card, u32 sram_address) | |
339 | |||
340 | static u32 ns_read_sram(ns_dev *card, u32 sram_address) | ||
341 | { | 318 | { |
342 | unsigned long flags; | 319 | unsigned long flags; |
343 | u32 data; | 320 | u32 data; |
344 | sram_address <<= 2; | 321 | sram_address <<= 2; |
345 | sram_address &= 0x0007FFFC; /* address must be dword aligned */ | 322 | sram_address &= 0x0007FFFC; /* address must be dword aligned */ |
346 | sram_address |= 0x50000000; /* SRAM read command */ | 323 | sram_address |= 0x50000000; /* SRAM read command */ |
347 | spin_lock_irqsave(&card->res_lock, flags); | 324 | spin_lock_irqsave(&card->res_lock, flags); |
348 | while (CMD_BUSY(card)); | 325 | while (CMD_BUSY(card)) ; |
349 | writel(sram_address, card->membase + CMD); | 326 | writel(sram_address, card->membase + CMD); |
350 | while (CMD_BUSY(card)); | 327 | while (CMD_BUSY(card)) ; |
351 | data = readl(card->membase + DR0); | 328 | data = readl(card->membase + DR0); |
352 | spin_unlock_irqrestore(&card->res_lock, flags); | 329 | spin_unlock_irqrestore(&card->res_lock, flags); |
353 | return data; | 330 | return data; |
354 | } | 331 | } |
355 | 332 | ||
356 | 333 | static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value, | |
357 | 334 | int count) | |
358 | static void ns_write_sram(ns_dev *card, u32 sram_address, u32 *value, int count) | ||
359 | { | 335 | { |
360 | unsigned long flags; | 336 | unsigned long flags; |
361 | int i, c; | 337 | int i, c; |
362 | count--; /* count range now is 0..3 instead of 1..4 */ | 338 | count--; /* count range now is 0..3 instead of 1..4 */ |
363 | c = count; | 339 | c = count; |
364 | c <<= 2; /* to use increments of 4 */ | 340 | c <<= 2; /* to use increments of 4 */ |
365 | spin_lock_irqsave(&card->res_lock, flags); | 341 | spin_lock_irqsave(&card->res_lock, flags); |
366 | while (CMD_BUSY(card)); | 342 | while (CMD_BUSY(card)) ; |
367 | for (i = 0; i <= c; i += 4) | 343 | for (i = 0; i <= c; i += 4) |
368 | writel(*(value++), card->membase + i); | 344 | writel(*(value++), card->membase + i); |
369 | /* Note: DR# registers are the first 4 dwords in nicstar's memspace, | 345 | /* Note: DR# registers are the first 4 dwords in nicstar's memspace, |
370 | so card->membase + DR0 == card->membase */ | 346 | so card->membase + DR0 == card->membase */ |
371 | sram_address <<= 2; | 347 | sram_address <<= 2; |
372 | sram_address &= 0x0007FFFC; | 348 | sram_address &= 0x0007FFFC; |
373 | sram_address |= (0x40000000 | count); | 349 | sram_address |= (0x40000000 | count); |
374 | writel(sram_address, card->membase + CMD); | 350 | writel(sram_address, card->membase + CMD); |
375 | spin_unlock_irqrestore(&card->res_lock, flags); | 351 | spin_unlock_irqrestore(&card->res_lock, flags); |
376 | } | 352 | } |
377 | 353 | ||
378 | |||
379 | static int __devinit ns_init_card(int i, struct pci_dev *pcidev) | 354 | static int __devinit ns_init_card(int i, struct pci_dev *pcidev) |
380 | { | 355 | { |
381 | int j; | 356 | int j; |
382 | struct ns_dev *card = NULL; | 357 | struct ns_dev *card = NULL; |
383 | unsigned char pci_latency; | 358 | unsigned char pci_latency; |
384 | unsigned error; | 359 | unsigned error; |
385 | u32 data; | 360 | u32 data; |
386 | u32 u32d[4]; | 361 | u32 u32d[4]; |
387 | u32 ns_cfg_rctsize; | 362 | u32 ns_cfg_rctsize; |
388 | int bcount; | 363 | int bcount; |
389 | unsigned long membase; | 364 | unsigned long membase; |
390 | 365 | ||
391 | error = 0; | 366 | error = 0; |
392 | 367 | ||
393 | if (pci_enable_device(pcidev)) | 368 | if (pci_enable_device(pcidev)) { |
394 | { | 369 | printk("nicstar%d: can't enable PCI device\n", i); |
395 | printk("nicstar%d: can't enable PCI device\n", i); | 370 | error = 2; |
396 | error = 2; | 371 | ns_init_card_error(card, error); |
397 | ns_init_card_error(card, error); | 372 | return error; |
398 | return error; | 373 | } |
399 | } | 374 | if ((pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)) != 0) || |
400 | 375 | (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)) != 0)) { | |
401 | if ((card = kmalloc(sizeof(ns_dev), GFP_KERNEL)) == NULL) | 376 | printk(KERN_WARNING |
402 | { | 377 | "nicstar%d: No suitable DMA available.\n", i); |
403 | printk("nicstar%d: can't allocate memory for device structure.\n", i); | 378 | error = 2; |
404 | error = 2; | 379 | ns_init_card_error(card, error); |
405 | ns_init_card_error(card, error); | 380 | return error; |
406 | return error; | 381 | } |
407 | } | 382 | |
408 | cards[i] = card; | 383 | if ((card = kmalloc(sizeof(ns_dev), GFP_KERNEL)) == NULL) { |
409 | spin_lock_init(&card->int_lock); | 384 | printk |
410 | spin_lock_init(&card->res_lock); | 385 | ("nicstar%d: can't allocate memory for device structure.\n", |
411 | 386 | i); | |
412 | pci_set_drvdata(pcidev, card); | 387 | error = 2; |
413 | 388 | ns_init_card_error(card, error); | |
414 | card->index = i; | 389 | return error; |
415 | card->atmdev = NULL; | 390 | } |
416 | card->pcidev = pcidev; | 391 | cards[i] = card; |
417 | membase = pci_resource_start(pcidev, 1); | 392 | spin_lock_init(&card->int_lock); |
418 | card->membase = ioremap(membase, NS_IOREMAP_SIZE); | 393 | spin_lock_init(&card->res_lock); |
419 | if (!card->membase) | 394 | |
420 | { | 395 | pci_set_drvdata(pcidev, card); |
421 | printk("nicstar%d: can't ioremap() membase.\n",i); | 396 | |
422 | error = 3; | 397 | card->index = i; |
423 | ns_init_card_error(card, error); | 398 | card->atmdev = NULL; |
424 | return error; | 399 | card->pcidev = pcidev; |
425 | } | 400 | membase = pci_resource_start(pcidev, 1); |
426 | PRINTK("nicstar%d: membase at 0x%x.\n", i, card->membase); | 401 | card->membase = ioremap(membase, NS_IOREMAP_SIZE); |
427 | 402 | if (!card->membase) { | |
428 | pci_set_master(pcidev); | 403 | printk("nicstar%d: can't ioremap() membase.\n", i); |
429 | 404 | error = 3; | |
430 | if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) | 405 | ns_init_card_error(card, error); |
431 | { | 406 | return error; |
432 | printk("nicstar%d: can't read PCI latency timer.\n", i); | 407 | } |
433 | error = 6; | 408 | PRINTK("nicstar%d: membase at 0x%p.\n", i, card->membase); |
434 | ns_init_card_error(card, error); | 409 | |
435 | return error; | 410 | pci_set_master(pcidev); |
436 | } | 411 | |
412 | if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) { | ||
413 | printk("nicstar%d: can't read PCI latency timer.\n", i); | ||
414 | error = 6; | ||
415 | ns_init_card_error(card, error); | ||
416 | return error; | ||
417 | } | ||
437 | #ifdef NS_PCI_LATENCY | 418 | #ifdef NS_PCI_LATENCY |
438 | if (pci_latency < NS_PCI_LATENCY) | 419 | if (pci_latency < NS_PCI_LATENCY) { |
439 | { | 420 | PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i, |
440 | PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i, NS_PCI_LATENCY); | 421 | NS_PCI_LATENCY); |
441 | for (j = 1; j < 4; j++) | 422 | for (j = 1; j < 4; j++) { |
442 | { | 423 | if (pci_write_config_byte |
443 | if (pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0) | 424 | (pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0) |
444 | break; | 425 | break; |
445 | } | 426 | } |
446 | if (j == 4) | 427 | if (j == 4) { |
447 | { | 428 | printk |
448 | printk("nicstar%d: can't set PCI latency timer to %d.\n", i, NS_PCI_LATENCY); | 429 | ("nicstar%d: can't set PCI latency timer to %d.\n", |
449 | error = 7; | 430 | i, NS_PCI_LATENCY); |
450 | ns_init_card_error(card, error); | 431 | error = 7; |
451 | return error; | 432 | ns_init_card_error(card, error); |
452 | } | 433 | return error; |
453 | } | 434 | } |
435 | } | ||
454 | #endif /* NS_PCI_LATENCY */ | 436 | #endif /* NS_PCI_LATENCY */ |
455 | 437 | ||
456 | /* Clear timer overflow */ | 438 | /* Clear timer overflow */ |
457 | data = readl(card->membase + STAT); | 439 | data = readl(card->membase + STAT); |
458 | if (data & NS_STAT_TMROF) | 440 | if (data & NS_STAT_TMROF) |
459 | writel(NS_STAT_TMROF, card->membase + STAT); | 441 | writel(NS_STAT_TMROF, card->membase + STAT); |
460 | 442 | ||
461 | /* Software reset */ | 443 | /* Software reset */ |
462 | writel(NS_CFG_SWRST, card->membase + CFG); | 444 | writel(NS_CFG_SWRST, card->membase + CFG); |
463 | NS_DELAY; | 445 | NS_DELAY; |
464 | writel(0x00000000, card->membase + CFG); | 446 | writel(0x00000000, card->membase + CFG); |
465 | 447 | ||
466 | /* PHY reset */ | 448 | /* PHY reset */ |
467 | writel(0x00000008, card->membase + GP); | 449 | writel(0x00000008, card->membase + GP); |
468 | NS_DELAY; | 450 | NS_DELAY; |
469 | writel(0x00000001, card->membase + GP); | 451 | writel(0x00000001, card->membase + GP); |
470 | NS_DELAY; | 452 | NS_DELAY; |
471 | while (CMD_BUSY(card)); | 453 | while (CMD_BUSY(card)) ; |
472 | writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD); /* Sync UTOPIA with SAR clock */ | 454 | writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD); /* Sync UTOPIA with SAR clock */ |
473 | NS_DELAY; | 455 | NS_DELAY; |
474 | 456 | ||
475 | /* Detect PHY type */ | 457 | /* Detect PHY type */ |
476 | while (CMD_BUSY(card)); | 458 | while (CMD_BUSY(card)) ; |
477 | writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD); | 459 | writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD); |
478 | while (CMD_BUSY(card)); | 460 | while (CMD_BUSY(card)) ; |
479 | data = readl(card->membase + DR0); | 461 | data = readl(card->membase + DR0); |
480 | switch(data) { | 462 | switch (data) { |
481 | case 0x00000009: | 463 | case 0x00000009: |
482 | printk("nicstar%d: PHY seems to be 25 Mbps.\n", i); | 464 | printk("nicstar%d: PHY seems to be 25 Mbps.\n", i); |
483 | card->max_pcr = ATM_25_PCR; | 465 | card->max_pcr = ATM_25_PCR; |
484 | while(CMD_BUSY(card)); | 466 | while (CMD_BUSY(card)) ; |
485 | writel(0x00000008, card->membase + DR0); | 467 | writel(0x00000008, card->membase + DR0); |
486 | writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD); | 468 | writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD); |
487 | /* Clear an eventual pending interrupt */ | 469 | /* Clear an eventual pending interrupt */ |
488 | writel(NS_STAT_SFBQF, card->membase + STAT); | 470 | writel(NS_STAT_SFBQF, card->membase + STAT); |
489 | #ifdef PHY_LOOPBACK | 471 | #ifdef PHY_LOOPBACK |
490 | while(CMD_BUSY(card)); | 472 | while (CMD_BUSY(card)) ; |
491 | writel(0x00000022, card->membase + DR0); | 473 | writel(0x00000022, card->membase + DR0); |
492 | writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD); | 474 | writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD); |
493 | #endif /* PHY_LOOPBACK */ | 475 | #endif /* PHY_LOOPBACK */ |
494 | break; | 476 | break; |
495 | case 0x00000030: | 477 | case 0x00000030: |
496 | case 0x00000031: | 478 | case 0x00000031: |
497 | printk("nicstar%d: PHY seems to be 155 Mbps.\n", i); | 479 | printk("nicstar%d: PHY seems to be 155 Mbps.\n", i); |
498 | card->max_pcr = ATM_OC3_PCR; | 480 | card->max_pcr = ATM_OC3_PCR; |
499 | #ifdef PHY_LOOPBACK | 481 | #ifdef PHY_LOOPBACK |
500 | while(CMD_BUSY(card)); | 482 | while (CMD_BUSY(card)) ; |
501 | writel(0x00000002, card->membase + DR0); | 483 | writel(0x00000002, card->membase + DR0); |
502 | writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD); | 484 | writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD); |
503 | #endif /* PHY_LOOPBACK */ | 485 | #endif /* PHY_LOOPBACK */ |
504 | break; | 486 | break; |
505 | default: | 487 | default: |
506 | printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data); | 488 | printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data); |
507 | error = 8; | 489 | error = 8; |
508 | ns_init_card_error(card, error); | 490 | ns_init_card_error(card, error); |
509 | return error; | 491 | return error; |
510 | } | 492 | } |
511 | writel(0x00000000, card->membase + GP); | 493 | writel(0x00000000, card->membase + GP); |
512 | 494 | ||
513 | /* Determine SRAM size */ | 495 | /* Determine SRAM size */ |
514 | data = 0x76543210; | 496 | data = 0x76543210; |
515 | ns_write_sram(card, 0x1C003, &data, 1); | 497 | ns_write_sram(card, 0x1C003, &data, 1); |
516 | data = 0x89ABCDEF; | 498 | data = 0x89ABCDEF; |
517 | ns_write_sram(card, 0x14003, &data, 1); | 499 | ns_write_sram(card, 0x14003, &data, 1); |
518 | if (ns_read_sram(card, 0x14003) == 0x89ABCDEF && | 500 | if (ns_read_sram(card, 0x14003) == 0x89ABCDEF && |
519 | ns_read_sram(card, 0x1C003) == 0x76543210) | 501 | ns_read_sram(card, 0x1C003) == 0x76543210) |
520 | card->sram_size = 128; | 502 | card->sram_size = 128; |
521 | else | 503 | else |
522 | card->sram_size = 32; | 504 | card->sram_size = 32; |
523 | PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size); | 505 | PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size); |
524 | 506 | ||
525 | card->rct_size = NS_MAX_RCTSIZE; | 507 | card->rct_size = NS_MAX_RCTSIZE; |
526 | 508 | ||
527 | #if (NS_MAX_RCTSIZE == 4096) | 509 | #if (NS_MAX_RCTSIZE == 4096) |
528 | if (card->sram_size == 128) | 510 | if (card->sram_size == 128) |
529 | printk("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n", i); | 511 | printk |
512 | ("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n", | ||
513 | i); | ||
530 | #elif (NS_MAX_RCTSIZE == 16384) | 514 | #elif (NS_MAX_RCTSIZE == 16384) |
531 | if (card->sram_size == 32) | 515 | if (card->sram_size == 32) { |
532 | { | 516 | printk |
533 | printk("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n", i); | 517 | ("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n", |
534 | card->rct_size = 4096; | 518 | i); |
535 | } | 519 | card->rct_size = 4096; |
520 | } | ||
536 | #else | 521 | #else |
537 | #error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c | 522 | #error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c |
538 | #endif | 523 | #endif |
539 | 524 | ||
540 | card->vpibits = NS_VPIBITS; | 525 | card->vpibits = NS_VPIBITS; |
541 | if (card->rct_size == 4096) | 526 | if (card->rct_size == 4096) |
542 | card->vcibits = 12 - NS_VPIBITS; | 527 | card->vcibits = 12 - NS_VPIBITS; |
543 | else /* card->rct_size == 16384 */ | 528 | else /* card->rct_size == 16384 */ |
544 | card->vcibits = 14 - NS_VPIBITS; | 529 | card->vcibits = 14 - NS_VPIBITS; |
545 | 530 | ||
546 | /* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */ | 531 | /* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */ |
547 | if (mac[i] == NULL) | 532 | if (mac[i] == NULL) |
548 | nicstar_init_eprom(card->membase); | 533 | nicstar_init_eprom(card->membase); |
549 | 534 | ||
550 | /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ | 535 | /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ |
551 | writel(0x00000000, card->membase + VPM); | 536 | writel(0x00000000, card->membase + VPM); |
552 | 537 | ||
553 | /* Initialize TSQ */ | 538 | /* Initialize TSQ */ |
554 | card->tsq.org = kmalloc(NS_TSQSIZE + NS_TSQ_ALIGNMENT, GFP_KERNEL); | 539 | card->tsq.org = pci_alloc_consistent(card->pcidev, |
555 | if (card->tsq.org == NULL) | 540 | NS_TSQSIZE + NS_TSQ_ALIGNMENT, |
556 | { | 541 | &card->tsq.dma); |
557 | printk("nicstar%d: can't allocate TSQ.\n", i); | 542 | if (card->tsq.org == NULL) { |
558 | error = 10; | 543 | printk("nicstar%d: can't allocate TSQ.\n", i); |
559 | ns_init_card_error(card, error); | 544 | error = 10; |
560 | return error; | 545 | ns_init_card_error(card, error); |
561 | } | 546 | return error; |
562 | card->tsq.base = (ns_tsi *) ALIGN_ADDRESS(card->tsq.org, NS_TSQ_ALIGNMENT); | 547 | } |
563 | card->tsq.next = card->tsq.base; | 548 | card->tsq.base = PTR_ALIGN(card->tsq.org, NS_TSQ_ALIGNMENT); |
564 | card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1); | 549 | card->tsq.next = card->tsq.base; |
565 | for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++) | 550 | card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1); |
566 | ns_tsi_init(card->tsq.base + j); | 551 | for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++) |
567 | writel(0x00000000, card->membase + TSQH); | 552 | ns_tsi_init(card->tsq.base + j); |
568 | writel((u32) virt_to_bus(card->tsq.base), card->membase + TSQB); | 553 | writel(0x00000000, card->membase + TSQH); |
569 | PRINTK("nicstar%d: TSQ base at 0x%x 0x%x 0x%x.\n", i, (u32) card->tsq.base, | 554 | writel(ALIGN(card->tsq.dma, NS_TSQ_ALIGNMENT), card->membase + TSQB); |
570 | (u32) virt_to_bus(card->tsq.base), readl(card->membase + TSQB)); | 555 | PRINTK("nicstar%d: TSQ base at 0x%p.\n", i, card->tsq.base); |
571 | 556 | ||
572 | /* Initialize RSQ */ | 557 | /* Initialize RSQ */ |
573 | card->rsq.org = kmalloc(NS_RSQSIZE + NS_RSQ_ALIGNMENT, GFP_KERNEL); | 558 | card->rsq.org = pci_alloc_consistent(card->pcidev, |
574 | if (card->rsq.org == NULL) | 559 | NS_RSQSIZE + NS_RSQ_ALIGNMENT, |
575 | { | 560 | &card->rsq.dma); |
576 | printk("nicstar%d: can't allocate RSQ.\n", i); | 561 | if (card->rsq.org == NULL) { |
577 | error = 11; | 562 | printk("nicstar%d: can't allocate RSQ.\n", i); |
578 | ns_init_card_error(card, error); | 563 | error = 11; |
579 | return error; | 564 | ns_init_card_error(card, error); |
580 | } | 565 | return error; |
581 | card->rsq.base = (ns_rsqe *) ALIGN_ADDRESS(card->rsq.org, NS_RSQ_ALIGNMENT); | 566 | } |
582 | card->rsq.next = card->rsq.base; | 567 | card->rsq.base = PTR_ALIGN(card->rsq.org, NS_RSQ_ALIGNMENT); |
583 | card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1); | 568 | card->rsq.next = card->rsq.base; |
584 | for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++) | 569 | card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1); |
585 | ns_rsqe_init(card->rsq.base + j); | 570 | for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++) |
586 | writel(0x00000000, card->membase + RSQH); | 571 | ns_rsqe_init(card->rsq.base + j); |
587 | writel((u32) virt_to_bus(card->rsq.base), card->membase + RSQB); | 572 | writel(0x00000000, card->membase + RSQH); |
588 | PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base); | 573 | writel(ALIGN(card->rsq.dma, NS_RSQ_ALIGNMENT), card->membase + RSQB); |
589 | 574 | PRINTK("nicstar%d: RSQ base at 0x%p.\n", i, card->rsq.base); | |
590 | /* Initialize SCQ0, the only VBR SCQ used */ | 575 | |
591 | card->scq1 = NULL; | 576 | /* Initialize SCQ0, the only VBR SCQ used */ |
592 | card->scq2 = NULL; | 577 | card->scq1 = NULL; |
593 | card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); | 578 | card->scq2 = NULL; |
594 | if (card->scq0 == NULL) | 579 | card->scq0 = get_scq(card, VBR_SCQSIZE, NS_VRSCD0); |
595 | { | 580 | if (card->scq0 == NULL) { |
596 | printk("nicstar%d: can't get SCQ0.\n", i); | 581 | printk("nicstar%d: can't get SCQ0.\n", i); |
597 | error = 12; | 582 | error = 12; |
598 | ns_init_card_error(card, error); | 583 | ns_init_card_error(card, error); |
599 | return error; | 584 | return error; |
600 | } | 585 | } |
601 | u32d[0] = (u32) virt_to_bus(card->scq0->base); | 586 | u32d[0] = scq_virt_to_bus(card->scq0, card->scq0->base); |
602 | u32d[1] = (u32) 0x00000000; | 587 | u32d[1] = (u32) 0x00000000; |
603 | u32d[2] = (u32) 0xffffffff; | 588 | u32d[2] = (u32) 0xffffffff; |
604 | u32d[3] = (u32) 0x00000000; | 589 | u32d[3] = (u32) 0x00000000; |
605 | ns_write_sram(card, NS_VRSCD0, u32d, 4); | 590 | ns_write_sram(card, NS_VRSCD0, u32d, 4); |
606 | ns_write_sram(card, NS_VRSCD1, u32d, 4); /* These last two won't be used */ | 591 | ns_write_sram(card, NS_VRSCD1, u32d, 4); /* These last two won't be used */ |
607 | ns_write_sram(card, NS_VRSCD2, u32d, 4); /* but are initialized, just in case... */ | 592 | ns_write_sram(card, NS_VRSCD2, u32d, 4); /* but are initialized, just in case... */ |
608 | card->scq0->scd = NS_VRSCD0; | 593 | card->scq0->scd = NS_VRSCD0; |
609 | PRINTK("nicstar%d: VBR-SCQ0 base at 0x%x.\n", i, (u32) card->scq0->base); | 594 | PRINTK("nicstar%d: VBR-SCQ0 base at 0x%p.\n", i, card->scq0->base); |
610 | 595 | ||
611 | /* Initialize TSTs */ | 596 | /* Initialize TSTs */ |
612 | card->tst_addr = NS_TST0; | 597 | card->tst_addr = NS_TST0; |
613 | card->tst_free_entries = NS_TST_NUM_ENTRIES; | 598 | card->tst_free_entries = NS_TST_NUM_ENTRIES; |
614 | data = NS_TST_OPCODE_VARIABLE; | 599 | data = NS_TST_OPCODE_VARIABLE; |
615 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) | 600 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) |
616 | ns_write_sram(card, NS_TST0 + j, &data, 1); | 601 | ns_write_sram(card, NS_TST0 + j, &data, 1); |
617 | data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0); | 602 | data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0); |
618 | ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1); | 603 | ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1); |
619 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) | 604 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) |
620 | ns_write_sram(card, NS_TST1 + j, &data, 1); | 605 | ns_write_sram(card, NS_TST1 + j, &data, 1); |
621 | data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1); | 606 | data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1); |
622 | ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1); | 607 | ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1); |
623 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) | 608 | for (j = 0; j < NS_TST_NUM_ENTRIES; j++) |
624 | card->tste2vc[j] = NULL; | 609 | card->tste2vc[j] = NULL; |
625 | writel(NS_TST0 << 2, card->membase + TSTB); | 610 | writel(NS_TST0 << 2, card->membase + TSTB); |
626 | 611 | ||
627 | 612 | /* Initialize RCT. AAL type is set on opening the VC. */ | |
628 | /* Initialize RCT. AAL type is set on opening the VC. */ | ||
629 | #ifdef RCQ_SUPPORT | 613 | #ifdef RCQ_SUPPORT |
630 | u32d[0] = NS_RCTE_RAWCELLINTEN; | 614 | u32d[0] = NS_RCTE_RAWCELLINTEN; |
631 | #else | 615 | #else |
632 | u32d[0] = 0x00000000; | 616 | u32d[0] = 0x00000000; |
633 | #endif /* RCQ_SUPPORT */ | 617 | #endif /* RCQ_SUPPORT */ |
634 | u32d[1] = 0x00000000; | 618 | u32d[1] = 0x00000000; |
635 | u32d[2] = 0x00000000; | 619 | u32d[2] = 0x00000000; |
636 | u32d[3] = 0xFFFFFFFF; | 620 | u32d[3] = 0xFFFFFFFF; |
637 | for (j = 0; j < card->rct_size; j++) | 621 | for (j = 0; j < card->rct_size; j++) |
638 | ns_write_sram(card, j * 4, u32d, 4); | 622 | ns_write_sram(card, j * 4, u32d, 4); |
639 | 623 | ||
640 | memset(card->vcmap, 0, NS_MAX_RCTSIZE * sizeof(vc_map)); | 624 | memset(card->vcmap, 0, NS_MAX_RCTSIZE * sizeof(vc_map)); |
641 | 625 | ||
642 | for (j = 0; j < NS_FRSCD_NUM; j++) | 626 | for (j = 0; j < NS_FRSCD_NUM; j++) |
643 | card->scd2vc[j] = NULL; | 627 | card->scd2vc[j] = NULL; |
644 | 628 | ||
645 | /* Initialize buffer levels */ | 629 | /* Initialize buffer levels */ |
646 | card->sbnr.min = MIN_SB; | 630 | card->sbnr.min = MIN_SB; |
647 | card->sbnr.init = NUM_SB; | 631 | card->sbnr.init = NUM_SB; |
648 | card->sbnr.max = MAX_SB; | 632 | card->sbnr.max = MAX_SB; |
649 | card->lbnr.min = MIN_LB; | 633 | card->lbnr.min = MIN_LB; |
650 | card->lbnr.init = NUM_LB; | 634 | card->lbnr.init = NUM_LB; |
651 | card->lbnr.max = MAX_LB; | 635 | card->lbnr.max = MAX_LB; |
652 | card->iovnr.min = MIN_IOVB; | 636 | card->iovnr.min = MIN_IOVB; |
653 | card->iovnr.init = NUM_IOVB; | 637 | card->iovnr.init = NUM_IOVB; |
654 | card->iovnr.max = MAX_IOVB; | 638 | card->iovnr.max = MAX_IOVB; |
655 | card->hbnr.min = MIN_HB; | 639 | card->hbnr.min = MIN_HB; |
656 | card->hbnr.init = NUM_HB; | 640 | card->hbnr.init = NUM_HB; |
657 | card->hbnr.max = MAX_HB; | 641 | card->hbnr.max = MAX_HB; |
658 | 642 | ||
659 | card->sm_handle = 0x00000000; | 643 | card->sm_handle = 0x00000000; |
660 | card->sm_addr = 0x00000000; | 644 | card->sm_addr = 0x00000000; |
661 | card->lg_handle = 0x00000000; | 645 | card->lg_handle = 0x00000000; |
662 | card->lg_addr = 0x00000000; | 646 | card->lg_addr = 0x00000000; |
663 | 647 | ||
664 | card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */ | 648 | card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */ |
665 | 649 | ||
666 | /* Pre-allocate some huge buffers */ | 650 | idr_init(&card->idr); |
667 | skb_queue_head_init(&card->hbpool.queue); | 651 | |
668 | card->hbpool.count = 0; | 652 | /* Pre-allocate some huge buffers */ |
669 | for (j = 0; j < NUM_HB; j++) | 653 | skb_queue_head_init(&card->hbpool.queue); |
670 | { | 654 | card->hbpool.count = 0; |
671 | struct sk_buff *hb; | 655 | for (j = 0; j < NUM_HB; j++) { |
672 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); | 656 | struct sk_buff *hb; |
673 | if (hb == NULL) | 657 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); |
674 | { | 658 | if (hb == NULL) { |
675 | printk("nicstar%d: can't allocate %dth of %d huge buffers.\n", | 659 | printk |
676 | i, j, NUM_HB); | 660 | ("nicstar%d: can't allocate %dth of %d huge buffers.\n", |
677 | error = 13; | 661 | i, j, NUM_HB); |
678 | ns_init_card_error(card, error); | 662 | error = 13; |
679 | return error; | 663 | ns_init_card_error(card, error); |
680 | } | 664 | return error; |
681 | NS_SKB_CB(hb)->buf_type = BUF_NONE; | 665 | } |
682 | skb_queue_tail(&card->hbpool.queue, hb); | 666 | NS_PRV_BUFTYPE(hb) = BUF_NONE; |
683 | card->hbpool.count++; | 667 | skb_queue_tail(&card->hbpool.queue, hb); |
684 | } | 668 | card->hbpool.count++; |
685 | 669 | } | |
686 | 670 | ||
687 | /* Allocate large buffers */ | 671 | /* Allocate large buffers */ |
688 | skb_queue_head_init(&card->lbpool.queue); | 672 | skb_queue_head_init(&card->lbpool.queue); |
689 | card->lbpool.count = 0; /* Not used */ | 673 | card->lbpool.count = 0; /* Not used */ |
690 | for (j = 0; j < NUM_LB; j++) | 674 | for (j = 0; j < NUM_LB; j++) { |
691 | { | 675 | struct sk_buff *lb; |
692 | struct sk_buff *lb; | 676 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); |
693 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); | 677 | if (lb == NULL) { |
694 | if (lb == NULL) | 678 | printk |
695 | { | 679 | ("nicstar%d: can't allocate %dth of %d large buffers.\n", |
696 | printk("nicstar%d: can't allocate %dth of %d large buffers.\n", | 680 | i, j, NUM_LB); |
697 | i, j, NUM_LB); | 681 | error = 14; |
698 | error = 14; | 682 | ns_init_card_error(card, error); |
699 | ns_init_card_error(card, error); | 683 | return error; |
700 | return error; | 684 | } |
701 | } | 685 | NS_PRV_BUFTYPE(lb) = BUF_LG; |
702 | NS_SKB_CB(lb)->buf_type = BUF_LG; | 686 | skb_queue_tail(&card->lbpool.queue, lb); |
703 | skb_queue_tail(&card->lbpool.queue, lb); | 687 | skb_reserve(lb, NS_SMBUFSIZE); |
704 | skb_reserve(lb, NS_SMBUFSIZE); | 688 | push_rxbufs(card, lb); |
705 | push_rxbufs(card, lb); | 689 | /* Due to the implementation of push_rxbufs() this is 1, not 0 */ |
706 | /* Due to the implementation of push_rxbufs() this is 1, not 0 */ | 690 | if (j == 1) { |
707 | if (j == 1) | 691 | card->rcbuf = lb; |
708 | { | 692 | card->rawcell = (struct ns_rcqe *) lb->data; |
709 | card->rcbuf = lb; | 693 | card->rawch = NS_PRV_DMA(lb); |
710 | card->rawch = (u32) virt_to_bus(lb->data); | 694 | } |
711 | } | 695 | } |
712 | } | 696 | /* Test for strange behaviour which leads to crashes */ |
713 | /* Test for strange behaviour which leads to crashes */ | 697 | if ((bcount = |
714 | if ((bcount = ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min) | 698 | ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min) { |
715 | { | 699 | printk |
716 | printk("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n", | 700 | ("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n", |
717 | i, j, bcount); | 701 | i, j, bcount); |
718 | error = 14; | 702 | error = 14; |
719 | ns_init_card_error(card, error); | 703 | ns_init_card_error(card, error); |
720 | return error; | 704 | return error; |
721 | } | 705 | } |
722 | 706 | ||
723 | 707 | /* Allocate small buffers */ | |
724 | /* Allocate small buffers */ | 708 | skb_queue_head_init(&card->sbpool.queue); |
725 | skb_queue_head_init(&card->sbpool.queue); | 709 | card->sbpool.count = 0; /* Not used */ |
726 | card->sbpool.count = 0; /* Not used */ | 710 | for (j = 0; j < NUM_SB; j++) { |
727 | for (j = 0; j < NUM_SB; j++) | 711 | struct sk_buff *sb; |
728 | { | 712 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); |
729 | struct sk_buff *sb; | 713 | if (sb == NULL) { |
730 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); | 714 | printk |
731 | if (sb == NULL) | 715 | ("nicstar%d: can't allocate %dth of %d small buffers.\n", |
732 | { | 716 | i, j, NUM_SB); |
733 | printk("nicstar%d: can't allocate %dth of %d small buffers.\n", | 717 | error = 15; |
734 | i, j, NUM_SB); | 718 | ns_init_card_error(card, error); |
735 | error = 15; | 719 | return error; |
736 | ns_init_card_error(card, error); | 720 | } |
737 | return error; | 721 | NS_PRV_BUFTYPE(sb) = BUF_SM; |
738 | } | 722 | skb_queue_tail(&card->sbpool.queue, sb); |
739 | NS_SKB_CB(sb)->buf_type = BUF_SM; | 723 | skb_reserve(sb, NS_AAL0_HEADER); |
740 | skb_queue_tail(&card->sbpool.queue, sb); | 724 | push_rxbufs(card, sb); |
741 | skb_reserve(sb, NS_AAL0_HEADER); | 725 | } |
742 | push_rxbufs(card, sb); | 726 | /* Test for strange behaviour which leads to crashes */ |
743 | } | 727 | if ((bcount = |
744 | /* Test for strange behaviour which leads to crashes */ | 728 | ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) { |
745 | if ((bcount = ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) | 729 | printk |
746 | { | 730 | ("nicstar%d: Strange... Just allocated %d small buffers and sfbqc = %d.\n", |
747 | printk("nicstar%d: Strange... Just allocated %d small buffers and sfbqc = %d.\n", | 731 | i, j, bcount); |
748 | i, j, bcount); | 732 | error = 15; |
749 | error = 15; | 733 | ns_init_card_error(card, error); |
750 | ns_init_card_error(card, error); | 734 | return error; |
751 | return error; | 735 | } |
752 | } | 736 | |
753 | 737 | /* Allocate iovec buffers */ | |
754 | 738 | skb_queue_head_init(&card->iovpool.queue); | |
755 | /* Allocate iovec buffers */ | 739 | card->iovpool.count = 0; |
756 | skb_queue_head_init(&card->iovpool.queue); | 740 | for (j = 0; j < NUM_IOVB; j++) { |
757 | card->iovpool.count = 0; | 741 | struct sk_buff *iovb; |
758 | for (j = 0; j < NUM_IOVB; j++) | 742 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL); |
759 | { | 743 | if (iovb == NULL) { |
760 | struct sk_buff *iovb; | 744 | printk |
761 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL); | 745 | ("nicstar%d: can't allocate %dth of %d iovec buffers.\n", |
762 | if (iovb == NULL) | 746 | i, j, NUM_IOVB); |
763 | { | 747 | error = 16; |
764 | printk("nicstar%d: can't allocate %dth of %d iovec buffers.\n", | 748 | ns_init_card_error(card, error); |
765 | i, j, NUM_IOVB); | 749 | return error; |
766 | error = 16; | 750 | } |
767 | ns_init_card_error(card, error); | 751 | NS_PRV_BUFTYPE(iovb) = BUF_NONE; |
768 | return error; | 752 | skb_queue_tail(&card->iovpool.queue, iovb); |
769 | } | 753 | card->iovpool.count++; |
770 | NS_SKB_CB(iovb)->buf_type = BUF_NONE; | 754 | } |
771 | skb_queue_tail(&card->iovpool.queue, iovb); | 755 | |
772 | card->iovpool.count++; | 756 | /* Configure NICStAR */ |
773 | } | 757 | if (card->rct_size == 4096) |
774 | 758 | ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES; | |
775 | /* Configure NICStAR */ | 759 | else /* (card->rct_size == 16384) */ |
776 | if (card->rct_size == 4096) | 760 | ns_cfg_rctsize = NS_CFG_RCTSIZE_16384_ENTRIES; |
777 | ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES; | 761 | |
778 | else /* (card->rct_size == 16384) */ | 762 | card->efbie = 1; |
779 | ns_cfg_rctsize = NS_CFG_RCTSIZE_16384_ENTRIES; | 763 | |
780 | 764 | card->intcnt = 0; | |
781 | card->efbie = 1; | 765 | if (request_irq |
782 | 766 | (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { | |
783 | card->intcnt = 0; | 767 | printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); |
784 | if (request_irq(pcidev->irq, &ns_irq_handler, IRQF_DISABLED | IRQF_SHARED, "nicstar", card) != 0) | 768 | error = 9; |
785 | { | 769 | ns_init_card_error(card, error); |
786 | printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); | 770 | return error; |
787 | error = 9; | 771 | } |
788 | ns_init_card_error(card, error); | 772 | |
789 | return error; | 773 | /* Register device */ |
790 | } | 774 | card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); |
791 | 775 | if (card->atmdev == NULL) { | |
792 | /* Register device */ | 776 | printk("nicstar%d: can't register device.\n", i); |
793 | card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); | 777 | error = 17; |
794 | if (card->atmdev == NULL) | 778 | ns_init_card_error(card, error); |
795 | { | 779 | return error; |
796 | printk("nicstar%d: can't register device.\n", i); | 780 | } |
797 | error = 17; | 781 | |
798 | ns_init_card_error(card, error); | 782 | if (ns_parse_mac(mac[i], card->atmdev->esi)) { |
799 | return error; | 783 | nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET, |
800 | } | 784 | card->atmdev->esi, 6); |
801 | 785 | if (memcmp(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00", 6) == | |
802 | if (ns_parse_mac(mac[i], card->atmdev->esi)) { | 786 | 0) { |
803 | nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET, | 787 | nicstar_read_eprom(card->membase, |
804 | card->atmdev->esi, 6); | 788 | NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT, |
805 | if (memcmp(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00", 6) == 0) { | 789 | card->atmdev->esi, 6); |
806 | nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT, | 790 | } |
807 | card->atmdev->esi, 6); | 791 | } |
808 | } | 792 | |
809 | } | 793 | printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi); |
810 | 794 | ||
811 | printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi); | 795 | card->atmdev->dev_data = card; |
812 | 796 | card->atmdev->ci_range.vpi_bits = card->vpibits; | |
813 | card->atmdev->dev_data = card; | 797 | card->atmdev->ci_range.vci_bits = card->vcibits; |
814 | card->atmdev->ci_range.vpi_bits = card->vpibits; | 798 | card->atmdev->link_rate = card->max_pcr; |
815 | card->atmdev->ci_range.vci_bits = card->vcibits; | 799 | card->atmdev->phy = NULL; |
816 | card->atmdev->link_rate = card->max_pcr; | ||
817 | card->atmdev->phy = NULL; | ||
818 | 800 | ||
819 | #ifdef CONFIG_ATM_NICSTAR_USE_SUNI | 801 | #ifdef CONFIG_ATM_NICSTAR_USE_SUNI |
820 | if (card->max_pcr == ATM_OC3_PCR) | 802 | if (card->max_pcr == ATM_OC3_PCR) |
821 | suni_init(card->atmdev); | 803 | suni_init(card->atmdev); |
822 | #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ | 804 | #endif /* CONFIG_ATM_NICSTAR_USE_SUNI */ |
823 | 805 | ||
824 | #ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 | 806 | #ifdef CONFIG_ATM_NICSTAR_USE_IDT77105 |
825 | if (card->max_pcr == ATM_25_PCR) | 807 | if (card->max_pcr == ATM_25_PCR) |
826 | idt77105_init(card->atmdev); | 808 | idt77105_init(card->atmdev); |
827 | #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ | 809 | #endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */ |
828 | 810 | ||
829 | if (card->atmdev->phy && card->atmdev->phy->start) | 811 | if (card->atmdev->phy && card->atmdev->phy->start) |
830 | card->atmdev->phy->start(card->atmdev); | 812 | card->atmdev->phy->start(card->atmdev); |
831 | |||
832 | writel(NS_CFG_RXPATH | | ||
833 | NS_CFG_SMBUFSIZE | | ||
834 | NS_CFG_LGBUFSIZE | | ||
835 | NS_CFG_EFBIE | | ||
836 | NS_CFG_RSQSIZE | | ||
837 | NS_CFG_VPIBITS | | ||
838 | ns_cfg_rctsize | | ||
839 | NS_CFG_RXINT_NODELAY | | ||
840 | NS_CFG_RAWIE | /* Only enabled if RCQ_SUPPORT */ | ||
841 | NS_CFG_RSQAFIE | | ||
842 | NS_CFG_TXEN | | ||
843 | NS_CFG_TXIE | | ||
844 | NS_CFG_TSQFIE_OPT | /* Only enabled if ENABLE_TSQFIE */ | ||
845 | NS_CFG_PHYIE, | ||
846 | card->membase + CFG); | ||
847 | |||
848 | num_cards++; | ||
849 | |||
850 | return error; | ||
851 | } | ||
852 | 813 | ||
814 | writel(NS_CFG_RXPATH | NS_CFG_SMBUFSIZE | NS_CFG_LGBUFSIZE | NS_CFG_EFBIE | NS_CFG_RSQSIZE | NS_CFG_VPIBITS | ns_cfg_rctsize | NS_CFG_RXINT_NODELAY | NS_CFG_RAWIE | /* Only enabled if RCQ_SUPPORT */ | ||
815 | NS_CFG_RSQAFIE | NS_CFG_TXEN | NS_CFG_TXIE | NS_CFG_TSQFIE_OPT | /* Only enabled if ENABLE_TSQFIE */ | ||
816 | NS_CFG_PHYIE, card->membase + CFG); | ||
853 | 817 | ||
818 | num_cards++; | ||
854 | 819 | ||
855 | static void __devinit ns_init_card_error(ns_dev *card, int error) | 820 | return error; |
856 | { | ||
857 | if (error >= 17) | ||
858 | { | ||
859 | writel(0x00000000, card->membase + CFG); | ||
860 | } | ||
861 | if (error >= 16) | ||
862 | { | ||
863 | struct sk_buff *iovb; | ||
864 | while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) | ||
865 | dev_kfree_skb_any(iovb); | ||
866 | } | ||
867 | if (error >= 15) | ||
868 | { | ||
869 | struct sk_buff *sb; | ||
870 | while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) | ||
871 | dev_kfree_skb_any(sb); | ||
872 | free_scq(card->scq0, NULL); | ||
873 | } | ||
874 | if (error >= 14) | ||
875 | { | ||
876 | struct sk_buff *lb; | ||
877 | while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) | ||
878 | dev_kfree_skb_any(lb); | ||
879 | } | ||
880 | if (error >= 13) | ||
881 | { | ||
882 | struct sk_buff *hb; | ||
883 | while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) | ||
884 | dev_kfree_skb_any(hb); | ||
885 | } | ||
886 | if (error >= 12) | ||
887 | { | ||
888 | kfree(card->rsq.org); | ||
889 | } | ||
890 | if (error >= 11) | ||
891 | { | ||
892 | kfree(card->tsq.org); | ||
893 | } | ||
894 | if (error >= 10) | ||
895 | { | ||
896 | free_irq(card->pcidev->irq, card); | ||
897 | } | ||
898 | if (error >= 4) | ||
899 | { | ||
900 | iounmap(card->membase); | ||
901 | } | ||
902 | if (error >= 3) | ||
903 | { | ||
904 | pci_disable_device(card->pcidev); | ||
905 | kfree(card); | ||
906 | } | ||
907 | } | 821 | } |
908 | 822 | ||
909 | 823 | static void __devinit ns_init_card_error(ns_dev * card, int error) | |
910 | |||
911 | static scq_info *get_scq(int size, u32 scd) | ||
912 | { | 824 | { |
913 | scq_info *scq; | 825 | if (error >= 17) { |
914 | int i; | 826 | writel(0x00000000, card->membase + CFG); |
915 | 827 | } | |
916 | if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) | 828 | if (error >= 16) { |
917 | return NULL; | 829 | struct sk_buff *iovb; |
918 | 830 | while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) | |
919 | scq = kmalloc(sizeof(scq_info), GFP_KERNEL); | 831 | dev_kfree_skb_any(iovb); |
920 | if (scq == NULL) | 832 | } |
921 | return NULL; | 833 | if (error >= 15) { |
922 | scq->org = kmalloc(2 * size, GFP_KERNEL); | 834 | struct sk_buff *sb; |
923 | if (scq->org == NULL) | 835 | while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL) |
924 | { | 836 | dev_kfree_skb_any(sb); |
925 | kfree(scq); | 837 | free_scq(card, card->scq0, NULL); |
926 | return NULL; | 838 | } |
927 | } | 839 | if (error >= 14) { |
928 | scq->skb = kmalloc(sizeof(struct sk_buff *) * | 840 | struct sk_buff *lb; |
929 | (size / NS_SCQE_SIZE), GFP_KERNEL); | 841 | while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL) |
930 | if (scq->skb == NULL) | 842 | dev_kfree_skb_any(lb); |
931 | { | 843 | } |
932 | kfree(scq->org); | 844 | if (error >= 13) { |
933 | kfree(scq); | 845 | struct sk_buff *hb; |
934 | return NULL; | 846 | while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) |
935 | } | 847 | dev_kfree_skb_any(hb); |
936 | scq->num_entries = size / NS_SCQE_SIZE; | 848 | } |
937 | scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size); | 849 | if (error >= 12) { |
938 | scq->next = scq->base; | 850 | kfree(card->rsq.org); |
939 | scq->last = scq->base + (scq->num_entries - 1); | 851 | } |
940 | scq->tail = scq->last; | 852 | if (error >= 11) { |
941 | scq->scd = scd; | 853 | kfree(card->tsq.org); |
942 | scq->num_entries = size / NS_SCQE_SIZE; | 854 | } |
943 | scq->tbd_count = 0; | 855 | if (error >= 10) { |
944 | init_waitqueue_head(&scq->scqfull_waitq); | 856 | free_irq(card->pcidev->irq, card); |
945 | scq->full = 0; | 857 | } |
946 | spin_lock_init(&scq->lock); | 858 | if (error >= 4) { |
947 | 859 | iounmap(card->membase); | |
948 | for (i = 0; i < scq->num_entries; i++) | 860 | } |
949 | scq->skb[i] = NULL; | 861 | if (error >= 3) { |
950 | 862 | pci_disable_device(card->pcidev); | |
951 | return scq; | 863 | kfree(card); |
864 | } | ||
952 | } | 865 | } |
953 | 866 | ||
954 | 867 | static scq_info *get_scq(ns_dev *card, int size, u32 scd) | |
868 | { | ||
869 | scq_info *scq; | ||
870 | int i; | ||
871 | |||
872 | if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) | ||
873 | return NULL; | ||
874 | |||
875 | scq = kmalloc(sizeof(scq_info), GFP_KERNEL); | ||
876 | if (!scq) | ||
877 | return NULL; | ||
878 | scq->org = pci_alloc_consistent(card->pcidev, 2 * size, &scq->dma); | ||
879 | if (!scq->org) { | ||
880 | kfree(scq); | ||
881 | return NULL; | ||
882 | } | ||
883 | scq->skb = kmalloc(sizeof(struct sk_buff *) * | ||
884 | (size / NS_SCQE_SIZE), GFP_KERNEL); | ||
885 | if (!scq->skb) { | ||
886 | kfree(scq->org); | ||
887 | kfree(scq); | ||
888 | return NULL; | ||
889 | } | ||
890 | scq->num_entries = size / NS_SCQE_SIZE; | ||
891 | scq->base = PTR_ALIGN(scq->org, size); | ||
892 | scq->next = scq->base; | ||
893 | scq->last = scq->base + (scq->num_entries - 1); | ||
894 | scq->tail = scq->last; | ||
895 | scq->scd = scd; | ||
896 | scq->num_entries = size / NS_SCQE_SIZE; | ||
897 | scq->tbd_count = 0; | ||
898 | init_waitqueue_head(&scq->scqfull_waitq); | ||
899 | scq->full = 0; | ||
900 | spin_lock_init(&scq->lock); | ||
901 | |||
902 | for (i = 0; i < scq->num_entries; i++) | ||
903 | scq->skb[i] = NULL; | ||
904 | |||
905 | return scq; | ||
906 | } | ||
955 | 907 | ||
956 | /* For variable rate SCQ vcc must be NULL */ | 908 | /* For variable rate SCQ vcc must be NULL */ |
957 | static void free_scq(scq_info *scq, struct atm_vcc *vcc) | 909 | static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc) |
958 | { | 910 | { |
959 | int i; | 911 | int i; |
960 | 912 | ||
961 | if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) | 913 | if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) |
962 | for (i = 0; i < scq->num_entries; i++) | 914 | for (i = 0; i < scq->num_entries; i++) { |
963 | { | 915 | if (scq->skb[i] != NULL) { |
964 | if (scq->skb[i] != NULL) | 916 | vcc = ATM_SKB(scq->skb[i])->vcc; |
965 | { | 917 | if (vcc->pop != NULL) |
966 | vcc = ATM_SKB(scq->skb[i])->vcc; | 918 | vcc->pop(vcc, scq->skb[i]); |
967 | if (vcc->pop != NULL) | 919 | else |
968 | vcc->pop(vcc, scq->skb[i]); | 920 | dev_kfree_skb_any(scq->skb[i]); |
969 | else | 921 | } |
970 | dev_kfree_skb_any(scq->skb[i]); | 922 | } else { /* vcc must be != NULL */ |
971 | } | 923 | |
972 | } | 924 | if (vcc == NULL) { |
973 | else /* vcc must be != NULL */ | 925 | printk |
974 | { | 926 | ("nicstar: free_scq() called with vcc == NULL for fixed rate scq."); |
975 | if (vcc == NULL) | 927 | for (i = 0; i < scq->num_entries; i++) |
976 | { | 928 | dev_kfree_skb_any(scq->skb[i]); |
977 | printk("nicstar: free_scq() called with vcc == NULL for fixed rate scq."); | 929 | } else |
978 | for (i = 0; i < scq->num_entries; i++) | 930 | for (i = 0; i < scq->num_entries; i++) { |
979 | dev_kfree_skb_any(scq->skb[i]); | 931 | if (scq->skb[i] != NULL) { |
980 | } | 932 | if (vcc->pop != NULL) |
981 | else | 933 | vcc->pop(vcc, scq->skb[i]); |
982 | for (i = 0; i < scq->num_entries; i++) | 934 | else |
983 | { | 935 | dev_kfree_skb_any(scq->skb[i]); |
984 | if (scq->skb[i] != NULL) | 936 | } |
985 | { | 937 | } |
986 | if (vcc->pop != NULL) | 938 | } |
987 | vcc->pop(vcc, scq->skb[i]); | 939 | kfree(scq->skb); |
988 | else | 940 | pci_free_consistent(card->pcidev, |
989 | dev_kfree_skb_any(scq->skb[i]); | 941 | 2 * (scq->num_entries == VBR_SCQ_NUM_ENTRIES ? |
990 | } | 942 | VBR_SCQSIZE : CBR_SCQSIZE), |
991 | } | 943 | scq->org, scq->dma); |
992 | } | 944 | kfree(scq); |
993 | kfree(scq->skb); | ||
994 | kfree(scq->org); | ||
995 | kfree(scq); | ||
996 | } | 945 | } |
997 | 946 | ||
998 | |||
999 | |||
1000 | /* The handles passed must be pointers to the sk_buff containing the small | 947 | /* The handles passed must be pointers to the sk_buff containing the small |
1001 | or large buffer(s) cast to u32. */ | 948 | or large buffer(s) cast to u32. */ |
1002 | static void push_rxbufs(ns_dev *card, struct sk_buff *skb) | 949 | static void push_rxbufs(ns_dev * card, struct sk_buff *skb) |
1003 | { | 950 | { |
1004 | struct ns_skb_cb *cb = NS_SKB_CB(skb); | 951 | struct sk_buff *handle1, *handle2; |
1005 | u32 handle1, addr1; | 952 | u32 id1 = 0, id2 = 0; |
1006 | u32 handle2, addr2; | 953 | u32 addr1, addr2; |
1007 | u32 stat; | 954 | u32 stat; |
1008 | unsigned long flags; | 955 | unsigned long flags; |
1009 | 956 | int err; | |
1010 | /* *BARF* */ | 957 | |
1011 | handle2 = addr2 = 0; | 958 | /* *BARF* */ |
1012 | handle1 = (u32)skb; | 959 | handle2 = NULL; |
1013 | addr1 = (u32)virt_to_bus(skb->data); | 960 | addr2 = 0; |
961 | handle1 = skb; | ||
962 | addr1 = pci_map_single(card->pcidev, | ||
963 | skb->data, | ||
964 | (NS_PRV_BUFTYPE(skb) == BUF_SM | ||
965 | ? NS_SMSKBSIZE : NS_LGSKBSIZE), | ||
966 | PCI_DMA_TODEVICE); | ||
967 | NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */ | ||
1014 | 968 | ||
1015 | #ifdef GENERAL_DEBUG | 969 | #ifdef GENERAL_DEBUG |
1016 | if (!addr1) | 970 | if (!addr1) |
1017 | printk("nicstar%d: push_rxbufs called with addr1 = 0.\n", card->index); | 971 | printk("nicstar%d: push_rxbufs called with addr1 = 0.\n", |
972 | card->index); | ||
1018 | #endif /* GENERAL_DEBUG */ | 973 | #endif /* GENERAL_DEBUG */ |
1019 | 974 | ||
1020 | stat = readl(card->membase + STAT); | 975 | stat = readl(card->membase + STAT); |
1021 | card->sbfqc = ns_stat_sfbqc_get(stat); | 976 | card->sbfqc = ns_stat_sfbqc_get(stat); |
1022 | card->lbfqc = ns_stat_lfbqc_get(stat); | 977 | card->lbfqc = ns_stat_lfbqc_get(stat); |
1023 | if (cb->buf_type == BUF_SM) | 978 | if (NS_PRV_BUFTYPE(skb) == BUF_SM) { |
1024 | { | 979 | if (!addr2) { |
1025 | if (!addr2) | 980 | if (card->sm_addr) { |
1026 | { | 981 | addr2 = card->sm_addr; |
1027 | if (card->sm_addr) | 982 | handle2 = card->sm_handle; |
1028 | { | 983 | card->sm_addr = 0x00000000; |
1029 | addr2 = card->sm_addr; | 984 | card->sm_handle = 0x00000000; |
1030 | handle2 = card->sm_handle; | 985 | } else { /* (!sm_addr) */ |
1031 | card->sm_addr = 0x00000000; | 986 | |
1032 | card->sm_handle = 0x00000000; | 987 | card->sm_addr = addr1; |
1033 | } | 988 | card->sm_handle = handle1; |
1034 | else /* (!sm_addr) */ | 989 | } |
1035 | { | 990 | } |
1036 | card->sm_addr = addr1; | 991 | } else { /* buf_type == BUF_LG */ |
1037 | card->sm_handle = handle1; | 992 | |
1038 | } | 993 | if (!addr2) { |
1039 | } | 994 | if (card->lg_addr) { |
1040 | } | 995 | addr2 = card->lg_addr; |
1041 | else /* buf_type == BUF_LG */ | 996 | handle2 = card->lg_handle; |
1042 | { | 997 | card->lg_addr = 0x00000000; |
1043 | if (!addr2) | 998 | card->lg_handle = 0x00000000; |
1044 | { | 999 | } else { /* (!lg_addr) */ |
1045 | if (card->lg_addr) | 1000 | |
1046 | { | 1001 | card->lg_addr = addr1; |
1047 | addr2 = card->lg_addr; | 1002 | card->lg_handle = handle1; |
1048 | handle2 = card->lg_handle; | 1003 | } |
1049 | card->lg_addr = 0x00000000; | 1004 | } |
1050 | card->lg_handle = 0x00000000; | 1005 | } |
1051 | } | 1006 | |
1052 | else /* (!lg_addr) */ | 1007 | if (addr2) { |
1053 | { | 1008 | if (NS_PRV_BUFTYPE(skb) == BUF_SM) { |
1054 | card->lg_addr = addr1; | 1009 | if (card->sbfqc >= card->sbnr.max) { |
1055 | card->lg_handle = handle1; | 1010 | skb_unlink(handle1, &card->sbpool.queue); |
1056 | } | 1011 | dev_kfree_skb_any(handle1); |
1057 | } | 1012 | skb_unlink(handle2, &card->sbpool.queue); |
1058 | } | 1013 | dev_kfree_skb_any(handle2); |
1059 | 1014 | return; | |
1060 | if (addr2) | 1015 | } else |
1061 | { | 1016 | card->sbfqc += 2; |
1062 | if (cb->buf_type == BUF_SM) | 1017 | } else { /* (buf_type == BUF_LG) */ |
1063 | { | 1018 | |
1064 | if (card->sbfqc >= card->sbnr.max) | 1019 | if (card->lbfqc >= card->lbnr.max) { |
1065 | { | 1020 | skb_unlink(handle1, &card->lbpool.queue); |
1066 | skb_unlink((struct sk_buff *) handle1, &card->sbpool.queue); | 1021 | dev_kfree_skb_any(handle1); |
1067 | dev_kfree_skb_any((struct sk_buff *) handle1); | 1022 | skb_unlink(handle2, &card->lbpool.queue); |
1068 | skb_unlink((struct sk_buff *) handle2, &card->sbpool.queue); | 1023 | dev_kfree_skb_any(handle2); |
1069 | dev_kfree_skb_any((struct sk_buff *) handle2); | 1024 | return; |
1070 | return; | 1025 | } else |
1071 | } | 1026 | card->lbfqc += 2; |
1072 | else | 1027 | } |
1073 | card->sbfqc += 2; | 1028 | |
1074 | } | 1029 | do { |
1075 | else /* (buf_type == BUF_LG) */ | 1030 | if (!idr_pre_get(&card->idr, GFP_ATOMIC)) { |
1076 | { | 1031 | printk(KERN_ERR |
1077 | if (card->lbfqc >= card->lbnr.max) | 1032 | "nicstar%d: no free memory for idr\n", |
1078 | { | 1033 | card->index); |
1079 | skb_unlink((struct sk_buff *) handle1, &card->lbpool.queue); | 1034 | goto out; |
1080 | dev_kfree_skb_any((struct sk_buff *) handle1); | 1035 | } |
1081 | skb_unlink((struct sk_buff *) handle2, &card->lbpool.queue); | 1036 | |
1082 | dev_kfree_skb_any((struct sk_buff *) handle2); | 1037 | if (!id1) |
1083 | return; | 1038 | err = idr_get_new_above(&card->idr, handle1, 0, &id1); |
1084 | } | 1039 | |
1085 | else | 1040 | if (!id2 && err == 0) |
1086 | card->lbfqc += 2; | 1041 | err = idr_get_new_above(&card->idr, handle2, 0, &id2); |
1087 | } | 1042 | |
1088 | 1043 | } while (err == -EAGAIN); | |
1089 | spin_lock_irqsave(&card->res_lock, flags); | 1044 | |
1090 | 1045 | if (err) | |
1091 | while (CMD_BUSY(card)); | 1046 | goto out; |
1092 | writel(addr2, card->membase + DR3); | 1047 | |
1093 | writel(handle2, card->membase + DR2); | 1048 | spin_lock_irqsave(&card->res_lock, flags); |
1094 | writel(addr1, card->membase + DR1); | 1049 | while (CMD_BUSY(card)) ; |
1095 | writel(handle1, card->membase + DR0); | 1050 | writel(addr2, card->membase + DR3); |
1096 | writel(NS_CMD_WRITE_FREEBUFQ | cb->buf_type, card->membase + CMD); | 1051 | writel(id2, card->membase + DR2); |
1097 | 1052 | writel(addr1, card->membase + DR1); | |
1098 | spin_unlock_irqrestore(&card->res_lock, flags); | 1053 | writel(id1, card->membase + DR0); |
1099 | 1054 | writel(NS_CMD_WRITE_FREEBUFQ | NS_PRV_BUFTYPE(skb), | |
1100 | XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index, | 1055 | card->membase + CMD); |
1101 | (cb->buf_type == BUF_SM ? "small" : "large"), addr1, addr2); | 1056 | spin_unlock_irqrestore(&card->res_lock, flags); |
1102 | } | 1057 | |
1103 | 1058 | XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", | |
1104 | if (!card->efbie && card->sbfqc >= card->sbnr.min && | 1059 | card->index, |
1105 | card->lbfqc >= card->lbnr.min) | 1060 | (NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"), |
1106 | { | 1061 | addr1, addr2); |
1107 | card->efbie = 1; | 1062 | } |
1108 | writel((readl(card->membase + CFG) | NS_CFG_EFBIE), card->membase + CFG); | 1063 | |
1109 | } | 1064 | if (!card->efbie && card->sbfqc >= card->sbnr.min && |
1110 | 1065 | card->lbfqc >= card->lbnr.min) { | |
1111 | return; | 1066 | card->efbie = 1; |
1067 | writel((readl(card->membase + CFG) | NS_CFG_EFBIE), | ||
1068 | card->membase + CFG); | ||
1069 | } | ||
1070 | |||
1071 | out: | ||
1072 | return; | ||
1112 | } | 1073 | } |
1113 | 1074 | ||
1114 | |||
1115 | |||
1116 | static irqreturn_t ns_irq_handler(int irq, void *dev_id) | 1075 | static irqreturn_t ns_irq_handler(int irq, void *dev_id) |
1117 | { | 1076 | { |
1118 | u32 stat_r; | 1077 | u32 stat_r; |
1119 | ns_dev *card; | 1078 | ns_dev *card; |
1120 | struct atm_dev *dev; | 1079 | struct atm_dev *dev; |
1121 | unsigned long flags; | 1080 | unsigned long flags; |
1122 | 1081 | ||
1123 | card = (ns_dev *) dev_id; | 1082 | card = (ns_dev *) dev_id; |
1124 | dev = card->atmdev; | 1083 | dev = card->atmdev; |
1125 | card->intcnt++; | 1084 | card->intcnt++; |
1126 | 1085 | ||
1127 | PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index); | 1086 | PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index); |
1128 | 1087 | ||
1129 | spin_lock_irqsave(&card->int_lock, flags); | 1088 | spin_lock_irqsave(&card->int_lock, flags); |
1130 | 1089 | ||
1131 | stat_r = readl(card->membase + STAT); | 1090 | stat_r = readl(card->membase + STAT); |
1132 | 1091 | ||
1133 | /* Transmit Status Indicator has been written to T. S. Queue */ | 1092 | /* Transmit Status Indicator has been written to T. S. Queue */ |
1134 | if (stat_r & NS_STAT_TSIF) | 1093 | if (stat_r & NS_STAT_TSIF) { |
1135 | { | 1094 | TXPRINTK("nicstar%d: TSI interrupt\n", card->index); |
1136 | TXPRINTK("nicstar%d: TSI interrupt\n", card->index); | 1095 | process_tsq(card); |
1137 | process_tsq(card); | 1096 | writel(NS_STAT_TSIF, card->membase + STAT); |
1138 | writel(NS_STAT_TSIF, card->membase + STAT); | 1097 | } |
1139 | } | 1098 | |
1140 | 1099 | /* Incomplete CS-PDU has been transmitted */ | |
1141 | /* Incomplete CS-PDU has been transmitted */ | 1100 | if (stat_r & NS_STAT_TXICP) { |
1142 | if (stat_r & NS_STAT_TXICP) | 1101 | writel(NS_STAT_TXICP, card->membase + STAT); |
1143 | { | 1102 | TXPRINTK("nicstar%d: Incomplete CS-PDU transmitted.\n", |
1144 | writel(NS_STAT_TXICP, card->membase + STAT); | 1103 | card->index); |
1145 | TXPRINTK("nicstar%d: Incomplete CS-PDU transmitted.\n", | 1104 | } |
1146 | card->index); | 1105 | |
1147 | } | 1106 | /* Transmit Status Queue 7/8 full */ |
1148 | 1107 | if (stat_r & NS_STAT_TSQF) { | |
1149 | /* Transmit Status Queue 7/8 full */ | 1108 | writel(NS_STAT_TSQF, card->membase + STAT); |
1150 | if (stat_r & NS_STAT_TSQF) | 1109 | PRINTK("nicstar%d: TSQ full.\n", card->index); |
1151 | { | 1110 | process_tsq(card); |
1152 | writel(NS_STAT_TSQF, card->membase + STAT); | 1111 | } |
1153 | PRINTK("nicstar%d: TSQ full.\n", card->index); | 1112 | |
1154 | process_tsq(card); | 1113 | /* Timer overflow */ |
1155 | } | 1114 | if (stat_r & NS_STAT_TMROF) { |
1156 | 1115 | writel(NS_STAT_TMROF, card->membase + STAT); | |
1157 | /* Timer overflow */ | 1116 | PRINTK("nicstar%d: Timer overflow.\n", card->index); |
1158 | if (stat_r & NS_STAT_TMROF) | 1117 | } |
1159 | { | 1118 | |
1160 | writel(NS_STAT_TMROF, card->membase + STAT); | 1119 | /* PHY device interrupt signal active */ |
1161 | PRINTK("nicstar%d: Timer overflow.\n", card->index); | 1120 | if (stat_r & NS_STAT_PHYI) { |
1162 | } | 1121 | writel(NS_STAT_PHYI, card->membase + STAT); |
1163 | 1122 | PRINTK("nicstar%d: PHY interrupt.\n", card->index); | |
1164 | /* PHY device interrupt signal active */ | 1123 | if (dev->phy && dev->phy->interrupt) { |
1165 | if (stat_r & NS_STAT_PHYI) | 1124 | dev->phy->interrupt(dev); |
1166 | { | 1125 | } |
1167 | writel(NS_STAT_PHYI, card->membase + STAT); | 1126 | } |
1168 | PRINTK("nicstar%d: PHY interrupt.\n", card->index); | 1127 | |
1169 | if (dev->phy && dev->phy->interrupt) { | 1128 | /* Small Buffer Queue is full */ |
1170 | dev->phy->interrupt(dev); | 1129 | if (stat_r & NS_STAT_SFBQF) { |
1171 | } | 1130 | writel(NS_STAT_SFBQF, card->membase + STAT); |
1172 | } | 1131 | printk("nicstar%d: Small free buffer queue is full.\n", |
1173 | 1132 | card->index); | |
1174 | /* Small Buffer Queue is full */ | 1133 | } |
1175 | if (stat_r & NS_STAT_SFBQF) | 1134 | |
1176 | { | 1135 | /* Large Buffer Queue is full */ |
1177 | writel(NS_STAT_SFBQF, card->membase + STAT); | 1136 | if (stat_r & NS_STAT_LFBQF) { |
1178 | printk("nicstar%d: Small free buffer queue is full.\n", card->index); | 1137 | writel(NS_STAT_LFBQF, card->membase + STAT); |
1179 | } | 1138 | printk("nicstar%d: Large free buffer queue is full.\n", |
1180 | 1139 | card->index); | |
1181 | /* Large Buffer Queue is full */ | 1140 | } |
1182 | if (stat_r & NS_STAT_LFBQF) | 1141 | |
1183 | { | 1142 | /* Receive Status Queue is full */ |
1184 | writel(NS_STAT_LFBQF, card->membase + STAT); | 1143 | if (stat_r & NS_STAT_RSQF) { |
1185 | printk("nicstar%d: Large free buffer queue is full.\n", card->index); | 1144 | writel(NS_STAT_RSQF, card->membase + STAT); |
1186 | } | 1145 | printk("nicstar%d: RSQ full.\n", card->index); |
1187 | 1146 | process_rsq(card); | |
1188 | /* Receive Status Queue is full */ | 1147 | } |
1189 | if (stat_r & NS_STAT_RSQF) | 1148 | |
1190 | { | 1149 | /* Complete CS-PDU received */ |
1191 | writel(NS_STAT_RSQF, card->membase + STAT); | 1150 | if (stat_r & NS_STAT_EOPDU) { |
1192 | printk("nicstar%d: RSQ full.\n", card->index); | 1151 | RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index); |
1193 | process_rsq(card); | 1152 | process_rsq(card); |
1194 | } | 1153 | writel(NS_STAT_EOPDU, card->membase + STAT); |
1195 | 1154 | } | |
1196 | /* Complete CS-PDU received */ | 1155 | |
1197 | if (stat_r & NS_STAT_EOPDU) | 1156 | /* Raw cell received */ |
1198 | { | 1157 | if (stat_r & NS_STAT_RAWCF) { |
1199 | RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index); | 1158 | writel(NS_STAT_RAWCF, card->membase + STAT); |
1200 | process_rsq(card); | ||
1201 | writel(NS_STAT_EOPDU, card->membase + STAT); | ||
1202 | } | ||
1203 | |||
1204 | /* Raw cell received */ | ||
1205 | if (stat_r & NS_STAT_RAWCF) | ||
1206 | { | ||
1207 | writel(NS_STAT_RAWCF, card->membase + STAT); | ||
1208 | #ifndef RCQ_SUPPORT | 1159 | #ifndef RCQ_SUPPORT |
1209 | printk("nicstar%d: Raw cell received and no support yet...\n", | 1160 | printk("nicstar%d: Raw cell received and no support yet...\n", |
1210 | card->index); | 1161 | card->index); |
1211 | #endif /* RCQ_SUPPORT */ | 1162 | #endif /* RCQ_SUPPORT */ |
1212 | /* NOTE: the following procedure may keep a raw cell pending until the | 1163 | /* NOTE: the following procedure may keep a raw cell pending until the |
1213 | next interrupt. As this preliminary support is only meant to | 1164 | next interrupt. As this preliminary support is only meant to |
1214 | avoid buffer leakage, this is not an issue. */ | 1165 | avoid buffer leakage, this is not an issue. */ |
1215 | while (readl(card->membase + RAWCT) != card->rawch) | 1166 | while (readl(card->membase + RAWCT) != card->rawch) { |
1216 | { | 1167 | |
1217 | ns_rcqe *rawcell; | 1168 | if (ns_rcqe_islast(card->rawcell)) { |
1218 | 1169 | struct sk_buff *oldbuf; | |
1219 | rawcell = (ns_rcqe *) bus_to_virt(card->rawch); | 1170 | |
1220 | if (ns_rcqe_islast(rawcell)) | 1171 | oldbuf = card->rcbuf; |
1221 | { | 1172 | card->rcbuf = idr_find(&card->idr, |
1222 | struct sk_buff *oldbuf; | 1173 | ns_rcqe_nextbufhandle(card->rawcell)); |
1223 | 1174 | card->rawch = NS_PRV_DMA(card->rcbuf); | |
1224 | oldbuf = card->rcbuf; | 1175 | card->rawcell = (struct ns_rcqe *) |
1225 | card->rcbuf = (struct sk_buff *) ns_rcqe_nextbufhandle(rawcell); | 1176 | card->rcbuf->data; |
1226 | card->rawch = (u32) virt_to_bus(card->rcbuf->data); | 1177 | recycle_rx_buf(card, oldbuf); |
1227 | recycle_rx_buf(card, oldbuf); | 1178 | } else { |
1228 | } | 1179 | card->rawch += NS_RCQE_SIZE; |
1229 | else | 1180 | card->rawcell++; |
1230 | card->rawch += NS_RCQE_SIZE; | 1181 | } |
1231 | } | 1182 | } |
1232 | } | 1183 | } |
1233 | 1184 | ||
1234 | /* Small buffer queue is empty */ | 1185 | /* Small buffer queue is empty */ |
1235 | if (stat_r & NS_STAT_SFBQE) | 1186 | if (stat_r & NS_STAT_SFBQE) { |
1236 | { | 1187 | int i; |
1237 | int i; | 1188 | struct sk_buff *sb; |
1238 | struct sk_buff *sb; | 1189 | |
1239 | 1190 | writel(NS_STAT_SFBQE, card->membase + STAT); | |
1240 | writel(NS_STAT_SFBQE, card->membase + STAT); | 1191 | printk("nicstar%d: Small free buffer queue empty.\n", |
1241 | printk("nicstar%d: Small free buffer queue empty.\n", | 1192 | card->index); |
1242 | card->index); | 1193 | for (i = 0; i < card->sbnr.min; i++) { |
1243 | for (i = 0; i < card->sbnr.min; i++) | 1194 | sb = dev_alloc_skb(NS_SMSKBSIZE); |
1244 | { | 1195 | if (sb == NULL) { |
1245 | sb = dev_alloc_skb(NS_SMSKBSIZE); | 1196 | writel(readl(card->membase + CFG) & |
1246 | if (sb == NULL) | 1197 | ~NS_CFG_EFBIE, card->membase + CFG); |
1247 | { | 1198 | card->efbie = 0; |
1248 | writel(readl(card->membase + CFG) & ~NS_CFG_EFBIE, card->membase + CFG); | 1199 | break; |
1249 | card->efbie = 0; | 1200 | } |
1250 | break; | 1201 | NS_PRV_BUFTYPE(sb) = BUF_SM; |
1251 | } | 1202 | skb_queue_tail(&card->sbpool.queue, sb); |
1252 | NS_SKB_CB(sb)->buf_type = BUF_SM; | 1203 | skb_reserve(sb, NS_AAL0_HEADER); |
1253 | skb_queue_tail(&card->sbpool.queue, sb); | 1204 | push_rxbufs(card, sb); |
1254 | skb_reserve(sb, NS_AAL0_HEADER); | 1205 | } |
1255 | push_rxbufs(card, sb); | 1206 | card->sbfqc = i; |
1256 | } | 1207 | process_rsq(card); |
1257 | card->sbfqc = i; | 1208 | } |
1258 | process_rsq(card); | 1209 | |
1259 | } | 1210 | /* Large buffer queue empty */ |
1260 | 1211 | if (stat_r & NS_STAT_LFBQE) { | |
1261 | /* Large buffer queue empty */ | 1212 | int i; |
1262 | if (stat_r & NS_STAT_LFBQE) | 1213 | struct sk_buff *lb; |
1263 | { | 1214 | |
1264 | int i; | 1215 | writel(NS_STAT_LFBQE, card->membase + STAT); |
1265 | struct sk_buff *lb; | 1216 | printk("nicstar%d: Large free buffer queue empty.\n", |
1266 | 1217 | card->index); | |
1267 | writel(NS_STAT_LFBQE, card->membase + STAT); | 1218 | for (i = 0; i < card->lbnr.min; i++) { |
1268 | printk("nicstar%d: Large free buffer queue empty.\n", | 1219 | lb = dev_alloc_skb(NS_LGSKBSIZE); |
1269 | card->index); | 1220 | if (lb == NULL) { |
1270 | for (i = 0; i < card->lbnr.min; i++) | 1221 | writel(readl(card->membase + CFG) & |
1271 | { | 1222 | ~NS_CFG_EFBIE, card->membase + CFG); |
1272 | lb = dev_alloc_skb(NS_LGSKBSIZE); | 1223 | card->efbie = 0; |
1273 | if (lb == NULL) | 1224 | break; |
1274 | { | 1225 | } |
1275 | writel(readl(card->membase + CFG) & ~NS_CFG_EFBIE, card->membase + CFG); | 1226 | NS_PRV_BUFTYPE(lb) = BUF_LG; |
1276 | card->efbie = 0; | 1227 | skb_queue_tail(&card->lbpool.queue, lb); |
1277 | break; | 1228 | skb_reserve(lb, NS_SMBUFSIZE); |
1278 | } | 1229 | push_rxbufs(card, lb); |
1279 | NS_SKB_CB(lb)->buf_type = BUF_LG; | 1230 | } |
1280 | skb_queue_tail(&card->lbpool.queue, lb); | 1231 | card->lbfqc = i; |
1281 | skb_reserve(lb, NS_SMBUFSIZE); | 1232 | process_rsq(card); |
1282 | push_rxbufs(card, lb); | 1233 | } |
1283 | } | 1234 | |
1284 | card->lbfqc = i; | 1235 | /* Receive Status Queue is 7/8 full */ |
1285 | process_rsq(card); | 1236 | if (stat_r & NS_STAT_RSQAF) { |
1286 | } | 1237 | writel(NS_STAT_RSQAF, card->membase + STAT); |
1287 | 1238 | RXPRINTK("nicstar%d: RSQ almost full.\n", card->index); | |
1288 | /* Receive Status Queue is 7/8 full */ | 1239 | process_rsq(card); |
1289 | if (stat_r & NS_STAT_RSQAF) | 1240 | } |
1290 | { | 1241 | |
1291 | writel(NS_STAT_RSQAF, card->membase + STAT); | 1242 | spin_unlock_irqrestore(&card->int_lock, flags); |
1292 | RXPRINTK("nicstar%d: RSQ almost full.\n", card->index); | 1243 | PRINTK("nicstar%d: end of interrupt service\n", card->index); |
1293 | process_rsq(card); | 1244 | return IRQ_HANDLED; |
1294 | } | ||
1295 | |||
1296 | spin_unlock_irqrestore(&card->int_lock, flags); | ||
1297 | PRINTK("nicstar%d: end of interrupt service\n", card->index); | ||
1298 | return IRQ_HANDLED; | ||
1299 | } | 1245 | } |
1300 | 1246 | ||
1301 | |||
1302 | |||
1303 | static int ns_open(struct atm_vcc *vcc) | 1247 | static int ns_open(struct atm_vcc *vcc) |
1304 | { | 1248 | { |
1305 | ns_dev *card; | 1249 | ns_dev *card; |
1306 | vc_map *vc; | 1250 | vc_map *vc; |
1307 | unsigned long tmpl, modl; | 1251 | unsigned long tmpl, modl; |
1308 | int tcr, tcra; /* target cell rate, and absolute value */ | 1252 | int tcr, tcra; /* target cell rate, and absolute value */ |
1309 | int n = 0; /* Number of entries in the TST. Initialized to remove | 1253 | int n = 0; /* Number of entries in the TST. Initialized to remove |
1310 | the compiler warning. */ | 1254 | the compiler warning. */ |
1311 | u32 u32d[4]; | 1255 | u32 u32d[4]; |
1312 | int frscdi = 0; /* Index of the SCD. Initialized to remove the compiler | 1256 | int frscdi = 0; /* Index of the SCD. Initialized to remove the compiler |
1313 | warning. How I wish compilers were clever enough to | 1257 | warning. How I wish compilers were clever enough to |
1314 | tell which variables can truly be used | 1258 | tell which variables can truly be used |
1315 | uninitialized... */ | 1259 | uninitialized... */ |
1316 | int inuse; /* tx or rx vc already in use by another vcc */ | 1260 | int inuse; /* tx or rx vc already in use by another vcc */ |
1317 | short vpi = vcc->vpi; | 1261 | short vpi = vcc->vpi; |
1318 | int vci = vcc->vci; | 1262 | int vci = vcc->vci; |
1319 | 1263 | ||
1320 | card = (ns_dev *) vcc->dev->dev_data; | 1264 | card = (ns_dev *) vcc->dev->dev_data; |
1321 | PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int) vpi, vci); | 1265 | PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int)vpi, |
1322 | if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) | 1266 | vci); |
1323 | { | 1267 | if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) { |
1324 | PRINTK("nicstar%d: unsupported AAL.\n", card->index); | 1268 | PRINTK("nicstar%d: unsupported AAL.\n", card->index); |
1325 | return -EINVAL; | 1269 | return -EINVAL; |
1326 | } | 1270 | } |
1327 | 1271 | ||
1328 | vc = &(card->vcmap[vpi << card->vcibits | vci]); | 1272 | vc = &(card->vcmap[vpi << card->vcibits | vci]); |
1329 | vcc->dev_data = vc; | 1273 | vcc->dev_data = vc; |
1330 | 1274 | ||
1331 | inuse = 0; | 1275 | inuse = 0; |
1332 | if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx) | 1276 | if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx) |
1333 | inuse = 1; | 1277 | inuse = 1; |
1334 | if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx) | 1278 | if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx) |
1335 | inuse += 2; | 1279 | inuse += 2; |
1336 | if (inuse) | 1280 | if (inuse) { |
1337 | { | 1281 | printk("nicstar%d: %s vci already in use.\n", card->index, |
1338 | printk("nicstar%d: %s vci already in use.\n", card->index, | 1282 | inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx"); |
1339 | inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx"); | 1283 | return -EINVAL; |
1340 | return -EINVAL; | 1284 | } |
1341 | } | 1285 | |
1342 | 1286 | set_bit(ATM_VF_ADDR, &vcc->flags); | |
1343 | set_bit(ATM_VF_ADDR,&vcc->flags); | 1287 | |
1344 | 1288 | /* NOTE: You are not allowed to modify an open connection's QOS. To change | |
1345 | /* NOTE: You are not allowed to modify an open connection's QOS. To change | 1289 | that, remove the ATM_VF_PARTIAL flag checking. There may be other changes |
1346 | that, remove the ATM_VF_PARTIAL flag checking. There may be other changes | 1290 | needed to do that. */ |
1347 | needed to do that. */ | 1291 | if (!test_bit(ATM_VF_PARTIAL, &vcc->flags)) { |
1348 | if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) | 1292 | scq_info *scq; |
1349 | { | 1293 | |
1350 | scq_info *scq; | 1294 | set_bit(ATM_VF_PARTIAL, &vcc->flags); |
1351 | 1295 | if (vcc->qos.txtp.traffic_class == ATM_CBR) { | |
1352 | set_bit(ATM_VF_PARTIAL,&vcc->flags); | 1296 | /* Check requested cell rate and availability of SCD */ |
1353 | if (vcc->qos.txtp.traffic_class == ATM_CBR) | 1297 | if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0 |
1354 | { | 1298 | && vcc->qos.txtp.min_pcr == 0) { |
1355 | /* Check requested cell rate and availability of SCD */ | 1299 | PRINTK |
1356 | if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0 && | 1300 | ("nicstar%d: trying to open a CBR vc with cell rate = 0 \n", |
1357 | vcc->qos.txtp.min_pcr == 0) | 1301 | card->index); |
1358 | { | 1302 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1359 | PRINTK("nicstar%d: trying to open a CBR vc with cell rate = 0 \n", | 1303 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1360 | card->index); | 1304 | return -EINVAL; |
1361 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1305 | } |
1362 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1306 | |
1363 | return -EINVAL; | 1307 | tcr = atm_pcr_goal(&(vcc->qos.txtp)); |
1364 | } | 1308 | tcra = tcr >= 0 ? tcr : -tcr; |
1365 | 1309 | ||
1366 | tcr = atm_pcr_goal(&(vcc->qos.txtp)); | 1310 | PRINTK("nicstar%d: target cell rate = %d.\n", |
1367 | tcra = tcr >= 0 ? tcr : -tcr; | 1311 | card->index, vcc->qos.txtp.max_pcr); |
1368 | 1312 | ||
1369 | PRINTK("nicstar%d: target cell rate = %d.\n", card->index, | 1313 | tmpl = |
1370 | vcc->qos.txtp.max_pcr); | 1314 | (unsigned long)tcra *(unsigned long) |
1371 | 1315 | NS_TST_NUM_ENTRIES; | |
1372 | tmpl = (unsigned long)tcra * (unsigned long)NS_TST_NUM_ENTRIES; | 1316 | modl = tmpl % card->max_pcr; |
1373 | modl = tmpl % card->max_pcr; | 1317 | |
1374 | 1318 | n = (int)(tmpl / card->max_pcr); | |
1375 | n = (int)(tmpl / card->max_pcr); | 1319 | if (tcr > 0) { |
1376 | if (tcr > 0) | 1320 | if (modl > 0) |
1377 | { | 1321 | n++; |
1378 | if (modl > 0) n++; | 1322 | } else if (tcr == 0) { |
1379 | } | 1323 | if ((n = |
1380 | else if (tcr == 0) | 1324 | (card->tst_free_entries - |
1381 | { | 1325 | NS_TST_RESERVED)) <= 0) { |
1382 | if ((n = (card->tst_free_entries - NS_TST_RESERVED)) <= 0) | 1326 | PRINTK |
1383 | { | 1327 | ("nicstar%d: no CBR bandwidth free.\n", |
1384 | PRINTK("nicstar%d: no CBR bandwidth free.\n", card->index); | 1328 | card->index); |
1385 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1329 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1386 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1330 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1387 | return -EINVAL; | 1331 | return -EINVAL; |
1388 | } | 1332 | } |
1389 | } | 1333 | } |
1390 | 1334 | ||
1391 | if (n == 0) | 1335 | if (n == 0) { |
1392 | { | 1336 | printk |
1393 | printk("nicstar%d: selected bandwidth < granularity.\n", card->index); | 1337 | ("nicstar%d: selected bandwidth < granularity.\n", |
1394 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1338 | card->index); |
1395 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1339 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1396 | return -EINVAL; | 1340 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1397 | } | 1341 | return -EINVAL; |
1398 | 1342 | } | |
1399 | if (n > (card->tst_free_entries - NS_TST_RESERVED)) | 1343 | |
1400 | { | 1344 | if (n > (card->tst_free_entries - NS_TST_RESERVED)) { |
1401 | PRINTK("nicstar%d: not enough free CBR bandwidth.\n", card->index); | 1345 | PRINTK |
1402 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1346 | ("nicstar%d: not enough free CBR bandwidth.\n", |
1403 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1347 | card->index); |
1404 | return -EINVAL; | 1348 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1405 | } | 1349 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1406 | else | 1350 | return -EINVAL; |
1407 | card->tst_free_entries -= n; | 1351 | } else |
1408 | 1352 | card->tst_free_entries -= n; | |
1409 | XPRINTK("nicstar%d: writing %d tst entries.\n", card->index, n); | 1353 | |
1410 | for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) | 1354 | XPRINTK("nicstar%d: writing %d tst entries.\n", |
1411 | { | 1355 | card->index, n); |
1412 | if (card->scd2vc[frscdi] == NULL) | 1356 | for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) { |
1413 | { | 1357 | if (card->scd2vc[frscdi] == NULL) { |
1414 | card->scd2vc[frscdi] = vc; | 1358 | card->scd2vc[frscdi] = vc; |
1415 | break; | 1359 | break; |
1416 | } | 1360 | } |
1417 | } | 1361 | } |
1418 | if (frscdi == NS_FRSCD_NUM) | 1362 | if (frscdi == NS_FRSCD_NUM) { |
1419 | { | 1363 | PRINTK |
1420 | PRINTK("nicstar%d: no SCD available for CBR channel.\n", card->index); | 1364 | ("nicstar%d: no SCD available for CBR channel.\n", |
1421 | card->tst_free_entries += n; | 1365 | card->index); |
1422 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1366 | card->tst_free_entries += n; |
1423 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1367 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1424 | return -EBUSY; | 1368 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1425 | } | 1369 | return -EBUSY; |
1426 | 1370 | } | |
1427 | vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; | 1371 | |
1428 | 1372 | vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; | |
1429 | scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); | 1373 | |
1430 | if (scq == NULL) | 1374 | scq = get_scq(card, CBR_SCQSIZE, vc->cbr_scd); |
1431 | { | 1375 | if (scq == NULL) { |
1432 | PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); | 1376 | PRINTK("nicstar%d: can't get fixed rate SCQ.\n", |
1433 | card->scd2vc[frscdi] = NULL; | 1377 | card->index); |
1434 | card->tst_free_entries += n; | 1378 | card->scd2vc[frscdi] = NULL; |
1435 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | 1379 | card->tst_free_entries += n; |
1436 | clear_bit(ATM_VF_ADDR,&vcc->flags); | 1380 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); |
1437 | return -ENOMEM; | 1381 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1438 | } | 1382 | return -ENOMEM; |
1439 | vc->scq = scq; | 1383 | } |
1440 | u32d[0] = (u32) virt_to_bus(scq->base); | 1384 | vc->scq = scq; |
1441 | u32d[1] = (u32) 0x00000000; | 1385 | u32d[0] = scq_virt_to_bus(scq, scq->base); |
1442 | u32d[2] = (u32) 0xffffffff; | 1386 | u32d[1] = (u32) 0x00000000; |
1443 | u32d[3] = (u32) 0x00000000; | 1387 | u32d[2] = (u32) 0xffffffff; |
1444 | ns_write_sram(card, vc->cbr_scd, u32d, 4); | 1388 | u32d[3] = (u32) 0x00000000; |
1445 | 1389 | ns_write_sram(card, vc->cbr_scd, u32d, 4); | |
1446 | fill_tst(card, n, vc); | 1390 | |
1447 | } | 1391 | fill_tst(card, n, vc); |
1448 | else if (vcc->qos.txtp.traffic_class == ATM_UBR) | 1392 | } else if (vcc->qos.txtp.traffic_class == ATM_UBR) { |
1449 | { | 1393 | vc->cbr_scd = 0x00000000; |
1450 | vc->cbr_scd = 0x00000000; | 1394 | vc->scq = card->scq0; |
1451 | vc->scq = card->scq0; | 1395 | } |
1452 | } | 1396 | |
1453 | 1397 | if (vcc->qos.txtp.traffic_class != ATM_NONE) { | |
1454 | if (vcc->qos.txtp.traffic_class != ATM_NONE) | 1398 | vc->tx = 1; |
1455 | { | 1399 | vc->tx_vcc = vcc; |
1456 | vc->tx = 1; | 1400 | vc->tbd_count = 0; |
1457 | vc->tx_vcc = vcc; | 1401 | } |
1458 | vc->tbd_count = 0; | 1402 | if (vcc->qos.rxtp.traffic_class != ATM_NONE) { |
1459 | } | 1403 | u32 status; |
1460 | if (vcc->qos.rxtp.traffic_class != ATM_NONE) | 1404 | |
1461 | { | 1405 | vc->rx = 1; |
1462 | u32 status; | 1406 | vc->rx_vcc = vcc; |
1463 | 1407 | vc->rx_iov = NULL; | |
1464 | vc->rx = 1; | 1408 | |
1465 | vc->rx_vcc = vcc; | 1409 | /* Open the connection in hardware */ |
1466 | vc->rx_iov = NULL; | 1410 | if (vcc->qos.aal == ATM_AAL5) |
1467 | 1411 | status = NS_RCTE_AAL5 | NS_RCTE_CONNECTOPEN; | |
1468 | /* Open the connection in hardware */ | 1412 | else /* vcc->qos.aal == ATM_AAL0 */ |
1469 | if (vcc->qos.aal == ATM_AAL5) | 1413 | status = NS_RCTE_AAL0 | NS_RCTE_CONNECTOPEN; |
1470 | status = NS_RCTE_AAL5 | NS_RCTE_CONNECTOPEN; | ||
1471 | else /* vcc->qos.aal == ATM_AAL0 */ | ||
1472 | status = NS_RCTE_AAL0 | NS_RCTE_CONNECTOPEN; | ||
1473 | #ifdef RCQ_SUPPORT | 1414 | #ifdef RCQ_SUPPORT |
1474 | status |= NS_RCTE_RAWCELLINTEN; | 1415 | status |= NS_RCTE_RAWCELLINTEN; |
1475 | #endif /* RCQ_SUPPORT */ | 1416 | #endif /* RCQ_SUPPORT */ |
1476 | ns_write_sram(card, NS_RCT + (vpi << card->vcibits | vci) * | 1417 | ns_write_sram(card, |
1477 | NS_RCT_ENTRY_SIZE, &status, 1); | 1418 | NS_RCT + |
1478 | } | 1419 | (vpi << card->vcibits | vci) * |
1479 | 1420 | NS_RCT_ENTRY_SIZE, &status, 1); | |
1480 | } | 1421 | } |
1481 | |||
1482 | set_bit(ATM_VF_READY,&vcc->flags); | ||
1483 | return 0; | ||
1484 | } | ||
1485 | 1422 | ||
1423 | } | ||
1486 | 1424 | ||
1425 | set_bit(ATM_VF_READY, &vcc->flags); | ||
1426 | return 0; | ||
1427 | } | ||
1487 | 1428 | ||
1488 | static void ns_close(struct atm_vcc *vcc) | 1429 | static void ns_close(struct atm_vcc *vcc) |
1489 | { | 1430 | { |
1490 | vc_map *vc; | 1431 | vc_map *vc; |
1491 | ns_dev *card; | 1432 | ns_dev *card; |
1492 | u32 data; | 1433 | u32 data; |
1493 | int i; | 1434 | int i; |
1494 | 1435 | ||
1495 | vc = vcc->dev_data; | 1436 | vc = vcc->dev_data; |
1496 | card = vcc->dev->dev_data; | 1437 | card = vcc->dev->dev_data; |
1497 | PRINTK("nicstar%d: closing vpi.vci %d.%d \n", card->index, | 1438 | PRINTK("nicstar%d: closing vpi.vci %d.%d \n", card->index, |
1498 | (int) vcc->vpi, vcc->vci); | 1439 | (int)vcc->vpi, vcc->vci); |
1499 | 1440 | ||
1500 | clear_bit(ATM_VF_READY,&vcc->flags); | 1441 | clear_bit(ATM_VF_READY, &vcc->flags); |
1501 | 1442 | ||
1502 | if (vcc->qos.rxtp.traffic_class != ATM_NONE) | 1443 | if (vcc->qos.rxtp.traffic_class != ATM_NONE) { |
1503 | { | 1444 | u32 addr; |
1504 | u32 addr; | 1445 | unsigned long flags; |
1505 | unsigned long flags; | 1446 | |
1506 | 1447 | addr = | |
1507 | addr = NS_RCT + (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE; | 1448 | NS_RCT + |
1508 | spin_lock_irqsave(&card->res_lock, flags); | 1449 | (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE; |
1509 | while(CMD_BUSY(card)); | 1450 | spin_lock_irqsave(&card->res_lock, flags); |
1510 | writel(NS_CMD_CLOSE_CONNECTION | addr << 2, card->membase + CMD); | 1451 | while (CMD_BUSY(card)) ; |
1511 | spin_unlock_irqrestore(&card->res_lock, flags); | 1452 | writel(NS_CMD_CLOSE_CONNECTION | addr << 2, |
1512 | 1453 | card->membase + CMD); | |
1513 | vc->rx = 0; | 1454 | spin_unlock_irqrestore(&card->res_lock, flags); |
1514 | if (vc->rx_iov != NULL) | 1455 | |
1515 | { | 1456 | vc->rx = 0; |
1516 | struct sk_buff *iovb; | 1457 | if (vc->rx_iov != NULL) { |
1517 | u32 stat; | 1458 | struct sk_buff *iovb; |
1518 | 1459 | u32 stat; | |
1519 | stat = readl(card->membase + STAT); | 1460 | |
1520 | card->sbfqc = ns_stat_sfbqc_get(stat); | 1461 | stat = readl(card->membase + STAT); |
1521 | card->lbfqc = ns_stat_lfbqc_get(stat); | 1462 | card->sbfqc = ns_stat_sfbqc_get(stat); |
1522 | 1463 | card->lbfqc = ns_stat_lfbqc_get(stat); | |
1523 | PRINTK("nicstar%d: closing a VC with pending rx buffers.\n", | 1464 | |
1524 | card->index); | 1465 | PRINTK |
1525 | iovb = vc->rx_iov; | 1466 | ("nicstar%d: closing a VC with pending rx buffers.\n", |
1526 | recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, | 1467 | card->index); |
1527 | NS_SKB(iovb)->iovcnt); | 1468 | iovb = vc->rx_iov; |
1528 | NS_SKB(iovb)->iovcnt = 0; | 1469 | recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data, |
1529 | NS_SKB(iovb)->vcc = NULL; | 1470 | NS_PRV_IOVCNT(iovb)); |
1530 | spin_lock_irqsave(&card->int_lock, flags); | 1471 | NS_PRV_IOVCNT(iovb) = 0; |
1531 | recycle_iov_buf(card, iovb); | 1472 | spin_lock_irqsave(&card->int_lock, flags); |
1532 | spin_unlock_irqrestore(&card->int_lock, flags); | 1473 | recycle_iov_buf(card, iovb); |
1533 | vc->rx_iov = NULL; | 1474 | spin_unlock_irqrestore(&card->int_lock, flags); |
1534 | } | 1475 | vc->rx_iov = NULL; |
1535 | } | 1476 | } |
1536 | 1477 | } | |
1537 | if (vcc->qos.txtp.traffic_class != ATM_NONE) | 1478 | |
1538 | { | 1479 | if (vcc->qos.txtp.traffic_class != ATM_NONE) { |
1539 | vc->tx = 0; | 1480 | vc->tx = 0; |
1540 | } | 1481 | } |
1541 | 1482 | ||
1542 | if (vcc->qos.txtp.traffic_class == ATM_CBR) | 1483 | if (vcc->qos.txtp.traffic_class == ATM_CBR) { |
1543 | { | 1484 | unsigned long flags; |
1544 | unsigned long flags; | 1485 | ns_scqe *scqep; |
1545 | ns_scqe *scqep; | 1486 | scq_info *scq; |
1546 | scq_info *scq; | 1487 | |
1547 | 1488 | scq = vc->scq; | |
1548 | scq = vc->scq; | 1489 | |
1549 | 1490 | for (;;) { | |
1550 | for (;;) | 1491 | spin_lock_irqsave(&scq->lock, flags); |
1551 | { | 1492 | scqep = scq->next; |
1552 | spin_lock_irqsave(&scq->lock, flags); | 1493 | if (scqep == scq->base) |
1553 | scqep = scq->next; | 1494 | scqep = scq->last; |
1554 | if (scqep == scq->base) | 1495 | else |
1555 | scqep = scq->last; | 1496 | scqep--; |
1556 | else | 1497 | if (scqep == scq->tail) { |
1557 | scqep--; | 1498 | spin_unlock_irqrestore(&scq->lock, flags); |
1558 | if (scqep == scq->tail) | 1499 | break; |
1559 | { | 1500 | } |
1560 | spin_unlock_irqrestore(&scq->lock, flags); | 1501 | /* If the last entry is not a TSR, place one in the SCQ in order to |
1561 | break; | 1502 | be able to completely drain it and then close. */ |
1562 | } | 1503 | if (!ns_scqe_is_tsr(scqep) && scq->tail != scq->next) { |
1563 | /* If the last entry is not a TSR, place one in the SCQ in order to | 1504 | ns_scqe tsr; |
1564 | be able to completely drain it and then close. */ | 1505 | u32 scdi, scqi; |
1565 | if (!ns_scqe_is_tsr(scqep) && scq->tail != scq->next) | 1506 | u32 data; |
1566 | { | 1507 | int index; |
1567 | ns_scqe tsr; | 1508 | |
1568 | u32 scdi, scqi; | 1509 | tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); |
1569 | u32 data; | 1510 | scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; |
1570 | int index; | 1511 | scqi = scq->next - scq->base; |
1571 | 1512 | tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); | |
1572 | tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); | 1513 | tsr.word_3 = 0x00000000; |
1573 | scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; | 1514 | tsr.word_4 = 0x00000000; |
1574 | scqi = scq->next - scq->base; | 1515 | *scq->next = tsr; |
1575 | tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); | 1516 | index = (int)scqi; |
1576 | tsr.word_3 = 0x00000000; | 1517 | scq->skb[index] = NULL; |
1577 | tsr.word_4 = 0x00000000; | 1518 | if (scq->next == scq->last) |
1578 | *scq->next = tsr; | 1519 | scq->next = scq->base; |
1579 | index = (int) scqi; | 1520 | else |
1580 | scq->skb[index] = NULL; | 1521 | scq->next++; |
1581 | if (scq->next == scq->last) | 1522 | data = scq_virt_to_bus(scq, scq->next); |
1582 | scq->next = scq->base; | 1523 | ns_write_sram(card, scq->scd, &data, 1); |
1583 | else | 1524 | } |
1584 | scq->next++; | 1525 | spin_unlock_irqrestore(&scq->lock, flags); |
1585 | data = (u32) virt_to_bus(scq->next); | 1526 | schedule(); |
1586 | ns_write_sram(card, scq->scd, &data, 1); | 1527 | } |
1587 | } | 1528 | |
1588 | spin_unlock_irqrestore(&scq->lock, flags); | 1529 | /* Free all TST entries */ |
1589 | schedule(); | 1530 | data = NS_TST_OPCODE_VARIABLE; |
1590 | } | 1531 | for (i = 0; i < NS_TST_NUM_ENTRIES; i++) { |
1591 | 1532 | if (card->tste2vc[i] == vc) { | |
1592 | /* Free all TST entries */ | 1533 | ns_write_sram(card, card->tst_addr + i, &data, |
1593 | data = NS_TST_OPCODE_VARIABLE; | 1534 | 1); |
1594 | for (i = 0; i < NS_TST_NUM_ENTRIES; i++) | 1535 | card->tste2vc[i] = NULL; |
1595 | { | 1536 | card->tst_free_entries++; |
1596 | if (card->tste2vc[i] == vc) | 1537 | } |
1597 | { | 1538 | } |
1598 | ns_write_sram(card, card->tst_addr + i, &data, 1); | 1539 | |
1599 | card->tste2vc[i] = NULL; | 1540 | card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL; |
1600 | card->tst_free_entries++; | 1541 | free_scq(card, vc->scq, vcc); |
1601 | } | 1542 | } |
1602 | } | 1543 | |
1603 | 1544 | /* remove all references to vcc before deleting it */ | |
1604 | card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL; | 1545 | if (vcc->qos.txtp.traffic_class != ATM_NONE) { |
1605 | free_scq(vc->scq, vcc); | 1546 | unsigned long flags; |
1606 | } | 1547 | scq_info *scq = card->scq0; |
1607 | 1548 | ||
1608 | /* remove all references to vcc before deleting it */ | 1549 | spin_lock_irqsave(&scq->lock, flags); |
1609 | if (vcc->qos.txtp.traffic_class != ATM_NONE) | 1550 | |
1610 | { | 1551 | for (i = 0; i < scq->num_entries; i++) { |
1611 | unsigned long flags; | 1552 | if (scq->skb[i] && ATM_SKB(scq->skb[i])->vcc == vcc) { |
1612 | scq_info *scq = card->scq0; | 1553 | ATM_SKB(scq->skb[i])->vcc = NULL; |
1613 | 1554 | atm_return(vcc, scq->skb[i]->truesize); | |
1614 | spin_lock_irqsave(&scq->lock, flags); | 1555 | PRINTK |
1615 | 1556 | ("nicstar: deleted pending vcc mapping\n"); | |
1616 | for(i = 0; i < scq->num_entries; i++) { | 1557 | } |
1617 | if(scq->skb[i] && ATM_SKB(scq->skb[i])->vcc == vcc) { | 1558 | } |
1618 | ATM_SKB(scq->skb[i])->vcc = NULL; | 1559 | |
1619 | atm_return(vcc, scq->skb[i]->truesize); | 1560 | spin_unlock_irqrestore(&scq->lock, flags); |
1620 | PRINTK("nicstar: deleted pending vcc mapping\n"); | 1561 | } |
1621 | } | 1562 | |
1622 | } | 1563 | vcc->dev_data = NULL; |
1623 | 1564 | clear_bit(ATM_VF_PARTIAL, &vcc->flags); | |
1624 | spin_unlock_irqrestore(&scq->lock, flags); | 1565 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
1625 | } | ||
1626 | |||
1627 | vcc->dev_data = NULL; | ||
1628 | clear_bit(ATM_VF_PARTIAL,&vcc->flags); | ||
1629 | clear_bit(ATM_VF_ADDR,&vcc->flags); | ||
1630 | 1566 | ||
1631 | #ifdef RX_DEBUG | 1567 | #ifdef RX_DEBUG |
1632 | { | 1568 | { |
1633 | u32 stat, cfg; | 1569 | u32 stat, cfg; |
1634 | stat = readl(card->membase + STAT); | 1570 | stat = readl(card->membase + STAT); |
1635 | cfg = readl(card->membase + CFG); | 1571 | cfg = readl(card->membase + CFG); |
1636 | printk("STAT = 0x%08X CFG = 0x%08X \n", stat, cfg); | 1572 | printk("STAT = 0x%08X CFG = 0x%08X \n", stat, cfg); |
1637 | printk("TSQ: base = 0x%08X next = 0x%08X last = 0x%08X TSQT = 0x%08X \n", | 1573 | printk |
1638 | (u32) card->tsq.base, (u32) card->tsq.next,(u32) card->tsq.last, | 1574 | ("TSQ: base = 0x%p next = 0x%p last = 0x%p TSQT = 0x%08X \n", |
1639 | readl(card->membase + TSQT)); | 1575 | card->tsq.base, card->tsq.next, |
1640 | printk("RSQ: base = 0x%08X next = 0x%08X last = 0x%08X RSQT = 0x%08X \n", | 1576 | card->tsq.last, readl(card->membase + TSQT)); |
1641 | (u32) card->rsq.base, (u32) card->rsq.next,(u32) card->rsq.last, | 1577 | printk |
1642 | readl(card->membase + RSQT)); | 1578 | ("RSQ: base = 0x%p next = 0x%p last = 0x%p RSQT = 0x%08X \n", |
1643 | printk("Empty free buffer queue interrupt %s \n", | 1579 | card->rsq.base, card->rsq.next, |
1644 | card->efbie ? "enabled" : "disabled"); | 1580 | card->rsq.last, readl(card->membase + RSQT)); |
1645 | printk("SBCNT = %d count = %d LBCNT = %d count = %d \n", | 1581 | printk("Empty free buffer queue interrupt %s \n", |
1646 | ns_stat_sfbqc_get(stat), card->sbpool.count, | 1582 | card->efbie ? "enabled" : "disabled"); |
1647 | ns_stat_lfbqc_get(stat), card->lbpool.count); | 1583 | printk("SBCNT = %d count = %d LBCNT = %d count = %d \n", |
1648 | printk("hbpool.count = %d iovpool.count = %d \n", | 1584 | ns_stat_sfbqc_get(stat), card->sbpool.count, |
1649 | card->hbpool.count, card->iovpool.count); | 1585 | ns_stat_lfbqc_get(stat), card->lbpool.count); |
1650 | } | 1586 | printk("hbpool.count = %d iovpool.count = %d \n", |
1587 | card->hbpool.count, card->iovpool.count); | ||
1588 | } | ||
1651 | #endif /* RX_DEBUG */ | 1589 | #endif /* RX_DEBUG */ |
1652 | } | 1590 | } |
1653 | 1591 | ||
1654 | 1592 | static void fill_tst(ns_dev * card, int n, vc_map * vc) | |
1655 | |||
1656 | static void fill_tst(ns_dev *card, int n, vc_map *vc) | ||
1657 | { | 1593 | { |
1658 | u32 new_tst; | 1594 | u32 new_tst; |
1659 | unsigned long cl; | 1595 | unsigned long cl; |
1660 | int e, r; | 1596 | int e, r; |
1661 | u32 data; | 1597 | u32 data; |
1662 | 1598 | ||
1663 | /* It would be very complicated to keep the two TSTs synchronized while | 1599 | /* It would be very complicated to keep the two TSTs synchronized while |
1664 | assuring that writes are only made to the inactive TST. So, for now I | 1600 | assuring that writes are only made to the inactive TST. So, for now I |
1665 | will use only one TST. If problems occur, I will change this again */ | 1601 | will use only one TST. If problems occur, I will change this again */ |
1666 | 1602 | ||
1667 | new_tst = card->tst_addr; | 1603 | new_tst = card->tst_addr; |
1668 | 1604 | ||
1669 | /* Fill procedure */ | 1605 | /* Fill procedure */ |
1670 | 1606 | ||
1671 | for (e = 0; e < NS_TST_NUM_ENTRIES; e++) | 1607 | for (e = 0; e < NS_TST_NUM_ENTRIES; e++) { |
1672 | { | 1608 | if (card->tste2vc[e] == NULL) |
1673 | if (card->tste2vc[e] == NULL) | 1609 | break; |
1674 | break; | 1610 | } |
1675 | } | 1611 | if (e == NS_TST_NUM_ENTRIES) { |
1676 | if (e == NS_TST_NUM_ENTRIES) { | 1612 | printk("nicstar%d: No free TST entries found. \n", card->index); |
1677 | printk("nicstar%d: No free TST entries found. \n", card->index); | 1613 | return; |
1678 | return; | 1614 | } |
1679 | } | 1615 | |
1680 | 1616 | r = n; | |
1681 | r = n; | 1617 | cl = NS_TST_NUM_ENTRIES; |
1682 | cl = NS_TST_NUM_ENTRIES; | 1618 | data = ns_tste_make(NS_TST_OPCODE_FIXED, vc->cbr_scd); |
1683 | data = ns_tste_make(NS_TST_OPCODE_FIXED, vc->cbr_scd); | 1619 | |
1684 | 1620 | while (r > 0) { | |
1685 | while (r > 0) | 1621 | if (cl >= NS_TST_NUM_ENTRIES && card->tste2vc[e] == NULL) { |
1686 | { | 1622 | card->tste2vc[e] = vc; |
1687 | if (cl >= NS_TST_NUM_ENTRIES && card->tste2vc[e] == NULL) | 1623 | ns_write_sram(card, new_tst + e, &data, 1); |
1688 | { | 1624 | cl -= NS_TST_NUM_ENTRIES; |
1689 | card->tste2vc[e] = vc; | 1625 | r--; |
1690 | ns_write_sram(card, new_tst + e, &data, 1); | 1626 | } |
1691 | cl -= NS_TST_NUM_ENTRIES; | 1627 | |
1692 | r--; | 1628 | if (++e == NS_TST_NUM_ENTRIES) { |
1693 | } | 1629 | e = 0; |
1694 | 1630 | } | |
1695 | if (++e == NS_TST_NUM_ENTRIES) { | 1631 | cl += n; |
1696 | e = 0; | 1632 | } |
1697 | } | 1633 | |
1698 | cl += n; | 1634 | /* End of fill procedure */ |
1699 | } | 1635 | |
1700 | 1636 | data = ns_tste_make(NS_TST_OPCODE_END, new_tst); | |
1701 | /* End of fill procedure */ | 1637 | ns_write_sram(card, new_tst + NS_TST_NUM_ENTRIES, &data, 1); |
1702 | 1638 | ns_write_sram(card, card->tst_addr + NS_TST_NUM_ENTRIES, &data, 1); | |
1703 | data = ns_tste_make(NS_TST_OPCODE_END, new_tst); | 1639 | card->tst_addr = new_tst; |
1704 | ns_write_sram(card, new_tst + NS_TST_NUM_ENTRIES, &data, 1); | ||
1705 | ns_write_sram(card, card->tst_addr + NS_TST_NUM_ENTRIES, &data, 1); | ||
1706 | card->tst_addr = new_tst; | ||
1707 | } | 1640 | } |
1708 | 1641 | ||
1709 | |||
1710 | |||
1711 | static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb) | 1642 | static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb) |
1712 | { | 1643 | { |
1713 | ns_dev *card; | 1644 | ns_dev *card; |
1714 | vc_map *vc; | 1645 | vc_map *vc; |
1715 | scq_info *scq; | 1646 | scq_info *scq; |
1716 | unsigned long buflen; | 1647 | unsigned long buflen; |
1717 | ns_scqe scqe; | 1648 | ns_scqe scqe; |
1718 | u32 flags; /* TBD flags, not CPU flags */ | 1649 | u32 flags; /* TBD flags, not CPU flags */ |
1719 | 1650 | ||
1720 | card = vcc->dev->dev_data; | 1651 | card = vcc->dev->dev_data; |
1721 | TXPRINTK("nicstar%d: ns_send() called.\n", card->index); | 1652 | TXPRINTK("nicstar%d: ns_send() called.\n", card->index); |
1722 | if ((vc = (vc_map *) vcc->dev_data) == NULL) | 1653 | if ((vc = (vc_map *) vcc->dev_data) == NULL) { |
1723 | { | 1654 | printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", |
1724 | printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n", card->index); | 1655 | card->index); |
1725 | atomic_inc(&vcc->stats->tx_err); | 1656 | atomic_inc(&vcc->stats->tx_err); |
1726 | dev_kfree_skb_any(skb); | 1657 | dev_kfree_skb_any(skb); |
1727 | return -EINVAL; | 1658 | return -EINVAL; |
1728 | } | 1659 | } |
1729 | |||
1730 | if (!vc->tx) | ||
1731 | { | ||
1732 | printk("nicstar%d: Trying to transmit on a non-tx VC.\n", card->index); | ||
1733 | atomic_inc(&vcc->stats->tx_err); | ||
1734 | dev_kfree_skb_any(skb); | ||
1735 | return -EINVAL; | ||
1736 | } | ||
1737 | |||
1738 | if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) | ||
1739 | { | ||
1740 | printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", card->index); | ||
1741 | atomic_inc(&vcc->stats->tx_err); | ||
1742 | dev_kfree_skb_any(skb); | ||
1743 | return -EINVAL; | ||
1744 | } | ||
1745 | |||
1746 | if (skb_shinfo(skb)->nr_frags != 0) | ||
1747 | { | ||
1748 | printk("nicstar%d: No scatter-gather yet.\n", card->index); | ||
1749 | atomic_inc(&vcc->stats->tx_err); | ||
1750 | dev_kfree_skb_any(skb); | ||
1751 | return -EINVAL; | ||
1752 | } | ||
1753 | |||
1754 | ATM_SKB(skb)->vcc = vcc; | ||
1755 | |||
1756 | if (vcc->qos.aal == ATM_AAL5) | ||
1757 | { | ||
1758 | buflen = (skb->len + 47 + 8) / 48 * 48; /* Multiple of 48 */ | ||
1759 | flags = NS_TBD_AAL5; | ||
1760 | scqe.word_2 = cpu_to_le32((u32) virt_to_bus(skb->data)); | ||
1761 | scqe.word_3 = cpu_to_le32((u32) skb->len); | ||
1762 | scqe.word_4 = ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0, | ||
1763 | ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? 1 : 0); | ||
1764 | flags |= NS_TBD_EOPDU; | ||
1765 | } | ||
1766 | else /* (vcc->qos.aal == ATM_AAL0) */ | ||
1767 | { | ||
1768 | buflen = ATM_CELL_PAYLOAD; /* i.e., 48 bytes */ | ||
1769 | flags = NS_TBD_AAL0; | ||
1770 | scqe.word_2 = cpu_to_le32((u32) virt_to_bus(skb->data) + NS_AAL0_HEADER); | ||
1771 | scqe.word_3 = cpu_to_le32(0x00000000); | ||
1772 | if (*skb->data & 0x02) /* Payload type 1 - end of pdu */ | ||
1773 | flags |= NS_TBD_EOPDU; | ||
1774 | scqe.word_4 = cpu_to_le32(*((u32 *) skb->data) & ~NS_TBD_VC_MASK); | ||
1775 | /* Force the VPI/VCI to be the same as in VCC struct */ | ||
1776 | scqe.word_4 |= cpu_to_le32((((u32) vcc->vpi) << NS_TBD_VPI_SHIFT | | ||
1777 | ((u32) vcc->vci) << NS_TBD_VCI_SHIFT) & | ||
1778 | NS_TBD_VC_MASK); | ||
1779 | } | ||
1780 | |||
1781 | if (vcc->qos.txtp.traffic_class == ATM_CBR) | ||
1782 | { | ||
1783 | scqe.word_1 = ns_tbd_mkword_1_novbr(flags, (u32) buflen); | ||
1784 | scq = ((vc_map *) vcc->dev_data)->scq; | ||
1785 | } | ||
1786 | else | ||
1787 | { | ||
1788 | scqe.word_1 = ns_tbd_mkword_1(flags, (u32) 1, (u32) 1, (u32) buflen); | ||
1789 | scq = card->scq0; | ||
1790 | } | ||
1791 | |||
1792 | if (push_scqe(card, vc, scq, &scqe, skb) != 0) | ||
1793 | { | ||
1794 | atomic_inc(&vcc->stats->tx_err); | ||
1795 | dev_kfree_skb_any(skb); | ||
1796 | return -EIO; | ||
1797 | } | ||
1798 | atomic_inc(&vcc->stats->tx); | ||
1799 | |||
1800 | return 0; | ||
1801 | } | ||
1802 | |||
1803 | 1660 | ||
1661 | if (!vc->tx) { | ||
1662 | printk("nicstar%d: Trying to transmit on a non-tx VC.\n", | ||
1663 | card->index); | ||
1664 | atomic_inc(&vcc->stats->tx_err); | ||
1665 | dev_kfree_skb_any(skb); | ||
1666 | return -EINVAL; | ||
1667 | } | ||
1804 | 1668 | ||
1805 | static int push_scqe(ns_dev *card, vc_map *vc, scq_info *scq, ns_scqe *tbd, | 1669 | if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) { |
1806 | struct sk_buff *skb) | 1670 | printk("nicstar%d: Only AAL0 and AAL5 are supported.\n", |
1807 | { | 1671 | card->index); |
1808 | unsigned long flags; | 1672 | atomic_inc(&vcc->stats->tx_err); |
1809 | ns_scqe tsr; | 1673 | dev_kfree_skb_any(skb); |
1810 | u32 scdi, scqi; | 1674 | return -EINVAL; |
1811 | int scq_is_vbr; | 1675 | } |
1812 | u32 data; | ||
1813 | int index; | ||
1814 | |||
1815 | spin_lock_irqsave(&scq->lock, flags); | ||
1816 | while (scq->tail == scq->next) | ||
1817 | { | ||
1818 | if (in_interrupt()) { | ||
1819 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1820 | printk("nicstar%d: Error pushing TBD.\n", card->index); | ||
1821 | return 1; | ||
1822 | } | ||
1823 | |||
1824 | scq->full = 1; | ||
1825 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1826 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, SCQFULL_TIMEOUT); | ||
1827 | spin_lock_irqsave(&scq->lock, flags); | ||
1828 | |||
1829 | if (scq->full) { | ||
1830 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1831 | printk("nicstar%d: Timeout pushing TBD.\n", card->index); | ||
1832 | return 1; | ||
1833 | } | ||
1834 | } | ||
1835 | *scq->next = *tbd; | ||
1836 | index = (int) (scq->next - scq->base); | ||
1837 | scq->skb[index] = skb; | ||
1838 | XPRINTK("nicstar%d: sending skb at 0x%x (pos %d).\n", | ||
1839 | card->index, (u32) skb, index); | ||
1840 | XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%x.\n", | ||
1841 | card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2), | ||
1842 | le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4), | ||
1843 | (u32) scq->next); | ||
1844 | if (scq->next == scq->last) | ||
1845 | scq->next = scq->base; | ||
1846 | else | ||
1847 | scq->next++; | ||
1848 | |||
1849 | vc->tbd_count++; | ||
1850 | if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) | ||
1851 | { | ||
1852 | scq->tbd_count++; | ||
1853 | scq_is_vbr = 1; | ||
1854 | } | ||
1855 | else | ||
1856 | scq_is_vbr = 0; | ||
1857 | |||
1858 | if (vc->tbd_count >= MAX_TBD_PER_VC || scq->tbd_count >= MAX_TBD_PER_SCQ) | ||
1859 | { | ||
1860 | int has_run = 0; | ||
1861 | |||
1862 | while (scq->tail == scq->next) | ||
1863 | { | ||
1864 | if (in_interrupt()) { | ||
1865 | data = (u32) virt_to_bus(scq->next); | ||
1866 | ns_write_sram(card, scq->scd, &data, 1); | ||
1867 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1868 | printk("nicstar%d: Error pushing TSR.\n", card->index); | ||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | scq->full = 1; | ||
1873 | if (has_run++) break; | ||
1874 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1875 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, SCQFULL_TIMEOUT); | ||
1876 | spin_lock_irqsave(&scq->lock, flags); | ||
1877 | } | ||
1878 | |||
1879 | if (!scq->full) | ||
1880 | { | ||
1881 | tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); | ||
1882 | if (scq_is_vbr) | ||
1883 | scdi = NS_TSR_SCDISVBR; | ||
1884 | else | ||
1885 | scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; | ||
1886 | scqi = scq->next - scq->base; | ||
1887 | tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); | ||
1888 | tsr.word_3 = 0x00000000; | ||
1889 | tsr.word_4 = 0x00000000; | ||
1890 | |||
1891 | *scq->next = tsr; | ||
1892 | index = (int) scqi; | ||
1893 | scq->skb[index] = NULL; | ||
1894 | XPRINTK("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%x.\n", | ||
1895 | card->index, le32_to_cpu(tsr.word_1), le32_to_cpu(tsr.word_2), | ||
1896 | le32_to_cpu(tsr.word_3), le32_to_cpu(tsr.word_4), | ||
1897 | (u32) scq->next); | ||
1898 | if (scq->next == scq->last) | ||
1899 | scq->next = scq->base; | ||
1900 | else | ||
1901 | scq->next++; | ||
1902 | vc->tbd_count = 0; | ||
1903 | scq->tbd_count = 0; | ||
1904 | } | ||
1905 | else | ||
1906 | PRINTK("nicstar%d: Timeout pushing TSR.\n", card->index); | ||
1907 | } | ||
1908 | data = (u32) virt_to_bus(scq->next); | ||
1909 | ns_write_sram(card, scq->scd, &data, 1); | ||
1910 | |||
1911 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1912 | |||
1913 | return 0; | ||
1914 | } | ||
1915 | 1676 | ||
1677 | if (skb_shinfo(skb)->nr_frags != 0) { | ||
1678 | printk("nicstar%d: No scatter-gather yet.\n", card->index); | ||
1679 | atomic_inc(&vcc->stats->tx_err); | ||
1680 | dev_kfree_skb_any(skb); | ||
1681 | return -EINVAL; | ||
1682 | } | ||
1683 | |||
1684 | ATM_SKB(skb)->vcc = vcc; | ||
1685 | |||
1686 | NS_PRV_DMA(skb) = pci_map_single(card->pcidev, skb->data, | ||
1687 | skb->len, PCI_DMA_TODEVICE); | ||
1688 | |||
1689 | if (vcc->qos.aal == ATM_AAL5) { | ||
1690 | buflen = (skb->len + 47 + 8) / 48 * 48; /* Multiple of 48 */ | ||
1691 | flags = NS_TBD_AAL5; | ||
1692 | scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb)); | ||
1693 | scqe.word_3 = cpu_to_le32(skb->len); | ||
1694 | scqe.word_4 = | ||
1695 | ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0, | ||
1696 | ATM_SKB(skb)-> | ||
1697 | atm_options & ATM_ATMOPT_CLP ? 1 : 0); | ||
1698 | flags |= NS_TBD_EOPDU; | ||
1699 | } else { /* (vcc->qos.aal == ATM_AAL0) */ | ||
1700 | |||
1701 | buflen = ATM_CELL_PAYLOAD; /* i.e., 48 bytes */ | ||
1702 | flags = NS_TBD_AAL0; | ||
1703 | scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb) + NS_AAL0_HEADER); | ||
1704 | scqe.word_3 = cpu_to_le32(0x00000000); | ||
1705 | if (*skb->data & 0x02) /* Payload type 1 - end of pdu */ | ||
1706 | flags |= NS_TBD_EOPDU; | ||
1707 | scqe.word_4 = | ||
1708 | cpu_to_le32(*((u32 *) skb->data) & ~NS_TBD_VC_MASK); | ||
1709 | /* Force the VPI/VCI to be the same as in VCC struct */ | ||
1710 | scqe.word_4 |= | ||
1711 | cpu_to_le32((((u32) vcc-> | ||
1712 | vpi) << NS_TBD_VPI_SHIFT | ((u32) vcc-> | ||
1713 | vci) << | ||
1714 | NS_TBD_VCI_SHIFT) & NS_TBD_VC_MASK); | ||
1715 | } | ||
1716 | |||
1717 | if (vcc->qos.txtp.traffic_class == ATM_CBR) { | ||
1718 | scqe.word_1 = ns_tbd_mkword_1_novbr(flags, (u32) buflen); | ||
1719 | scq = ((vc_map *) vcc->dev_data)->scq; | ||
1720 | } else { | ||
1721 | scqe.word_1 = | ||
1722 | ns_tbd_mkword_1(flags, (u32) 1, (u32) 1, (u32) buflen); | ||
1723 | scq = card->scq0; | ||
1724 | } | ||
1725 | |||
1726 | if (push_scqe(card, vc, scq, &scqe, skb) != 0) { | ||
1727 | atomic_inc(&vcc->stats->tx_err); | ||
1728 | dev_kfree_skb_any(skb); | ||
1729 | return -EIO; | ||
1730 | } | ||
1731 | atomic_inc(&vcc->stats->tx); | ||
1916 | 1732 | ||
1733 | return 0; | ||
1734 | } | ||
1917 | 1735 | ||
1918 | static void process_tsq(ns_dev *card) | 1736 | static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd, |
1737 | struct sk_buff *skb) | ||
1919 | { | 1738 | { |
1920 | u32 scdi; | 1739 | unsigned long flags; |
1921 | scq_info *scq; | 1740 | ns_scqe tsr; |
1922 | ns_tsi *previous = NULL, *one_ahead, *two_ahead; | 1741 | u32 scdi, scqi; |
1923 | int serviced_entries; /* flag indicating at least on entry was serviced */ | 1742 | int scq_is_vbr; |
1924 | 1743 | u32 data; | |
1925 | serviced_entries = 0; | 1744 | int index; |
1926 | 1745 | ||
1927 | if (card->tsq.next == card->tsq.last) | 1746 | spin_lock_irqsave(&scq->lock, flags); |
1928 | one_ahead = card->tsq.base; | 1747 | while (scq->tail == scq->next) { |
1929 | else | 1748 | if (in_interrupt()) { |
1930 | one_ahead = card->tsq.next + 1; | 1749 | spin_unlock_irqrestore(&scq->lock, flags); |
1931 | 1750 | printk("nicstar%d: Error pushing TBD.\n", card->index); | |
1932 | if (one_ahead == card->tsq.last) | 1751 | return 1; |
1933 | two_ahead = card->tsq.base; | 1752 | } |
1934 | else | 1753 | |
1935 | two_ahead = one_ahead + 1; | 1754 | scq->full = 1; |
1936 | 1755 | spin_unlock_irqrestore(&scq->lock, flags); | |
1937 | while (!ns_tsi_isempty(card->tsq.next) || !ns_tsi_isempty(one_ahead) || | 1756 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, |
1938 | !ns_tsi_isempty(two_ahead)) | 1757 | SCQFULL_TIMEOUT); |
1939 | /* At most two empty, as stated in the 77201 errata */ | 1758 | spin_lock_irqsave(&scq->lock, flags); |
1940 | { | 1759 | |
1941 | serviced_entries = 1; | 1760 | if (scq->full) { |
1942 | 1761 | spin_unlock_irqrestore(&scq->lock, flags); | |
1943 | /* Skip the one or two possible empty entries */ | 1762 | printk("nicstar%d: Timeout pushing TBD.\n", |
1944 | while (ns_tsi_isempty(card->tsq.next)) { | 1763 | card->index); |
1945 | if (card->tsq.next == card->tsq.last) | 1764 | return 1; |
1946 | card->tsq.next = card->tsq.base; | 1765 | } |
1947 | else | 1766 | } |
1948 | card->tsq.next++; | 1767 | *scq->next = *tbd; |
1949 | } | 1768 | index = (int)(scq->next - scq->base); |
1950 | 1769 | scq->skb[index] = skb; | |
1951 | if (!ns_tsi_tmrof(card->tsq.next)) | 1770 | XPRINTK("nicstar%d: sending skb at 0x%p (pos %d).\n", |
1952 | { | 1771 | card->index, skb, index); |
1953 | scdi = ns_tsi_getscdindex(card->tsq.next); | 1772 | XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n", |
1954 | if (scdi == NS_TSI_SCDISVBR) | 1773 | card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2), |
1955 | scq = card->scq0; | 1774 | le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4), |
1956 | else | 1775 | scq->next); |
1957 | { | 1776 | if (scq->next == scq->last) |
1958 | if (card->scd2vc[scdi] == NULL) | 1777 | scq->next = scq->base; |
1959 | { | 1778 | else |
1960 | printk("nicstar%d: could not find VC from SCD index.\n", | 1779 | scq->next++; |
1961 | card->index); | 1780 | |
1962 | ns_tsi_init(card->tsq.next); | 1781 | vc->tbd_count++; |
1963 | return; | 1782 | if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) { |
1964 | } | 1783 | scq->tbd_count++; |
1965 | scq = card->scd2vc[scdi]->scq; | 1784 | scq_is_vbr = 1; |
1966 | } | 1785 | } else |
1967 | drain_scq(card, scq, ns_tsi_getscqpos(card->tsq.next)); | 1786 | scq_is_vbr = 0; |
1968 | scq->full = 0; | 1787 | |
1969 | wake_up_interruptible(&(scq->scqfull_waitq)); | 1788 | if (vc->tbd_count >= MAX_TBD_PER_VC |
1970 | } | 1789 | || scq->tbd_count >= MAX_TBD_PER_SCQ) { |
1971 | 1790 | int has_run = 0; | |
1972 | ns_tsi_init(card->tsq.next); | 1791 | |
1973 | previous = card->tsq.next; | 1792 | while (scq->tail == scq->next) { |
1974 | if (card->tsq.next == card->tsq.last) | 1793 | if (in_interrupt()) { |
1975 | card->tsq.next = card->tsq.base; | 1794 | data = scq_virt_to_bus(scq, scq->next); |
1976 | else | 1795 | ns_write_sram(card, scq->scd, &data, 1); |
1977 | card->tsq.next++; | 1796 | spin_unlock_irqrestore(&scq->lock, flags); |
1978 | 1797 | printk("nicstar%d: Error pushing TSR.\n", | |
1979 | if (card->tsq.next == card->tsq.last) | 1798 | card->index); |
1980 | one_ahead = card->tsq.base; | 1799 | return 0; |
1981 | else | 1800 | } |
1982 | one_ahead = card->tsq.next + 1; | 1801 | |
1983 | 1802 | scq->full = 1; | |
1984 | if (one_ahead == card->tsq.last) | 1803 | if (has_run++) |
1985 | two_ahead = card->tsq.base; | 1804 | break; |
1986 | else | 1805 | spin_unlock_irqrestore(&scq->lock, flags); |
1987 | two_ahead = one_ahead + 1; | 1806 | interruptible_sleep_on_timeout(&scq->scqfull_waitq, |
1988 | } | 1807 | SCQFULL_TIMEOUT); |
1989 | 1808 | spin_lock_irqsave(&scq->lock, flags); | |
1990 | if (serviced_entries) { | 1809 | } |
1991 | writel((((u32) previous) - ((u32) card->tsq.base)), | 1810 | |
1992 | card->membase + TSQH); | 1811 | if (!scq->full) { |
1993 | } | 1812 | tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE); |
1813 | if (scq_is_vbr) | ||
1814 | scdi = NS_TSR_SCDISVBR; | ||
1815 | else | ||
1816 | scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE; | ||
1817 | scqi = scq->next - scq->base; | ||
1818 | tsr.word_2 = ns_tsr_mkword_2(scdi, scqi); | ||
1819 | tsr.word_3 = 0x00000000; | ||
1820 | tsr.word_4 = 0x00000000; | ||
1821 | |||
1822 | *scq->next = tsr; | ||
1823 | index = (int)scqi; | ||
1824 | scq->skb[index] = NULL; | ||
1825 | XPRINTK | ||
1826 | ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n", | ||
1827 | card->index, le32_to_cpu(tsr.word_1), | ||
1828 | le32_to_cpu(tsr.word_2), le32_to_cpu(tsr.word_3), | ||
1829 | le32_to_cpu(tsr.word_4), scq->next); | ||
1830 | if (scq->next == scq->last) | ||
1831 | scq->next = scq->base; | ||
1832 | else | ||
1833 | scq->next++; | ||
1834 | vc->tbd_count = 0; | ||
1835 | scq->tbd_count = 0; | ||
1836 | } else | ||
1837 | PRINTK("nicstar%d: Timeout pushing TSR.\n", | ||
1838 | card->index); | ||
1839 | } | ||
1840 | data = scq_virt_to_bus(scq, scq->next); | ||
1841 | ns_write_sram(card, scq->scd, &data, 1); | ||
1842 | |||
1843 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1844 | |||
1845 | return 0; | ||
1994 | } | 1846 | } |
1995 | 1847 | ||
1996 | 1848 | static void process_tsq(ns_dev * card) | |
1997 | |||
1998 | static void drain_scq(ns_dev *card, scq_info *scq, int pos) | ||
1999 | { | 1849 | { |
2000 | struct atm_vcc *vcc; | 1850 | u32 scdi; |
2001 | struct sk_buff *skb; | 1851 | scq_info *scq; |
2002 | int i; | 1852 | ns_tsi *previous = NULL, *one_ahead, *two_ahead; |
2003 | unsigned long flags; | 1853 | int serviced_entries; /* flag indicating at least on entry was serviced */ |
2004 | 1854 | ||
2005 | XPRINTK("nicstar%d: drain_scq() called, scq at 0x%x, pos %d.\n", | 1855 | serviced_entries = 0; |
2006 | card->index, (u32) scq, pos); | 1856 | |
2007 | if (pos >= scq->num_entries) | 1857 | if (card->tsq.next == card->tsq.last) |
2008 | { | 1858 | one_ahead = card->tsq.base; |
2009 | printk("nicstar%d: Bad index on drain_scq().\n", card->index); | 1859 | else |
2010 | return; | 1860 | one_ahead = card->tsq.next + 1; |
2011 | } | 1861 | |
2012 | 1862 | if (one_ahead == card->tsq.last) | |
2013 | spin_lock_irqsave(&scq->lock, flags); | 1863 | two_ahead = card->tsq.base; |
2014 | i = (int) (scq->tail - scq->base); | 1864 | else |
2015 | if (++i == scq->num_entries) | 1865 | two_ahead = one_ahead + 1; |
2016 | i = 0; | 1866 | |
2017 | while (i != pos) | 1867 | while (!ns_tsi_isempty(card->tsq.next) || !ns_tsi_isempty(one_ahead) || |
2018 | { | 1868 | !ns_tsi_isempty(two_ahead)) |
2019 | skb = scq->skb[i]; | 1869 | /* At most two empty, as stated in the 77201 errata */ |
2020 | XPRINTK("nicstar%d: freeing skb at 0x%x (index %d).\n", | 1870 | { |
2021 | card->index, (u32) skb, i); | 1871 | serviced_entries = 1; |
2022 | if (skb != NULL) | 1872 | |
2023 | { | 1873 | /* Skip the one or two possible empty entries */ |
2024 | vcc = ATM_SKB(skb)->vcc; | 1874 | while (ns_tsi_isempty(card->tsq.next)) { |
2025 | if (vcc && vcc->pop != NULL) { | 1875 | if (card->tsq.next == card->tsq.last) |
2026 | vcc->pop(vcc, skb); | 1876 | card->tsq.next = card->tsq.base; |
2027 | } else { | 1877 | else |
2028 | dev_kfree_skb_irq(skb); | 1878 | card->tsq.next++; |
2029 | } | 1879 | } |
2030 | scq->skb[i] = NULL; | 1880 | |
2031 | } | 1881 | if (!ns_tsi_tmrof(card->tsq.next)) { |
2032 | if (++i == scq->num_entries) | 1882 | scdi = ns_tsi_getscdindex(card->tsq.next); |
2033 | i = 0; | 1883 | if (scdi == NS_TSI_SCDISVBR) |
2034 | } | 1884 | scq = card->scq0; |
2035 | scq->tail = scq->base + pos; | 1885 | else { |
2036 | spin_unlock_irqrestore(&scq->lock, flags); | 1886 | if (card->scd2vc[scdi] == NULL) { |
1887 | printk | ||
1888 | ("nicstar%d: could not find VC from SCD index.\n", | ||
1889 | card->index); | ||
1890 | ns_tsi_init(card->tsq.next); | ||
1891 | return; | ||
1892 | } | ||
1893 | scq = card->scd2vc[scdi]->scq; | ||
1894 | } | ||
1895 | drain_scq(card, scq, ns_tsi_getscqpos(card->tsq.next)); | ||
1896 | scq->full = 0; | ||
1897 | wake_up_interruptible(&(scq->scqfull_waitq)); | ||
1898 | } | ||
1899 | |||
1900 | ns_tsi_init(card->tsq.next); | ||
1901 | previous = card->tsq.next; | ||
1902 | if (card->tsq.next == card->tsq.last) | ||
1903 | card->tsq.next = card->tsq.base; | ||
1904 | else | ||
1905 | card->tsq.next++; | ||
1906 | |||
1907 | if (card->tsq.next == card->tsq.last) | ||
1908 | one_ahead = card->tsq.base; | ||
1909 | else | ||
1910 | one_ahead = card->tsq.next + 1; | ||
1911 | |||
1912 | if (one_ahead == card->tsq.last) | ||
1913 | two_ahead = card->tsq.base; | ||
1914 | else | ||
1915 | two_ahead = one_ahead + 1; | ||
1916 | } | ||
1917 | |||
1918 | if (serviced_entries) | ||
1919 | writel(PTR_DIFF(previous, card->tsq.base), | ||
1920 | card->membase + TSQH); | ||
2037 | } | 1921 | } |
2038 | 1922 | ||
1923 | static void drain_scq(ns_dev * card, scq_info * scq, int pos) | ||
1924 | { | ||
1925 | struct atm_vcc *vcc; | ||
1926 | struct sk_buff *skb; | ||
1927 | int i; | ||
1928 | unsigned long flags; | ||
1929 | |||
1930 | XPRINTK("nicstar%d: drain_scq() called, scq at 0x%p, pos %d.\n", | ||
1931 | card->index, scq, pos); | ||
1932 | if (pos >= scq->num_entries) { | ||
1933 | printk("nicstar%d: Bad index on drain_scq().\n", card->index); | ||
1934 | return; | ||
1935 | } | ||
1936 | |||
1937 | spin_lock_irqsave(&scq->lock, flags); | ||
1938 | i = (int)(scq->tail - scq->base); | ||
1939 | if (++i == scq->num_entries) | ||
1940 | i = 0; | ||
1941 | while (i != pos) { | ||
1942 | skb = scq->skb[i]; | ||
1943 | XPRINTK("nicstar%d: freeing skb at 0x%p (index %d).\n", | ||
1944 | card->index, skb, i); | ||
1945 | if (skb != NULL) { | ||
1946 | pci_unmap_single(card->pcidev, | ||
1947 | NS_PRV_DMA(skb), | ||
1948 | skb->len, | ||
1949 | PCI_DMA_TODEVICE); | ||
1950 | vcc = ATM_SKB(skb)->vcc; | ||
1951 | if (vcc && vcc->pop != NULL) { | ||
1952 | vcc->pop(vcc, skb); | ||
1953 | } else { | ||
1954 | dev_kfree_skb_irq(skb); | ||
1955 | } | ||
1956 | scq->skb[i] = NULL; | ||
1957 | } | ||
1958 | if (++i == scq->num_entries) | ||
1959 | i = 0; | ||
1960 | } | ||
1961 | scq->tail = scq->base + pos; | ||
1962 | spin_unlock_irqrestore(&scq->lock, flags); | ||
1963 | } | ||
2039 | 1964 | ||
2040 | 1965 | static void process_rsq(ns_dev * card) | |
2041 | static void process_rsq(ns_dev *card) | ||
2042 | { | 1966 | { |
2043 | ns_rsqe *previous; | 1967 | ns_rsqe *previous; |
2044 | 1968 | ||
2045 | if (!ns_rsqe_valid(card->rsq.next)) | 1969 | if (!ns_rsqe_valid(card->rsq.next)) |
2046 | return; | 1970 | return; |
2047 | do { | 1971 | do { |
2048 | dequeue_rx(card, card->rsq.next); | 1972 | dequeue_rx(card, card->rsq.next); |
2049 | ns_rsqe_init(card->rsq.next); | 1973 | ns_rsqe_init(card->rsq.next); |
2050 | previous = card->rsq.next; | 1974 | previous = card->rsq.next; |
2051 | if (card->rsq.next == card->rsq.last) | 1975 | if (card->rsq.next == card->rsq.last) |
2052 | card->rsq.next = card->rsq.base; | 1976 | card->rsq.next = card->rsq.base; |
2053 | else | 1977 | else |
2054 | card->rsq.next++; | 1978 | card->rsq.next++; |
2055 | } while (ns_rsqe_valid(card->rsq.next)); | 1979 | } while (ns_rsqe_valid(card->rsq.next)); |
2056 | writel((((u32) previous) - ((u32) card->rsq.base)), | 1980 | writel(PTR_DIFF(previous, card->rsq.base), card->membase + RSQH); |
2057 | card->membase + RSQH); | ||
2058 | } | 1981 | } |
2059 | 1982 | ||
1983 | static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) | ||
1984 | { | ||
1985 | u32 vpi, vci; | ||
1986 | vc_map *vc; | ||
1987 | struct sk_buff *iovb; | ||
1988 | struct iovec *iov; | ||
1989 | struct atm_vcc *vcc; | ||
1990 | struct sk_buff *skb; | ||
1991 | unsigned short aal5_len; | ||
1992 | int len; | ||
1993 | u32 stat; | ||
1994 | u32 id; | ||
1995 | |||
1996 | stat = readl(card->membase + STAT); | ||
1997 | card->sbfqc = ns_stat_sfbqc_get(stat); | ||
1998 | card->lbfqc = ns_stat_lfbqc_get(stat); | ||
1999 | |||
2000 | id = le32_to_cpu(rsqe->buffer_handle); | ||
2001 | skb = idr_find(&card->idr, id); | ||
2002 | if (!skb) { | ||
2003 | RXPRINTK(KERN_ERR | ||
2004 | "nicstar%d: idr_find() failed!\n", card->index); | ||
2005 | return; | ||
2006 | } | ||
2007 | idr_remove(&card->idr, id); | ||
2008 | pci_dma_sync_single_for_cpu(card->pcidev, | ||
2009 | NS_PRV_DMA(skb), | ||
2010 | (NS_PRV_BUFTYPE(skb) == BUF_SM | ||
2011 | ? NS_SMSKBSIZE : NS_LGSKBSIZE), | ||
2012 | PCI_DMA_FROMDEVICE); | ||
2013 | pci_unmap_single(card->pcidev, | ||
2014 | NS_PRV_DMA(skb), | ||
2015 | (NS_PRV_BUFTYPE(skb) == BUF_SM | ||
2016 | ? NS_SMSKBSIZE : NS_LGSKBSIZE), | ||
2017 | PCI_DMA_FROMDEVICE); | ||
2018 | vpi = ns_rsqe_vpi(rsqe); | ||
2019 | vci = ns_rsqe_vci(rsqe); | ||
2020 | if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) { | ||
2021 | printk("nicstar%d: SDU received for out-of-range vc %d.%d.\n", | ||
2022 | card->index, vpi, vci); | ||
2023 | recycle_rx_buf(card, skb); | ||
2024 | return; | ||
2025 | } | ||
2026 | |||
2027 | vc = &(card->vcmap[vpi << card->vcibits | vci]); | ||
2028 | if (!vc->rx) { | ||
2029 | RXPRINTK("nicstar%d: SDU received on non-rx vc %d.%d.\n", | ||
2030 | card->index, vpi, vci); | ||
2031 | recycle_rx_buf(card, skb); | ||
2032 | return; | ||
2033 | } | ||
2034 | |||
2035 | vcc = vc->rx_vcc; | ||
2036 | |||
2037 | if (vcc->qos.aal == ATM_AAL0) { | ||
2038 | struct sk_buff *sb; | ||
2039 | unsigned char *cell; | ||
2040 | int i; | ||
2041 | |||
2042 | cell = skb->data; | ||
2043 | for (i = ns_rsqe_cellcount(rsqe); i; i--) { | ||
2044 | if ((sb = dev_alloc_skb(NS_SMSKBSIZE)) == NULL) { | ||
2045 | printk | ||
2046 | ("nicstar%d: Can't allocate buffers for aal0.\n", | ||
2047 | card->index); | ||
2048 | atomic_add(i, &vcc->stats->rx_drop); | ||
2049 | break; | ||
2050 | } | ||
2051 | if (!atm_charge(vcc, sb->truesize)) { | ||
2052 | RXPRINTK | ||
2053 | ("nicstar%d: atm_charge() dropped aal0 packets.\n", | ||
2054 | card->index); | ||
2055 | atomic_add(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */ | ||
2056 | dev_kfree_skb_any(sb); | ||
2057 | break; | ||
2058 | } | ||
2059 | /* Rebuild the header */ | ||
2060 | *((u32 *) sb->data) = le32_to_cpu(rsqe->word_1) << 4 | | ||
2061 | (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000); | ||
2062 | if (i == 1 && ns_rsqe_eopdu(rsqe)) | ||
2063 | *((u32 *) sb->data) |= 0x00000002; | ||
2064 | skb_put(sb, NS_AAL0_HEADER); | ||
2065 | memcpy(skb_tail_pointer(sb), cell, ATM_CELL_PAYLOAD); | ||
2066 | skb_put(sb, ATM_CELL_PAYLOAD); | ||
2067 | ATM_SKB(sb)->vcc = vcc; | ||
2068 | __net_timestamp(sb); | ||
2069 | vcc->push(vcc, sb); | ||
2070 | atomic_inc(&vcc->stats->rx); | ||
2071 | cell += ATM_CELL_PAYLOAD; | ||
2072 | } | ||
2073 | |||
2074 | recycle_rx_buf(card, skb); | ||
2075 | return; | ||
2076 | } | ||
2077 | |||
2078 | /* To reach this point, the AAL layer can only be AAL5 */ | ||
2079 | |||
2080 | if ((iovb = vc->rx_iov) == NULL) { | ||
2081 | iovb = skb_dequeue(&(card->iovpool.queue)); | ||
2082 | if (iovb == NULL) { /* No buffers in the queue */ | ||
2083 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC); | ||
2084 | if (iovb == NULL) { | ||
2085 | printk("nicstar%d: Out of iovec buffers.\n", | ||
2086 | card->index); | ||
2087 | atomic_inc(&vcc->stats->rx_drop); | ||
2088 | recycle_rx_buf(card, skb); | ||
2089 | return; | ||
2090 | } | ||
2091 | NS_PRV_BUFTYPE(iovb) = BUF_NONE; | ||
2092 | } else if (--card->iovpool.count < card->iovnr.min) { | ||
2093 | struct sk_buff *new_iovb; | ||
2094 | if ((new_iovb = | ||
2095 | alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) { | ||
2096 | NS_PRV_BUFTYPE(iovb) = BUF_NONE; | ||
2097 | skb_queue_tail(&card->iovpool.queue, new_iovb); | ||
2098 | card->iovpool.count++; | ||
2099 | } | ||
2100 | } | ||
2101 | vc->rx_iov = iovb; | ||
2102 | NS_PRV_IOVCNT(iovb) = 0; | ||
2103 | iovb->len = 0; | ||
2104 | iovb->data = iovb->head; | ||
2105 | skb_reset_tail_pointer(iovb); | ||
2106 | /* IMPORTANT: a pointer to the sk_buff containing the small or large | ||
2107 | buffer is stored as iovec base, NOT a pointer to the | ||
2108 | small or large buffer itself. */ | ||
2109 | } else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) { | ||
2110 | printk("nicstar%d: received too big AAL5 SDU.\n", card->index); | ||
2111 | atomic_inc(&vcc->stats->rx_err); | ||
2112 | recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data, | ||
2113 | NS_MAX_IOVECS); | ||
2114 | NS_PRV_IOVCNT(iovb) = 0; | ||
2115 | iovb->len = 0; | ||
2116 | iovb->data = iovb->head; | ||
2117 | skb_reset_tail_pointer(iovb); | ||
2118 | } | ||
2119 | iov = &((struct iovec *)iovb->data)[NS_PRV_IOVCNT(iovb)++]; | ||
2120 | iov->iov_base = (void *)skb; | ||
2121 | iov->iov_len = ns_rsqe_cellcount(rsqe) * 48; | ||
2122 | iovb->len += iov->iov_len; | ||
2060 | 2123 | ||
2124 | #ifdef EXTRA_DEBUG | ||
2125 | if (NS_PRV_IOVCNT(iovb) == 1) { | ||
2126 | if (NS_PRV_BUFTYPE(skb) != BUF_SM) { | ||
2127 | printk | ||
2128 | ("nicstar%d: Expected a small buffer, and this is not one.\n", | ||
2129 | card->index); | ||
2130 | which_list(card, skb); | ||
2131 | atomic_inc(&vcc->stats->rx_err); | ||
2132 | recycle_rx_buf(card, skb); | ||
2133 | vc->rx_iov = NULL; | ||
2134 | recycle_iov_buf(card, iovb); | ||
2135 | return; | ||
2136 | } | ||
2137 | } else { /* NS_PRV_IOVCNT(iovb) >= 2 */ | ||
2138 | |||
2139 | if (NS_PRV_BUFTYPE(skb) != BUF_LG) { | ||
2140 | printk | ||
2141 | ("nicstar%d: Expected a large buffer, and this is not one.\n", | ||
2142 | card->index); | ||
2143 | which_list(card, skb); | ||
2144 | atomic_inc(&vcc->stats->rx_err); | ||
2145 | recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data, | ||
2146 | NS_PRV_IOVCNT(iovb)); | ||
2147 | vc->rx_iov = NULL; | ||
2148 | recycle_iov_buf(card, iovb); | ||
2149 | return; | ||
2150 | } | ||
2151 | } | ||
2152 | #endif /* EXTRA_DEBUG */ | ||
2061 | 2153 | ||
2062 | static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe) | 2154 | if (ns_rsqe_eopdu(rsqe)) { |
2063 | { | 2155 | /* This works correctly regardless of the endianness of the host */ |
2064 | u32 vpi, vci; | 2156 | unsigned char *L1L2 = (unsigned char *) |
2065 | vc_map *vc; | 2157 | (skb->data + iov->iov_len - 6); |
2066 | struct sk_buff *iovb; | 2158 | aal5_len = L1L2[0] << 8 | L1L2[1]; |
2067 | struct iovec *iov; | 2159 | len = (aal5_len == 0x0000) ? 0x10000 : aal5_len; |
2068 | struct atm_vcc *vcc; | 2160 | if (ns_rsqe_crcerr(rsqe) || |
2069 | struct sk_buff *skb; | 2161 | len + 8 > iovb->len || len + (47 + 8) < iovb->len) { |
2070 | unsigned short aal5_len; | 2162 | printk("nicstar%d: AAL5 CRC error", card->index); |
2071 | int len; | 2163 | if (len + 8 > iovb->len || len + (47 + 8) < iovb->len) |
2072 | u32 stat; | 2164 | printk(" - PDU size mismatch.\n"); |
2073 | 2165 | else | |
2074 | stat = readl(card->membase + STAT); | 2166 | printk(".\n"); |
2075 | card->sbfqc = ns_stat_sfbqc_get(stat); | 2167 | atomic_inc(&vcc->stats->rx_err); |
2076 | card->lbfqc = ns_stat_lfbqc_get(stat); | 2168 | recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data, |
2077 | 2169 | NS_PRV_IOVCNT(iovb)); | |
2078 | skb = (struct sk_buff *) le32_to_cpu(rsqe->buffer_handle); | 2170 | vc->rx_iov = NULL; |
2079 | vpi = ns_rsqe_vpi(rsqe); | 2171 | recycle_iov_buf(card, iovb); |
2080 | vci = ns_rsqe_vci(rsqe); | 2172 | return; |
2081 | if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) | 2173 | } |
2082 | { | 2174 | |
2083 | printk("nicstar%d: SDU received for out-of-range vc %d.%d.\n", | 2175 | /* By this point we (hopefully) have a complete SDU without errors. */ |
2084 | card->index, vpi, vci); | 2176 | |
2085 | recycle_rx_buf(card, skb); | 2177 | if (NS_PRV_IOVCNT(iovb) == 1) { /* Just a small buffer */ |
2086 | return; | 2178 | /* skb points to a small buffer */ |
2087 | } | 2179 | if (!atm_charge(vcc, skb->truesize)) { |
2088 | 2180 | push_rxbufs(card, skb); | |
2089 | vc = &(card->vcmap[vpi << card->vcibits | vci]); | 2181 | atomic_inc(&vcc->stats->rx_drop); |
2090 | if (!vc->rx) | 2182 | } else { |
2091 | { | 2183 | skb_put(skb, len); |
2092 | RXPRINTK("nicstar%d: SDU received on non-rx vc %d.%d.\n", | 2184 | dequeue_sm_buf(card, skb); |
2093 | card->index, vpi, vci); | ||
2094 | recycle_rx_buf(card, skb); | ||
2095 | return; | ||
2096 | } | ||
2097 | |||
2098 | vcc = vc->rx_vcc; | ||
2099 | |||
2100 | if (vcc->qos.aal == ATM_AAL0) | ||
2101 | { | ||
2102 | struct sk_buff *sb; | ||
2103 | unsigned char *cell; | ||
2104 | int i; | ||
2105 | |||
2106 | cell = skb->data; | ||
2107 | for (i = ns_rsqe_cellcount(rsqe); i; i--) | ||
2108 | { | ||
2109 | if ((sb = dev_alloc_skb(NS_SMSKBSIZE)) == NULL) | ||
2110 | { | ||
2111 | printk("nicstar%d: Can't allocate buffers for aal0.\n", | ||
2112 | card->index); | ||
2113 | atomic_add(i,&vcc->stats->rx_drop); | ||
2114 | break; | ||
2115 | } | ||
2116 | if (!atm_charge(vcc, sb->truesize)) | ||
2117 | { | ||
2118 | RXPRINTK("nicstar%d: atm_charge() dropped aal0 packets.\n", | ||
2119 | card->index); | ||
2120 | atomic_add(i-1,&vcc->stats->rx_drop); /* already increased by 1 */ | ||
2121 | dev_kfree_skb_any(sb); | ||
2122 | break; | ||
2123 | } | ||
2124 | /* Rebuild the header */ | ||
2125 | *((u32 *) sb->data) = le32_to_cpu(rsqe->word_1) << 4 | | ||
2126 | (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000); | ||
2127 | if (i == 1 && ns_rsqe_eopdu(rsqe)) | ||
2128 | *((u32 *) sb->data) |= 0x00000002; | ||
2129 | skb_put(sb, NS_AAL0_HEADER); | ||
2130 | memcpy(skb_tail_pointer(sb), cell, ATM_CELL_PAYLOAD); | ||
2131 | skb_put(sb, ATM_CELL_PAYLOAD); | ||
2132 | ATM_SKB(sb)->vcc = vcc; | ||
2133 | __net_timestamp(sb); | ||
2134 | vcc->push(vcc, sb); | ||
2135 | atomic_inc(&vcc->stats->rx); | ||
2136 | cell += ATM_CELL_PAYLOAD; | ||
2137 | } | ||
2138 | |||
2139 | recycle_rx_buf(card, skb); | ||
2140 | return; | ||
2141 | } | ||
2142 | |||
2143 | /* To reach this point, the AAL layer can only be AAL5 */ | ||
2144 | |||
2145 | if ((iovb = vc->rx_iov) == NULL) | ||
2146 | { | ||
2147 | iovb = skb_dequeue(&(card->iovpool.queue)); | ||
2148 | if (iovb == NULL) /* No buffers in the queue */ | ||
2149 | { | ||
2150 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC); | ||
2151 | if (iovb == NULL) | ||
2152 | { | ||
2153 | printk("nicstar%d: Out of iovec buffers.\n", card->index); | ||
2154 | atomic_inc(&vcc->stats->rx_drop); | ||
2155 | recycle_rx_buf(card, skb); | ||
2156 | return; | ||
2157 | } | ||
2158 | NS_SKB_CB(iovb)->buf_type = BUF_NONE; | ||
2159 | } | ||
2160 | else | ||
2161 | if (--card->iovpool.count < card->iovnr.min) | ||
2162 | { | ||
2163 | struct sk_buff *new_iovb; | ||
2164 | if ((new_iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) | ||
2165 | { | ||
2166 | NS_SKB_CB(iovb)->buf_type = BUF_NONE; | ||
2167 | skb_queue_tail(&card->iovpool.queue, new_iovb); | ||
2168 | card->iovpool.count++; | ||
2169 | } | ||
2170 | } | ||
2171 | vc->rx_iov = iovb; | ||
2172 | NS_SKB(iovb)->iovcnt = 0; | ||
2173 | iovb->len = 0; | ||
2174 | iovb->data = iovb->head; | ||
2175 | skb_reset_tail_pointer(iovb); | ||
2176 | NS_SKB(iovb)->vcc = vcc; | ||
2177 | /* IMPORTANT: a pointer to the sk_buff containing the small or large | ||
2178 | buffer is stored as iovec base, NOT a pointer to the | ||
2179 | small or large buffer itself. */ | ||
2180 | } | ||
2181 | else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS) | ||
2182 | { | ||
2183 | printk("nicstar%d: received too big AAL5 SDU.\n", card->index); | ||
2184 | atomic_inc(&vcc->stats->rx_err); | ||
2185 | recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, NS_MAX_IOVECS); | ||
2186 | NS_SKB(iovb)->iovcnt = 0; | ||
2187 | iovb->len = 0; | ||
2188 | iovb->data = iovb->head; | ||
2189 | skb_reset_tail_pointer(iovb); | ||
2190 | NS_SKB(iovb)->vcc = vcc; | ||
2191 | } | ||
2192 | iov = &((struct iovec *) iovb->data)[NS_SKB(iovb)->iovcnt++]; | ||
2193 | iov->iov_base = (void *) skb; | ||
2194 | iov->iov_len = ns_rsqe_cellcount(rsqe) * 48; | ||
2195 | iovb->len += iov->iov_len; | ||
2196 | |||
2197 | if (NS_SKB(iovb)->iovcnt == 1) | ||
2198 | { | ||
2199 | if (NS_SKB_CB(skb)->buf_type != BUF_SM) | ||
2200 | { | ||
2201 | printk("nicstar%d: Expected a small buffer, and this is not one.\n", | ||
2202 | card->index); | ||
2203 | which_list(card, skb); | ||
2204 | atomic_inc(&vcc->stats->rx_err); | ||
2205 | recycle_rx_buf(card, skb); | ||
2206 | vc->rx_iov = NULL; | ||
2207 | recycle_iov_buf(card, iovb); | ||
2208 | return; | ||
2209 | } | ||
2210 | } | ||
2211 | else /* NS_SKB(iovb)->iovcnt >= 2 */ | ||
2212 | { | ||
2213 | if (NS_SKB_CB(skb)->buf_type != BUF_LG) | ||
2214 | { | ||
2215 | printk("nicstar%d: Expected a large buffer, and this is not one.\n", | ||
2216 | card->index); | ||
2217 | which_list(card, skb); | ||
2218 | atomic_inc(&vcc->stats->rx_err); | ||
2219 | recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, | ||
2220 | NS_SKB(iovb)->iovcnt); | ||
2221 | vc->rx_iov = NULL; | ||
2222 | recycle_iov_buf(card, iovb); | ||
2223 | return; | ||
2224 | } | ||
2225 | } | ||
2226 | |||
2227 | if (ns_rsqe_eopdu(rsqe)) | ||
2228 | { | ||
2229 | /* This works correctly regardless of the endianness of the host */ | ||
2230 | unsigned char *L1L2 = (unsigned char *)((u32)skb->data + | ||
2231 | iov->iov_len - 6); | ||
2232 | aal5_len = L1L2[0] << 8 | L1L2[1]; | ||
2233 | len = (aal5_len == 0x0000) ? 0x10000 : aal5_len; | ||
2234 | if (ns_rsqe_crcerr(rsqe) || | ||
2235 | len + 8 > iovb->len || len + (47 + 8) < iovb->len) | ||
2236 | { | ||
2237 | printk("nicstar%d: AAL5 CRC error", card->index); | ||
2238 | if (len + 8 > iovb->len || len + (47 + 8) < iovb->len) | ||
2239 | printk(" - PDU size mismatch.\n"); | ||
2240 | else | ||
2241 | printk(".\n"); | ||
2242 | atomic_inc(&vcc->stats->rx_err); | ||
2243 | recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, | ||
2244 | NS_SKB(iovb)->iovcnt); | ||
2245 | vc->rx_iov = NULL; | ||
2246 | recycle_iov_buf(card, iovb); | ||
2247 | return; | ||
2248 | } | ||
2249 | |||
2250 | /* By this point we (hopefully) have a complete SDU without errors. */ | ||
2251 | |||
2252 | if (NS_SKB(iovb)->iovcnt == 1) /* Just a small buffer */ | ||
2253 | { | ||
2254 | /* skb points to a small buffer */ | ||
2255 | if (!atm_charge(vcc, skb->truesize)) | ||
2256 | { | ||
2257 | push_rxbufs(card, skb); | ||
2258 | atomic_inc(&vcc->stats->rx_drop); | ||
2259 | } | ||
2260 | else | ||
2261 | { | ||
2262 | skb_put(skb, len); | ||
2263 | dequeue_sm_buf(card, skb); | ||
2264 | #ifdef NS_USE_DESTRUCTORS | 2185 | #ifdef NS_USE_DESTRUCTORS |
2265 | skb->destructor = ns_sb_destructor; | 2186 | skb->destructor = ns_sb_destructor; |
2266 | #endif /* NS_USE_DESTRUCTORS */ | 2187 | #endif /* NS_USE_DESTRUCTORS */ |
2267 | ATM_SKB(skb)->vcc = vcc; | 2188 | ATM_SKB(skb)->vcc = vcc; |
2268 | __net_timestamp(skb); | 2189 | __net_timestamp(skb); |
2269 | vcc->push(vcc, skb); | 2190 | vcc->push(vcc, skb); |
2270 | atomic_inc(&vcc->stats->rx); | 2191 | atomic_inc(&vcc->stats->rx); |
2271 | } | 2192 | } |
2272 | } | 2193 | } else if (NS_PRV_IOVCNT(iovb) == 2) { /* One small plus one large buffer */ |
2273 | else if (NS_SKB(iovb)->iovcnt == 2) /* One small plus one large buffer */ | 2194 | struct sk_buff *sb; |
2274 | { | 2195 | |
2275 | struct sk_buff *sb; | 2196 | sb = (struct sk_buff *)(iov - 1)->iov_base; |
2276 | 2197 | /* skb points to a large buffer */ | |
2277 | sb = (struct sk_buff *) (iov - 1)->iov_base; | 2198 | |
2278 | /* skb points to a large buffer */ | 2199 | if (len <= NS_SMBUFSIZE) { |
2279 | 2200 | if (!atm_charge(vcc, sb->truesize)) { | |
2280 | if (len <= NS_SMBUFSIZE) | 2201 | push_rxbufs(card, sb); |
2281 | { | 2202 | atomic_inc(&vcc->stats->rx_drop); |
2282 | if (!atm_charge(vcc, sb->truesize)) | 2203 | } else { |
2283 | { | 2204 | skb_put(sb, len); |
2284 | push_rxbufs(card, sb); | 2205 | dequeue_sm_buf(card, sb); |
2285 | atomic_inc(&vcc->stats->rx_drop); | ||
2286 | } | ||
2287 | else | ||
2288 | { | ||
2289 | skb_put(sb, len); | ||
2290 | dequeue_sm_buf(card, sb); | ||
2291 | #ifdef NS_USE_DESTRUCTORS | 2206 | #ifdef NS_USE_DESTRUCTORS |
2292 | sb->destructor = ns_sb_destructor; | 2207 | sb->destructor = ns_sb_destructor; |
2293 | #endif /* NS_USE_DESTRUCTORS */ | 2208 | #endif /* NS_USE_DESTRUCTORS */ |
2294 | ATM_SKB(sb)->vcc = vcc; | 2209 | ATM_SKB(sb)->vcc = vcc; |
2295 | __net_timestamp(sb); | 2210 | __net_timestamp(sb); |
2296 | vcc->push(vcc, sb); | 2211 | vcc->push(vcc, sb); |
2297 | atomic_inc(&vcc->stats->rx); | 2212 | atomic_inc(&vcc->stats->rx); |
2298 | } | 2213 | } |
2299 | 2214 | ||
2300 | push_rxbufs(card, skb); | 2215 | push_rxbufs(card, skb); |
2301 | 2216 | ||
2302 | } | 2217 | } else { /* len > NS_SMBUFSIZE, the usual case */ |
2303 | else /* len > NS_SMBUFSIZE, the usual case */ | 2218 | |
2304 | { | 2219 | if (!atm_charge(vcc, skb->truesize)) { |
2305 | if (!atm_charge(vcc, skb->truesize)) | 2220 | push_rxbufs(card, skb); |
2306 | { | 2221 | atomic_inc(&vcc->stats->rx_drop); |
2307 | push_rxbufs(card, skb); | 2222 | } else { |
2308 | atomic_inc(&vcc->stats->rx_drop); | 2223 | dequeue_lg_buf(card, skb); |
2309 | } | ||
2310 | else | ||
2311 | { | ||
2312 | dequeue_lg_buf(card, skb); | ||
2313 | #ifdef NS_USE_DESTRUCTORS | 2224 | #ifdef NS_USE_DESTRUCTORS |
2314 | skb->destructor = ns_lb_destructor; | 2225 | skb->destructor = ns_lb_destructor; |
2315 | #endif /* NS_USE_DESTRUCTORS */ | 2226 | #endif /* NS_USE_DESTRUCTORS */ |
2316 | skb_push(skb, NS_SMBUFSIZE); | 2227 | skb_push(skb, NS_SMBUFSIZE); |
2317 | skb_copy_from_linear_data(sb, skb->data, NS_SMBUFSIZE); | 2228 | skb_copy_from_linear_data(sb, skb->data, |
2318 | skb_put(skb, len - NS_SMBUFSIZE); | 2229 | NS_SMBUFSIZE); |
2319 | ATM_SKB(skb)->vcc = vcc; | 2230 | skb_put(skb, len - NS_SMBUFSIZE); |
2320 | __net_timestamp(skb); | 2231 | ATM_SKB(skb)->vcc = vcc; |
2321 | vcc->push(vcc, skb); | 2232 | __net_timestamp(skb); |
2322 | atomic_inc(&vcc->stats->rx); | 2233 | vcc->push(vcc, skb); |
2323 | } | 2234 | atomic_inc(&vcc->stats->rx); |
2324 | 2235 | } | |
2325 | push_rxbufs(card, sb); | 2236 | |
2326 | 2237 | push_rxbufs(card, sb); | |
2327 | } | 2238 | |
2328 | 2239 | } | |
2329 | } | 2240 | |
2330 | else /* Must push a huge buffer */ | 2241 | } else { /* Must push a huge buffer */ |
2331 | { | 2242 | |
2332 | struct sk_buff *hb, *sb, *lb; | 2243 | struct sk_buff *hb, *sb, *lb; |
2333 | int remaining, tocopy; | 2244 | int remaining, tocopy; |
2334 | int j; | 2245 | int j; |
2335 | 2246 | ||
2336 | hb = skb_dequeue(&(card->hbpool.queue)); | 2247 | hb = skb_dequeue(&(card->hbpool.queue)); |
2337 | if (hb == NULL) /* No buffers in the queue */ | 2248 | if (hb == NULL) { /* No buffers in the queue */ |
2338 | { | 2249 | |
2339 | 2250 | hb = dev_alloc_skb(NS_HBUFSIZE); | |
2340 | hb = dev_alloc_skb(NS_HBUFSIZE); | 2251 | if (hb == NULL) { |
2341 | if (hb == NULL) | 2252 | printk |
2342 | { | 2253 | ("nicstar%d: Out of huge buffers.\n", |
2343 | printk("nicstar%d: Out of huge buffers.\n", card->index); | 2254 | card->index); |
2344 | atomic_inc(&vcc->stats->rx_drop); | 2255 | atomic_inc(&vcc->stats->rx_drop); |
2345 | recycle_iovec_rx_bufs(card, (struct iovec *) iovb->data, | 2256 | recycle_iovec_rx_bufs(card, |
2346 | NS_SKB(iovb)->iovcnt); | 2257 | (struct iovec *) |
2347 | vc->rx_iov = NULL; | 2258 | iovb->data, |
2348 | recycle_iov_buf(card, iovb); | 2259 | NS_PRV_IOVCNT(iovb)); |
2349 | return; | 2260 | vc->rx_iov = NULL; |
2350 | } | 2261 | recycle_iov_buf(card, iovb); |
2351 | else if (card->hbpool.count < card->hbnr.min) | 2262 | return; |
2352 | { | 2263 | } else if (card->hbpool.count < card->hbnr.min) { |
2353 | struct sk_buff *new_hb; | 2264 | struct sk_buff *new_hb; |
2354 | if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) | 2265 | if ((new_hb = |
2355 | { | 2266 | dev_alloc_skb(NS_HBUFSIZE)) != |
2356 | skb_queue_tail(&card->hbpool.queue, new_hb); | 2267 | NULL) { |
2357 | card->hbpool.count++; | 2268 | skb_queue_tail(&card->hbpool. |
2358 | } | 2269 | queue, new_hb); |
2359 | } | 2270 | card->hbpool.count++; |
2360 | NS_SKB_CB(hb)->buf_type = BUF_NONE; | 2271 | } |
2361 | } | 2272 | } |
2362 | else | 2273 | NS_PRV_BUFTYPE(hb) = BUF_NONE; |
2363 | if (--card->hbpool.count < card->hbnr.min) | 2274 | } else if (--card->hbpool.count < card->hbnr.min) { |
2364 | { | 2275 | struct sk_buff *new_hb; |
2365 | struct sk_buff *new_hb; | 2276 | if ((new_hb = |
2366 | if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) | 2277 | dev_alloc_skb(NS_HBUFSIZE)) != NULL) { |
2367 | { | 2278 | NS_PRV_BUFTYPE(new_hb) = BUF_NONE; |
2368 | NS_SKB_CB(new_hb)->buf_type = BUF_NONE; | 2279 | skb_queue_tail(&card->hbpool.queue, |
2369 | skb_queue_tail(&card->hbpool.queue, new_hb); | 2280 | new_hb); |
2370 | card->hbpool.count++; | 2281 | card->hbpool.count++; |
2371 | } | 2282 | } |
2372 | if (card->hbpool.count < card->hbnr.min) | 2283 | if (card->hbpool.count < card->hbnr.min) { |
2373 | { | 2284 | if ((new_hb = |
2374 | if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) | 2285 | dev_alloc_skb(NS_HBUFSIZE)) != |
2375 | { | 2286 | NULL) { |
2376 | NS_SKB_CB(new_hb)->buf_type = BUF_NONE; | 2287 | NS_PRV_BUFTYPE(new_hb) = |
2377 | skb_queue_tail(&card->hbpool.queue, new_hb); | 2288 | BUF_NONE; |
2378 | card->hbpool.count++; | 2289 | skb_queue_tail(&card->hbpool. |
2379 | } | 2290 | queue, new_hb); |
2380 | } | 2291 | card->hbpool.count++; |
2381 | } | 2292 | } |
2382 | 2293 | } | |
2383 | iov = (struct iovec *) iovb->data; | 2294 | } |
2384 | 2295 | ||
2385 | if (!atm_charge(vcc, hb->truesize)) | 2296 | iov = (struct iovec *)iovb->data; |
2386 | { | 2297 | |
2387 | recycle_iovec_rx_bufs(card, iov, NS_SKB(iovb)->iovcnt); | 2298 | if (!atm_charge(vcc, hb->truesize)) { |
2388 | if (card->hbpool.count < card->hbnr.max) | 2299 | recycle_iovec_rx_bufs(card, iov, |
2389 | { | 2300 | NS_PRV_IOVCNT(iovb)); |
2390 | skb_queue_tail(&card->hbpool.queue, hb); | 2301 | if (card->hbpool.count < card->hbnr.max) { |
2391 | card->hbpool.count++; | 2302 | skb_queue_tail(&card->hbpool.queue, hb); |
2392 | } | 2303 | card->hbpool.count++; |
2393 | else | 2304 | } else |
2394 | dev_kfree_skb_any(hb); | 2305 | dev_kfree_skb_any(hb); |
2395 | atomic_inc(&vcc->stats->rx_drop); | 2306 | atomic_inc(&vcc->stats->rx_drop); |
2396 | } | 2307 | } else { |
2397 | else | 2308 | /* Copy the small buffer to the huge buffer */ |
2398 | { | 2309 | sb = (struct sk_buff *)iov->iov_base; |
2399 | /* Copy the small buffer to the huge buffer */ | 2310 | skb_copy_from_linear_data(sb, hb->data, |
2400 | sb = (struct sk_buff *) iov->iov_base; | 2311 | iov->iov_len); |
2401 | skb_copy_from_linear_data(sb, hb->data, iov->iov_len); | 2312 | skb_put(hb, iov->iov_len); |
2402 | skb_put(hb, iov->iov_len); | 2313 | remaining = len - iov->iov_len; |
2403 | remaining = len - iov->iov_len; | 2314 | iov++; |
2404 | iov++; | 2315 | /* Free the small buffer */ |
2405 | /* Free the small buffer */ | 2316 | push_rxbufs(card, sb); |
2406 | push_rxbufs(card, sb); | 2317 | |
2407 | 2318 | /* Copy all large buffers to the huge buffer and free them */ | |
2408 | /* Copy all large buffers to the huge buffer and free them */ | 2319 | for (j = 1; j < NS_PRV_IOVCNT(iovb); j++) { |
2409 | for (j = 1; j < NS_SKB(iovb)->iovcnt; j++) | 2320 | lb = (struct sk_buff *)iov->iov_base; |
2410 | { | 2321 | tocopy = |
2411 | lb = (struct sk_buff *) iov->iov_base; | 2322 | min_t(int, remaining, iov->iov_len); |
2412 | tocopy = min_t(int, remaining, iov->iov_len); | 2323 | skb_copy_from_linear_data(lb, |
2413 | skb_copy_from_linear_data(lb, skb_tail_pointer(hb), tocopy); | 2324 | skb_tail_pointer |
2414 | skb_put(hb, tocopy); | 2325 | (hb), tocopy); |
2415 | iov++; | 2326 | skb_put(hb, tocopy); |
2416 | remaining -= tocopy; | 2327 | iov++; |
2417 | push_rxbufs(card, lb); | 2328 | remaining -= tocopy; |
2418 | } | 2329 | push_rxbufs(card, lb); |
2330 | } | ||
2419 | #ifdef EXTRA_DEBUG | 2331 | #ifdef EXTRA_DEBUG |
2420 | if (remaining != 0 || hb->len != len) | 2332 | if (remaining != 0 || hb->len != len) |
2421 | printk("nicstar%d: Huge buffer len mismatch.\n", card->index); | 2333 | printk |
2334 | ("nicstar%d: Huge buffer len mismatch.\n", | ||
2335 | card->index); | ||
2422 | #endif /* EXTRA_DEBUG */ | 2336 | #endif /* EXTRA_DEBUG */ |
2423 | ATM_SKB(hb)->vcc = vcc; | 2337 | ATM_SKB(hb)->vcc = vcc; |
2424 | #ifdef NS_USE_DESTRUCTORS | 2338 | #ifdef NS_USE_DESTRUCTORS |
2425 | hb->destructor = ns_hb_destructor; | 2339 | hb->destructor = ns_hb_destructor; |
2426 | #endif /* NS_USE_DESTRUCTORS */ | 2340 | #endif /* NS_USE_DESTRUCTORS */ |
2427 | __net_timestamp(hb); | 2341 | __net_timestamp(hb); |
2428 | vcc->push(vcc, hb); | 2342 | vcc->push(vcc, hb); |
2429 | atomic_inc(&vcc->stats->rx); | 2343 | atomic_inc(&vcc->stats->rx); |
2430 | } | 2344 | } |
2431 | } | 2345 | } |
2432 | 2346 | ||
2433 | vc->rx_iov = NULL; | 2347 | vc->rx_iov = NULL; |
2434 | recycle_iov_buf(card, iovb); | 2348 | recycle_iov_buf(card, iovb); |
2435 | } | 2349 | } |
2436 | 2350 | ||
2437 | } | 2351 | } |
2438 | 2352 | ||
2439 | |||
2440 | |||
2441 | #ifdef NS_USE_DESTRUCTORS | 2353 | #ifdef NS_USE_DESTRUCTORS |
2442 | 2354 | ||
2443 | static void ns_sb_destructor(struct sk_buff *sb) | 2355 | static void ns_sb_destructor(struct sk_buff *sb) |
2444 | { | 2356 | { |
2445 | ns_dev *card; | 2357 | ns_dev *card; |
2446 | u32 stat; | 2358 | u32 stat; |
2447 | 2359 | ||
2448 | card = (ns_dev *) ATM_SKB(sb)->vcc->dev->dev_data; | 2360 | card = (ns_dev *) ATM_SKB(sb)->vcc->dev->dev_data; |
2449 | stat = readl(card->membase + STAT); | 2361 | stat = readl(card->membase + STAT); |
2450 | card->sbfqc = ns_stat_sfbqc_get(stat); | 2362 | card->sbfqc = ns_stat_sfbqc_get(stat); |
2451 | card->lbfqc = ns_stat_lfbqc_get(stat); | 2363 | card->lbfqc = ns_stat_lfbqc_get(stat); |
2452 | 2364 | ||
2453 | do | 2365 | do { |
2454 | { | 2366 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); |
2455 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); | 2367 | if (sb == NULL) |
2456 | if (sb == NULL) | 2368 | break; |
2457 | break; | 2369 | NS_PRV_BUFTYPE(sb) = BUF_SM; |
2458 | NS_SKB_CB(sb)->buf_type = BUF_SM; | 2370 | skb_queue_tail(&card->sbpool.queue, sb); |
2459 | skb_queue_tail(&card->sbpool.queue, sb); | 2371 | skb_reserve(sb, NS_AAL0_HEADER); |
2460 | skb_reserve(sb, NS_AAL0_HEADER); | 2372 | push_rxbufs(card, sb); |
2461 | push_rxbufs(card, sb); | 2373 | } while (card->sbfqc < card->sbnr.min); |
2462 | } while (card->sbfqc < card->sbnr.min); | ||
2463 | } | 2374 | } |
2464 | 2375 | ||
2465 | |||
2466 | |||
2467 | static void ns_lb_destructor(struct sk_buff *lb) | 2376 | static void ns_lb_destructor(struct sk_buff *lb) |
2468 | { | 2377 | { |
2469 | ns_dev *card; | 2378 | ns_dev *card; |
2470 | u32 stat; | 2379 | u32 stat; |
2471 | 2380 | ||
2472 | card = (ns_dev *) ATM_SKB(lb)->vcc->dev->dev_data; | 2381 | card = (ns_dev *) ATM_SKB(lb)->vcc->dev->dev_data; |
2473 | stat = readl(card->membase + STAT); | 2382 | stat = readl(card->membase + STAT); |
2474 | card->sbfqc = ns_stat_sfbqc_get(stat); | 2383 | card->sbfqc = ns_stat_sfbqc_get(stat); |
2475 | card->lbfqc = ns_stat_lfbqc_get(stat); | 2384 | card->lbfqc = ns_stat_lfbqc_get(stat); |
2476 | 2385 | ||
2477 | do | 2386 | do { |
2478 | { | 2387 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); |
2479 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); | 2388 | if (lb == NULL) |
2480 | if (lb == NULL) | 2389 | break; |
2481 | break; | 2390 | NS_PRV_BUFTYPE(lb) = BUF_LG; |
2482 | NS_SKB_CB(lb)->buf_type = BUF_LG; | 2391 | skb_queue_tail(&card->lbpool.queue, lb); |
2483 | skb_queue_tail(&card->lbpool.queue, lb); | 2392 | skb_reserve(lb, NS_SMBUFSIZE); |
2484 | skb_reserve(lb, NS_SMBUFSIZE); | 2393 | push_rxbufs(card, lb); |
2485 | push_rxbufs(card, lb); | 2394 | } while (card->lbfqc < card->lbnr.min); |
2486 | } while (card->lbfqc < card->lbnr.min); | ||
2487 | } | 2395 | } |
2488 | 2396 | ||
2489 | |||
2490 | |||
2491 | static void ns_hb_destructor(struct sk_buff *hb) | 2397 | static void ns_hb_destructor(struct sk_buff *hb) |
2492 | { | 2398 | { |
2493 | ns_dev *card; | 2399 | ns_dev *card; |
2494 | 2400 | ||
2495 | card = (ns_dev *) ATM_SKB(hb)->vcc->dev->dev_data; | 2401 | card = (ns_dev *) ATM_SKB(hb)->vcc->dev->dev_data; |
2496 | 2402 | ||
2497 | while (card->hbpool.count < card->hbnr.init) | 2403 | while (card->hbpool.count < card->hbnr.init) { |
2498 | { | 2404 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); |
2499 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); | 2405 | if (hb == NULL) |
2500 | if (hb == NULL) | 2406 | break; |
2501 | break; | 2407 | NS_PRV_BUFTYPE(hb) = BUF_NONE; |
2502 | NS_SKB_CB(hb)->buf_type = BUF_NONE; | 2408 | skb_queue_tail(&card->hbpool.queue, hb); |
2503 | skb_queue_tail(&card->hbpool.queue, hb); | 2409 | card->hbpool.count++; |
2504 | card->hbpool.count++; | 2410 | } |
2505 | } | ||
2506 | } | 2411 | } |
2507 | 2412 | ||
2508 | #endif /* NS_USE_DESTRUCTORS */ | 2413 | #endif /* NS_USE_DESTRUCTORS */ |
2509 | 2414 | ||
2510 | 2415 | static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb) | |
2511 | static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb) | ||
2512 | { | 2416 | { |
2513 | struct ns_skb_cb *cb = NS_SKB_CB(skb); | 2417 | if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) { |
2514 | 2418 | printk("nicstar%d: What kind of rx buffer is this?\n", | |
2515 | if (unlikely(cb->buf_type == BUF_NONE)) { | 2419 | card->index); |
2516 | printk("nicstar%d: What kind of rx buffer is this?\n", card->index); | ||
2517 | dev_kfree_skb_any(skb); | 2420 | dev_kfree_skb_any(skb); |
2518 | } else | 2421 | } else |
2519 | push_rxbufs(card, skb); | 2422 | push_rxbufs(card, skb); |
2520 | } | 2423 | } |
2521 | 2424 | ||
2522 | 2425 | static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count) | |
2523 | static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count) | ||
2524 | { | 2426 | { |
2525 | while (count-- > 0) | 2427 | while (count-- > 0) |
2526 | recycle_rx_buf(card, (struct sk_buff *) (iov++)->iov_base); | 2428 | recycle_rx_buf(card, (struct sk_buff *)(iov++)->iov_base); |
2527 | } | 2429 | } |
2528 | 2430 | ||
2529 | 2431 | static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb) | |
2530 | static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb) | ||
2531 | { | 2432 | { |
2532 | if (card->iovpool.count < card->iovnr.max) | 2433 | if (card->iovpool.count < card->iovnr.max) { |
2533 | { | 2434 | skb_queue_tail(&card->iovpool.queue, iovb); |
2534 | skb_queue_tail(&card->iovpool.queue, iovb); | 2435 | card->iovpool.count++; |
2535 | card->iovpool.count++; | 2436 | } else |
2536 | } | 2437 | dev_kfree_skb_any(iovb); |
2537 | else | ||
2538 | dev_kfree_skb_any(iovb); | ||
2539 | } | 2438 | } |
2540 | 2439 | ||
2541 | 2440 | static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb) | |
2542 | |||
2543 | static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb) | ||
2544 | { | 2441 | { |
2545 | skb_unlink(sb, &card->sbpool.queue); | 2442 | skb_unlink(sb, &card->sbpool.queue); |
2546 | #ifdef NS_USE_DESTRUCTORS | 2443 | #ifdef NS_USE_DESTRUCTORS |
2547 | if (card->sbfqc < card->sbnr.min) | 2444 | if (card->sbfqc < card->sbnr.min) |
2548 | #else | 2445 | #else |
2549 | if (card->sbfqc < card->sbnr.init) | 2446 | if (card->sbfqc < card->sbnr.init) { |
2550 | { | 2447 | struct sk_buff *new_sb; |
2551 | struct sk_buff *new_sb; | 2448 | if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { |
2552 | if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) | 2449 | NS_PRV_BUFTYPE(new_sb) = BUF_SM; |
2553 | { | 2450 | skb_queue_tail(&card->sbpool.queue, new_sb); |
2554 | NS_SKB_CB(new_sb)->buf_type = BUF_SM; | 2451 | skb_reserve(new_sb, NS_AAL0_HEADER); |
2555 | skb_queue_tail(&card->sbpool.queue, new_sb); | 2452 | push_rxbufs(card, new_sb); |
2556 | skb_reserve(new_sb, NS_AAL0_HEADER); | 2453 | } |
2557 | push_rxbufs(card, new_sb); | 2454 | } |
2558 | } | 2455 | if (card->sbfqc < card->sbnr.init) |
2559 | } | ||
2560 | if (card->sbfqc < card->sbnr.init) | ||
2561 | #endif /* NS_USE_DESTRUCTORS */ | 2456 | #endif /* NS_USE_DESTRUCTORS */ |
2562 | { | 2457 | { |
2563 | struct sk_buff *new_sb; | 2458 | struct sk_buff *new_sb; |
2564 | if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) | 2459 | if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { |
2565 | { | 2460 | NS_PRV_BUFTYPE(new_sb) = BUF_SM; |
2566 | NS_SKB_CB(new_sb)->buf_type = BUF_SM; | 2461 | skb_queue_tail(&card->sbpool.queue, new_sb); |
2567 | skb_queue_tail(&card->sbpool.queue, new_sb); | 2462 | skb_reserve(new_sb, NS_AAL0_HEADER); |
2568 | skb_reserve(new_sb, NS_AAL0_HEADER); | 2463 | push_rxbufs(card, new_sb); |
2569 | push_rxbufs(card, new_sb); | 2464 | } |
2570 | } | 2465 | } |
2571 | } | ||
2572 | } | 2466 | } |
2573 | 2467 | ||
2574 | 2468 | static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb) | |
2575 | |||
2576 | static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb) | ||
2577 | { | 2469 | { |
2578 | skb_unlink(lb, &card->lbpool.queue); | 2470 | skb_unlink(lb, &card->lbpool.queue); |
2579 | #ifdef NS_USE_DESTRUCTORS | 2471 | #ifdef NS_USE_DESTRUCTORS |
2580 | if (card->lbfqc < card->lbnr.min) | 2472 | if (card->lbfqc < card->lbnr.min) |
2581 | #else | 2473 | #else |
2582 | if (card->lbfqc < card->lbnr.init) | 2474 | if (card->lbfqc < card->lbnr.init) { |
2583 | { | 2475 | struct sk_buff *new_lb; |
2584 | struct sk_buff *new_lb; | 2476 | if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { |
2585 | if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) | 2477 | NS_PRV_BUFTYPE(new_lb) = BUF_LG; |
2586 | { | 2478 | skb_queue_tail(&card->lbpool.queue, new_lb); |
2587 | NS_SKB_CB(new_lb)->buf_type = BUF_LG; | 2479 | skb_reserve(new_lb, NS_SMBUFSIZE); |
2588 | skb_queue_tail(&card->lbpool.queue, new_lb); | 2480 | push_rxbufs(card, new_lb); |
2589 | skb_reserve(new_lb, NS_SMBUFSIZE); | 2481 | } |
2590 | push_rxbufs(card, new_lb); | 2482 | } |
2591 | } | 2483 | if (card->lbfqc < card->lbnr.init) |
2592 | } | ||
2593 | if (card->lbfqc < card->lbnr.init) | ||
2594 | #endif /* NS_USE_DESTRUCTORS */ | 2484 | #endif /* NS_USE_DESTRUCTORS */ |
2595 | { | 2485 | { |
2596 | struct sk_buff *new_lb; | 2486 | struct sk_buff *new_lb; |
2597 | if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) | 2487 | if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { |
2598 | { | 2488 | NS_PRV_BUFTYPE(new_lb) = BUF_LG; |
2599 | NS_SKB_CB(new_lb)->buf_type = BUF_LG; | 2489 | skb_queue_tail(&card->lbpool.queue, new_lb); |
2600 | skb_queue_tail(&card->lbpool.queue, new_lb); | 2490 | skb_reserve(new_lb, NS_SMBUFSIZE); |
2601 | skb_reserve(new_lb, NS_SMBUFSIZE); | 2491 | push_rxbufs(card, new_lb); |
2602 | push_rxbufs(card, new_lb); | 2492 | } |
2603 | } | 2493 | } |
2604 | } | ||
2605 | } | 2494 | } |
2606 | 2495 | ||
2607 | 2496 | static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page) | |
2608 | |||
2609 | static int ns_proc_read(struct atm_dev *dev, loff_t *pos, char *page) | ||
2610 | { | 2497 | { |
2611 | u32 stat; | 2498 | u32 stat; |
2612 | ns_dev *card; | 2499 | ns_dev *card; |
2613 | int left; | 2500 | int left; |
2614 | 2501 | ||
2615 | left = (int) *pos; | 2502 | left = (int)*pos; |
2616 | card = (ns_dev *) dev->dev_data; | 2503 | card = (ns_dev *) dev->dev_data; |
2617 | stat = readl(card->membase + STAT); | 2504 | stat = readl(card->membase + STAT); |
2618 | if (!left--) | 2505 | if (!left--) |
2619 | return sprintf(page, "Pool count min init max \n"); | 2506 | return sprintf(page, "Pool count min init max \n"); |
2620 | if (!left--) | 2507 | if (!left--) |
2621 | return sprintf(page, "Small %5d %5d %5d %5d \n", | 2508 | return sprintf(page, "Small %5d %5d %5d %5d \n", |
2622 | ns_stat_sfbqc_get(stat), card->sbnr.min, card->sbnr.init, | 2509 | ns_stat_sfbqc_get(stat), card->sbnr.min, |
2623 | card->sbnr.max); | 2510 | card->sbnr.init, card->sbnr.max); |
2624 | if (!left--) | 2511 | if (!left--) |
2625 | return sprintf(page, "Large %5d %5d %5d %5d \n", | 2512 | return sprintf(page, "Large %5d %5d %5d %5d \n", |
2626 | ns_stat_lfbqc_get(stat), card->lbnr.min, card->lbnr.init, | 2513 | ns_stat_lfbqc_get(stat), card->lbnr.min, |
2627 | card->lbnr.max); | 2514 | card->lbnr.init, card->lbnr.max); |
2628 | if (!left--) | 2515 | if (!left--) |
2629 | return sprintf(page, "Huge %5d %5d %5d %5d \n", card->hbpool.count, | 2516 | return sprintf(page, "Huge %5d %5d %5d %5d \n", |
2630 | card->hbnr.min, card->hbnr.init, card->hbnr.max); | 2517 | card->hbpool.count, card->hbnr.min, |
2631 | if (!left--) | 2518 | card->hbnr.init, card->hbnr.max); |
2632 | return sprintf(page, "Iovec %5d %5d %5d %5d \n", card->iovpool.count, | 2519 | if (!left--) |
2633 | card->iovnr.min, card->iovnr.init, card->iovnr.max); | 2520 | return sprintf(page, "Iovec %5d %5d %5d %5d \n", |
2634 | if (!left--) | 2521 | card->iovpool.count, card->iovnr.min, |
2635 | { | 2522 | card->iovnr.init, card->iovnr.max); |
2636 | int retval; | 2523 | if (!left--) { |
2637 | retval = sprintf(page, "Interrupt counter: %u \n", card->intcnt); | 2524 | int retval; |
2638 | card->intcnt = 0; | 2525 | retval = |
2639 | return retval; | 2526 | sprintf(page, "Interrupt counter: %u \n", card->intcnt); |
2640 | } | 2527 | card->intcnt = 0; |
2528 | return retval; | ||
2529 | } | ||
2641 | #if 0 | 2530 | #if 0 |
2642 | /* Dump 25.6 Mbps PHY registers */ | 2531 | /* Dump 25.6 Mbps PHY registers */ |
2643 | /* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it | 2532 | /* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it |
2644 | here just in case it's needed for debugging. */ | 2533 | here just in case it's needed for debugging. */ |
2645 | if (card->max_pcr == ATM_25_PCR && !left--) | 2534 | if (card->max_pcr == ATM_25_PCR && !left--) { |
2646 | { | 2535 | u32 phy_regs[4]; |
2647 | u32 phy_regs[4]; | 2536 | u32 i; |
2648 | u32 i; | 2537 | |
2649 | 2538 | for (i = 0; i < 4; i++) { | |
2650 | for (i = 0; i < 4; i++) | 2539 | while (CMD_BUSY(card)) ; |
2651 | { | 2540 | writel(NS_CMD_READ_UTILITY | 0x00000200 | i, |
2652 | while (CMD_BUSY(card)); | 2541 | card->membase + CMD); |
2653 | writel(NS_CMD_READ_UTILITY | 0x00000200 | i, card->membase + CMD); | 2542 | while (CMD_BUSY(card)) ; |
2654 | while (CMD_BUSY(card)); | 2543 | phy_regs[i] = readl(card->membase + DR0) & 0x000000FF; |
2655 | phy_regs[i] = readl(card->membase + DR0) & 0x000000FF; | 2544 | } |
2656 | } | 2545 | |
2657 | 2546 | return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n", | |
2658 | return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n", | 2547 | phy_regs[0], phy_regs[1], phy_regs[2], |
2659 | phy_regs[0], phy_regs[1], phy_regs[2], phy_regs[3]); | 2548 | phy_regs[3]); |
2660 | } | 2549 | } |
2661 | #endif /* 0 - Dump 25.6 Mbps PHY registers */ | 2550 | #endif /* 0 - Dump 25.6 Mbps PHY registers */ |
2662 | #if 0 | 2551 | #if 0 |
2663 | /* Dump TST */ | 2552 | /* Dump TST */ |
2664 | if (left-- < NS_TST_NUM_ENTRIES) | 2553 | if (left-- < NS_TST_NUM_ENTRIES) { |
2665 | { | 2554 | if (card->tste2vc[left + 1] == NULL) |
2666 | if (card->tste2vc[left + 1] == NULL) | 2555 | return sprintf(page, "%5d - VBR/UBR \n", left + 1); |
2667 | return sprintf(page, "%5d - VBR/UBR \n", left + 1); | 2556 | else |
2668 | else | 2557 | return sprintf(page, "%5d - %d %d \n", left + 1, |
2669 | return sprintf(page, "%5d - %d %d \n", left + 1, | 2558 | card->tste2vc[left + 1]->tx_vcc->vpi, |
2670 | card->tste2vc[left + 1]->tx_vcc->vpi, | 2559 | card->tste2vc[left + 1]->tx_vcc->vci); |
2671 | card->tste2vc[left + 1]->tx_vcc->vci); | 2560 | } |
2672 | } | ||
2673 | #endif /* 0 */ | 2561 | #endif /* 0 */ |
2674 | return 0; | 2562 | return 0; |
2675 | } | 2563 | } |
2676 | 2564 | ||
2677 | 2565 | static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg) | |
2678 | |||
2679 | static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) | ||
2680 | { | 2566 | { |
2681 | ns_dev *card; | 2567 | ns_dev *card; |
2682 | pool_levels pl; | 2568 | pool_levels pl; |
2683 | long btype; | 2569 | long btype; |
2684 | unsigned long flags; | 2570 | unsigned long flags; |
2685 | 2571 | ||
2686 | card = dev->dev_data; | 2572 | card = dev->dev_data; |
2687 | switch (cmd) | 2573 | switch (cmd) { |
2688 | { | 2574 | case NS_GETPSTAT: |
2689 | case NS_GETPSTAT: | 2575 | if (get_user |
2690 | if (get_user(pl.buftype, &((pool_levels __user *) arg)->buftype)) | 2576 | (pl.buftype, &((pool_levels __user *) arg)->buftype)) |
2691 | return -EFAULT; | 2577 | return -EFAULT; |
2692 | switch (pl.buftype) | 2578 | switch (pl.buftype) { |
2693 | { | 2579 | case NS_BUFTYPE_SMALL: |
2694 | case NS_BUFTYPE_SMALL: | 2580 | pl.count = |
2695 | pl.count = ns_stat_sfbqc_get(readl(card->membase + STAT)); | 2581 | ns_stat_sfbqc_get(readl(card->membase + STAT)); |
2696 | pl.level.min = card->sbnr.min; | 2582 | pl.level.min = card->sbnr.min; |
2697 | pl.level.init = card->sbnr.init; | 2583 | pl.level.init = card->sbnr.init; |
2698 | pl.level.max = card->sbnr.max; | 2584 | pl.level.max = card->sbnr.max; |
2699 | break; | 2585 | break; |
2700 | 2586 | ||
2701 | case NS_BUFTYPE_LARGE: | 2587 | case NS_BUFTYPE_LARGE: |
2702 | pl.count = ns_stat_lfbqc_get(readl(card->membase + STAT)); | 2588 | pl.count = |
2703 | pl.level.min = card->lbnr.min; | 2589 | ns_stat_lfbqc_get(readl(card->membase + STAT)); |
2704 | pl.level.init = card->lbnr.init; | 2590 | pl.level.min = card->lbnr.min; |
2705 | pl.level.max = card->lbnr.max; | 2591 | pl.level.init = card->lbnr.init; |
2706 | break; | 2592 | pl.level.max = card->lbnr.max; |
2707 | 2593 | break; | |
2708 | case NS_BUFTYPE_HUGE: | 2594 | |
2709 | pl.count = card->hbpool.count; | 2595 | case NS_BUFTYPE_HUGE: |
2710 | pl.level.min = card->hbnr.min; | 2596 | pl.count = card->hbpool.count; |
2711 | pl.level.init = card->hbnr.init; | 2597 | pl.level.min = card->hbnr.min; |
2712 | pl.level.max = card->hbnr.max; | 2598 | pl.level.init = card->hbnr.init; |
2713 | break; | 2599 | pl.level.max = card->hbnr.max; |
2714 | 2600 | break; | |
2715 | case NS_BUFTYPE_IOVEC: | 2601 | |
2716 | pl.count = card->iovpool.count; | 2602 | case NS_BUFTYPE_IOVEC: |
2717 | pl.level.min = card->iovnr.min; | 2603 | pl.count = card->iovpool.count; |
2718 | pl.level.init = card->iovnr.init; | 2604 | pl.level.min = card->iovnr.min; |
2719 | pl.level.max = card->iovnr.max; | 2605 | pl.level.init = card->iovnr.init; |
2720 | break; | 2606 | pl.level.max = card->iovnr.max; |
2721 | 2607 | break; | |
2722 | default: | 2608 | |
2723 | return -ENOIOCTLCMD; | 2609 | default: |
2724 | 2610 | return -ENOIOCTLCMD; | |
2725 | } | 2611 | |
2726 | if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl))) | 2612 | } |
2727 | return (sizeof(pl)); | 2613 | if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl))) |
2728 | else | 2614 | return (sizeof(pl)); |
2729 | return -EFAULT; | 2615 | else |
2730 | 2616 | return -EFAULT; | |
2731 | case NS_SETBUFLEV: | 2617 | |
2732 | if (!capable(CAP_NET_ADMIN)) | 2618 | case NS_SETBUFLEV: |
2733 | return -EPERM; | 2619 | if (!capable(CAP_NET_ADMIN)) |
2734 | if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl))) | 2620 | return -EPERM; |
2735 | return -EFAULT; | 2621 | if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl))) |
2736 | if (pl.level.min >= pl.level.init || pl.level.init >= pl.level.max) | 2622 | return -EFAULT; |
2737 | return -EINVAL; | 2623 | if (pl.level.min >= pl.level.init |
2738 | if (pl.level.min == 0) | 2624 | || pl.level.init >= pl.level.max) |
2739 | return -EINVAL; | 2625 | return -EINVAL; |
2740 | switch (pl.buftype) | 2626 | if (pl.level.min == 0) |
2741 | { | 2627 | return -EINVAL; |
2742 | case NS_BUFTYPE_SMALL: | 2628 | switch (pl.buftype) { |
2743 | if (pl.level.max > TOP_SB) | 2629 | case NS_BUFTYPE_SMALL: |
2744 | return -EINVAL; | 2630 | if (pl.level.max > TOP_SB) |
2745 | card->sbnr.min = pl.level.min; | 2631 | return -EINVAL; |
2746 | card->sbnr.init = pl.level.init; | 2632 | card->sbnr.min = pl.level.min; |
2747 | card->sbnr.max = pl.level.max; | 2633 | card->sbnr.init = pl.level.init; |
2748 | break; | 2634 | card->sbnr.max = pl.level.max; |
2749 | 2635 | break; | |
2750 | case NS_BUFTYPE_LARGE: | 2636 | |
2751 | if (pl.level.max > TOP_LB) | 2637 | case NS_BUFTYPE_LARGE: |
2752 | return -EINVAL; | 2638 | if (pl.level.max > TOP_LB) |
2753 | card->lbnr.min = pl.level.min; | 2639 | return -EINVAL; |
2754 | card->lbnr.init = pl.level.init; | 2640 | card->lbnr.min = pl.level.min; |
2755 | card->lbnr.max = pl.level.max; | 2641 | card->lbnr.init = pl.level.init; |
2756 | break; | 2642 | card->lbnr.max = pl.level.max; |
2757 | 2643 | break; | |
2758 | case NS_BUFTYPE_HUGE: | 2644 | |
2759 | if (pl.level.max > TOP_HB) | 2645 | case NS_BUFTYPE_HUGE: |
2760 | return -EINVAL; | 2646 | if (pl.level.max > TOP_HB) |
2761 | card->hbnr.min = pl.level.min; | 2647 | return -EINVAL; |
2762 | card->hbnr.init = pl.level.init; | 2648 | card->hbnr.min = pl.level.min; |
2763 | card->hbnr.max = pl.level.max; | 2649 | card->hbnr.init = pl.level.init; |
2764 | break; | 2650 | card->hbnr.max = pl.level.max; |
2765 | 2651 | break; | |
2766 | case NS_BUFTYPE_IOVEC: | 2652 | |
2767 | if (pl.level.max > TOP_IOVB) | 2653 | case NS_BUFTYPE_IOVEC: |
2768 | return -EINVAL; | 2654 | if (pl.level.max > TOP_IOVB) |
2769 | card->iovnr.min = pl.level.min; | 2655 | return -EINVAL; |
2770 | card->iovnr.init = pl.level.init; | 2656 | card->iovnr.min = pl.level.min; |
2771 | card->iovnr.max = pl.level.max; | 2657 | card->iovnr.init = pl.level.init; |
2772 | break; | 2658 | card->iovnr.max = pl.level.max; |
2773 | 2659 | break; | |
2774 | default: | 2660 | |
2775 | return -EINVAL; | 2661 | default: |
2776 | 2662 | return -EINVAL; | |
2777 | } | 2663 | |
2778 | return 0; | 2664 | } |
2779 | 2665 | return 0; | |
2780 | case NS_ADJBUFLEV: | 2666 | |
2781 | if (!capable(CAP_NET_ADMIN)) | 2667 | case NS_ADJBUFLEV: |
2782 | return -EPERM; | 2668 | if (!capable(CAP_NET_ADMIN)) |
2783 | btype = (long) arg; /* a long is the same size as a pointer or bigger */ | 2669 | return -EPERM; |
2784 | switch (btype) | 2670 | btype = (long)arg; /* a long is the same size as a pointer or bigger */ |
2785 | { | 2671 | switch (btype) { |
2786 | case NS_BUFTYPE_SMALL: | 2672 | case NS_BUFTYPE_SMALL: |
2787 | while (card->sbfqc < card->sbnr.init) | 2673 | while (card->sbfqc < card->sbnr.init) { |
2788 | { | 2674 | struct sk_buff *sb; |
2789 | struct sk_buff *sb; | 2675 | |
2790 | 2676 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); | |
2791 | sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); | 2677 | if (sb == NULL) |
2792 | if (sb == NULL) | 2678 | return -ENOMEM; |
2793 | return -ENOMEM; | 2679 | NS_PRV_BUFTYPE(sb) = BUF_SM; |
2794 | NS_SKB_CB(sb)->buf_type = BUF_SM; | 2680 | skb_queue_tail(&card->sbpool.queue, sb); |
2795 | skb_queue_tail(&card->sbpool.queue, sb); | 2681 | skb_reserve(sb, NS_AAL0_HEADER); |
2796 | skb_reserve(sb, NS_AAL0_HEADER); | 2682 | push_rxbufs(card, sb); |
2797 | push_rxbufs(card, sb); | 2683 | } |
2798 | } | 2684 | break; |
2799 | break; | 2685 | |
2800 | 2686 | case NS_BUFTYPE_LARGE: | |
2801 | case NS_BUFTYPE_LARGE: | 2687 | while (card->lbfqc < card->lbnr.init) { |
2802 | while (card->lbfqc < card->lbnr.init) | 2688 | struct sk_buff *lb; |
2803 | { | 2689 | |
2804 | struct sk_buff *lb; | 2690 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); |
2805 | 2691 | if (lb == NULL) | |
2806 | lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); | 2692 | return -ENOMEM; |
2807 | if (lb == NULL) | 2693 | NS_PRV_BUFTYPE(lb) = BUF_LG; |
2808 | return -ENOMEM; | 2694 | skb_queue_tail(&card->lbpool.queue, lb); |
2809 | NS_SKB_CB(lb)->buf_type = BUF_LG; | 2695 | skb_reserve(lb, NS_SMBUFSIZE); |
2810 | skb_queue_tail(&card->lbpool.queue, lb); | 2696 | push_rxbufs(card, lb); |
2811 | skb_reserve(lb, NS_SMBUFSIZE); | 2697 | } |
2812 | push_rxbufs(card, lb); | 2698 | break; |
2813 | } | 2699 | |
2814 | break; | 2700 | case NS_BUFTYPE_HUGE: |
2815 | 2701 | while (card->hbpool.count > card->hbnr.init) { | |
2816 | case NS_BUFTYPE_HUGE: | 2702 | struct sk_buff *hb; |
2817 | while (card->hbpool.count > card->hbnr.init) | 2703 | |
2818 | { | 2704 | spin_lock_irqsave(&card->int_lock, flags); |
2819 | struct sk_buff *hb; | 2705 | hb = skb_dequeue(&card->hbpool.queue); |
2820 | 2706 | card->hbpool.count--; | |
2821 | spin_lock_irqsave(&card->int_lock, flags); | 2707 | spin_unlock_irqrestore(&card->int_lock, flags); |
2822 | hb = skb_dequeue(&card->hbpool.queue); | 2708 | if (hb == NULL) |
2823 | card->hbpool.count--; | 2709 | printk |
2824 | spin_unlock_irqrestore(&card->int_lock, flags); | 2710 | ("nicstar%d: huge buffer count inconsistent.\n", |
2825 | if (hb == NULL) | 2711 | card->index); |
2826 | printk("nicstar%d: huge buffer count inconsistent.\n", | 2712 | else |
2827 | card->index); | 2713 | dev_kfree_skb_any(hb); |
2828 | else | 2714 | |
2829 | dev_kfree_skb_any(hb); | 2715 | } |
2830 | 2716 | while (card->hbpool.count < card->hbnr.init) { | |
2831 | } | 2717 | struct sk_buff *hb; |
2832 | while (card->hbpool.count < card->hbnr.init) | 2718 | |
2833 | { | 2719 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); |
2834 | struct sk_buff *hb; | 2720 | if (hb == NULL) |
2835 | 2721 | return -ENOMEM; | |
2836 | hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); | 2722 | NS_PRV_BUFTYPE(hb) = BUF_NONE; |
2837 | if (hb == NULL) | 2723 | spin_lock_irqsave(&card->int_lock, flags); |
2838 | return -ENOMEM; | 2724 | skb_queue_tail(&card->hbpool.queue, hb); |
2839 | NS_SKB_CB(hb)->buf_type = BUF_NONE; | 2725 | card->hbpool.count++; |
2840 | spin_lock_irqsave(&card->int_lock, flags); | 2726 | spin_unlock_irqrestore(&card->int_lock, flags); |
2841 | skb_queue_tail(&card->hbpool.queue, hb); | 2727 | } |
2842 | card->hbpool.count++; | 2728 | break; |
2843 | spin_unlock_irqrestore(&card->int_lock, flags); | 2729 | |
2844 | } | 2730 | case NS_BUFTYPE_IOVEC: |
2845 | break; | 2731 | while (card->iovpool.count > card->iovnr.init) { |
2846 | 2732 | struct sk_buff *iovb; | |
2847 | case NS_BUFTYPE_IOVEC: | 2733 | |
2848 | while (card->iovpool.count > card->iovnr.init) | 2734 | spin_lock_irqsave(&card->int_lock, flags); |
2849 | { | 2735 | iovb = skb_dequeue(&card->iovpool.queue); |
2850 | struct sk_buff *iovb; | 2736 | card->iovpool.count--; |
2851 | 2737 | spin_unlock_irqrestore(&card->int_lock, flags); | |
2852 | spin_lock_irqsave(&card->int_lock, flags); | 2738 | if (iovb == NULL) |
2853 | iovb = skb_dequeue(&card->iovpool.queue); | 2739 | printk |
2854 | card->iovpool.count--; | 2740 | ("nicstar%d: iovec buffer count inconsistent.\n", |
2855 | spin_unlock_irqrestore(&card->int_lock, flags); | 2741 | card->index); |
2856 | if (iovb == NULL) | 2742 | else |
2857 | printk("nicstar%d: iovec buffer count inconsistent.\n", | 2743 | dev_kfree_skb_any(iovb); |
2858 | card->index); | 2744 | |
2859 | else | 2745 | } |
2860 | dev_kfree_skb_any(iovb); | 2746 | while (card->iovpool.count < card->iovnr.init) { |
2861 | 2747 | struct sk_buff *iovb; | |
2862 | } | 2748 | |
2863 | while (card->iovpool.count < card->iovnr.init) | 2749 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL); |
2864 | { | 2750 | if (iovb == NULL) |
2865 | struct sk_buff *iovb; | 2751 | return -ENOMEM; |
2866 | 2752 | NS_PRV_BUFTYPE(iovb) = BUF_NONE; | |
2867 | iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL); | 2753 | spin_lock_irqsave(&card->int_lock, flags); |
2868 | if (iovb == NULL) | 2754 | skb_queue_tail(&card->iovpool.queue, iovb); |
2869 | return -ENOMEM; | 2755 | card->iovpool.count++; |
2870 | NS_SKB_CB(iovb)->buf_type = BUF_NONE; | 2756 | spin_unlock_irqrestore(&card->int_lock, flags); |
2871 | spin_lock_irqsave(&card->int_lock, flags); | 2757 | } |
2872 | skb_queue_tail(&card->iovpool.queue, iovb); | 2758 | break; |
2873 | card->iovpool.count++; | 2759 | |
2874 | spin_unlock_irqrestore(&card->int_lock, flags); | 2760 | default: |
2875 | } | 2761 | return -EINVAL; |
2876 | break; | 2762 | |
2877 | 2763 | } | |
2878 | default: | 2764 | return 0; |
2879 | return -EINVAL; | 2765 | |
2880 | 2766 | default: | |
2881 | } | 2767 | if (dev->phy && dev->phy->ioctl) { |
2882 | return 0; | 2768 | return dev->phy->ioctl(dev, cmd, arg); |
2883 | 2769 | } else { | |
2884 | default: | 2770 | printk("nicstar%d: %s == NULL \n", card->index, |
2885 | if (dev->phy && dev->phy->ioctl) { | 2771 | dev->phy ? "dev->phy->ioctl" : "dev->phy"); |
2886 | return dev->phy->ioctl(dev, cmd, arg); | 2772 | return -ENOIOCTLCMD; |
2887 | } | 2773 | } |
2888 | else { | 2774 | } |
2889 | printk("nicstar%d: %s == NULL \n", card->index, | ||
2890 | dev->phy ? "dev->phy->ioctl" : "dev->phy"); | ||
2891 | return -ENOIOCTLCMD; | ||
2892 | } | ||
2893 | } | ||
2894 | } | 2775 | } |
2895 | 2776 | ||
2896 | 2777 | #ifdef EXTRA_DEBUG | |
2897 | static void which_list(ns_dev *card, struct sk_buff *skb) | 2778 | static void which_list(ns_dev * card, struct sk_buff *skb) |
2898 | { | 2779 | { |
2899 | printk("skb buf_type: 0x%08x\n", NS_SKB_CB(skb)->buf_type); | 2780 | printk("skb buf_type: 0x%08x\n", NS_PRV_BUFTYPE(skb)); |
2900 | } | 2781 | } |
2901 | 2782 | #endif /* EXTRA_DEBUG */ | |
2902 | 2783 | ||
2903 | static void ns_poll(unsigned long arg) | 2784 | static void ns_poll(unsigned long arg) |
2904 | { | 2785 | { |
2905 | int i; | 2786 | int i; |
2906 | ns_dev *card; | 2787 | ns_dev *card; |
2907 | unsigned long flags; | 2788 | unsigned long flags; |
2908 | u32 stat_r, stat_w; | 2789 | u32 stat_r, stat_w; |
2909 | 2790 | ||
2910 | PRINTK("nicstar: Entering ns_poll().\n"); | 2791 | PRINTK("nicstar: Entering ns_poll().\n"); |
2911 | for (i = 0; i < num_cards; i++) | 2792 | for (i = 0; i < num_cards; i++) { |
2912 | { | 2793 | card = cards[i]; |
2913 | card = cards[i]; | 2794 | if (spin_is_locked(&card->int_lock)) { |
2914 | if (spin_is_locked(&card->int_lock)) { | 2795 | /* Probably it isn't worth spinning */ |
2915 | /* Probably it isn't worth spinning */ | 2796 | continue; |
2916 | continue; | 2797 | } |
2917 | } | 2798 | spin_lock_irqsave(&card->int_lock, flags); |
2918 | spin_lock_irqsave(&card->int_lock, flags); | 2799 | |
2919 | 2800 | stat_w = 0; | |
2920 | stat_w = 0; | 2801 | stat_r = readl(card->membase + STAT); |
2921 | stat_r = readl(card->membase + STAT); | 2802 | if (stat_r & NS_STAT_TSIF) |
2922 | if (stat_r & NS_STAT_TSIF) | 2803 | stat_w |= NS_STAT_TSIF; |
2923 | stat_w |= NS_STAT_TSIF; | 2804 | if (stat_r & NS_STAT_EOPDU) |
2924 | if (stat_r & NS_STAT_EOPDU) | 2805 | stat_w |= NS_STAT_EOPDU; |
2925 | stat_w |= NS_STAT_EOPDU; | 2806 | |
2926 | 2807 | process_tsq(card); | |
2927 | process_tsq(card); | 2808 | process_rsq(card); |
2928 | process_rsq(card); | 2809 | |
2929 | 2810 | writel(stat_w, card->membase + STAT); | |
2930 | writel(stat_w, card->membase + STAT); | 2811 | spin_unlock_irqrestore(&card->int_lock, flags); |
2931 | spin_unlock_irqrestore(&card->int_lock, flags); | 2812 | } |
2932 | } | 2813 | mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD); |
2933 | mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD); | 2814 | PRINTK("nicstar: Leaving ns_poll().\n"); |
2934 | PRINTK("nicstar: Leaving ns_poll().\n"); | ||
2935 | } | 2815 | } |
2936 | 2816 | ||
2937 | |||
2938 | |||
2939 | static int ns_parse_mac(char *mac, unsigned char *esi) | 2817 | static int ns_parse_mac(char *mac, unsigned char *esi) |
2940 | { | 2818 | { |
2941 | int i, j; | 2819 | int i, j; |
2942 | short byte1, byte0; | 2820 | short byte1, byte0; |
2943 | 2821 | ||
2944 | if (mac == NULL || esi == NULL) | 2822 | if (mac == NULL || esi == NULL) |
2945 | return -1; | 2823 | return -1; |
2946 | j = 0; | 2824 | j = 0; |
2947 | for (i = 0; i < 6; i++) | 2825 | for (i = 0; i < 6; i++) { |
2948 | { | 2826 | if ((byte1 = hex_to_bin(mac[j++])) < 0) |
2949 | if ((byte1 = ns_h2i(mac[j++])) < 0) | 2827 | return -1; |
2950 | return -1; | 2828 | if ((byte0 = hex_to_bin(mac[j++])) < 0) |
2951 | if ((byte0 = ns_h2i(mac[j++])) < 0) | 2829 | return -1; |
2952 | return -1; | 2830 | esi[i] = (unsigned char)(byte1 * 16 + byte0); |
2953 | esi[i] = (unsigned char) (byte1 * 16 + byte0); | 2831 | if (i < 5) { |
2954 | if (i < 5) | 2832 | if (mac[j++] != ':') |
2955 | { | 2833 | return -1; |
2956 | if (mac[j++] != ':') | 2834 | } |
2957 | return -1; | 2835 | } |
2958 | } | 2836 | return 0; |
2959 | } | ||
2960 | return 0; | ||
2961 | } | ||
2962 | |||
2963 | |||
2964 | |||
2965 | static short ns_h2i(char c) | ||
2966 | { | ||
2967 | if (c >= '0' && c <= '9') | ||
2968 | return (short) (c - '0'); | ||
2969 | if (c >= 'A' && c <= 'F') | ||
2970 | return (short) (c - 'A' + 10); | ||
2971 | if (c >= 'a' && c <= 'f') | ||
2972 | return (short) (c - 'a' + 10); | ||
2973 | return -1; | ||
2974 | } | 2837 | } |
2975 | 2838 | ||
2976 | 2839 | ||
2977 | |||
2978 | static void ns_phy_put(struct atm_dev *dev, unsigned char value, | 2840 | static void ns_phy_put(struct atm_dev *dev, unsigned char value, |
2979 | unsigned long addr) | 2841 | unsigned long addr) |
2980 | { | 2842 | { |
2981 | ns_dev *card; | 2843 | ns_dev *card; |
2982 | unsigned long flags; | 2844 | unsigned long flags; |
2983 | 2845 | ||
2984 | card = dev->dev_data; | 2846 | card = dev->dev_data; |
2985 | spin_lock_irqsave(&card->res_lock, flags); | 2847 | spin_lock_irqsave(&card->res_lock, flags); |
2986 | while(CMD_BUSY(card)); | 2848 | while (CMD_BUSY(card)) ; |
2987 | writel((unsigned long) value, card->membase + DR0); | 2849 | writel((u32) value, card->membase + DR0); |
2988 | writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF), | 2850 | writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF), |
2989 | card->membase + CMD); | 2851 | card->membase + CMD); |
2990 | spin_unlock_irqrestore(&card->res_lock, flags); | 2852 | spin_unlock_irqrestore(&card->res_lock, flags); |
2991 | } | 2853 | } |
2992 | 2854 | ||
2993 | |||
2994 | |||
2995 | static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr) | 2855 | static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr) |
2996 | { | 2856 | { |
2997 | ns_dev *card; | 2857 | ns_dev *card; |
2998 | unsigned long flags; | 2858 | unsigned long flags; |
2999 | unsigned long data; | 2859 | u32 data; |
3000 | 2860 | ||
3001 | card = dev->dev_data; | 2861 | card = dev->dev_data; |
3002 | spin_lock_irqsave(&card->res_lock, flags); | 2862 | spin_lock_irqsave(&card->res_lock, flags); |
3003 | while(CMD_BUSY(card)); | 2863 | while (CMD_BUSY(card)) ; |
3004 | writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF), | 2864 | writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF), |
3005 | card->membase + CMD); | 2865 | card->membase + CMD); |
3006 | while(CMD_BUSY(card)); | 2866 | while (CMD_BUSY(card)) ; |
3007 | data = readl(card->membase + DR0) & 0x000000FF; | 2867 | data = readl(card->membase + DR0) & 0x000000FF; |
3008 | spin_unlock_irqrestore(&card->res_lock, flags); | 2868 | spin_unlock_irqrestore(&card->res_lock, flags); |
3009 | return (unsigned char) data; | 2869 | return (unsigned char)data; |
3010 | } | 2870 | } |
3011 | 2871 | ||
3012 | |||
3013 | |||
3014 | module_init(nicstar_init); | 2872 | module_init(nicstar_init); |
3015 | module_exit(nicstar_cleanup); | 2873 | module_exit(nicstar_cleanup); |
diff --git a/drivers/atm/nicstar.h b/drivers/atm/nicstar.h index 6010e3daa6a2..9bc27ea5088e 100644 --- a/drivers/atm/nicstar.h +++ b/drivers/atm/nicstar.h | |||
@@ -1,5 +1,4 @@ | |||
1 | /****************************************************************************** | 1 | /* |
2 | * | ||
3 | * nicstar.h | 2 | * nicstar.h |
4 | * | 3 | * |
5 | * Header file for the nicstar device driver. | 4 | * Header file for the nicstar device driver. |
@@ -8,29 +7,26 @@ | |||
8 | * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999 | 7 | * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999 |
9 | * | 8 | * |
10 | * (C) INESC 1998 | 9 | * (C) INESC 1998 |
11 | * | 10 | */ |
12 | ******************************************************************************/ | ||
13 | |||
14 | 11 | ||
15 | #ifndef _LINUX_NICSTAR_H_ | 12 | #ifndef _LINUX_NICSTAR_H_ |
16 | #define _LINUX_NICSTAR_H_ | 13 | #define _LINUX_NICSTAR_H_ |
17 | 14 | ||
18 | 15 | /* Includes */ | |
19 | /* Includes *******************************************************************/ | ||
20 | 16 | ||
21 | #include <linux/types.h> | 17 | #include <linux/types.h> |
22 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/idr.h> | ||
23 | #include <linux/uio.h> | 20 | #include <linux/uio.h> |
24 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
25 | #include <linux/atmdev.h> | 22 | #include <linux/atmdev.h> |
26 | #include <linux/atm_nicstar.h> | 23 | #include <linux/atm_nicstar.h> |
27 | 24 | ||
28 | 25 | /* Options */ | |
29 | /* Options ********************************************************************/ | ||
30 | 26 | ||
31 | #define NS_MAX_CARDS 4 /* Maximum number of NICStAR based cards | 27 | #define NS_MAX_CARDS 4 /* Maximum number of NICStAR based cards |
32 | controlled by the device driver. Must | 28 | controlled by the device driver. Must |
33 | be <= 5 */ | 29 | be <= 5 */ |
34 | 30 | ||
35 | #undef RCQ_SUPPORT /* Do not define this for now */ | 31 | #undef RCQ_SUPPORT /* Do not define this for now */ |
36 | 32 | ||
@@ -43,7 +39,7 @@ | |||
43 | #define NS_VPIBITS 2 /* 0, 1, 2, or 8 */ | 39 | #define NS_VPIBITS 2 /* 0, 1, 2, or 8 */ |
44 | 40 | ||
45 | #define NS_MAX_RCTSIZE 4096 /* Number of entries. 4096 or 16384. | 41 | #define NS_MAX_RCTSIZE 4096 /* Number of entries. 4096 or 16384. |
46 | Define 4096 only if (all) your card(s) | 42 | Define 4096 only if (all) your card(s) |
47 | have 32K x 32bit SRAM, in which case | 43 | have 32K x 32bit SRAM, in which case |
48 | setting this to 16384 will just waste a | 44 | setting this to 16384 will just waste a |
49 | lot of memory. | 45 | lot of memory. |
@@ -51,33 +47,32 @@ | |||
51 | 128K x 32bit SRAM will limit the maximum | 47 | 128K x 32bit SRAM will limit the maximum |
52 | VCI. */ | 48 | VCI. */ |
53 | 49 | ||
54 | /*#define NS_PCI_LATENCY 64*/ /* Must be a multiple of 32 */ | 50 | /*#define NS_PCI_LATENCY 64*//* Must be a multiple of 32 */ |
55 | 51 | ||
56 | /* Number of buffers initially allocated */ | 52 | /* Number of buffers initially allocated */ |
57 | #define NUM_SB 32 /* Must be even */ | 53 | #define NUM_SB 32 /* Must be even */ |
58 | #define NUM_LB 24 /* Must be even */ | 54 | #define NUM_LB 24 /* Must be even */ |
59 | #define NUM_HB 8 /* Pre-allocated huge buffers */ | 55 | #define NUM_HB 8 /* Pre-allocated huge buffers */ |
60 | #define NUM_IOVB 48 /* Iovec buffers */ | 56 | #define NUM_IOVB 48 /* Iovec buffers */ |
61 | 57 | ||
62 | /* Lower level for count of buffers */ | 58 | /* Lower level for count of buffers */ |
63 | #define MIN_SB 8 /* Must be even */ | 59 | #define MIN_SB 8 /* Must be even */ |
64 | #define MIN_LB 8 /* Must be even */ | 60 | #define MIN_LB 8 /* Must be even */ |
65 | #define MIN_HB 6 | 61 | #define MIN_HB 6 |
66 | #define MIN_IOVB 8 | 62 | #define MIN_IOVB 8 |
67 | 63 | ||
68 | /* Upper level for count of buffers */ | 64 | /* Upper level for count of buffers */ |
69 | #define MAX_SB 64 /* Must be even, <= 508 */ | 65 | #define MAX_SB 64 /* Must be even, <= 508 */ |
70 | #define MAX_LB 48 /* Must be even, <= 508 */ | 66 | #define MAX_LB 48 /* Must be even, <= 508 */ |
71 | #define MAX_HB 10 | 67 | #define MAX_HB 10 |
72 | #define MAX_IOVB 80 | 68 | #define MAX_IOVB 80 |
73 | 69 | ||
74 | /* These are the absolute maximum allowed for the ioctl() */ | 70 | /* These are the absolute maximum allowed for the ioctl() */ |
75 | #define TOP_SB 256 /* Must be even, <= 508 */ | 71 | #define TOP_SB 256 /* Must be even, <= 508 */ |
76 | #define TOP_LB 128 /* Must be even, <= 508 */ | 72 | #define TOP_LB 128 /* Must be even, <= 508 */ |
77 | #define TOP_HB 64 | 73 | #define TOP_HB 64 |
78 | #define TOP_IOVB 256 | 74 | #define TOP_IOVB 256 |
79 | 75 | ||
80 | |||
81 | #define MAX_TBD_PER_VC 1 /* Number of TBDs before a TSR */ | 76 | #define MAX_TBD_PER_VC 1 /* Number of TBDs before a TSR */ |
82 | #define MAX_TBD_PER_SCQ 10 /* Only meaningful for variable rate SCQs */ | 77 | #define MAX_TBD_PER_SCQ 10 /* Only meaningful for variable rate SCQs */ |
83 | 78 | ||
@@ -89,15 +84,12 @@ | |||
89 | 84 | ||
90 | #define PCR_TOLERANCE (1.0001) | 85 | #define PCR_TOLERANCE (1.0001) |
91 | 86 | ||
92 | 87 | /* ESI stuff */ | |
93 | |||
94 | /* ESI stuff ******************************************************************/ | ||
95 | 88 | ||
96 | #define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C | 89 | #define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C |
97 | #define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6 | 90 | #define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6 |
98 | 91 | ||
99 | 92 | /* #defines */ | |
100 | /* #defines *******************************************************************/ | ||
101 | 93 | ||
102 | #define NS_IOREMAP_SIZE 4096 | 94 | #define NS_IOREMAP_SIZE 4096 |
103 | 95 | ||
@@ -123,22 +115,19 @@ | |||
123 | #define NS_SMSKBSIZE (NS_SMBUFSIZE + NS_AAL0_HEADER) | 115 | #define NS_SMSKBSIZE (NS_SMBUFSIZE + NS_AAL0_HEADER) |
124 | #define NS_LGSKBSIZE (NS_SMBUFSIZE + NS_LGBUFSIZE) | 116 | #define NS_LGSKBSIZE (NS_SMBUFSIZE + NS_LGBUFSIZE) |
125 | 117 | ||
118 | /* NICStAR structures located in host memory */ | ||
126 | 119 | ||
127 | /* NICStAR structures located in host memory **********************************/ | 120 | /* |
128 | 121 | * RSQ - Receive Status Queue | |
129 | |||
130 | |||
131 | /* RSQ - Receive Status Queue | ||
132 | * | 122 | * |
133 | * Written by the NICStAR, read by the device driver. | 123 | * Written by the NICStAR, read by the device driver. |
134 | */ | 124 | */ |
135 | 125 | ||
136 | typedef struct ns_rsqe | 126 | typedef struct ns_rsqe { |
137 | { | 127 | u32 word_1; |
138 | u32 word_1; | 128 | u32 buffer_handle; |
139 | u32 buffer_handle; | 129 | u32 final_aal5_crc32; |
140 | u32 final_aal5_crc32; | 130 | u32 word_4; |
141 | u32 word_4; | ||
142 | } ns_rsqe; | 131 | } ns_rsqe; |
143 | 132 | ||
144 | #define ns_rsqe_vpi(ns_rsqep) \ | 133 | #define ns_rsqe_vpi(ns_rsqep) \ |
@@ -175,30 +164,27 @@ typedef struct ns_rsqe | |||
175 | #define ns_rsqe_cellcount(ns_rsqep) \ | 164 | #define ns_rsqe_cellcount(ns_rsqep) \ |
176 | (le32_to_cpu((ns_rsqep)->word_4) & 0x000001FF) | 165 | (le32_to_cpu((ns_rsqep)->word_4) & 0x000001FF) |
177 | #define ns_rsqe_init(ns_rsqep) \ | 166 | #define ns_rsqe_init(ns_rsqep) \ |
178 | ((ns_rsqep)->word_4 = cpu_to_le32(0x00000000)) | 167 | ((ns_rsqep)->word_4 = cpu_to_le32(0x00000000)) |
179 | 168 | ||
180 | #define NS_RSQ_NUM_ENTRIES (NS_RSQSIZE / 16) | 169 | #define NS_RSQ_NUM_ENTRIES (NS_RSQSIZE / 16) |
181 | #define NS_RSQ_ALIGNMENT NS_RSQSIZE | 170 | #define NS_RSQ_ALIGNMENT NS_RSQSIZE |
182 | 171 | ||
183 | 172 | /* | |
184 | 173 | * RCQ - Raw Cell Queue | |
185 | /* RCQ - Raw Cell Queue | ||
186 | * | 174 | * |
187 | * Written by the NICStAR, read by the device driver. | 175 | * Written by the NICStAR, read by the device driver. |
188 | */ | 176 | */ |
189 | 177 | ||
190 | typedef struct cell_payload | 178 | typedef struct cell_payload { |
191 | { | 179 | u32 word[12]; |
192 | u32 word[12]; | ||
193 | } cell_payload; | 180 | } cell_payload; |
194 | 181 | ||
195 | typedef struct ns_rcqe | 182 | typedef struct ns_rcqe { |
196 | { | 183 | u32 word_1; |
197 | u32 word_1; | 184 | u32 word_2; |
198 | u32 word_2; | 185 | u32 word_3; |
199 | u32 word_3; | 186 | u32 word_4; |
200 | u32 word_4; | 187 | cell_payload payload; |
201 | cell_payload payload; | ||
202 | } ns_rcqe; | 188 | } ns_rcqe; |
203 | 189 | ||
204 | #define NS_RCQE_SIZE 64 /* bytes */ | 190 | #define NS_RCQE_SIZE 64 /* bytes */ |
@@ -210,28 +196,25 @@ typedef struct ns_rcqe | |||
210 | #define ns_rcqe_nextbufhandle(ns_rcqep) \ | 196 | #define ns_rcqe_nextbufhandle(ns_rcqep) \ |
211 | (le32_to_cpu((ns_rcqep)->word_2)) | 197 | (le32_to_cpu((ns_rcqep)->word_2)) |
212 | 198 | ||
213 | 199 | /* | |
214 | 200 | * SCQ - Segmentation Channel Queue | |
215 | /* SCQ - Segmentation Channel Queue | ||
216 | * | 201 | * |
217 | * Written by the device driver, read by the NICStAR. | 202 | * Written by the device driver, read by the NICStAR. |
218 | */ | 203 | */ |
219 | 204 | ||
220 | typedef struct ns_scqe | 205 | typedef struct ns_scqe { |
221 | { | 206 | u32 word_1; |
222 | u32 word_1; | 207 | u32 word_2; |
223 | u32 word_2; | 208 | u32 word_3; |
224 | u32 word_3; | 209 | u32 word_4; |
225 | u32 word_4; | ||
226 | } ns_scqe; | 210 | } ns_scqe; |
227 | 211 | ||
228 | /* NOTE: SCQ entries can be either a TBD (Transmit Buffer Descriptors) | 212 | /* NOTE: SCQ entries can be either a TBD (Transmit Buffer Descriptors) |
229 | or TSR (Transmit Status Requests) */ | 213 | or TSR (Transmit Status Requests) */ |
230 | 214 | ||
231 | #define NS_SCQE_TYPE_TBD 0x00000000 | 215 | #define NS_SCQE_TYPE_TBD 0x00000000 |
232 | #define NS_SCQE_TYPE_TSR 0x80000000 | 216 | #define NS_SCQE_TYPE_TSR 0x80000000 |
233 | 217 | ||
234 | |||
235 | #define NS_TBD_EOPDU 0x40000000 | 218 | #define NS_TBD_EOPDU 0x40000000 |
236 | #define NS_TBD_AAL0 0x00000000 | 219 | #define NS_TBD_AAL0 0x00000000 |
237 | #define NS_TBD_AAL34 0x04000000 | 220 | #define NS_TBD_AAL34 0x04000000 |
@@ -253,10 +236,9 @@ typedef struct ns_scqe | |||
253 | #define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \ | 236 | #define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \ |
254 | (cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp))) | 237 | (cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp))) |
255 | 238 | ||
256 | |||
257 | #define NS_TSR_INTENABLE 0x20000000 | 239 | #define NS_TSR_INTENABLE 0x20000000 |
258 | 240 | ||
259 | #define NS_TSR_SCDISVBR 0xFFFF /* Use as scdi for VBR SCD */ | 241 | #define NS_TSR_SCDISVBR 0xFFFF /* Use as scdi for VBR SCD */ |
260 | 242 | ||
261 | #define ns_tsr_mkword_1(flags) \ | 243 | #define ns_tsr_mkword_1(flags) \ |
262 | (cpu_to_le32(NS_SCQE_TYPE_TSR | (flags))) | 244 | (cpu_to_le32(NS_SCQE_TYPE_TSR | (flags))) |
@@ -273,22 +255,20 @@ typedef struct ns_scqe | |||
273 | 255 | ||
274 | #define NS_SCQE_SIZE 16 | 256 | #define NS_SCQE_SIZE 16 |
275 | 257 | ||
276 | 258 | /* | |
277 | 259 | * TSQ - Transmit Status Queue | |
278 | /* TSQ - Transmit Status Queue | ||
279 | * | 260 | * |
280 | * Written by the NICStAR, read by the device driver. | 261 | * Written by the NICStAR, read by the device driver. |
281 | */ | 262 | */ |
282 | 263 | ||
283 | typedef struct ns_tsi | 264 | typedef struct ns_tsi { |
284 | { | 265 | u32 word_1; |
285 | u32 word_1; | 266 | u32 word_2; |
286 | u32 word_2; | ||
287 | } ns_tsi; | 267 | } ns_tsi; |
288 | 268 | ||
289 | /* NOTE: The first word can be a status word copied from the TSR which | 269 | /* NOTE: The first word can be a status word copied from the TSR which |
290 | originated the TSI, or a timer overflow indicator. In this last | 270 | originated the TSI, or a timer overflow indicator. In this last |
291 | case, the value of the first word is all zeroes. */ | 271 | case, the value of the first word is all zeroes. */ |
292 | 272 | ||
293 | #define NS_TSI_EMPTY 0x80000000 | 273 | #define NS_TSI_EMPTY 0x80000000 |
294 | #define NS_TSI_TIMESTAMP_MASK 0x00FFFFFF | 274 | #define NS_TSI_TIMESTAMP_MASK 0x00FFFFFF |
@@ -301,12 +281,10 @@ typedef struct ns_tsi | |||
301 | #define ns_tsi_init(ns_tsip) \ | 281 | #define ns_tsi_init(ns_tsip) \ |
302 | ((ns_tsip)->word_2 = cpu_to_le32(NS_TSI_EMPTY)) | 282 | ((ns_tsip)->word_2 = cpu_to_le32(NS_TSI_EMPTY)) |
303 | 283 | ||
304 | |||
305 | #define NS_TSQSIZE 8192 | 284 | #define NS_TSQSIZE 8192 |
306 | #define NS_TSQ_NUM_ENTRIES 1024 | 285 | #define NS_TSQ_NUM_ENTRIES 1024 |
307 | #define NS_TSQ_ALIGNMENT 8192 | 286 | #define NS_TSQ_ALIGNMENT 8192 |
308 | 287 | ||
309 | |||
310 | #define NS_TSI_SCDISVBR NS_TSR_SCDISVBR | 288 | #define NS_TSI_SCDISVBR NS_TSR_SCDISVBR |
311 | 289 | ||
312 | #define ns_tsi_tmrof(ns_tsip) \ | 290 | #define ns_tsi_tmrof(ns_tsip) \ |
@@ -316,26 +294,22 @@ typedef struct ns_tsi | |||
316 | #define ns_tsi_getscqpos(ns_tsip) \ | 294 | #define ns_tsi_getscqpos(ns_tsip) \ |
317 | (le32_to_cpu((ns_tsip)->word_1) & 0x00007FFF) | 295 | (le32_to_cpu((ns_tsip)->word_1) & 0x00007FFF) |
318 | 296 | ||
297 | /* NICStAR structures located in local SRAM */ | ||
319 | 298 | ||
320 | 299 | /* | |
321 | /* NICStAR structures located in local SRAM ***********************************/ | 300 | * RCT - Receive Connection Table |
322 | |||
323 | |||
324 | |||
325 | /* RCT - Receive Connection Table | ||
326 | * | 301 | * |
327 | * Written by both the NICStAR and the device driver. | 302 | * Written by both the NICStAR and the device driver. |
328 | */ | 303 | */ |
329 | 304 | ||
330 | typedef struct ns_rcte | 305 | typedef struct ns_rcte { |
331 | { | 306 | u32 word_1; |
332 | u32 word_1; | 307 | u32 buffer_handle; |
333 | u32 buffer_handle; | 308 | u32 dma_address; |
334 | u32 dma_address; | 309 | u32 aal5_crc32; |
335 | u32 aal5_crc32; | ||
336 | } ns_rcte; | 310 | } ns_rcte; |
337 | 311 | ||
338 | #define NS_RCTE_BSFB 0x00200000 /* Rev. D only */ | 312 | #define NS_RCTE_BSFB 0x00200000 /* Rev. D only */ |
339 | #define NS_RCTE_NZGFC 0x00100000 | 313 | #define NS_RCTE_NZGFC 0x00100000 |
340 | #define NS_RCTE_CONNECTOPEN 0x00080000 | 314 | #define NS_RCTE_CONNECTOPEN 0x00080000 |
341 | #define NS_RCTE_AALMASK 0x00070000 | 315 | #define NS_RCTE_AALMASK 0x00070000 |
@@ -358,25 +332,21 @@ typedef struct ns_rcte | |||
358 | #define NS_RCT_ENTRY_SIZE 4 /* Number of dwords */ | 332 | #define NS_RCT_ENTRY_SIZE 4 /* Number of dwords */ |
359 | 333 | ||
360 | /* NOTE: We could make macros to contruct the first word of the RCTE, | 334 | /* NOTE: We could make macros to contruct the first word of the RCTE, |
361 | but that doesn't seem to make much sense... */ | 335 | but that doesn't seem to make much sense... */ |
362 | 336 | ||
363 | 337 | /* | |
364 | 338 | * FBD - Free Buffer Descriptor | |
365 | /* FBD - Free Buffer Descriptor | ||
366 | * | 339 | * |
367 | * Written by the device driver using via the command register. | 340 | * Written by the device driver using via the command register. |
368 | */ | 341 | */ |
369 | 342 | ||
370 | typedef struct ns_fbd | 343 | typedef struct ns_fbd { |
371 | { | 344 | u32 buffer_handle; |
372 | u32 buffer_handle; | 345 | u32 dma_address; |
373 | u32 dma_address; | ||
374 | } ns_fbd; | 346 | } ns_fbd; |
375 | 347 | ||
376 | 348 | /* | |
377 | 349 | * TST - Transmit Schedule Table | |
378 | |||
379 | /* TST - Transmit Schedule Table | ||
380 | * | 350 | * |
381 | * Written by the device driver. | 351 | * Written by the device driver. |
382 | */ | 352 | */ |
@@ -385,40 +355,38 @@ typedef u32 ns_tste; | |||
385 | 355 | ||
386 | #define NS_TST_OPCODE_MASK 0x60000000 | 356 | #define NS_TST_OPCODE_MASK 0x60000000 |
387 | 357 | ||
388 | #define NS_TST_OPCODE_NULL 0x00000000 /* Insert null cell */ | 358 | #define NS_TST_OPCODE_NULL 0x00000000 /* Insert null cell */ |
389 | #define NS_TST_OPCODE_FIXED 0x20000000 /* Cell from a fixed rate channel */ | 359 | #define NS_TST_OPCODE_FIXED 0x20000000 /* Cell from a fixed rate channel */ |
390 | #define NS_TST_OPCODE_VARIABLE 0x40000000 | 360 | #define NS_TST_OPCODE_VARIABLE 0x40000000 |
391 | #define NS_TST_OPCODE_END 0x60000000 /* Jump */ | 361 | #define NS_TST_OPCODE_END 0x60000000 /* Jump */ |
392 | 362 | ||
393 | #define ns_tste_make(opcode, sramad) (opcode | sramad) | 363 | #define ns_tste_make(opcode, sramad) (opcode | sramad) |
394 | 364 | ||
395 | /* NOTE: | 365 | /* NOTE: |
396 | 366 | ||
397 | - When the opcode is FIXED, sramad specifies the SRAM address of the | 367 | - When the opcode is FIXED, sramad specifies the SRAM address of the |
398 | SCD for that fixed rate channel. | 368 | SCD for that fixed rate channel. |
399 | - When the opcode is END, sramad specifies the SRAM address of the | 369 | - When the opcode is END, sramad specifies the SRAM address of the |
400 | location of the next TST entry to read. | 370 | location of the next TST entry to read. |
401 | */ | 371 | */ |
402 | 372 | ||
403 | 373 | /* | |
404 | 374 | * SCD - Segmentation Channel Descriptor | |
405 | /* SCD - Segmentation Channel Descriptor | ||
406 | * | 375 | * |
407 | * Written by both the device driver and the NICStAR | 376 | * Written by both the device driver and the NICStAR |
408 | */ | 377 | */ |
409 | 378 | ||
410 | typedef struct ns_scd | 379 | typedef struct ns_scd { |
411 | { | 380 | u32 word_1; |
412 | u32 word_1; | 381 | u32 word_2; |
413 | u32 word_2; | 382 | u32 partial_aal5_crc; |
414 | u32 partial_aal5_crc; | 383 | u32 reserved; |
415 | u32 reserved; | 384 | ns_scqe cache_a; |
416 | ns_scqe cache_a; | 385 | ns_scqe cache_b; |
417 | ns_scqe cache_b; | ||
418 | } ns_scd; | 386 | } ns_scd; |
419 | 387 | ||
420 | #define NS_SCD_BASE_MASK_VAR 0xFFFFE000 /* Variable rate */ | 388 | #define NS_SCD_BASE_MASK_VAR 0xFFFFE000 /* Variable rate */ |
421 | #define NS_SCD_BASE_MASK_FIX 0xFFFFFC00 /* Fixed rate */ | 389 | #define NS_SCD_BASE_MASK_FIX 0xFFFFFC00 /* Fixed rate */ |
422 | #define NS_SCD_TAIL_MASK_VAR 0x00001FF0 | 390 | #define NS_SCD_TAIL_MASK_VAR 0x00001FF0 |
423 | #define NS_SCD_TAIL_MASK_FIX 0x000003F0 | 391 | #define NS_SCD_TAIL_MASK_FIX 0x000003F0 |
424 | #define NS_SCD_HEAD_MASK_VAR 0x00001FF0 | 392 | #define NS_SCD_HEAD_MASK_VAR 0x00001FF0 |
@@ -426,13 +394,9 @@ typedef struct ns_scd | |||
426 | #define NS_SCD_XMITFOREVER 0x02000000 | 394 | #define NS_SCD_XMITFOREVER 0x02000000 |
427 | 395 | ||
428 | /* NOTE: There are other fields in word 2 of the SCD, but as they should | 396 | /* NOTE: There are other fields in word 2 of the SCD, but as they should |
429 | not be needed in the device driver they are not defined here. */ | 397 | not be needed in the device driver they are not defined here. */ |
430 | |||
431 | |||
432 | |||
433 | |||
434 | /* NICStAR local SRAM memory map **********************************************/ | ||
435 | 398 | ||
399 | /* NICStAR local SRAM memory map */ | ||
436 | 400 | ||
437 | #define NS_RCT 0x00000 | 401 | #define NS_RCT 0x00000 |
438 | #define NS_RCT_32_END 0x03FFF | 402 | #define NS_RCT_32_END 0x03FFF |
@@ -455,100 +419,93 @@ typedef struct ns_scd | |||
455 | #define NS_LGFBQ 0x1FC00 | 419 | #define NS_LGFBQ 0x1FC00 |
456 | #define NS_LGFBQ_END 0x1FFFF | 420 | #define NS_LGFBQ_END 0x1FFFF |
457 | 421 | ||
458 | 422 | /* NISCtAR operation registers */ | |
459 | |||
460 | /* NISCtAR operation registers ************************************************/ | ||
461 | |||
462 | 423 | ||
463 | /* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */ | 424 | /* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */ |
464 | 425 | ||
465 | enum ns_regs | 426 | enum ns_regs { |
466 | { | 427 | DR0 = 0x00, /* Data Register 0 R/W */ |
467 | DR0 = 0x00, /* Data Register 0 R/W*/ | 428 | DR1 = 0x04, /* Data Register 1 W */ |
468 | DR1 = 0x04, /* Data Register 1 W */ | 429 | DR2 = 0x08, /* Data Register 2 W */ |
469 | DR2 = 0x08, /* Data Register 2 W */ | 430 | DR3 = 0x0C, /* Data Register 3 W */ |
470 | DR3 = 0x0C, /* Data Register 3 W */ | 431 | CMD = 0x10, /* Command W */ |
471 | CMD = 0x10, /* Command W */ | 432 | CFG = 0x14, /* Configuration R/W */ |
472 | CFG = 0x14, /* Configuration R/W */ | 433 | STAT = 0x18, /* Status R/W */ |
473 | STAT = 0x18, /* Status R/W */ | 434 | RSQB = 0x1C, /* Receive Status Queue Base W */ |
474 | RSQB = 0x1C, /* Receive Status Queue Base W */ | 435 | RSQT = 0x20, /* Receive Status Queue Tail R */ |
475 | RSQT = 0x20, /* Receive Status Queue Tail R */ | 436 | RSQH = 0x24, /* Receive Status Queue Head W */ |
476 | RSQH = 0x24, /* Receive Status Queue Head W */ | 437 | CDC = 0x28, /* Cell Drop Counter R/clear */ |
477 | CDC = 0x28, /* Cell Drop Counter R/clear */ | 438 | VPEC = 0x2C, /* VPI/VCI Lookup Error Count R/clear */ |
478 | VPEC = 0x2C, /* VPI/VCI Lookup Error Count R/clear */ | 439 | ICC = 0x30, /* Invalid Cell Count R/clear */ |
479 | ICC = 0x30, /* Invalid Cell Count R/clear */ | 440 | RAWCT = 0x34, /* Raw Cell Tail R */ |
480 | RAWCT = 0x34, /* Raw Cell Tail R */ | 441 | TMR = 0x38, /* Timer R */ |
481 | TMR = 0x38, /* Timer R */ | 442 | TSTB = 0x3C, /* Transmit Schedule Table Base R/W */ |
482 | TSTB = 0x3C, /* Transmit Schedule Table Base R/W */ | 443 | TSQB = 0x40, /* Transmit Status Queue Base W */ |
483 | TSQB = 0x40, /* Transmit Status Queue Base W */ | 444 | TSQT = 0x44, /* Transmit Status Queue Tail R */ |
484 | TSQT = 0x44, /* Transmit Status Queue Tail R */ | 445 | TSQH = 0x48, /* Transmit Status Queue Head W */ |
485 | TSQH = 0x48, /* Transmit Status Queue Head W */ | 446 | GP = 0x4C, /* General Purpose R/W */ |
486 | GP = 0x4C, /* General Purpose R/W */ | 447 | VPM = 0x50 /* VPI/VCI Mask W */ |
487 | VPM = 0x50 /* VPI/VCI Mask W */ | ||
488 | }; | 448 | }; |
489 | 449 | ||
490 | 450 | /* NICStAR commands issued to the CMD register */ | |
491 | /* NICStAR commands issued to the CMD register ********************************/ | ||
492 | |||
493 | 451 | ||
494 | /* Top 4 bits are command opcode, lower 28 are parameters. */ | 452 | /* Top 4 bits are command opcode, lower 28 are parameters. */ |
495 | 453 | ||
496 | #define NS_CMD_NO_OPERATION 0x00000000 | 454 | #define NS_CMD_NO_OPERATION 0x00000000 |
497 | /* params always 0 */ | 455 | /* params always 0 */ |
498 | 456 | ||
499 | #define NS_CMD_OPENCLOSE_CONNECTION 0x20000000 | 457 | #define NS_CMD_OPENCLOSE_CONNECTION 0x20000000 |
500 | /* b19{1=open,0=close} b18-2{SRAM addr} */ | 458 | /* b19{1=open,0=close} b18-2{SRAM addr} */ |
501 | 459 | ||
502 | #define NS_CMD_WRITE_SRAM 0x40000000 | 460 | #define NS_CMD_WRITE_SRAM 0x40000000 |
503 | /* b18-2{SRAM addr} b1-0{burst size} */ | 461 | /* b18-2{SRAM addr} b1-0{burst size} */ |
504 | 462 | ||
505 | #define NS_CMD_READ_SRAM 0x50000000 | 463 | #define NS_CMD_READ_SRAM 0x50000000 |
506 | /* b18-2{SRAM addr} */ | 464 | /* b18-2{SRAM addr} */ |
507 | 465 | ||
508 | #define NS_CMD_WRITE_FREEBUFQ 0x60000000 | 466 | #define NS_CMD_WRITE_FREEBUFQ 0x60000000 |
509 | /* b0{large buf indicator} */ | 467 | /* b0{large buf indicator} */ |
510 | 468 | ||
511 | #define NS_CMD_READ_UTILITY 0x80000000 | 469 | #define NS_CMD_READ_UTILITY 0x80000000 |
512 | /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ | 470 | /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ |
513 | 471 | ||
514 | #define NS_CMD_WRITE_UTILITY 0x90000000 | 472 | #define NS_CMD_WRITE_UTILITY 0x90000000 |
515 | /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ | 473 | /* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */ |
516 | 474 | ||
517 | #define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000) | 475 | #define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000) |
518 | #define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION | 476 | #define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION |
519 | 477 | ||
520 | 478 | /* NICStAR configuration bits */ | |
521 | /* NICStAR configuration bits *************************************************/ | 479 | |
522 | 480 | #define NS_CFG_SWRST 0x80000000 /* Software Reset */ | |
523 | #define NS_CFG_SWRST 0x80000000 /* Software Reset */ | 481 | #define NS_CFG_RXPATH 0x20000000 /* Receive Path Enable */ |
524 | #define NS_CFG_RXPATH 0x20000000 /* Receive Path Enable */ | 482 | #define NS_CFG_SMBUFSIZE_MASK 0x18000000 /* Small Receive Buffer Size */ |
525 | #define NS_CFG_SMBUFSIZE_MASK 0x18000000 /* Small Receive Buffer Size */ | 483 | #define NS_CFG_LGBUFSIZE_MASK 0x06000000 /* Large Receive Buffer Size */ |
526 | #define NS_CFG_LGBUFSIZE_MASK 0x06000000 /* Large Receive Buffer Size */ | 484 | #define NS_CFG_EFBIE 0x01000000 /* Empty Free Buffer Queue |
527 | #define NS_CFG_EFBIE 0x01000000 /* Empty Free Buffer Queue | 485 | Interrupt Enable */ |
528 | Interrupt Enable */ | 486 | #define NS_CFG_RSQSIZE_MASK 0x00C00000 /* Receive Status Queue Size */ |
529 | #define NS_CFG_RSQSIZE_MASK 0x00C00000 /* Receive Status Queue Size */ | 487 | #define NS_CFG_ICACCEPT 0x00200000 /* Invalid Cell Accept */ |
530 | #define NS_CFG_ICACCEPT 0x00200000 /* Invalid Cell Accept */ | 488 | #define NS_CFG_IGNOREGFC 0x00100000 /* Ignore General Flow Control */ |
531 | #define NS_CFG_IGNOREGFC 0x00100000 /* Ignore General Flow Control */ | 489 | #define NS_CFG_VPIBITS_MASK 0x000C0000 /* VPI/VCI Bits Size Select */ |
532 | #define NS_CFG_VPIBITS_MASK 0x000C0000 /* VPI/VCI Bits Size Select */ | 490 | #define NS_CFG_RCTSIZE_MASK 0x00030000 /* Receive Connection Table Size */ |
533 | #define NS_CFG_RCTSIZE_MASK 0x00030000 /* Receive Connection Table Size */ | 491 | #define NS_CFG_VCERRACCEPT 0x00008000 /* VPI/VCI Error Cell Accept */ |
534 | #define NS_CFG_VCERRACCEPT 0x00008000 /* VPI/VCI Error Cell Accept */ | 492 | #define NS_CFG_RXINT_MASK 0x00007000 /* End of Receive PDU Interrupt |
535 | #define NS_CFG_RXINT_MASK 0x00007000 /* End of Receive PDU Interrupt | 493 | Handling */ |
536 | Handling */ | 494 | #define NS_CFG_RAWIE 0x00000800 /* Raw Cell Qu' Interrupt Enable */ |
537 | #define NS_CFG_RAWIE 0x00000800 /* Raw Cell Qu' Interrupt Enable */ | 495 | #define NS_CFG_RSQAFIE 0x00000400 /* Receive Queue Almost Full |
538 | #define NS_CFG_RSQAFIE 0x00000400 /* Receive Queue Almost Full | 496 | Interrupt Enable */ |
539 | Interrupt Enable */ | 497 | #define NS_CFG_RXRM 0x00000200 /* Receive RM Cells */ |
540 | #define NS_CFG_RXRM 0x00000200 /* Receive RM Cells */ | 498 | #define NS_CFG_TMRROIE 0x00000080 /* Timer Roll Over Interrupt |
541 | #define NS_CFG_TMRROIE 0x00000080 /* Timer Roll Over Interrupt | 499 | Enable */ |
542 | Enable */ | 500 | #define NS_CFG_TXEN 0x00000020 /* Transmit Operation Enable */ |
543 | #define NS_CFG_TXEN 0x00000020 /* Transmit Operation Enable */ | 501 | #define NS_CFG_TXIE 0x00000010 /* Transmit Status Interrupt |
544 | #define NS_CFG_TXIE 0x00000010 /* Transmit Status Interrupt | 502 | Enable */ |
545 | Enable */ | 503 | #define NS_CFG_TXURIE 0x00000008 /* Transmit Under-run Interrupt |
546 | #define NS_CFG_TXURIE 0x00000008 /* Transmit Under-run Interrupt | 504 | Enable */ |
547 | Enable */ | 505 | #define NS_CFG_UMODE 0x00000004 /* Utopia Mode (cell/byte) Select */ |
548 | #define NS_CFG_UMODE 0x00000004 /* Utopia Mode (cell/byte) Select */ | 506 | #define NS_CFG_TSQFIE 0x00000002 /* Transmit Status Queue Full |
549 | #define NS_CFG_TSQFIE 0x00000002 /* Transmit Status Queue Full | 507 | Interrupt Enable */ |
550 | Interrupt Enable */ | 508 | #define NS_CFG_PHYIE 0x00000001 /* PHY Interrupt Enable */ |
551 | #define NS_CFG_PHYIE 0x00000001 /* PHY Interrupt Enable */ | ||
552 | 509 | ||
553 | #define NS_CFG_SMBUFSIZE_48 0x00000000 | 510 | #define NS_CFG_SMBUFSIZE_48 0x00000000 |
554 | #define NS_CFG_SMBUFSIZE_96 0x08000000 | 511 | #define NS_CFG_SMBUFSIZE_96 0x08000000 |
@@ -579,33 +536,29 @@ enum ns_regs | |||
579 | #define NS_CFG_RXINT_624US 0x00003000 | 536 | #define NS_CFG_RXINT_624US 0x00003000 |
580 | #define NS_CFG_RXINT_899US 0x00004000 | 537 | #define NS_CFG_RXINT_899US 0x00004000 |
581 | 538 | ||
582 | 539 | /* NICStAR STATus bits */ | |
583 | /* NICStAR STATus bits ********************************************************/ | 540 | |
584 | 541 | #define NS_STAT_SFBQC_MASK 0xFF000000 /* hi 8 bits Small Buffer Queue Count */ | |
585 | #define NS_STAT_SFBQC_MASK 0xFF000000 /* hi 8 bits Small Buffer Queue Count */ | 542 | #define NS_STAT_LFBQC_MASK 0x00FF0000 /* hi 8 bits Large Buffer Queue Count */ |
586 | #define NS_STAT_LFBQC_MASK 0x00FF0000 /* hi 8 bits Large Buffer Queue Count */ | 543 | #define NS_STAT_TSIF 0x00008000 /* Transmit Status Queue Indicator */ |
587 | #define NS_STAT_TSIF 0x00008000 /* Transmit Status Queue Indicator */ | 544 | #define NS_STAT_TXICP 0x00004000 /* Transmit Incomplete PDU */ |
588 | #define NS_STAT_TXICP 0x00004000 /* Transmit Incomplete PDU */ | 545 | #define NS_STAT_TSQF 0x00001000 /* Transmit Status Queue Full */ |
589 | #define NS_STAT_TSQF 0x00001000 /* Transmit Status Queue Full */ | 546 | #define NS_STAT_TMROF 0x00000800 /* Timer Overflow */ |
590 | #define NS_STAT_TMROF 0x00000800 /* Timer Overflow */ | 547 | #define NS_STAT_PHYI 0x00000400 /* PHY Device Interrupt */ |
591 | #define NS_STAT_PHYI 0x00000400 /* PHY Device Interrupt */ | 548 | #define NS_STAT_CMDBZ 0x00000200 /* Command Busy */ |
592 | #define NS_STAT_CMDBZ 0x00000200 /* Command Busy */ | 549 | #define NS_STAT_SFBQF 0x00000100 /* Small Buffer Queue Full */ |
593 | #define NS_STAT_SFBQF 0x00000100 /* Small Buffer Queue Full */ | 550 | #define NS_STAT_LFBQF 0x00000080 /* Large Buffer Queue Full */ |
594 | #define NS_STAT_LFBQF 0x00000080 /* Large Buffer Queue Full */ | 551 | #define NS_STAT_RSQF 0x00000040 /* Receive Status Queue Full */ |
595 | #define NS_STAT_RSQF 0x00000040 /* Receive Status Queue Full */ | 552 | #define NS_STAT_EOPDU 0x00000020 /* End of PDU */ |
596 | #define NS_STAT_EOPDU 0x00000020 /* End of PDU */ | 553 | #define NS_STAT_RAWCF 0x00000010 /* Raw Cell Flag */ |
597 | #define NS_STAT_RAWCF 0x00000010 /* Raw Cell Flag */ | 554 | #define NS_STAT_SFBQE 0x00000008 /* Small Buffer Queue Empty */ |
598 | #define NS_STAT_SFBQE 0x00000008 /* Small Buffer Queue Empty */ | 555 | #define NS_STAT_LFBQE 0x00000004 /* Large Buffer Queue Empty */ |
599 | #define NS_STAT_LFBQE 0x00000004 /* Large Buffer Queue Empty */ | 556 | #define NS_STAT_RSQAF 0x00000002 /* Receive Status Queue Almost Full */ |
600 | #define NS_STAT_RSQAF 0x00000002 /* Receive Status Queue Almost Full */ | ||
601 | 557 | ||
602 | #define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23) | 558 | #define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23) |
603 | #define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15) | 559 | #define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15) |
604 | 560 | ||
605 | 561 | /* #defines which depend on other #defines */ | |
606 | |||
607 | /* #defines which depend on other #defines ************************************/ | ||
608 | |||
609 | 562 | ||
610 | #define NS_TST0 NS_TST_FRSCD | 563 | #define NS_TST0 NS_TST_FRSCD |
611 | #define NS_TST1 (NS_TST_FRSCD + NS_TST_NUM_ENTRIES + 1) | 564 | #define NS_TST1 (NS_TST_FRSCD + NS_TST_NUM_ENTRIES + 1) |
@@ -672,8 +625,7 @@ enum ns_regs | |||
672 | #define NS_CFG_TSQFIE_OPT 0x00000000 | 625 | #define NS_CFG_TSQFIE_OPT 0x00000000 |
673 | #endif /* ENABLE_TSQFIE */ | 626 | #endif /* ENABLE_TSQFIE */ |
674 | 627 | ||
675 | 628 | /* PCI stuff */ | |
676 | /* PCI stuff ******************************************************************/ | ||
677 | 629 | ||
678 | #ifndef PCI_VENDOR_ID_IDT | 630 | #ifndef PCI_VENDOR_ID_IDT |
679 | #define PCI_VENDOR_ID_IDT 0x111D | 631 | #define PCI_VENDOR_ID_IDT 0x111D |
@@ -683,138 +635,124 @@ enum ns_regs | |||
683 | #define PCI_DEVICE_ID_IDT_IDT77201 0x0001 | 635 | #define PCI_DEVICE_ID_IDT_IDT77201 0x0001 |
684 | #endif /* PCI_DEVICE_ID_IDT_IDT77201 */ | 636 | #endif /* PCI_DEVICE_ID_IDT_IDT77201 */ |
685 | 637 | ||
638 | /* Device driver structures */ | ||
686 | 639 | ||
687 | 640 | struct ns_skb_prv { | |
688 | /* Device driver structures ***************************************************/ | 641 | u32 buf_type; /* BUF_SM/BUF_LG/BUF_NONE */ |
689 | 642 | u32 dma; | |
690 | 643 | int iovcnt; | |
691 | struct ns_skb_cb { | ||
692 | u32 buf_type; /* BUF_SM/BUF_LG/BUF_NONE */ | ||
693 | }; | 644 | }; |
694 | 645 | ||
695 | #define NS_SKB_CB(skb) ((struct ns_skb_cb *)((skb)->cb)) | 646 | #define NS_PRV_BUFTYPE(skb) \ |
696 | 647 | (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->buf_type) | |
697 | typedef struct tsq_info | 648 | #define NS_PRV_DMA(skb) \ |
698 | { | 649 | (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->dma) |
699 | void *org; | 650 | #define NS_PRV_IOVCNT(skb) \ |
700 | ns_tsi *base; | 651 | (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->iovcnt) |
701 | ns_tsi *next; | 652 | |
702 | ns_tsi *last; | 653 | typedef struct tsq_info { |
654 | void *org; | ||
655 | dma_addr_t dma; | ||
656 | ns_tsi *base; | ||
657 | ns_tsi *next; | ||
658 | ns_tsi *last; | ||
703 | } tsq_info; | 659 | } tsq_info; |
704 | 660 | ||
705 | 661 | typedef struct scq_info { | |
706 | typedef struct scq_info | 662 | void *org; |
707 | { | 663 | dma_addr_t dma; |
708 | void *org; | 664 | ns_scqe *base; |
709 | ns_scqe *base; | 665 | ns_scqe *last; |
710 | ns_scqe *last; | 666 | ns_scqe *next; |
711 | ns_scqe *next; | 667 | volatile ns_scqe *tail; /* Not related to the nicstar register */ |
712 | volatile ns_scqe *tail; /* Not related to the nicstar register */ | 668 | unsigned num_entries; |
713 | unsigned num_entries; | 669 | struct sk_buff **skb; /* Pointer to an array of pointers |
714 | struct sk_buff **skb; /* Pointer to an array of pointers | 670 | to the sk_buffs used for tx */ |
715 | to the sk_buffs used for tx */ | 671 | u32 scd; /* SRAM address of the corresponding |
716 | u32 scd; /* SRAM address of the corresponding | 672 | SCD */ |
717 | SCD */ | 673 | int tbd_count; /* Only meaningful on variable rate */ |
718 | int tbd_count; /* Only meaningful on variable rate */ | 674 | wait_queue_head_t scqfull_waitq; |
719 | wait_queue_head_t scqfull_waitq; | 675 | volatile char full; /* SCQ full indicator */ |
720 | volatile char full; /* SCQ full indicator */ | 676 | spinlock_t lock; /* SCQ spinlock */ |
721 | spinlock_t lock; /* SCQ spinlock */ | ||
722 | } scq_info; | 677 | } scq_info; |
723 | 678 | ||
724 | 679 | typedef struct rsq_info { | |
725 | 680 | void *org; | |
726 | typedef struct rsq_info | 681 | dma_addr_t dma; |
727 | { | 682 | ns_rsqe *base; |
728 | void *org; | 683 | ns_rsqe *next; |
729 | ns_rsqe *base; | 684 | ns_rsqe *last; |
730 | ns_rsqe *next; | ||
731 | ns_rsqe *last; | ||
732 | } rsq_info; | 685 | } rsq_info; |
733 | 686 | ||
734 | 687 | typedef struct skb_pool { | |
735 | typedef struct skb_pool | 688 | volatile int count; /* number of buffers in the queue */ |
736 | { | 689 | struct sk_buff_head queue; |
737 | volatile int count; /* number of buffers in the queue */ | ||
738 | struct sk_buff_head queue; | ||
739 | } skb_pool; | 690 | } skb_pool; |
740 | 691 | ||
741 | /* NOTE: for small and large buffer pools, the count is not used, as the | 692 | /* NOTE: for small and large buffer pools, the count is not used, as the |
742 | actual value used for buffer management is the one read from the | 693 | actual value used for buffer management is the one read from the |
743 | card. */ | 694 | card. */ |
744 | 695 | ||
745 | 696 | typedef struct vc_map { | |
746 | typedef struct vc_map | 697 | volatile unsigned int tx:1; /* TX vc? */ |
747 | { | 698 | volatile unsigned int rx:1; /* RX vc? */ |
748 | volatile unsigned int tx:1; /* TX vc? */ | 699 | struct atm_vcc *tx_vcc, *rx_vcc; |
749 | volatile unsigned int rx:1; /* RX vc? */ | 700 | struct sk_buff *rx_iov; /* RX iovector skb */ |
750 | struct atm_vcc *tx_vcc, *rx_vcc; | 701 | scq_info *scq; /* To keep track of the SCQ */ |
751 | struct sk_buff *rx_iov; /* RX iovector skb */ | 702 | u32 cbr_scd; /* SRAM address of the corresponding |
752 | scq_info *scq; /* To keep track of the SCQ */ | 703 | SCD. 0x00000000 for UBR/VBR/ABR */ |
753 | u32 cbr_scd; /* SRAM address of the corresponding | 704 | int tbd_count; |
754 | SCD. 0x00000000 for UBR/VBR/ABR */ | ||
755 | int tbd_count; | ||
756 | } vc_map; | 705 | } vc_map; |
757 | 706 | ||
758 | 707 | typedef struct ns_dev { | |
759 | struct ns_skb_data | 708 | int index; /* Card ID to the device driver */ |
760 | { | 709 | int sram_size; /* In k x 32bit words. 32 or 128 */ |
761 | struct atm_vcc *vcc; | 710 | void __iomem *membase; /* Card's memory base address */ |
762 | int iovcnt; | 711 | unsigned long max_pcr; |
763 | }; | 712 | int rct_size; /* Number of entries */ |
764 | 713 | int vpibits; | |
765 | #define NS_SKB(skb) (((struct ns_skb_data *) (skb)->cb)) | 714 | int vcibits; |
766 | 715 | struct pci_dev *pcidev; | |
767 | 716 | struct idr idr; | |
768 | typedef struct ns_dev | 717 | struct atm_dev *atmdev; |
769 | { | 718 | tsq_info tsq; |
770 | int index; /* Card ID to the device driver */ | 719 | rsq_info rsq; |
771 | int sram_size; /* In k x 32bit words. 32 or 128 */ | 720 | scq_info *scq0, *scq1, *scq2; /* VBR SCQs */ |
772 | void __iomem *membase; /* Card's memory base address */ | 721 | skb_pool sbpool; /* Small buffers */ |
773 | unsigned long max_pcr; | 722 | skb_pool lbpool; /* Large buffers */ |
774 | int rct_size; /* Number of entries */ | 723 | skb_pool hbpool; /* Pre-allocated huge buffers */ |
775 | int vpibits; | 724 | skb_pool iovpool; /* iovector buffers */ |
776 | int vcibits; | 725 | volatile int efbie; /* Empty free buf. queue int. enabled */ |
777 | struct pci_dev *pcidev; | 726 | volatile u32 tst_addr; /* SRAM address of the TST in use */ |
778 | struct atm_dev *atmdev; | 727 | volatile int tst_free_entries; |
779 | tsq_info tsq; | 728 | vc_map vcmap[NS_MAX_RCTSIZE]; |
780 | rsq_info rsq; | 729 | vc_map *tste2vc[NS_TST_NUM_ENTRIES]; |
781 | scq_info *scq0, *scq1, *scq2; /* VBR SCQs */ | 730 | vc_map *scd2vc[NS_FRSCD_NUM]; |
782 | skb_pool sbpool; /* Small buffers */ | 731 | buf_nr sbnr; |
783 | skb_pool lbpool; /* Large buffers */ | 732 | buf_nr lbnr; |
784 | skb_pool hbpool; /* Pre-allocated huge buffers */ | 733 | buf_nr hbnr; |
785 | skb_pool iovpool; /* iovector buffers */ | 734 | buf_nr iovnr; |
786 | volatile int efbie; /* Empty free buf. queue int. enabled */ | 735 | int sbfqc; |
787 | volatile u32 tst_addr; /* SRAM address of the TST in use */ | 736 | int lbfqc; |
788 | volatile int tst_free_entries; | 737 | struct sk_buff *sm_handle; |
789 | vc_map vcmap[NS_MAX_RCTSIZE]; | 738 | u32 sm_addr; |
790 | vc_map *tste2vc[NS_TST_NUM_ENTRIES]; | 739 | struct sk_buff *lg_handle; |
791 | vc_map *scd2vc[NS_FRSCD_NUM]; | 740 | u32 lg_addr; |
792 | buf_nr sbnr; | 741 | struct sk_buff *rcbuf; /* Current raw cell buffer */ |
793 | buf_nr lbnr; | 742 | struct ns_rcqe *rawcell; |
794 | buf_nr hbnr; | 743 | u32 rawch; /* Raw cell queue head */ |
795 | buf_nr iovnr; | 744 | unsigned intcnt; /* Interrupt counter */ |
796 | int sbfqc; | 745 | spinlock_t int_lock; /* Interrupt lock */ |
797 | int lbfqc; | 746 | spinlock_t res_lock; /* Card resource lock */ |
798 | u32 sm_handle; | ||
799 | u32 sm_addr; | ||
800 | u32 lg_handle; | ||
801 | u32 lg_addr; | ||
802 | struct sk_buff *rcbuf; /* Current raw cell buffer */ | ||
803 | u32 rawch; /* Raw cell queue head */ | ||
804 | unsigned intcnt; /* Interrupt counter */ | ||
805 | spinlock_t int_lock; /* Interrupt lock */ | ||
806 | spinlock_t res_lock; /* Card resource lock */ | ||
807 | } ns_dev; | 747 | } ns_dev; |
808 | 748 | ||
809 | |||
810 | /* NOTE: Each tste2vc entry relates a given TST entry to the corresponding | 749 | /* NOTE: Each tste2vc entry relates a given TST entry to the corresponding |
811 | CBR vc. If the entry is not allocated, it must be NULL. | 750 | CBR vc. If the entry is not allocated, it must be NULL. |
812 | 751 | ||
813 | There are two TSTs so the driver can modify them on the fly | 752 | There are two TSTs so the driver can modify them on the fly |
814 | without stopping the transmission. | 753 | without stopping the transmission. |
815 | |||
816 | scd2vc allows us to find out unused fixed rate SCDs, because | ||
817 | they must have a NULL pointer here. */ | ||
818 | 754 | ||
755 | scd2vc allows us to find out unused fixed rate SCDs, because | ||
756 | they must have a NULL pointer here. */ | ||
819 | 757 | ||
820 | #endif /* _LINUX_NICSTAR_H_ */ | 758 | #endif /* _LINUX_NICSTAR_H_ */ |
diff --git a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c index 842e26c45557..f594526f8c6d 100644 --- a/drivers/atm/nicstarmac.c +++ b/drivers/atm/nicstarmac.c | |||
@@ -13,15 +13,15 @@ typedef void __iomem *virt_addr_t; | |||
13 | 13 | ||
14 | #define CYCLE_DELAY 5 | 14 | #define CYCLE_DELAY 5 |
15 | 15 | ||
16 | /* This was the original definition | 16 | /* |
17 | This was the original definition | ||
17 | #define osp_MicroDelay(microsec) \ | 18 | #define osp_MicroDelay(microsec) \ |
18 | do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) | 19 | do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) |
19 | */ | 20 | */ |
20 | #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \ | 21 | #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \ |
21 | udelay((useconds));} | 22 | udelay((useconds));} |
22 | 23 | /* | |
23 | 24 | * The following tables represent the timing diagrams found in | |
24 | /* The following tables represent the timing diagrams found in | ||
25 | * the Data Sheet for the Xicor X25020 EEProm. The #defines below | 25 | * the Data Sheet for the Xicor X25020 EEProm. The #defines below |
26 | * represent the bits in the NICStAR's General Purpose register | 26 | * represent the bits in the NICStAR's General Purpose register |
27 | * that must be toggled for the corresponding actions on the EEProm | 27 | * that must be toggled for the corresponding actions on the EEProm |
@@ -31,86 +31,80 @@ typedef void __iomem *virt_addr_t; | |||
31 | /* Write Data To EEProm from SI line on rising edge of CLK */ | 31 | /* Write Data To EEProm from SI line on rising edge of CLK */ |
32 | /* Read Data From EEProm on falling edge of CLK */ | 32 | /* Read Data From EEProm on falling edge of CLK */ |
33 | 33 | ||
34 | #define CS_HIGH 0x0002 /* Chip select high */ | 34 | #define CS_HIGH 0x0002 /* Chip select high */ |
35 | #define CS_LOW 0x0000 /* Chip select low (active low)*/ | 35 | #define CS_LOW 0x0000 /* Chip select low (active low) */ |
36 | #define CLK_HIGH 0x0004 /* Clock high */ | 36 | #define CLK_HIGH 0x0004 /* Clock high */ |
37 | #define CLK_LOW 0x0000 /* Clock low */ | 37 | #define CLK_LOW 0x0000 /* Clock low */ |
38 | #define SI_HIGH 0x0001 /* Serial input data high */ | 38 | #define SI_HIGH 0x0001 /* Serial input data high */ |
39 | #define SI_LOW 0x0000 /* Serial input data low */ | 39 | #define SI_LOW 0x0000 /* Serial input data low */ |
40 | 40 | ||
41 | /* Read Status Register = 0000 0101b */ | 41 | /* Read Status Register = 0000 0101b */ |
42 | #if 0 | 42 | #if 0 |
43 | static u_int32_t rdsrtab[] = | 43 | static u_int32_t rdsrtab[] = { |
44 | { | 44 | CS_HIGH | CLK_HIGH, |
45 | CS_HIGH | CLK_HIGH, | 45 | CS_LOW | CLK_LOW, |
46 | CS_LOW | CLK_LOW, | 46 | CLK_HIGH, /* 0 */ |
47 | CLK_HIGH, /* 0 */ | 47 | CLK_LOW, |
48 | CLK_LOW, | 48 | CLK_HIGH, /* 0 */ |
49 | CLK_HIGH, /* 0 */ | 49 | CLK_LOW, |
50 | CLK_LOW, | 50 | CLK_HIGH, /* 0 */ |
51 | CLK_HIGH, /* 0 */ | 51 | CLK_LOW, |
52 | CLK_LOW, | 52 | CLK_HIGH, /* 0 */ |
53 | CLK_HIGH, /* 0 */ | 53 | CLK_LOW, |
54 | CLK_LOW, | 54 | CLK_HIGH, /* 0 */ |
55 | CLK_HIGH, /* 0 */ | 55 | CLK_LOW | SI_HIGH, |
56 | CLK_LOW | SI_HIGH, | 56 | CLK_HIGH | SI_HIGH, /* 1 */ |
57 | CLK_HIGH | SI_HIGH, /* 1 */ | 57 | CLK_LOW | SI_LOW, |
58 | CLK_LOW | SI_LOW, | 58 | CLK_HIGH, /* 0 */ |
59 | CLK_HIGH, /* 0 */ | 59 | CLK_LOW | SI_HIGH, |
60 | CLK_LOW | SI_HIGH, | 60 | CLK_HIGH | SI_HIGH /* 1 */ |
61 | CLK_HIGH | SI_HIGH /* 1 */ | ||
62 | }; | 61 | }; |
63 | #endif /* 0 */ | 62 | #endif /* 0 */ |
64 | |||
65 | 63 | ||
66 | /* Read from EEPROM = 0000 0011b */ | 64 | /* Read from EEPROM = 0000 0011b */ |
67 | static u_int32_t readtab[] = | 65 | static u_int32_t readtab[] = { |
68 | { | 66 | /* |
69 | /* | 67 | CS_HIGH | CLK_HIGH, |
70 | CS_HIGH | CLK_HIGH, | 68 | */ |
71 | */ | 69 | CS_LOW | CLK_LOW, |
72 | CS_LOW | CLK_LOW, | 70 | CLK_HIGH, /* 0 */ |
73 | CLK_HIGH, /* 0 */ | 71 | CLK_LOW, |
74 | CLK_LOW, | 72 | CLK_HIGH, /* 0 */ |
75 | CLK_HIGH, /* 0 */ | 73 | CLK_LOW, |
76 | CLK_LOW, | 74 | CLK_HIGH, /* 0 */ |
77 | CLK_HIGH, /* 0 */ | 75 | CLK_LOW, |
78 | CLK_LOW, | 76 | CLK_HIGH, /* 0 */ |
79 | CLK_HIGH, /* 0 */ | 77 | CLK_LOW, |
80 | CLK_LOW, | 78 | CLK_HIGH, /* 0 */ |
81 | CLK_HIGH, /* 0 */ | 79 | CLK_LOW, |
82 | CLK_LOW, | 80 | CLK_HIGH, /* 0 */ |
83 | CLK_HIGH, /* 0 */ | 81 | CLK_LOW | SI_HIGH, |
84 | CLK_LOW | SI_HIGH, | 82 | CLK_HIGH | SI_HIGH, /* 1 */ |
85 | CLK_HIGH | SI_HIGH, /* 1 */ | 83 | CLK_LOW | SI_HIGH, |
86 | CLK_LOW | SI_HIGH, | 84 | CLK_HIGH | SI_HIGH /* 1 */ |
87 | CLK_HIGH | SI_HIGH /* 1 */ | ||
88 | }; | 85 | }; |
89 | 86 | ||
90 | |||
91 | /* Clock to read from/write to the eeprom */ | 87 | /* Clock to read from/write to the eeprom */ |
92 | static u_int32_t clocktab[] = | 88 | static u_int32_t clocktab[] = { |
93 | { | 89 | CLK_LOW, |
94 | CLK_LOW, | 90 | CLK_HIGH, |
95 | CLK_HIGH, | 91 | CLK_LOW, |
96 | CLK_LOW, | 92 | CLK_HIGH, |
97 | CLK_HIGH, | 93 | CLK_LOW, |
98 | CLK_LOW, | 94 | CLK_HIGH, |
99 | CLK_HIGH, | 95 | CLK_LOW, |
100 | CLK_LOW, | 96 | CLK_HIGH, |
101 | CLK_HIGH, | 97 | CLK_LOW, |
102 | CLK_LOW, | 98 | CLK_HIGH, |
103 | CLK_HIGH, | 99 | CLK_LOW, |
104 | CLK_LOW, | 100 | CLK_HIGH, |
105 | CLK_HIGH, | 101 | CLK_LOW, |
106 | CLK_LOW, | 102 | CLK_HIGH, |
107 | CLK_HIGH, | 103 | CLK_LOW, |
108 | CLK_LOW, | 104 | CLK_HIGH, |
109 | CLK_HIGH, | 105 | CLK_LOW |
110 | CLK_LOW | ||
111 | }; | 106 | }; |
112 | 107 | ||
113 | |||
114 | #define NICSTAR_REG_WRITE(bs, reg, val) \ | 108 | #define NICSTAR_REG_WRITE(bs, reg, val) \ |
115 | while ( readl(bs + STAT) & 0x0200 ) ; \ | 109 | while ( readl(bs + STAT) & 0x0200 ) ; \ |
116 | writel((val),(base)+(reg)) | 110 | writel((val),(base)+(reg)) |
@@ -124,153 +118,131 @@ static u_int32_t clocktab[] = | |||
124 | * register. | 118 | * register. |
125 | */ | 119 | */ |
126 | #if 0 | 120 | #if 0 |
127 | u_int32_t | 121 | u_int32_t nicstar_read_eprom_status(virt_addr_t base) |
128 | nicstar_read_eprom_status( virt_addr_t base ) | ||
129 | { | 122 | { |
130 | u_int32_t val; | 123 | u_int32_t val; |
131 | u_int32_t rbyte; | 124 | u_int32_t rbyte; |
132 | int32_t i, j; | 125 | int32_t i, j; |
133 | 126 | ||
134 | /* Send read instruction */ | 127 | /* Send read instruction */ |
135 | val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; | 128 | val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; |
136 | 129 | ||
137 | for (i=0; i<ARRAY_SIZE(rdsrtab); i++) | 130 | for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) { |
138 | { | 131 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
139 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 132 | (val | rdsrtab[i])); |
140 | (val | rdsrtab[i]) ); | 133 | osp_MicroDelay(CYCLE_DELAY); |
141 | osp_MicroDelay( CYCLE_DELAY ); | 134 | } |
142 | } | 135 | |
143 | 136 | /* Done sending instruction - now pull data off of bit 16, MSB first */ | |
144 | /* Done sending instruction - now pull data off of bit 16, MSB first */ | 137 | /* Data clocked out of eeprom on falling edge of clock */ |
145 | /* Data clocked out of eeprom on falling edge of clock */ | 138 | |
146 | 139 | rbyte = 0; | |
147 | rbyte = 0; | 140 | for (i = 7, j = 0; i >= 0; i--) { |
148 | for (i=7, j=0; i>=0; i--) | 141 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
149 | { | 142 | (val | clocktab[j++])); |
150 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 143 | rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) |
151 | (val | clocktab[j++]) ); | 144 | & 0x00010000) >> 16) << i); |
152 | rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE) | 145 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
153 | & 0x00010000) >> 16) << i); | 146 | (val | clocktab[j++])); |
154 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 147 | osp_MicroDelay(CYCLE_DELAY); |
155 | (val | clocktab[j++]) ); | 148 | } |
156 | osp_MicroDelay( CYCLE_DELAY ); | 149 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2); |
157 | } | 150 | osp_MicroDelay(CYCLE_DELAY); |
158 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); | 151 | return rbyte; |
159 | osp_MicroDelay( CYCLE_DELAY ); | ||
160 | return rbyte; | ||
161 | } | 152 | } |
162 | #endif /* 0 */ | 153 | #endif /* 0 */ |
163 | |||
164 | 154 | ||
165 | /* | 155 | /* |
166 | * This routine will clock the Read_data function into the X2520 | 156 | * This routine will clock the Read_data function into the X2520 |
167 | * eeprom, followed by the address to read from, through the NicSTaR's General | 157 | * eeprom, followed by the address to read from, through the NicSTaR's General |
168 | * Purpose register. | 158 | * Purpose register. |
169 | */ | 159 | */ |
170 | 160 | ||
171 | static u_int8_t | 161 | static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset) |
172 | read_eprom_byte(virt_addr_t base, u_int8_t offset) | ||
173 | { | 162 | { |
174 | u_int32_t val = 0; | 163 | u_int32_t val = 0; |
175 | int i,j=0; | 164 | int i, j = 0; |
176 | u_int8_t tempread = 0; | 165 | u_int8_t tempread = 0; |
177 | 166 | ||
178 | val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; | 167 | val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; |
179 | 168 | ||
180 | /* Send READ instruction */ | 169 | /* Send READ instruction */ |
181 | for (i=0; i<ARRAY_SIZE(readtab); i++) | 170 | for (i = 0; i < ARRAY_SIZE(readtab); i++) { |
182 | { | 171 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
183 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 172 | (val | readtab[i])); |
184 | (val | readtab[i]) ); | 173 | osp_MicroDelay(CYCLE_DELAY); |
185 | osp_MicroDelay( CYCLE_DELAY ); | 174 | } |
186 | } | 175 | |
187 | 176 | /* Next, we need to send the byte address to read from */ | |
188 | /* Next, we need to send the byte address to read from */ | 177 | for (i = 7; i >= 0; i--) { |
189 | for (i=7; i>=0; i--) | 178 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
190 | { | 179 | (val | clocktab[j++] | ((offset >> i) & 1))); |
191 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 180 | osp_MicroDelay(CYCLE_DELAY); |
192 | (val | clocktab[j++] | ((offset >> i) & 1) ) ); | 181 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
193 | osp_MicroDelay(CYCLE_DELAY); | 182 | (val | clocktab[j++] | ((offset >> i) & 1))); |
194 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 183 | osp_MicroDelay(CYCLE_DELAY); |
195 | (val | clocktab[j++] | ((offset >> i) & 1) ) ); | 184 | } |
196 | osp_MicroDelay( CYCLE_DELAY ); | 185 | |
197 | } | 186 | j = 0; |
198 | 187 | ||
199 | j = 0; | 188 | /* Now, we can read data from the eeprom by clocking it in */ |
200 | 189 | for (i = 7; i >= 0; i--) { | |
201 | /* Now, we can read data from the eeprom by clocking it in */ | 190 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
202 | for (i=7; i>=0; i--) | 191 | (val | clocktab[j++])); |
203 | { | 192 | osp_MicroDelay(CYCLE_DELAY); |
204 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 193 | tempread |= |
205 | (val | clocktab[j++]) ); | 194 | (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) |
206 | osp_MicroDelay( CYCLE_DELAY ); | 195 | & 0x00010000) >> 16) << i); |
207 | tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) | 196 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
208 | & 0x00010000) >> 16) << i); | 197 | (val | clocktab[j++])); |
209 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 198 | osp_MicroDelay(CYCLE_DELAY); |
210 | (val | clocktab[j++]) ); | 199 | } |
211 | osp_MicroDelay( CYCLE_DELAY ); | 200 | |
212 | } | 201 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2); |
213 | 202 | osp_MicroDelay(CYCLE_DELAY); | |
214 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); | 203 | return tempread; |
215 | osp_MicroDelay( CYCLE_DELAY ); | ||
216 | return tempread; | ||
217 | } | 204 | } |
218 | 205 | ||
219 | 206 | static void nicstar_init_eprom(virt_addr_t base) | |
220 | static void | ||
221 | nicstar_init_eprom( virt_addr_t base ) | ||
222 | { | 207 | { |
223 | u_int32_t val; | 208 | u_int32_t val; |
224 | 209 | ||
225 | /* | 210 | /* |
226 | * turn chip select off | 211 | * turn chip select off |
227 | */ | 212 | */ |
228 | val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; | 213 | val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; |
229 | 214 | ||
230 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, | 215 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
231 | (val | CS_HIGH | CLK_HIGH)); | 216 | (val | CS_HIGH | CLK_HIGH)); |
232 | osp_MicroDelay( CYCLE_DELAY ); | 217 | osp_MicroDelay(CYCLE_DELAY); |
233 | 218 | ||
234 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, | 219 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
235 | (val | CS_HIGH | CLK_LOW)); | 220 | (val | CS_HIGH | CLK_LOW)); |
236 | osp_MicroDelay( CYCLE_DELAY ); | 221 | osp_MicroDelay(CYCLE_DELAY); |
237 | 222 | ||
238 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, | 223 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
239 | (val | CS_HIGH | CLK_HIGH)); | 224 | (val | CS_HIGH | CLK_HIGH)); |
240 | osp_MicroDelay( CYCLE_DELAY ); | 225 | osp_MicroDelay(CYCLE_DELAY); |
241 | 226 | ||
242 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, | 227 | NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, |
243 | (val | CS_HIGH | CLK_LOW)); | 228 | (val | CS_HIGH | CLK_LOW)); |
244 | osp_MicroDelay( CYCLE_DELAY ); | 229 | osp_MicroDelay(CYCLE_DELAY); |
245 | } | 230 | } |
246 | 231 | ||
247 | |||
248 | /* | 232 | /* |
249 | * This routine will be the interface to the ReadPromByte function | 233 | * This routine will be the interface to the ReadPromByte function |
250 | * above. | 234 | * above. |
251 | */ | 235 | */ |
252 | 236 | ||
253 | static void | 237 | static void |
254 | nicstar_read_eprom( | 238 | nicstar_read_eprom(virt_addr_t base, |
255 | virt_addr_t base, | 239 | u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes) |
256 | u_int8_t prom_offset, | ||
257 | u_int8_t *buffer, | ||
258 | u_int32_t nbytes ) | ||
259 | { | 240 | { |
260 | u_int i; | 241 | u_int i; |
261 | |||
262 | for (i=0; i<nbytes; i++) | ||
263 | { | ||
264 | buffer[i] = read_eprom_byte( base, prom_offset ); | ||
265 | ++prom_offset; | ||
266 | osp_MicroDelay( CYCLE_DELAY ); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | 242 | ||
271 | /* | 243 | for (i = 0; i < nbytes; i++) { |
272 | void osp_MicroDelay(int x) { | 244 | buffer[i] = read_eprom_byte(base, prom_offset); |
273 | 245 | ++prom_offset; | |
246 | osp_MicroDelay(CYCLE_DELAY); | ||
247 | } | ||
274 | } | 248 | } |
275 | */ | ||
276 | |||
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index ded76c4c9f4f..6174965d9a4d 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -383,7 +383,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb | |||
383 | 383 | ||
384 | /* Anything but 'Showtime' is down */ | 384 | /* Anything but 'Showtime' is down */ |
385 | if (strcmp(state_str, "Showtime")) { | 385 | if (strcmp(state_str, "Showtime")) { |
386 | card->atmdev[port]->signal = ATM_PHY_SIG_LOST; | 386 | atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); |
387 | release_vccs(card->atmdev[port]); | 387 | release_vccs(card->atmdev[port]); |
388 | dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); | 388 | dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); |
389 | return 0; | 389 | return 0; |
@@ -401,7 +401,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb | |||
401 | snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn); | 401 | snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn); |
402 | 402 | ||
403 | card->atmdev[port]->link_rate = rate_down / 424; | 403 | card->atmdev[port]->link_rate = rate_down / 424; |
404 | card->atmdev[port]->signal = ATM_PHY_SIG_FOUND; | 404 | atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_FOUND); |
405 | 405 | ||
406 | return 0; | 406 | return 0; |
407 | } | 407 | } |
@@ -1246,7 +1246,7 @@ static int atm_init(struct solos_card *card) | |||
1246 | card->atmdev[i]->ci_range.vci_bits = 16; | 1246 | card->atmdev[i]->ci_range.vci_bits = 16; |
1247 | card->atmdev[i]->dev_data = card; | 1247 | card->atmdev[i]->dev_data = card; |
1248 | card->atmdev[i]->phy_data = (void *)(unsigned long)i; | 1248 | card->atmdev[i]->phy_data = (void *)(unsigned long)i; |
1249 | card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN; | 1249 | atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); |
1250 | 1250 | ||
1251 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); | 1251 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); |
1252 | if (!skb) { | 1252 | if (!skb) { |
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index da4b91ffa53e..41c56eae4c81 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c | |||
@@ -291,8 +291,9 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) | |||
291 | 291 | ||
292 | static void poll_los(struct atm_dev *dev) | 292 | static void poll_los(struct atm_dev *dev) |
293 | { | 293 | { |
294 | dev->signal = GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? ATM_PHY_SIG_LOST : | 294 | atm_dev_signal_change(dev, |
295 | ATM_PHY_SIG_FOUND; | 295 | GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ? |
296 | ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND); | ||
296 | } | 297 | } |
297 | 298 | ||
298 | 299 | ||
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 702accec89e9..4e885d2da49c 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
@@ -1637,10 +1637,8 @@ out_free: | |||
1637 | MODULE_LICENSE("GPL"); | 1637 | MODULE_LICENSE("GPL"); |
1638 | 1638 | ||
1639 | static struct pci_device_id zatm_pci_tbl[] __devinitdata = { | 1639 | static struct pci_device_id zatm_pci_tbl[] __devinitdata = { |
1640 | { PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1221, | 1640 | { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1221), ZATM_COPPER }, |
1641 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, ZATM_COPPER }, | 1641 | { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1225), 0 }, |
1642 | { PCI_VENDOR_ID_ZEITNET, PCI_DEVICE_ID_ZEITNET_1225, | ||
1643 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
1644 | { 0, } | 1642 | { 0, } |
1645 | }; | 1643 | }; |
1646 | MODULE_DEVICE_TABLE(pci, zatm_pci_tbl); | 1644 | MODULE_DEVICE_TABLE(pci, zatm_pci_tbl); |