^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* drivers/atm/zatm.c - ZeitNet ZN122x device driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/atm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/sonet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/atm_zatm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "uPD98401.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "uPD98402.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "zeprom.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "zatm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * TODO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Minor features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * - support 64 kB SDUs (will have to use multibuffer batches then :-( )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * - proper use of CDV, credit = max(1,CDVT*PCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * - AAL0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * - better receive timestamps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * - OAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ZATM_COPPER 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DPRINTK(format,args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #ifndef CONFIG_ATM_ZATM_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define NULLCHECK(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define EVENT(s,a,b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void event_dump(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * NULL pointer checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define NULLCHECK(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if ((unsigned long) (x) < 0x30) printk(KERN_CRIT #x "==0x%x\n", (int) (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Very extensive activity logging. Greatly improves bug detection speed but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * costs a few Mbps if enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define EV 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const char *ev[EV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static unsigned long ev_a[EV],ev_b[EV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int ec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void EVENT(const char *s,unsigned long a,unsigned long b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ev[ec] = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ev_a[ec] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ev_b[ec] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ec = (ec+1) % EV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void event_dump(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int n,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) printk(KERN_NOTICE "----- event dump follows -----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) for (n = 0; n < EV; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) i = (ec+n) % EV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) printk(KERN_NOTICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) printk(ev[i] ? ev[i] : "(null)",ev_a[i],ev_b[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) printk(KERN_NOTICE "----- event dump ends here -----\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif /* CONFIG_ATM_ZATM_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define RING_BUSY 1 /* indication from do_tx that PDU has to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) backlogged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static struct atm_dev *zatm_boards = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static unsigned long dummy[2] = {0,0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define zin_n(r) inl(zatm_dev->base+r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define zin(r) inl(zatm_dev->base+uPD98401_##r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define zout(v,r) outl(v,zatm_dev->base+uPD98401_##r*4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define zwait() do {} while (zin(CMR) & uPD98401_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* RX0, RX1, TX0, TX1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static const int mbx_entries[NR_MBX] = { 1024,1024,1024,1024 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static const int mbx_esize[NR_MBX] = { 16,16,4,4 }; /* entry size in bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define MBX_SIZE(i) (mbx_entries[i]*mbx_esize[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*-------------------------------- utilities --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void zpokel(struct zatm_dev *zatm_dev,u32 value,u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) zout(value,CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) zout(uPD98401_IND_ACC | uPD98401_IA_BALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static u32 zpeekl(struct zatm_dev *zatm_dev,u32 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) zout(uPD98401_IND_ACC | uPD98401_IA_BALL | uPD98401_IA_RW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) (uPD98401_IA_TGT_CM << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return zin(CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*------------------------------- free lists --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * Free buffer head structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * [0] pointer to buffer (for SAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * [1] buffer descr link pointer (for SAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * [2] back pointer to skb (for poll_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * [3] data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct rx_buffer_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 buffer; /* pointer to buffer (for SAR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 link; /* buffer descriptor link pointer (for SAR) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct sk_buff *skb; /* back pointer to skb (for poll_rx) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void refill_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct rx_buffer_head *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int align,offset,free,count,size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EVENT("refill_pool\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) size = (64 << (pool <= ZATM_AAL5_POOL_BASE ? 0 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) pool-ZATM_AAL5_POOL_BASE))+sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (size < PAGE_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) align = 32; /* for 32 byte alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) offset = sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) align = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) offset = zatm_dev->pool_info[pool].offset+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) sizeof(struct rx_buffer_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) size += align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) free = zpeekl(zatm_dev,zatm_dev->pool_base+2*pool) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) uPD98401_RXFP_REMAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (free >= zatm_dev->pool_info[pool].low_water) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) EVENT("starting ... POOL: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) first = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) while (free < zatm_dev->pool_info[pool].high_water) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct rx_buffer_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) skb = alloc_skb(size,GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) printk(KERN_WARNING DEV_LABEL "(Itf %d): got no new "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "skb (%d) with %d free\n",dev->number,size,free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) skb_reserve(skb,(unsigned char *) ((((unsigned long) skb->data+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) align+offset-1) & ~(unsigned long) (align-1))-offset)-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) head = (struct rx_buffer_head *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) skb_reserve(skb,sizeof(struct rx_buffer_head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!first) first = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) head->buffer = virt_to_bus(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) head->link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) head->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) EVENT("enq skb 0x%08lx/0x%08lx\n",(unsigned long) skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) (unsigned long) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (zatm_dev->last_free[pool])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ((struct rx_buffer_head *) (zatm_dev->last_free[pool]->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) data))[-1].link = virt_to_bus(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) zatm_dev->last_free[pool] = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) skb_queue_tail(&zatm_dev->pool[pool],skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) free++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) zout(virt_to_bus(first),CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) zout(uPD98401_ADD_BAT | (pool << uPD98401_POOL_SHIFT) | count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) EVENT ("POOL: 0x%x, 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) zpeekl(zatm_dev,zatm_dev->pool_base+2*pool),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) zpeekl(zatm_dev,zatm_dev->pool_base+2*pool+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) EVENT("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void drain_free(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) skb_queue_purge(&ZATM_DEV(dev)->pool[pool]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int pool_index(int max_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (max_pdu % ATM_CELL_PAYLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printk(KERN_ERR DEV_LABEL ": driver error in pool_index: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) "max_pdu is %d\n",max_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (max_pdu > 65536) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for (i = 0; (64 << i) < max_pdu; i++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return i+ZATM_AAL5_POOL_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* use_pool isn't reentrant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void use_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!(zatm_dev->pool_info[pool].ref_count++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) skb_queue_head_init(&zatm_dev->pool[pool]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) size = pool-ZATM_AAL5_POOL_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (size < 0) size = 0; /* 64B... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) else if (size > 10) size = 10; /* ... 64kB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) zpokel(zatm_dev,((zatm_dev->pool_info[pool].low_water/4) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) uPD98401_RXFP_ALERT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) (1 << uPD98401_RXFP_BTSZ_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) (size << uPD98401_RXFP_BFSZ_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) zatm_dev->pool_base+pool*2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) zpokel(zatm_dev,(unsigned long) dummy,zatm_dev->pool_base+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) pool*2+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) zatm_dev->last_free[pool] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) refill_pool(dev,pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) DPRINTK("pool %d: %d\n",pool,zatm_dev->pool_info[pool].ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void unuse_pool(struct atm_dev *dev,int pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!(--ZATM_DEV(dev)->pool_info[pool].ref_count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) drain_free(dev,pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*----------------------------------- RX ------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void exception(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct zatm_dev *zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct zatm_vcc *zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned long *qrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (count++ > 2) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) printk("TX%d: 0x%08lx\n",i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) for (i = 0; i < 5; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) printk("SH%d: 0x%08lx\n",i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) zpeekl(zatm_dev,uPD98401_IM(zatm_vcc->shaper)+16*i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) qrp = (unsigned long *) zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) uPD98401_TXVC_QRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) printk("qrp=0x%08lx\n",(unsigned long) qrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) for (i = 0; i < 4; i++) printk("QRP[%d]: 0x%08lx",i,qrp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static const char *err_txt[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) "No error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) "RX buf underflow",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "RX FIFO overrun",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) "Maximum len violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) "CRC error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) "User abort",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) "Length violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) "T1 error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) "Deactivated",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) "???"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static void poll_rx(struct atm_dev *dev,int mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) EVENT("poll_rx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u32 *here;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int cells,size,chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) here = (u32 *) pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (((pos += 16) & 0xffff) == zatm_dev->mbx_end[mbx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) pos = zatm_dev->mbx_start[mbx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) cells = here[0] & uPD98401_AAL5_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) printk("RX IND: 0x%x, 0x%x, 0x%x, 0x%x\n",here[0],here[1],here[2],here[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) unsigned long *x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) printk("POOL: 0x%08x, 0x%08x\n",zpeekl(zatm_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) zatm_dev->pool_base),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) zpeekl(zatm_dev,zatm_dev->pool_base+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) x = (unsigned long *) here[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) printk("[0..3] = 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) x[0],x[1],x[2],x[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (here[3] & uPD98401_AAL5_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) error = (here[3] & uPD98401_AAL5_ES) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) uPD98401_AAL5_ES_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (error == uPD98401_AAL5_ES_DEACT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) error == uPD98401_AAL5_ES_FREE) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) uPD98401_AAL5_ES_SHIFT,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) __net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ((unsigned *) skb->data)[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) EVENT("skb 0x%lx, here 0x%lx\n",(unsigned long) skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) (unsigned long) here);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) size = error ? 0 : ntohs(((__be16 *) skb->data)[cells*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ATM_CELL_PAYLOAD/sizeof(u16)-3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) EVENT("got skb 0x%lx, size %d\n",(unsigned long) skb,size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) chan = (here[3] & uPD98401_AAL5_CHAN) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) uPD98401_AAL5_CHAN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) vcc = zatm_dev->rx_map[chan];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pos = ZATM_VCC(vcc)->pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (skb == zatm_dev->last_free[pos])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) zatm_dev->last_free[pos] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) skb_unlink(skb, zatm_dev->pool + pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "for non-existing channel\n",dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static unsigned long silence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int last_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (error != last_error ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) time_after(jiffies, silence) || silence == 0){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) printk(KERN_WARNING DEV_LABEL "(itf %d): "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) "chan %d error %s\n",dev->number,chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) err_txt[error]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) last_error = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) silence = (jiffies+2*HZ)|1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (size && (size > cells*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) size <= (cells-1)*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) printk(KERN_ERR DEV_LABEL "(itf %d): size %d with %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) "cells\n",dev->number,size,cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (size > ATM_MAX_AAL5_PDU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) printk(KERN_ERR DEV_LABEL "(itf %d): size too big "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) "(%d)\n",dev->number,size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (!size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (vcc) atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!atm_charge(vcc,skb->truesize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) skb->len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ATM_SKB(skb)->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) vcc->push(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) atomic_inc(&vcc->stats->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) zout(pos & 0xffff,MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #if 0 /* probably a stupid idea */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) refill_pool(dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* maybe this saves us a few interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int open_rx_first(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned short chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) DPRINTK("open_rx_first (0x%x)\n",inb_p(0xc053));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) zatm_vcc->rx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (vcc->qos.aal == ATM_AAL5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (vcc->qos.rxtp.max_sdu > 65464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) vcc->qos.rxtp.max_sdu = 65464;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* fix this - we may want to receive 64kB SDUs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cells = DIV_ROUND_UP(vcc->qos.rxtp.max_sdu + ATM_AAL5_TRAILER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) cells = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) zatm_vcc->pool = ZATM_AAL0_POOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (zatm_vcc->pool < 0) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) zout(uPD98401_OPEN_CHAN,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) DPRINTK("chan is %d\n",chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (!chan) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) use_pool(vcc->dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) DPRINTK("pool %d\n",zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* set up VC descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) zpokel(zatm_dev,zatm_vcc->pool << uPD98401_RXVC_POOL_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) chan*VC_SIZE/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) zpokel(zatm_dev,uPD98401_RXVC_OD | (vcc->qos.aal == ATM_AAL5 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) uPD98401_RXVC_AR : 0) | cells,chan*VC_SIZE/4+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) zpokel(zatm_dev,0,chan*VC_SIZE/4+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) zatm_vcc->rx_chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) zatm_dev->rx_map[chan] = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int open_rx_second(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) int pos,shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) DPRINTK("open_rx_second (0x%x)\n",inb_p(0xc053));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!zatm_vcc->rx_chan) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* should also handle VPI @@@ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pos = vcc->vci >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) shift = (1-(vcc->vci & 1)) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) zpokel(zatm_dev,(zpeekl(zatm_dev,pos) & ~(0xffff << shift)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ((zatm_vcc->rx_chan | uPD98401_RXLT_ENBL) << shift),pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static void close_rx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int pos,shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!zatm_vcc->rx_chan) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) DPRINTK("close_rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* disable receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) pos = vcc->vci >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) shift = (1-(vcc->vci & 1)) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) zpokel(zatm_dev,zpeekl(zatm_dev,pos) & ~(0xffff << shift),pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) zout(uPD98401_NOP,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) zout(uPD98401_NOP,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) zout(uPD98401_DEACT_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) udelay(10); /* why oh why ... ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) zout(uPD98401_CLOSE_CHAN | uPD98401_CHAN_RT | (zatm_vcc->rx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (!(zin(CMR) & uPD98401_CHAN_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) printk(KERN_CRIT DEV_LABEL "(itf %d): can't close RX channel "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) "%d\n",vcc->dev->number,zatm_vcc->rx_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) zatm_dev->rx_map[zatm_vcc->rx_chan] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) zatm_vcc->rx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unuse_pool(vcc->dev,zatm_vcc->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static int start_rx(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) DPRINTK("start_rx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) zatm_dev->rx_map = kcalloc(zatm_dev->chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) sizeof(*zatm_dev->rx_map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (!zatm_dev->rx_map) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* set VPI/VCI split (use all VCIs and give what's left to VPIs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) zpokel(zatm_dev,(1 << dev->ci_range.vci_bits)-1,uPD98401_VRR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* prepare free buffer pools */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) for (i = 0; i <= ZATM_LAST_POOL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) zatm_dev->pool_info[i].ref_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) zatm_dev->pool_info[i].rqa_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) zatm_dev->pool_info[i].rqu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) zatm_dev->pool_info[i].low_water = LOW_MARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) zatm_dev->pool_info[i].high_water = HIGH_MARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) zatm_dev->pool_info[i].offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) zatm_dev->pool_info[i].next_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) zatm_dev->pool_info[i].next_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) zatm_dev->pool_info[i].next_thres = OFF_CNG_THRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*----------------------------------- TX ------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int do_tx(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct atm_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) u32 *dsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) EVENT("do_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) DPRINTK("sending skb %p\n",skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) vcc = ATM_SKB(skb)->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) EVENT("iovcnt=%d\n",skb_shinfo(skb)->nr_frags,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!skb_shinfo(skb)->nr_frags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (zatm_vcc->txing == RING_ENTRIES-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return RING_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) zatm_vcc->txing++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dsc = zatm_vcc->ring+zatm_vcc->ring_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) zatm_vcc->ring_curr = (zatm_vcc->ring_curr+RING_WORDS) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) (RING_ENTRIES*RING_WORDS-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dsc[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) dsc[2] = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) dsc[3] = virt_to_bus(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP | uPD98401_TXPD_SM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) | (vcc->qos.aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) uPD98401_CLPM_1 : uPD98401_CLPM_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) EVENT("dsc (0x%lx)\n",(unsigned long) dsc,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) printk("NONONONOO!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dsc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) u32 *put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dsc = kmalloc(uPD98401_TXPD_SIZE * 2 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) uPD98401_TXBD_SIZE * ATM_SKB(skb)->iovcnt, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (!dsc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (vcc->pop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) vcc->pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* @@@ should check alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) put = dsc+8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) dsc[0] = uPD98401_TXPD_V | uPD98401_TXPD_DP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) (vcc->aal == ATM_AAL5 ? uPD98401_TXPD_AAL5 : 0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) uPD98401_CLPM_1 : uPD98401_CLPM_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dsc[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dsc[2] = ATM_SKB(skb)->iovcnt * uPD98401_TXBD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dsc[3] = virt_to_bus(put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) for (i = 0; i < ATM_SKB(skb)->iovcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *put++ = ((struct iovec *) skb->data)[i].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *put++ = virt_to_bus(((struct iovec *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) skb->data)[i].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) put[-2] |= uPD98401_TXBD_LAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) ZATM_PRV_DSC(skb) = dsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) skb_queue_tail(&zatm_vcc->tx_queue,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) DPRINTK("QRP=0x%08lx\n",zpeekl(zatm_dev,zatm_vcc->tx_chan*VC_SIZE/4+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) uPD98401_TXVC_QRP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) zout(uPD98401_TX_READY | (zatm_vcc->tx_chan <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) EVENT("done\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static inline void dequeue_tx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) EVENT("dequeue_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) skb = skb_dequeue(&zatm_vcc->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) printk(KERN_CRIT DEV_LABEL "(itf %d): dequeue_tx but not "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) "txing\n",vcc->dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) #if 0 /* @@@ would fail on CLP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD_V | uPD98401_TXPD_DP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) uPD98401_TXPD_SM | uPD98401_TXPD_AAL5)) printk("@#*$!!!! (%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) *ZATM_PRV_DSC(skb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) *ZATM_PRV_DSC(skb) = 0; /* mark as invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) zatm_vcc->txing--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) else dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) while ((skb = skb_dequeue(&zatm_vcc->backlog)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (do_tx(skb) == RING_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) skb_queue_head(&zatm_vcc->backlog,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) atomic_inc(&vcc->stats->tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) wake_up(&zatm_vcc->tx_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static void poll_tx(struct atm_dev *dev,int mbx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) EVENT("poll_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u32 data,*addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) addr = (u32 *) pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) data = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) chan = (data & uPD98401_TXI_CONN) >> uPD98401_TXI_CONN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) EVENT("addr = 0x%lx, data = 0x%08x,",(unsigned long) addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) EVENT("chan = %d\n",chan,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) NO !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) chan = (zatm_dev->mbx_start[mbx][pos >> 2] & uPD98401_TXI_CONN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) >> uPD98401_TXI_CONN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (chan < zatm_dev->chans && zatm_dev->tx_map[chan])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dequeue_tx(zatm_dev->tx_map[chan]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) printk(KERN_CRIT DEV_LABEL "(itf %d): TX indication "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) "for non-existing channel %d\n",dev->number,chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (((pos += 4) & 0xffff) == zatm_dev->mbx_end[mbx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pos = zatm_dev->mbx_start[mbx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) zout(pos & 0xffff,MTA(mbx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * BUG BUG BUG: Doesn't handle "new-style" rate specification yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) unsigned long i,m,c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) int shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) DPRINTK("alloc_shaper (min = %d, max = %d)\n",min,max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (!zatm_dev->free_shapers) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) for (shaper = 0; !((zatm_dev->free_shapers >> shaper) & 1); shaper++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) zatm_dev->free_shapers &= ~1 << shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) c = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) i = m = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) zatm_dev->ubr_ref_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) zatm_dev->ubr = shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *pcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (min <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) i = min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) m = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) i = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) m = ATM_OC3_PCR*255/min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (max > zatm_dev->tx_bw) max = zatm_dev->tx_bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (max <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) i = max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) m = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) i = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) m = DIV_ROUND_UP(ATM_OC3_PCR*255, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (i > m) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) printk(KERN_CRIT DEV_LABEL "shaper algorithm botched "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) "[%d,%d] -> i=%ld,m=%ld\n",min,max,i,m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) m = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) *pcr = i*ATM_OC3_PCR/m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) c = 20; /* @@@ should use max_cdv ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if ((min && *pcr < min) || (max && *pcr > max)) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (zatm_dev->tx_bw < *pcr) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) zatm_dev->tx_bw -= *pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) zpokel(zatm_dev,0,uPD98401_X(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) zpokel(zatm_dev,0,uPD98401_Y(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static void dealloc_shaper(struct atm_dev *dev,int shaper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (shaper == zatm_dev->ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (--zatm_dev->ubr_ref_cnt) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) zatm_dev->ubr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) uPD98401_PS(shaper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) zatm_dev->free_shapers |= 1 << shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static void close_tx(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) chan = zatm_vcc->tx_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!chan) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) DPRINTK("close_tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (skb_peek(&zatm_vcc->backlog)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) printk("waiting for backlog to drain ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->backlog));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (skb_peek(&zatm_vcc->tx_queue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) printk("waiting for TX queue to drain ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) wait_event(zatm_vcc->tx_wait, !skb_peek(&zatm_vcc->tx_queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) zout(uPD98401_CLOSE_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (!(zin(CMR) & uPD98401_CHAN_ADDR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) "%d\n",vcc->dev->number,chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) zatm_vcc->tx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) zatm_dev->tx_map[chan] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (zatm_vcc->shaper != zatm_dev->ubr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) dealloc_shaper(vcc->dev,zatm_vcc->shaper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) kfree(zatm_vcc->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static int open_tx_first(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) u32 *loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) unsigned short chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int unlimited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) DPRINTK("open_tx_first\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) zatm_vcc->tx_chan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) zout(uPD98401_OPEN_CHAN,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) DPRINTK("chan is %d\n",chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (!chan) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) unlimited = vcc->qos.txtp.traffic_class == ATM_UBR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) (!vcc->qos.txtp.max_pcr || vcc->qos.txtp.max_pcr == ATM_MAX_PCR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) vcc->qos.txtp.max_pcr >= ATM_OC3_PCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,unlimited))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) close_tx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return zatm_vcc->shaper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (pcr > ATM_OC3_PCR) pcr = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) vcc->qos.txtp.min_pcr = vcc->qos.txtp.max_pcr = pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) zatm_vcc->tx_chan = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) skb_queue_head_init(&zatm_vcc->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) init_waitqueue_head(&zatm_vcc->tx_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* initialize ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) zatm_vcc->ring = kzalloc(RING_SIZE,GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!zatm_vcc->ring) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) loop[0] = uPD98401_TXPD_V;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) loop[1] = loop[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) loop[3] = virt_to_bus(zatm_vcc->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) zatm_vcc->ring_curr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) zatm_vcc->txing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) skb_queue_head_init(&zatm_vcc->backlog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) zpokel(zatm_dev,virt_to_bus(zatm_vcc->ring),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) chan*VC_SIZE/4+uPD98401_TXVC_QRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static int open_tx_second(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) DPRINTK("open_tx_second\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) zatm_dev = ZATM_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) zatm_vcc = ZATM_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!zatm_vcc->tx_chan) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) /* set up VC descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int start_tx(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) DPRINTK("start_tx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) zatm_dev->tx_map = kmalloc_array(zatm_dev->chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) sizeof(*zatm_dev->tx_map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (!zatm_dev->tx_map) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) zatm_dev->tx_bw = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) zatm_dev->free_shapers = (1 << NR_SHAPERS)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) zatm_dev->ubr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) zatm_dev->ubr_ref_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* initialize shapers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) for (i = 0; i < NR_SHAPERS; i++) zpokel(zatm_dev,0,uPD98401_PS(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /*------------------------------- interrupts --------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static irqreturn_t zatm_int(int irq,void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct atm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) u32 reason;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) while ((reason = zin(GSR))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) EVENT("reason 0x%x\n",reason,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (reason & uPD98401_INT_PI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) EVENT("PHY int\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) dev->phy->interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (reason & uPD98401_INT_RQA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) unsigned long pools;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) pools = zin(RQA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) EVENT("RQA (0x%08x)\n",pools,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) for (i = 0; pools; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (pools & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) refill_pool(dev,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) zatm_dev->pool_info[i].rqa_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pools >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (reason & uPD98401_INT_RQU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) unsigned long pools;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) pools = zin(RQU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) printk(KERN_WARNING DEV_LABEL "(itf %d): RQU 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dev->number,pools);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) for (i = 0; pools; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (pools & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) refill_pool(dev,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) zatm_dev->pool_info[i].rqu_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) pools >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* don't handle RD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (reason & uPD98401_INT_SPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) printk(KERN_ALERT DEV_LABEL "(itf %d): system parity "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) "error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (reason & uPD98401_INT_CPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) printk(KERN_ALERT DEV_LABEL "(itf %d): control memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) "parity error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (reason & uPD98401_INT_SBE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) printk(KERN_ALERT DEV_LABEL "(itf %d): system bus "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) "error at 0x%08x\n",dev->number,zin(ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* don't handle IND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (reason & uPD98401_INT_MF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) printk(KERN_CRIT DEV_LABEL "(itf %d): mailbox full "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) "(0x%x)\n",dev->number,(reason & uPD98401_INT_MF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) >> uPD98401_INT_MF_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) event_dump();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* @@@ should try to recover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (reason & uPD98401_INT_MM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (reason & 1) poll_rx(dev,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (reason & 2) poll_rx(dev,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (reason & 4) poll_tx(dev,2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (reason & 8) poll_tx(dev,3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* @@@ handle RCRn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /*----------------------------- (E)EPROM access -----------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static void eprom_set(struct zatm_dev *zatm_dev, unsigned long value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if ((error = pci_write_config_dword(zatm_dev->pci_dev,cmd,value)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) printk(KERN_ERR DEV_LABEL ": PCI write failed (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static unsigned long eprom_get(struct zatm_dev *zatm_dev, unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if ((error = pci_read_config_dword(zatm_dev->pci_dev,cmd,&value)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) printk(KERN_ERR DEV_LABEL ": PCI read failed (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static void eprom_put_bits(struct zatm_dev *zatm_dev, unsigned long data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) int bits, unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) for (i = bits-1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) value = ZEPROM_CS | (((data >> i) & 1) ? ZEPROM_DI : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) eprom_set(zatm_dev,value,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) eprom_set(zatm_dev,value | ZEPROM_SK,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) eprom_set(zatm_dev,value,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) static void eprom_get_byte(struct zatm_dev *zatm_dev, unsigned char *byte,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) unsigned short cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) *byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) for (i = 8; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) eprom_set(zatm_dev,ZEPROM_CS,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) eprom_set(zatm_dev,ZEPROM_CS | ZEPROM_SK,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) *byte <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (eprom_get(zatm_dev,cmd) & ZEPROM_DO) *byte |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) eprom_set(zatm_dev,ZEPROM_CS,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int eprom_try_esi(struct atm_dev *dev, unsigned short cmd, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) unsigned char buf[ZEPROM_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) for (i = 0; i < ZEPROM_SIZE; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) eprom_set(zatm_dev,ZEPROM_CS,cmd); /* select EPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) eprom_put_bits(zatm_dev,ZEPROM_CMD_READ,ZEPROM_CMD_LEN,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) eprom_put_bits(zatm_dev,i >> 1,ZEPROM_ADDR_LEN,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) eprom_get_byte(zatm_dev,buf+i+swap,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) eprom_get_byte(zatm_dev,buf+i+1-swap,cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) eprom_set(zatm_dev,0,cmd); /* deselect EPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) memcpy(dev->esi,buf+offset,ESI_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return memcmp(dev->esi,"\0\0\0\0\0",ESI_LEN); /* assumes ESI_LEN == 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) static void eprom_get_esi(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (eprom_try_esi(dev,ZEPROM_V1_REG,ZEPROM_V1_ESI_OFF,1)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) (void) eprom_try_esi(dev,ZEPROM_V2_REG,ZEPROM_V2_ESI_OFF,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /*--------------------------------- entries ---------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int zatm_init(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) unsigned short command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) int error,i,last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned long t0,t1,t2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) DPRINTK(">zatm_init\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) spin_lock_init(&zatm_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) pci_dev = zatm_dev->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) zatm_dev->base = pci_resource_start(pci_dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) zatm_dev->irq = pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) dev->number,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) command | PCI_COMMAND_IO | PCI_COMMAND_MASTER))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) printk(KERN_ERR DEV_LABEL "(itf %d): can't enable IO (0x%02x)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) "\n",dev->number,error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) eprom_get_esi(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) dev->number,pci_dev->revision,zatm_dev->base,zatm_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* reset uPD98401 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) zout(0,SWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) while (!(zin(GSR) & uPD98401_INT_IND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) zout(uPD98401_GMR_ONE /*uPD98401_BURST4*/,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) last = MAX_CRAM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) zpokel(zatm_dev,0x55555555,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (zpeekl(zatm_dev,i) != 0x55555555) last = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) zpokel(zatm_dev,0xAAAAAAAA,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (zpeekl(zatm_dev,i) != 0xAAAAAAAA) last = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) else zpokel(zatm_dev,i,i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) for (i = 0; i < last; i += RAM_INCREMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (zpeekl(zatm_dev,i) != i) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) zatm_dev->mem = i << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) while (i) zpokel(zatm_dev,0,--i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* reset again to rebuild memory pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) zout(0,SWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) while (!(zin(GSR) & uPD98401_INT_IND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) zout(uPD98401_GMR_ONE | uPD98401_BURST8 | uPD98401_BURST4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) uPD98401_BURST2 | uPD98401_GMR_PM | uPD98401_GMR_DR,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* TODO: should shrink allocation now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) printk("mem=%dkB,%s (",zatm_dev->mem >> 10,zatm_dev->copper ? "UTP" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) "MMF");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) for (i = 0; i < ESI_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) printk("%02X%s",dev->esi[i],i == ESI_LEN-1 ? ")\n" : "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) t0 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) t1 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) udelay(1010);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) t2 = zpeekl(zatm_dev,uPD98401_TSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) while (t0 > t1 || t1 > t2); /* loop if wrapping ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) zatm_dev->khz = t2-2*t1+t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) printk(KERN_NOTICE DEV_LABEL "(itf %d): uPD98401 %d.%d at %d.%03d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) "MHz\n",dev->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) (zin(VER) & uPD98401_MAJOR) >> uPD98401_MAJOR_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) zin(VER) & uPD98401_MINOR,zatm_dev->khz/1000,zatm_dev->khz % 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return uPD98402_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int zatm_start(struct atm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct zatm_dev *zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct pci_dev *pdev = zatm_dev->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) unsigned long curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) int pools,vccs,rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int error, i, ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) DPRINTK("zatm_start\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) zatm_dev->rx_map = zatm_dev->tx_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) for (i = 0; i < NR_MBX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) zatm_dev->mbx_start[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) error = request_irq(zatm_dev->irq, zatm_int, IRQF_SHARED, DEV_LABEL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) dev->number,zatm_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) /* define memory regions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) pools = NR_POOLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pools = NR_SHAPERS*SHAPER_SIZE/POOL_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) vccs = (zatm_dev->mem-NR_SHAPERS*SHAPER_SIZE-pools*POOL_SIZE)/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) (2*VC_SIZE+RX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ld = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) for (rx = 1; rx < vccs; rx <<= 1) ld++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) dev->ci_range.vpi_bits = 0; /* @@@ no VPI for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) dev->ci_range.vci_bits = ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) dev->link_rate = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) zatm_dev->chans = vccs; /* ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) curr = rx*RX_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) DPRINTK("RX pool 0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) zpokel(zatm_dev,curr,uPD98401_PMA); /* receive pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) zatm_dev->pool_base = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) curr += pools*POOL_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) DPRINTK("Shapers 0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) zpokel(zatm_dev,curr,uPD98401_SMA); /* shapers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) curr += NR_SHAPERS*SHAPER_SIZE/4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) DPRINTK("Free 0x%08lx\n",curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) zpokel(zatm_dev,curr,uPD98401_TOS); /* free pool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) printk(KERN_INFO DEV_LABEL "(itf %d): %d shapers, %d pools, %d RX, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) (zatm_dev->mem-curr*4)/VC_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* create mailboxes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) for (i = 0; i < NR_MBX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) void *mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) dma_addr_t mbx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (!mbx_entries[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) mbx = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 2 * MBX_SIZE(i), &mbx_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (!mbx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * Alignment provided by dma_alloc_coherent() isn't enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * for this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) printk(KERN_ERR DEV_LABEL "(itf %d): system "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) "bus incompatible with driver\n", dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) dma_free_coherent(&pdev->dev, 2*MBX_SIZE(i), mbx, mbx_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) zatm_dev->mbx_start[i] = (unsigned long)mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) zatm_dev->mbx_dma[i] = mbx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) zout(mbx_dma >> 16, MSH(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) zout(mbx_dma, MSL(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) zout(zatm_dev->mbx_end[i], MBA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) zout((unsigned long)mbx & 0xffff, MTA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) zout((unsigned long)mbx & 0xffff, MWA(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) error = start_tx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) error = start_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) goto out_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) error = dev->phy->start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) goto out_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) zout(0xffffffff,IMR); /* enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /* enable TX & RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) out_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) kfree(zatm_dev->rx_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) out_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) kfree(zatm_dev->tx_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) while (i-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) dma_free_coherent(&pdev->dev, 2 * MBX_SIZE(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) (void *)zatm_dev->mbx_start[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) zatm_dev->mbx_dma[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) free_irq(zatm_dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static void zatm_close(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) DPRINTK(">zatm_close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (!ZATM_VCC(vcc)) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) clear_bit(ATM_VF_READY,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) close_rx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) EVENT("close_tx\n",0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) close_tx(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) DPRINTK("zatm_close: done waiting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /* deallocate memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) kfree(ZATM_VCC(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) clear_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static int zatm_open(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct zatm_vcc *zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) short vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) int vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) DPRINTK(">zatm_open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) set_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (vcc->qos.aal != ATM_AAL5) return -EINVAL; /* @@@ AAL0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) zatm_vcc = kmalloc(sizeof(*zatm_vcc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (!zatm_vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) clear_bit(ATM_VF_ADDR,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) vcc->dev_data = zatm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ZATM_VCC(vcc)->tx_chan = 0; /* for zatm_close after open_rx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if ((error = open_rx_first(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if ((error = open_tx_first(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if ((error = open_rx_second(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if ((error = open_tx_second(vcc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) zatm_close(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) set_bit(ATM_VF_READY,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static int zatm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) printk("Not yet implemented\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* @@@ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) case ZATM_GETPOOLZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (!capable(CAP_NET_ADMIN)) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) case ZATM_GETPOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) struct zatm_pool_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) int pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (get_user(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) &((struct zatm_pool_req __user *) arg)->pool_num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (pool < 0 || pool > ZATM_LAST_POOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) pool = array_index_nospec(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) ZATM_LAST_POOL + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) info = zatm_dev->pool_info[pool];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (cmd == ZATM_GETPOOLZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) zatm_dev->pool_info[pool].rqa_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) zatm_dev->pool_info[pool].rqu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return copy_to_user(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) &((struct zatm_pool_req __user *) arg)->info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) &info,sizeof(info)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) case ZATM_SETPOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) struct zatm_pool_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) int pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (!capable(CAP_NET_ADMIN)) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (get_user(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) &((struct zatm_pool_req __user *) arg)->pool_num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (pool < 0 || pool > ZATM_LAST_POOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) pool = array_index_nospec(pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) ZATM_LAST_POOL + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (copy_from_user(&info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) &((struct zatm_pool_req __user *) arg)->info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) sizeof(info))) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (!info.low_water)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) info.low_water = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) pool_info[pool].low_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (!info.high_water)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) info.high_water = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) pool_info[pool].high_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (!info.next_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) info.next_thres = zatm_dev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) pool_info[pool].next_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (info.low_water >= info.high_water ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) info.low_water < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) spin_lock_irqsave(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) zatm_dev->pool_info[pool].low_water =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) info.low_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) zatm_dev->pool_info[pool].high_water =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) info.high_water;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) zatm_dev->pool_info[pool].next_thres =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) info.next_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) spin_unlock_irqrestore(&zatm_dev->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!dev->phy->ioctl) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return dev->phy->ioctl(dev,cmd,arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static int zatm_send(struct atm_vcc *vcc,struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) EVENT(">zatm_send 0x%lx\n",(unsigned long) skb,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (!ZATM_VCC(vcc)->tx_chan || !test_bit(ATM_VF_READY,&vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) else dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) printk(KERN_CRIT "!skb in zatm_send ?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (vcc->pop) vcc->pop(vcc,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) ATM_SKB(skb)->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) error = do_tx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (error != RING_BUSY) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) skb_queue_tail(&ZATM_VCC(vcc)->backlog,skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static void zatm_phy_put(struct atm_dev *dev,unsigned char value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) zout(value,CER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) zout(uPD98401_IND_ACC | uPD98401_IA_B0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static unsigned char zatm_phy_get(struct atm_dev *dev,unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) zatm_dev = ZATM_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) zout(uPD98401_IND_ACC | uPD98401_IA_B0 | uPD98401_IA_RW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) (uPD98401_IA_TGT_PHY << uPD98401_IA_TGT_SHIFT) | addr,CMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) zwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return zin(CER) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) static const struct atmdev_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .open = zatm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .close = zatm_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) .ioctl = zatm_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .send = zatm_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) .phy_put = zatm_phy_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .phy_get = zatm_phy_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) .change_qos = zatm_change_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static int zatm_init_one(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) struct atm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) struct zatm_dev *zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) zatm_dev = kmalloc(sizeof(*zatm_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (!zatm_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) printk(KERN_EMERG "%s: memory shortage\n", DEV_LABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) ret = pci_enable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) goto out_deregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) ret = pci_request_regions(pci_dev, DEV_LABEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) goto out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) zatm_dev->pci_dev = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) dev->dev_data = zatm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) zatm_dev->copper = (int)ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if ((ret = zatm_init(dev)) || (ret = zatm_start(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) pci_set_drvdata(pci_dev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) zatm_dev->more = zatm_boards;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) zatm_boards = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) pci_release_regions(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) out_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) out_deregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) atm_dev_deregister(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) kfree(zatm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) static const struct pci_device_id zatm_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1221), ZATM_COPPER },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) { PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1225), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) MODULE_DEVICE_TABLE(pci, zatm_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) static struct pci_driver zatm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) .name = DEV_LABEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) .id_table = zatm_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .probe = zatm_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static int __init zatm_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return pci_register_driver(&zatm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) module_init(zatm_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /* module_exit not defined so not unloadable */