File: /usr/src/linux/drivers/atm/iphase.c

1     /******************************************************************************
2              iphase.c: Device driver for Interphase ATM PCI adapter cards 
3                         Author: Peter Wang  <pwang@iphase.com>            
4     		   Some fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5                        Interphase Corporation  <www.iphase.com>           
6                                    Version: 1.0                           
7     *******************************************************************************
8           
9           This software may be used and distributed according to the terms
10           of the GNU General Public License (GPL), incorporated herein by reference.
11           Drivers based on this skeleton fall under the GPL and must retain
12           the authorship (implicit copyright) notice.
13     
14           This program is distributed in the hope that it will be useful, but
15           WITHOUT ANY WARRANTY; without even the implied warranty of
16           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17           General Public License for more details.
18           
19           Modified from an incomplete driver for Interphase 5575 1KVC 1M card which 
20           was originally written by Monalisa Agrawal at UNH. Now this driver 
21           supports a variety of varients of Interphase ATM PCI (i)Chip adapter 
22           card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) 
23           in terms of PHY type, the size of control memory and the size of 
24           packet memory. The followings are the change log and history:
25          
26               Bugfix the Mona's UBR driver.
27               Modify the basic memory allocation and dma logic.
28               Port the driver to the latest kernel from 2.0.46.
29               Complete the ABR logic of the driver, and added the ABR work-
30                   around for the hardware anormalies.
31               Add the CBR support.
32     	  Add the flow control logic to the driver to allow rate-limit VC.
33               Add 4K VC support to the board with 512K control memory.
34               Add the support of all the variants of the Interphase ATM PCI 
35               (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
36               (25M UTP25) and x531 (DS3 and E3).
37               Add SMP support.
38     
39           Support and updates available at: ftp://ftp.iphase.com/pub/atm
40     
41     *******************************************************************************/
42     
43     #ifdef IA_MODULE
44     #define MODULE
45     #endif
46     #include <linux/version.h>
47     #include <linux/module.h>  
48     #include <linux/kernel.h>  
49     #include <linux/mm.h>  
50     #include <linux/pci.h>  
51     #include <linux/errno.h>  
52     #include <linux/atm.h>  
53     #include <linux/atmdev.h>  
54     #include <linux/sonet.h>  
55     #include <linux/skbuff.h>  
56     #include <linux/time.h>  
57     #include <linux/sched.h> /* for xtime */  
58     #include <linux/delay.h>  
59     #include <linux/uio.h>  
60     #include <linux/init.h>  
61     #include <asm/system.h>  
62     #include <asm/io.h>  
63     #include <asm/atomic.h>  
64     #include <asm/uaccess.h>  
65     #include <asm/string.h>  
66     #include <asm/byteorder.h>  
67     #include <linux/vmalloc.h>  
68     #include "iphase.h"		  
69     #include "suni.h"		  
70     #define swap(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))  
71     struct suni_priv {
72             struct k_sonet_stats sonet_stats; /* link diagnostics */
73             unsigned char loop_mode;        /* loopback mode */
74             struct atm_dev *dev;            /* device back-pointer */
75             struct suni_priv *next;         /* next SUNI */
76     }; 
77     #define PRIV(dev) ((struct suni_priv *) dev->phy_data)
78     
79     static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
80     
81     static IADEV *ia_dev[8];
82     static struct atm_dev *_ia_dev[8];
83     static int iadev_count;
84     static void ia_led_timer(unsigned long arg);
85     static struct timer_list ia_timer = { function: ia_led_timer };
86     struct atm_vcc *vcc_close_que[100];
87     static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
88     static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
89     static u32 IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
90                 |IF_IADBG_ABR | IF_IADBG_EVENT*/ 0; 
91     
92     #ifdef MODULE
93     MODULE_PARM(IA_TX_BUF, "i");
94     MODULE_PARM(IA_TX_BUF_SZ, "i");
95     MODULE_PARM(IA_RX_BUF, "i");
96     MODULE_PARM(IA_RX_BUF_SZ, "i");
97     MODULE_PARM(IADebugFlag, "i");
98     #endif
99     
100     MODULE_LICENSE("GPL");
101     
102     #if BITS_PER_LONG != 32
103     #  error FIXME: this driver only works on 32-bit platforms
104     #endif
105     
106     /**************************** IA_LIB **********************************/
107     
108     static void ia_init_rtn_q (IARTN_Q *que) 
109     { 
110        que->next = NULL; 
111        que->tail = NULL; 
112     }
113     
114     static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data) 
115     {
116        data->next = NULL;
117        if (que->next == NULL) 
118           que->next = que->tail = data;
119        else {
120           data->next = que->next;
121           que->next = data;
122        } 
123        return;
124     }
125     
126     static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) {
127        IARTN_Q *entry = kmalloc(sizeof(*entry), GFP_KERNEL);
128        if (!entry) return -1;
129        entry->data = data;
130        entry->next = NULL;
131        if (que->next == NULL) 
132           que->next = que->tail = entry;
133        else {
134           que->tail->next = entry;
135           que->tail = que->tail->next;
136        }      
137        return 1;
138     }
139     
140     static IARTN_Q * ia_deque_rtn_q (IARTN_Q *que) {
141        IARTN_Q *tmpdata;
142        if (que->next == NULL)
143           return NULL;
144        tmpdata = que->next;
145        if ( que->next == que->tail)  
146           que->next = que->tail = NULL;
147        else 
148           que->next = que->next->next;
149        return tmpdata;
150     }
151     
152     static void ia_hack_tcq(IADEV *dev) {
153     
154       u_short 		desc1;
155       u_short		tcq_wr;
156       struct ia_vcc         *iavcc_r = NULL; 
157       extern void desc_dbg(IADEV *iadev);
158     
159       tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff;
160       while (dev->host_tcq_wr != tcq_wr) {
161          desc1 = *(u_short *)(dev->seg_ram + dev->host_tcq_wr);
162          if (!desc1) ;
163          else if (!dev->desc_tbl[desc1 -1].timestamp) {
164             IF_ABR(printk(" Desc %d is reset at %ld\n", desc1 -1, jiffies);)
165             *(u_short *) (dev->seg_ram + dev->host_tcq_wr) = 0;
166          }                                 
167          else if (dev->desc_tbl[desc1 -1].timestamp) {
168             if (!(iavcc_r = dev->desc_tbl[desc1 -1].iavcc)) { 
169                printk("IA: Fatal err in get_desc\n");
170                continue;
171             }
172             iavcc_r->vc_desc_cnt--;
173             dev->desc_tbl[desc1 -1].timestamp = 0;
174             IF_EVENT(printk("ia_hack: return_q skb = 0x%x desc = %d\n", 
175                                        (u32)dev->desc_tbl[desc1 -1].txskb, desc1);)
176             if (iavcc_r->pcr < dev->rate_limit) {
177                IA_SKB_STATE (dev->desc_tbl[desc1-1].txskb) |= IA_TX_DONE;
178                if (ia_enque_rtn_q(&dev->tx_return_q, dev->desc_tbl[desc1 -1]) < 0)
179                   printk("ia_hack_tcq: No memory available\n");
180             } 
181             dev->desc_tbl[desc1 -1].iavcc = NULL;
182             dev->desc_tbl[desc1 -1].txskb = NULL;
183          }
184          dev->host_tcq_wr += 2;
185          if (dev->host_tcq_wr > dev->ffL.tcq_ed) 
186             dev->host_tcq_wr = dev->ffL.tcq_st;
187       }
188     } /* ia_hack_tcq */
189     
190     static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
191       u_short 		desc_num, i;
192       struct sk_buff        *skb;
193       struct ia_vcc         *iavcc_r = NULL; 
194       unsigned long delta;
195       static unsigned long timer = 0;
196       int ltimeout;
197       extern void desc_dbg(IADEV *iadev);
198     
199       ia_hack_tcq (dev);
200       if(((jiffies - timer)>50)||((dev->ffL.tcq_rd==dev->host_tcq_wr))){      
201          timer = jiffies; 
202          i=0;
203          while (i < dev->num_tx_desc) {
204             if (!dev->desc_tbl[i].timestamp) {
205                i++;
206                continue;
207             }
208             ltimeout = dev->desc_tbl[i].iavcc->ltimeout; 
209             delta = jiffies - dev->desc_tbl[i].timestamp;
210             if (delta >= ltimeout) {
211                IF_ABR(printk("RECOVER run!! desc_tbl %d = %d  delta = %ld, 
212                    time = %ld\n", i,dev->desc_tbl[i].timestamp, delta, jiffies);)
213                if (dev->ffL.tcq_rd == dev->ffL.tcq_st) 
214                   dev->ffL.tcq_rd =  dev->ffL.tcq_ed;
215                else 
216                   dev->ffL.tcq_rd -= 2;
217                *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1;
218                if (!(skb = dev->desc_tbl[i].txskb) || 
219                               !(iavcc_r = dev->desc_tbl[i].iavcc))
220                   printk("Fatal err, desc table vcc or skb is NULL\n");
221                else 
222                   iavcc_r->vc_desc_cnt--;
223                dev->desc_tbl[i].timestamp = 0;
224                dev->desc_tbl[i].iavcc = NULL;
225                dev->desc_tbl[i].txskb = NULL;
226             }
227             i++;
228          } /* while */
229       }
230       if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
231          return 0xFFFF;
232         
233       /* Get the next available descriptor number from TCQ */
234       desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
235     
236       while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
237          dev->ffL.tcq_rd += 2;
238          if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) 
239          dev->ffL.tcq_rd = dev->ffL.tcq_st;
240          if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
241             return 0xFFFF; 
242          desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
243       }
244     
245       /* get system time */
246       dev->desc_tbl[desc_num -1].timestamp = jiffies;
247       return desc_num;
248     }
249     
250     static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) {
251       u_char          	foundLockUp;
252       vcstatus_t		*vcstatus;
253       u_short               *shd_tbl;
254       u_short               tempCellSlot, tempFract;
255       struct main_vc *abr_vc = (struct main_vc *)dev->MAIN_VC_TABLE_ADDR;
256       struct ext_vc *eabr_vc = (struct ext_vc *)dev->EXT_VC_TABLE_ADDR;
257       u_int  i;
258     
259       if (vcc->qos.txtp.traffic_class == ATM_ABR) {
260          vcstatus = (vcstatus_t *) &(dev->testTable[vcc->vci]->vc_status);
261          vcstatus->cnt++;
262          foundLockUp = 0;
263          if( vcstatus->cnt == 0x05 ) {
264             abr_vc += vcc->vci;
265     	eabr_vc += vcc->vci;
266     	if( eabr_vc->last_desc ) {
267     	   if( (abr_vc->status & 0x07) == ABR_STATE /* 0x2 */ ) {
268                   /* Wait for 10 Micro sec */
269                   udelay(10);
270     	      if ((eabr_vc->last_desc)&&((abr_vc->status & 0x07)==ABR_STATE))
271     		 foundLockUp = 1;
272                }
273     	   else {
274     	      tempCellSlot = abr_vc->last_cell_slot;
275                   tempFract    = abr_vc->fraction;
276                   if((tempCellSlot == dev->testTable[vcc->vci]->lastTime)
277                              && (tempFract == dev->testTable[vcc->vci]->fract))
278     	         foundLockUp = 1; 		    
279                   dev->testTable[vcc->vci]->lastTime = tempCellSlot;   
280                   dev->testTable[vcc->vci]->fract = tempFract; 
281     	   } 	    
282             } /* last descriptor */	 	   
283             vcstatus->cnt = 0;     	
284          } /* vcstatus->cnt */
285     	
286          if (foundLockUp) {
287             IF_ABR(printk("LOCK UP found\n");) 
288     	writew(0xFFFD, dev->seg_reg+MODE_REG_0);
289             /* Wait for 10 Micro sec */
290             udelay(10); 
291             abr_vc->status &= 0xFFF8;
292             abr_vc->status |= 0x0001;  /* state is idle */
293     	shd_tbl = (u_short *)dev->ABR_SCHED_TABLE_ADDR;                
294     	for( i = 0; ((i < dev->num_vc) && (shd_tbl[i])); i++ );
295     	if (i < dev->num_vc)
296                shd_tbl[i] = vcc->vci;
297             else
298                IF_ERR(printk("ABR Seg. may not continue on VC %x\n",vcc->vci);)
299             writew(T_ONLINE, dev->seg_reg+MODE_REG_0);
300             writew(~(TRANSMIT_DONE|TCQ_NOT_EMPTY), dev->seg_reg+SEG_MASK_REG);
301             writew(TRANSMIT_DONE, dev->seg_reg+SEG_INTR_STATUS_REG);       
302     	vcstatus->cnt = 0;
303          } /* foundLockUp */
304     
305       } /* if an ABR VC */
306     
307     
308     }
309      
310     /*
311     ** Conversion of 24-bit cellrate (cells/sec) to 16-bit floating point format.
312     **
313     **  +----+----+------------------+-------------------------------+
314     **  |  R | NZ |  5-bit exponent  |        9-bit mantissa         |
315     **  +----+----+------------------+-------------------------------+
316     ** 
317     **    R = reserverd (written as 0)
318     **    NZ = 0 if 0 cells/sec; 1 otherwise
319     **
320     **    if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec
321     */
322     static u16
323     cellrate_to_float(u32 cr)
324     {
325     
326     #define	NZ 		0x4000
327     #define	M_BITS		9		/* Number of bits in mantissa */
328     #define	E_BITS		5		/* Number of bits in exponent */
329     #define	M_MASK		0x1ff		
330     #define	E_MASK		0x1f
331       u16   flot;
332       u32	tmp = cr & 0x00ffffff;
333       int 	i   = 0;
334       if (cr == 0)
335          return 0;
336       while (tmp != 1) {
337          tmp >>= 1;
338          i++;
339       }
340       if (i == M_BITS)
341          flot = NZ | (i << M_BITS) | (cr & M_MASK);
342       else if (i < M_BITS)
343          flot = NZ | (i << M_BITS) | ((cr << (M_BITS - i)) & M_MASK);
344       else
345          flot = NZ | (i << M_BITS) | ((cr >> (i - M_BITS)) & M_MASK);
346       return flot;
347     }
348     
349     #if 0
350     /*
351     ** Conversion of 16-bit floating point format to 24-bit cellrate (cells/sec).
352     */
353     static u32
354     float_to_cellrate(u16 rate)
355     {
356       u32   exp, mantissa, cps;
357       if ((rate & NZ) == 0)
358          return 0;
359       exp = (rate >> M_BITS) & E_MASK;
360       mantissa = rate & M_MASK;
361       if (exp == 0)
362          return 1;
363       cps = (1 << M_BITS) | mantissa;
364       if (exp == M_BITS)
365          cps = cps;
366       else if (exp > M_BITS)
367          cps <<= (exp - M_BITS);
368       else
369          cps >>= (M_BITS - exp);
370       return cps;
371     }
372     #endif 
373     
374     static void init_abr_vc (IADEV *dev, srv_cls_param_t *srv_p) {
375       srv_p->class_type = ATM_ABR;
376       srv_p->pcr        = dev->LineRate;
377       srv_p->mcr        = 0;
378       srv_p->icr        = 0x055cb7;
379       srv_p->tbe        = 0xffffff;
380       srv_p->frtt       = 0x3a;
381       srv_p->rif        = 0xf;
382       srv_p->rdf        = 0xb;
383       srv_p->nrm        = 0x4;
384       srv_p->trm        = 0x7;
385       srv_p->cdf        = 0x3;
386       srv_p->adtf       = 50;
387     }
388     
389     static int
390     ia_open_abr_vc(IADEV *dev, srv_cls_param_t *srv_p, 
391                                                     struct atm_vcc *vcc, u8 flag)
392     {
393       f_vc_abr_entry  *f_abr_vc;
394       r_vc_abr_entry  *r_abr_vc;
395       u32		icr;
396       u8		trm, nrm, crm;
397       u16		adtf, air, *ptr16;	
398       f_abr_vc =(f_vc_abr_entry *)dev->MAIN_VC_TABLE_ADDR;
399       f_abr_vc += vcc->vci;       
400       switch (flag) {
401          case 1: /* FFRED initialization */
402     #if 0  /* sanity check */
403            if (srv_p->pcr == 0)
404               return INVALID_PCR;
405            if (srv_p->pcr > dev->LineRate)
406               srv_p->pcr = dev->LineRate;
407            if ((srv_p->mcr + dev->sum_mcr) > dev->LineRate)
408     	  return MCR_UNAVAILABLE;
409            if (srv_p->mcr > srv_p->pcr)
410     	  return INVALID_MCR;
411            if (!(srv_p->icr))
412     	  srv_p->icr = srv_p->pcr;
413            if ((srv_p->icr < srv_p->mcr) || (srv_p->icr > srv_p->pcr))
414     	  return INVALID_ICR;
415            if ((srv_p->tbe < MIN_TBE) || (srv_p->tbe > MAX_TBE))
416     	  return INVALID_TBE;
417            if ((srv_p->frtt < MIN_FRTT) || (srv_p->frtt > MAX_FRTT))
418     	  return INVALID_FRTT;
419            if (srv_p->nrm > MAX_NRM)
420     	  return INVALID_NRM;
421            if (srv_p->trm > MAX_TRM)
422     	  return INVALID_TRM;
423            if (srv_p->adtf > MAX_ADTF)
424               return INVALID_ADTF;
425            else if (srv_p->adtf == 0)
426     	  srv_p->adtf = 1;
427            if (srv_p->cdf > MAX_CDF)
428     	  return INVALID_CDF;
429            if (srv_p->rif > MAX_RIF)
430     	  return INVALID_RIF;
431            if (srv_p->rdf > MAX_RDF)
432     	  return INVALID_RDF;
433     #endif
434            memset ((caddr_t)f_abr_vc, 0, sizeof(*f_abr_vc));
435            f_abr_vc->f_vc_type = ABR;
436            nrm = 2 << srv_p->nrm;     /* (2 ** (srv_p->nrm +1)) */
437     			          /* i.e 2**n = 2 << (n-1) */
438            f_abr_vc->f_nrm = nrm << 8 | nrm;
439            trm = 100000/(2 << (16 - srv_p->trm));
440            if ( trm == 0) trm = 1;
441            f_abr_vc->f_nrmexp =(((srv_p->nrm +1) & 0x0f) << 12)|(MRM << 8) | trm;
442            crm = srv_p->tbe / nrm;
443            if (crm == 0) crm = 1;
444            f_abr_vc->f_crm = crm & 0xff;
445            f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr);
446            icr = MIN( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
447     				((srv_p->tbe/srv_p->frtt)*1000000) :
448     				(1000000/(srv_p->frtt/srv_p->tbe)));
449            f_abr_vc->f_icr = cellrate_to_float(icr);
450            adtf = (10000 * srv_p->adtf)/8192;
451            if (adtf == 0) adtf = 1; 
452            f_abr_vc->f_cdf = ((7 - srv_p->cdf) << 12 | adtf) & 0xfff;
453            f_abr_vc->f_mcr = cellrate_to_float(srv_p->mcr);
454            f_abr_vc->f_acr = f_abr_vc->f_icr;
455            f_abr_vc->f_status = 0x0042;
456            break;
457         case 0: /* RFRED initialization */	
458            ptr16 = (u_short *)(dev->reass_ram + REASS_TABLE*dev->memSize); 
459            *(ptr16 + vcc->vci) = NO_AAL5_PKT | REASS_ABR;
460            r_abr_vc = (r_vc_abr_entry*)(dev->reass_ram+ABR_VC_TABLE*dev->memSize);
461            r_abr_vc += vcc->vci;
462            r_abr_vc->r_status_rdf = (15 - srv_p->rdf) & 0x000f;
463            air = srv_p->pcr << (15 - srv_p->rif);
464            if (air == 0) air = 1;
465            r_abr_vc->r_air = cellrate_to_float(air);
466            dev->testTable[vcc->vci]->vc_status = VC_ACTIVE | VC_ABR;
467            dev->sum_mcr	   += srv_p->mcr;
468            dev->n_abr++;
469            break;
470         default:
471            break;
472       }
473       return	0;
474     }
475     static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) {
476        u32 rateLow=0, rateHigh, rate;
477        int entries;
478        struct ia_vcc *ia_vcc;
479     
480        int   idealSlot =0, testSlot, toBeAssigned, inc;
481        u32   spacing;
482        u16  *SchedTbl, *TstSchedTbl;
483        u16  cbrVC, vcIndex;
484        u32   fracSlot    = 0;
485        u32   sp_mod      = 0;
486        u32   sp_mod2     = 0;
487     
488        /* IpAdjustTrafficParams */
489        if (vcc->qos.txtp.max_pcr <= 0) {
490           IF_ERR(printk("PCR for CBR not defined\n");)
491           return -1;
492        }
493        rate = vcc->qos.txtp.max_pcr;
494        entries = rate / dev->Granularity;
495        IF_CBR(printk("CBR: CBR entries=0x%x for rate=0x%x & Gran=0x%x\n",
496                                     entries, rate, dev->Granularity);)
497        if (entries < 1)
498           IF_CBR(printk("CBR: Bandwidth smaller than granularity of CBR table\n");) 
499        rateLow  =  entries * dev->Granularity;
500        rateHigh = (entries + 1) * dev->Granularity;
501        if (3*(rate - rateLow) > (rateHigh - rate))
502           entries++;
503        if (entries > dev->CbrRemEntries) {
504           IF_CBR(printk("CBR: Not enough bandwidth to support this PCR.\n");)
505           IF_CBR(printk("Entries = 0x%x, CbrRemEntries = 0x%x.\n",
506                                            entries, dev->CbrRemEntries);)
507           return -EBUSY;
508        }   
509     
510        ia_vcc = INPH_IA_VCC(vcc);
511        ia_vcc->NumCbrEntry = entries; 
512        dev->sum_mcr += entries * dev->Granularity; 
513        /* IaFFrednInsertCbrSched */
514        // Starting at an arbitrary location, place the entries into the table
515        // as smoothly as possible
516        cbrVC   = 0;
517        spacing = dev->CbrTotEntries / entries;
518        sp_mod  = dev->CbrTotEntries % entries; // get modulo
519        toBeAssigned = entries;
520        fracSlot = 0;
521        vcIndex  = vcc->vci;
522        IF_CBR(printk("Vci=0x%x,Spacing=0x%x,Sp_mod=0x%x\n",vcIndex,spacing,sp_mod);)
523        while (toBeAssigned)
524        {
525           // If this is the first time, start the table loading for this connection
526           // as close to entryPoint as possible.
527           if (toBeAssigned == entries)
528           {
529              idealSlot = dev->CbrEntryPt;
530              dev->CbrEntryPt += 2;    // Adding 2 helps to prevent clumping
531              if (dev->CbrEntryPt >= dev->CbrTotEntries) 
532                 dev->CbrEntryPt -= dev->CbrTotEntries;// Wrap if necessary
533           } else {
534              idealSlot += (u32)(spacing + fracSlot); // Point to the next location
535              // in the table that would be  smoothest
536              fracSlot = ((sp_mod + sp_mod2) / entries);  // get new integer part
537              sp_mod2  = ((sp_mod + sp_mod2) % entries);  // calc new fractional part
538           }
539           if (idealSlot >= (int)dev->CbrTotEntries) 
540              idealSlot -= dev->CbrTotEntries;  
541           // Continuously check around this ideal value until a null
542           // location is encountered.
543           SchedTbl = (u16*)(dev->seg_ram+CBR_SCHED_TABLE*dev->memSize); 
544           inc = 0;
545           testSlot = idealSlot;
546           TstSchedTbl = (u16*)(SchedTbl+testSlot);  //set index and read in value
547           IF_CBR(printk("CBR Testslot 0x%x AT Location 0x%x, NumToAssign=%d\n",
548                                     testSlot, (u32)TstSchedTbl,toBeAssigned);) 
549           memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
550           while (cbrVC)  // If another VC at this location, we have to keep looking
551           {
552               inc++;
553               testSlot = idealSlot - inc;
554               if (testSlot < 0) { // Wrap if necessary
555                  testSlot += dev->CbrTotEntries;
556                  IF_CBR(printk("Testslot Wrap. STable Start=0x%x,Testslot=%d\n",
557                                                            (u32)SchedTbl,testSlot);)
558               }
559               TstSchedTbl = (u16 *)(SchedTbl + testSlot);  // set table index
560               memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC)); 
561               if (!cbrVC)
562                  break;
563               testSlot = idealSlot + inc;
564               if (testSlot >= (int)dev->CbrTotEntries) { // Wrap if necessary
565                  testSlot -= dev->CbrTotEntries;
566                  IF_CBR(printk("TotCbrEntries=%d",dev->CbrTotEntries);)
567                  IF_CBR(printk(" Testslot=0x%x ToBeAssgned=%d\n", 
568                                                 testSlot, toBeAssigned);)
569               } 
570               // set table index and read in value
571               TstSchedTbl = (u16*)(SchedTbl + testSlot);
572               IF_CBR(printk("Reading CBR Tbl from 0x%x, CbrVal=0x%x Iteration %d\n",
573                               (u32)TstSchedTbl,cbrVC,inc);) 
574               memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
575            } /* while */
576            // Move this VCI number into this location of the CBR Sched table.
577            memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex,sizeof(TstSchedTbl));
578            dev->CbrRemEntries--;
579            toBeAssigned--;
580        } /* while */ 
581     
582        /* IaFFrednCbrEnable */
583        dev->NumEnabledCBR++;
584        if (dev->NumEnabledCBR == 1) {
585            writew((CBR_EN | UBR_EN | ABR_EN | (0x23 << 2)), dev->seg_reg+STPARMS);
586            IF_CBR(printk("CBR is enabled\n");)
587        }
588        return 0;
589     }
590     static void ia_cbrVc_close (struct atm_vcc *vcc) {
591        IADEV *iadev;
592        u16 *SchedTbl, NullVci = 0;
593        u32 i, NumFound;
594     
595        iadev = INPH_IA_DEV(vcc->dev);
596        iadev->NumEnabledCBR--;
597        SchedTbl = (u16*)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize);
598        if (iadev->NumEnabledCBR == 0) {
599           writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);
600           IF_CBR (printk("CBR support disabled\n");)
601        }
602        NumFound = 0;
603        for (i=0; i < iadev->CbrTotEntries; i++)
604        {
605           if (*SchedTbl == vcc->vci) {
606              iadev->CbrRemEntries++;
607              *SchedTbl = NullVci;
608              IF_CBR(NumFound++;)
609           }
610           SchedTbl++;   
611        } 
612        IF_CBR(printk("Exit ia_cbrVc_close, NumRemoved=%d\n",NumFound);)
613     }
614     
615     static int ia_avail_descs(IADEV *iadev) {
616        int tmp = 0;
617        ia_hack_tcq(iadev);
618        if (iadev->host_tcq_wr >= iadev->ffL.tcq_rd)
619           tmp = (iadev->host_tcq_wr - iadev->ffL.tcq_rd) / 2;
620        else
621           tmp = (iadev->ffL.tcq_ed - iadev->ffL.tcq_rd + 2 + iadev->host_tcq_wr -
622                        iadev->ffL.tcq_st) / 2;
623        return tmp;
624     }    
625     
626     static int ia_que_tx (IADEV *iadev) { 
627        struct sk_buff *skb;
628        int num_desc;
629        struct atm_vcc *vcc;
630        struct ia_vcc *iavcc;
631        static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb);
632        num_desc = ia_avail_descs(iadev);
633        while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
634           if (!(vcc = ATM_SKB(skb)->vcc)) {
635              dev_kfree_skb_any(skb);
636              printk("ia_que_tx: Null vcc\n");
637              break;
638           }
639           if (!test_bit(ATM_VF_READY,&vcc->flags)) {
640              dev_kfree_skb_any(skb);
641              printk("Free the SKB on closed vci %d \n", vcc->vci);
642              break;
643           }
644           iavcc = INPH_IA_VCC(vcc);
645           if (ia_pkt_tx (vcc, skb)) {
646              skb_queue_head(&iadev->tx_backlog, skb);
647           }
648           num_desc--;
649        }
650        return 0;
651     }
652     void ia_tx_poll (IADEV *iadev) {
653        struct atm_vcc *vcc = NULL;
654        struct sk_buff *skb = NULL, *skb1 = NULL;
655        struct ia_vcc *iavcc;
656        IARTN_Q *  rtne;
657     
658        ia_hack_tcq(iadev);
659        while ( (rtne = ia_deque_rtn_q(&iadev->tx_return_q))) {
660            skb = rtne->data.txskb;
661            if (!skb) {
662                printk("ia_tx_poll: skb is null\n");
663                goto out;
664            }
665            vcc = ATM_SKB(skb)->vcc;
666            if (!vcc) {
667                printk("ia_tx_poll: vcc is null\n");
668                dev_kfree_skb_any(skb);
669     	   goto out;
670            }
671     
672            iavcc = INPH_IA_VCC(vcc);
673            if (!iavcc) {
674                printk("ia_tx_poll: iavcc is null\n");
675                dev_kfree_skb_any(skb);
676     	   goto out;
677            }
678     
679            skb1 = skb_dequeue(&iavcc->txing_skb);
680            while (skb1 && (skb1 != skb)) {
681               if (!(IA_SKB_STATE(skb1) & IA_TX_DONE)) {
682                  printk("IA_tx_intr: Vci %d lost pkt!!!\n", vcc->vci);
683               }
684               IF_ERR(printk("Release the SKB not match\n");)
685               if ((vcc->pop) && (skb1->len != 0))
686               {
687                  vcc->pop(vcc, skb1);
688                  IF_EVENT(printk("Tansmit Done - skb 0x%lx return\n",
689                                                               (long)skb1);)
690               }
691               else 
692                  dev_kfree_skb_any(skb1);
693               skb1 = skb_dequeue(&iavcc->txing_skb);
694            }                                                        
695            if (!skb1) {
696               IF_EVENT(printk("IA: Vci %d - skb not found requed\n",vcc->vci);)
697               ia_enque_head_rtn_q (&iadev->tx_return_q, rtne);
698               break;
699            }
700            if ((vcc->pop) && (skb->len != 0))
701            {
702               vcc->pop(vcc, skb);
703               IF_EVENT(printk("Tx Done - skb 0x%lx return\n",(long)skb);)
704            }
705            else 
706               dev_kfree_skb_any(skb);
707            kfree(rtne);
708         }
709         ia_que_tx(iadev);
710     out:
711         return;
712     }
713     #if 0
714     static void ia_eeprom_put (IADEV *iadev, u32 addr, u_short val)
715     {
716             u32	t;
717     	int	i;
718     	/*
719     	 * Issue a command to enable writes to the NOVRAM
720     	 */
721     	NVRAM_CMD (EXTEND + EWEN);
722     	NVRAM_CLR_CE;
723     	/*
724     	 * issue the write command
725     	 */
726     	NVRAM_CMD(IAWRITE + addr);
727     	/* 
728     	 * Send the data, starting with D15, then D14, and so on for 16 bits
729     	 */
730     	for (i=15; i>=0; i--) {
731     		NVRAM_CLKOUT (val & 0x8000);
732     		val <<= 1;
733     	}
734     	NVRAM_CLR_CE;
735     	CFG_OR(NVCE);
736     	t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
737     	while (!(t & NVDO))
738     		t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
739     
740     	NVRAM_CLR_CE;
741     	/*
742     	 * disable writes again
743     	 */
744     	NVRAM_CMD(EXTEND + EWDS)
745     	NVRAM_CLR_CE;
746     	CFG_AND(~NVDI);
747     }
748     #endif
749     
750     static u16 ia_eeprom_get (IADEV *iadev, u32 addr)
751     {
752     	u_short	val;
753             u32	t;
754     	int	i;
755     	/*
756     	 * Read the first bit that was clocked with the falling edge of the
757     	 * the last command data clock
758     	 */
759     	NVRAM_CMD(IAREAD + addr);
760     	/*
761     	 * Now read the rest of the bits, the next bit read is D14, then D13,
762     	 * and so on.
763     	 */
764     	val = 0;
765     	for (i=15; i>=0; i--) {
766     		NVRAM_CLKIN(t);
767     		val |= (t << i);
768     	}
769     	NVRAM_CLR_CE;
770     	CFG_AND(~NVDI);
771     	return val;
772     }
773     
774     static void ia_hw_type(IADEV *iadev) {
775        u_short memType = ia_eeprom_get(iadev, 25);   
776        iadev->memType = memType;
777        if ((memType & MEM_SIZE_MASK) == MEM_SIZE_1M) {
778           iadev->num_tx_desc = IA_TX_BUF;
779           iadev->tx_buf_sz = IA_TX_BUF_SZ;
780           iadev->num_rx_desc = IA_RX_BUF;
781           iadev->rx_buf_sz = IA_RX_BUF_SZ; 
782        } else if ((memType & MEM_SIZE_MASK) == MEM_SIZE_512K) {
783           if (IA_TX_BUF == DFL_TX_BUFFERS)
784             iadev->num_tx_desc = IA_TX_BUF / 2;
785           else 
786             iadev->num_tx_desc = IA_TX_BUF;
787           iadev->tx_buf_sz = IA_TX_BUF_SZ;
788           if (IA_RX_BUF == DFL_RX_BUFFERS)
789             iadev->num_rx_desc = IA_RX_BUF / 2;
790           else
791             iadev->num_rx_desc = IA_RX_BUF;
792           iadev->rx_buf_sz = IA_RX_BUF_SZ;
793        }
794        else {
795           if (IA_TX_BUF == DFL_TX_BUFFERS) 
796             iadev->num_tx_desc = IA_TX_BUF / 8;
797           else
798             iadev->num_tx_desc = IA_TX_BUF;
799           iadev->tx_buf_sz = IA_TX_BUF_SZ;
800           if (IA_RX_BUF == DFL_RX_BUFFERS)
801             iadev->num_rx_desc = IA_RX_BUF / 8;
802           else
803             iadev->num_rx_desc = IA_RX_BUF;
804           iadev->rx_buf_sz = IA_RX_BUF_SZ; 
805        } 
806        iadev->rx_pkt_ram = TX_PACKET_RAM + (iadev->num_tx_desc * iadev->tx_buf_sz); 
807        IF_INIT(printk("BUF: tx=%d,sz=%d rx=%d sz= %d rx_pkt_ram=%d\n",
808              iadev->num_tx_desc, iadev->tx_buf_sz, iadev->num_rx_desc,
809              iadev->rx_buf_sz, iadev->rx_pkt_ram);)
810     
811     #if 0
812        if ((memType & FE_MASK) == FE_SINGLE_MODE) {
813           iadev->phy_type = PHY_OC3C_S;
814        else if ((memType & FE_MASK) == FE_UTP_OPTION)
815           iadev->phy_type = PHY_UTP155;
816        else
817          iadev->phy_type = PHY_OC3C_M;
818     #endif
819        
820        iadev->phy_type = memType & FE_MASK;
821        IF_INIT(printk("memType = 0x%x iadev->phy_type = 0x%x\n", 
822                                              memType,iadev->phy_type);)
823        if (iadev->phy_type == FE_25MBIT_PHY) 
824           iadev->LineRate = (u32)(((25600000/8)*26)/(27*53));
825        else if (iadev->phy_type == FE_DS3_PHY)
826           iadev->LineRate = (u32)(((44736000/8)*26)/(27*53));
827        else if (iadev->phy_type == FE_E3_PHY) 
828           iadev->LineRate = (u32)(((34368000/8)*26)/(27*53));
829        else
830            iadev->LineRate = (u32)(ATM_OC3_PCR);
831        IF_INIT(printk("iadev->LineRate = %d \n", iadev->LineRate);)
832     
833     }
834     
835     static void IaFrontEndIntr(IADEV *iadev) {
836       volatile IA_SUNI *suni;
837       volatile ia_mb25_t *mb25;
838       volatile suni_pm7345_t *suni_pm7345;
839       u32 intr_status;
840       u_int frmr_intr;
841     
842       if(iadev->phy_type & FE_25MBIT_PHY) {
843          mb25 = (ia_mb25_t*)iadev->phy;
844          iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
845       } else if (iadev->phy_type & FE_DS3_PHY) {
846          suni_pm7345 = (suni_pm7345_t *)iadev->phy;
847          /* clear FRMR interrupts */
848          frmr_intr   = suni_pm7345->suni_ds3_frm_intr_stat; 
849          iadev->carrier_detect =  
850                Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
851       } else if (iadev->phy_type & FE_E3_PHY ) {
852          suni_pm7345 = (suni_pm7345_t *)iadev->phy;
853          frmr_intr   = suni_pm7345->suni_e3_frm_maint_intr_ind;
854          iadev->carrier_detect =
855                Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
856       }
857       else { 
858          suni = (IA_SUNI *)iadev->phy;
859          intr_status = suni->suni_rsop_status & 0xff;
860          iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
861       }
862       if (iadev->carrier_detect)
863         printk("IA: SUNI carrier detected\n");
864       else
865         printk("IA: SUNI carrier lost signal\n"); 
866       return;
867     }
868     
869     void ia_mb25_init (IADEV *iadev)
870     {
871        volatile ia_mb25_t  *mb25 = (ia_mb25_t*)iadev->phy;
872     #if 0
873        mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
874     #endif
875        mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC;
876        mb25->mb25_diag_control = 0;
877        /*
878         * Initialize carrier detect state
879         */
880        iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
881        return;
882     }                   
883     
884     void ia_suni_pm7345_init (IADEV *iadev)
885     {
886        volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy;
887        if (iadev->phy_type & FE_DS3_PHY)
888        {
889           iadev->carrier_detect = 
890               Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); 
891           suni_pm7345->suni_ds3_frm_intr_enbl = 0x17;
892           suni_pm7345->suni_ds3_frm_cfg = 1;
893           suni_pm7345->suni_ds3_tran_cfg = 1;
894           suni_pm7345->suni_config = 0;
895           suni_pm7345->suni_splr_cfg = 0;
896           suni_pm7345->suni_splt_cfg = 0;
897        }
898        else 
899        {
900           iadev->carrier_detect = 
901               Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS));
902           suni_pm7345->suni_e3_frm_fram_options = 0x4;
903           suni_pm7345->suni_e3_frm_maint_options = 0x20;
904           suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d;
905           suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30;
906           suni_pm7345->suni_e3_tran_stat_diag_options = 0x0;
907           suni_pm7345->suni_e3_tran_fram_options = 0x1;
908           suni_pm7345->suni_config = SUNI_PM7345_E3ENBL;
909           suni_pm7345->suni_splr_cfg = 0x41;
910           suni_pm7345->suni_splt_cfg = 0x41;
911        } 
912        /*
913         * Enable RSOP loss of signal interrupt.
914         */
915        suni_pm7345->suni_intr_enbl = 0x28;
916      
917        /*
918         * Clear error counters
919         */
920        suni_pm7345->suni_id_reset = 0;
921     
922        /*
923         * Clear "PMCTST" in master test register.
924         */
925        suni_pm7345->suni_master_test = 0;
926     
927        suni_pm7345->suni_rxcp_ctrl = 0x2c;
928        suni_pm7345->suni_rxcp_fctrl = 0x81;
929      
930        suni_pm7345->suni_rxcp_idle_pat_h1 =
931        	suni_pm7345->suni_rxcp_idle_pat_h2 =
932        	suni_pm7345->suni_rxcp_idle_pat_h3 = 0;
933        suni_pm7345->suni_rxcp_idle_pat_h4 = 1;
934      
935        suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff;
936        suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff;
937        suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff;
938        suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe;
939      
940        suni_pm7345->suni_rxcp_cell_pat_h1 =
941        	suni_pm7345->suni_rxcp_cell_pat_h2 =
942        	suni_pm7345->suni_rxcp_cell_pat_h3 = 0;
943        suni_pm7345->suni_rxcp_cell_pat_h4 = 1;
944      
945        suni_pm7345->suni_rxcp_cell_mask_h1 =
946        	suni_pm7345->suni_rxcp_cell_mask_h2 =
947        	suni_pm7345->suni_rxcp_cell_mask_h3 =
948        	suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff;
949      
950        suni_pm7345->suni_txcp_ctrl = 0xa4;
951        suni_pm7345->suni_txcp_intr_en_sts = 0x10;
952        suni_pm7345->suni_txcp_idle_pat_h5 = 0x55;
953      
954        suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB |
955                                      SUNI_PM7345_CLB |
956                                      SUNI_PM7345_DLB |
957                                       SUNI_PM7345_PLB);
958     #ifdef __SNMP__
959        suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
960     #endif /* __SNMP__ */
961        return;
962     }
963     
964     
965     /***************************** IA_LIB END *****************************/
966         
967     /* pwang_test debug utility */
968     int tcnter = 0, rcnter = 0;
969     void xdump( u_char*  cp, int  length, char*  prefix )
970     {
971         int col, count;
972         u_char prntBuf[120];
973         u_char*  pBuf = prntBuf;
974         count = 0;
975         while(count < length){
976             pBuf += sprintf( pBuf, "%s", prefix );
977             for(col = 0;count + col < length && col < 16; col++){
978                 if (col != 0 && (col % 4) == 0)
979                     pBuf += sprintf( pBuf, " " );
980                 pBuf += sprintf( pBuf, "%02X ", cp[count + col] );
981             }
982             while(col++ < 16){      /* pad end of buffer with blanks */
983                 if ((col % 4) == 0)
984                     sprintf( pBuf, " " );
985                 pBuf += sprintf( pBuf, "   " );
986             }
987             pBuf += sprintf( pBuf, "  " );
988             for(col = 0;count + col < length && col < 16; col++){
989                 if (isprint((int)cp[count + col]))
990                     pBuf += sprintf( pBuf, "%c", cp[count + col] );
991                 else
992                     pBuf += sprintf( pBuf, "." );
993                     }
994             sprintf( pBuf, "\n" );
995             // SPrint(prntBuf);
996             printk(prntBuf);
997             count += col;
998             pBuf = prntBuf;
999         }
1000     
1001     }  /* close xdump(... */
1002     
1003       
1004     static struct atm_dev *ia_boards = NULL;  
1005       
1006     #define ACTUAL_RAM_BASE \
1007     	RAM_BASE*((iadev->mem)/(128 * 1024))  
1008     #define ACTUAL_SEG_RAM_BASE \
1009     	IPHASE5575_FRAG_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
1010     #define ACTUAL_REASS_RAM_BASE \
1011     	IPHASE5575_REASS_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
1012       
1013       
1014     /*-- some utilities and memory allocation stuff will come here -------------*/  
1015       
1016     void desc_dbg(IADEV *iadev) {
1017     
1018       u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr;
1019       u32 tmp, i;
1020       // regval = readl((u32)ia_cmds->maddr);
1021       tcq_wr_ptr =  readw(iadev->seg_reg+TCQ_WR_PTR);
1022       printk("B_tcq_wr = 0x%x desc = %d last desc = %d\n",
1023                          tcq_wr_ptr, readw(iadev->seg_ram+tcq_wr_ptr),
1024                          readw(iadev->seg_ram+tcq_wr_ptr-2));
1025       printk(" host_tcq_wr = 0x%x  host_tcq_rd = 0x%x \n",  iadev->host_tcq_wr, 
1026                        iadev->ffL.tcq_rd);
1027       tcq_st_ptr =  readw(iadev->seg_reg+TCQ_ST_ADR);
1028       tcq_ed_ptr =  readw(iadev->seg_reg+TCQ_ED_ADR);
1029       printk("tcq_st_ptr = 0x%x    tcq_ed_ptr = 0x%x \n", tcq_st_ptr, tcq_ed_ptr);
1030       i = 0;
1031       while (tcq_st_ptr != tcq_ed_ptr) {
1032           tmp = iadev->seg_ram+tcq_st_ptr;
1033           printk("TCQ slot %d desc = %d  Addr = 0x%x\n", i++, readw(tmp), tmp);
1034           tcq_st_ptr += 2;
1035       }
1036       for(i=0; i <iadev->num_tx_desc; i++)
1037           printk("Desc_tbl[%d] = %d \n", i, iadev->desc_tbl[i].timestamp);
1038     } 
1039       
1040       
1041     /*----------------------------- Recieving side stuff --------------------------*/  
1042      
1043     static void rx_excp_rcvd(struct atm_dev *dev)  
1044     {  
1045     #if 0 /* closing the receiving size will cause too many excp int */  
1046       IADEV *iadev;  
1047       u_short state;  
1048       u_short excpq_rd_ptr;  
1049       //u_short *ptr;  
1050       int vci, error = 1;  
1051       iadev = INPH_IA_DEV(dev);  
1052       state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
1053       while((state & EXCPQ_EMPTY) != EXCPQ_EMPTY)  
1054       { printk("state = %x \n", state); 
1055             excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_RD_PTR) & 0xffff;  
1056      printk("state = %x excpq_rd_ptr = %x \n", state, excpq_rd_ptr); 
1057             if (excpq_rd_ptr == *(u16*)(iadev->reass_reg + EXCP_Q_WR_PTR))
1058                 IF_ERR(printk("excpq_rd_ptr is wrong!!!\n");)
1059             // TODO: update exception stat
1060     	vci = readw(iadev->reass_ram+excpq_rd_ptr);  
1061     	error = readw(iadev->reass_ram+excpq_rd_ptr+2) & 0x0007;  
1062             // pwang_test
1063     	excpq_rd_ptr += 4;  
1064     	if (excpq_rd_ptr > (readw(iadev->reass_reg + EXCP_Q_ED_ADR)& 0xffff))  
1065      	    excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_ST_ADR)& 0xffff;
1066     	writew( excpq_rd_ptr, iadev->reass_reg + EXCP_Q_RD_PTR);  
1067             state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
1068       }  
1069     #endif
1070     }  
1071       
1072     static void free_desc(struct atm_dev *dev, int desc)  
1073     {  
1074     	IADEV *iadev;  
1075     	iadev = INPH_IA_DEV(dev);  
1076             writew(desc, iadev->reass_ram+iadev->rfL.fdq_wr); 
1077     	iadev->rfL.fdq_wr +=2;
1078     	if (iadev->rfL.fdq_wr > iadev->rfL.fdq_ed)
1079     		iadev->rfL.fdq_wr =  iadev->rfL.fdq_st;  
1080     	writew(iadev->rfL.fdq_wr, iadev->reass_reg+FREEQ_WR_PTR);  
1081     }  
1082       
1083       
1084     static int rx_pkt(struct atm_dev *dev)  
1085     {  
1086     	IADEV *iadev;  
1087     	struct atm_vcc *vcc;  
1088     	unsigned short status;  
1089     	struct rx_buf_desc *buf_desc_ptr;  
1090     	int desc;   
1091     	struct dle* wr_ptr;  
1092     	int len;  
1093     	struct sk_buff *skb;  
1094     	u_int buf_addr, dma_addr;  
1095     	iadev = INPH_IA_DEV(dev);  
1096     	if (iadev->rfL.pcq_rd == (readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff)) 
1097     	{  
1098        	    printk(KERN_ERR DEV_LABEL "(itf %d) Receive queue empty\n", dev->number);  
1099     	    return -EINVAL;  
1100     	}  
1101     	/* mask 1st 3 bits to get the actual descno. */  
1102     	desc = readw(iadev->reass_ram+iadev->rfL.pcq_rd) & 0x1fff;  
1103             IF_RX(printk("reass_ram = 0x%x iadev->rfL.pcq_rd = 0x%x desc = %d\n", 
1104                                         iadev->reass_ram, iadev->rfL.pcq_rd, desc);
1105                   printk(" pcq_wr_ptr = 0x%x\n",
1106                                    readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff);)
1107     	/* update the read pointer  - maybe we shud do this in the end*/  
1108     	if ( iadev->rfL.pcq_rd== iadev->rfL.pcq_ed) 
1109     		iadev->rfL.pcq_rd = iadev->rfL.pcq_st;  
1110     	else  
1111     		iadev->rfL.pcq_rd += 2;
1112     	writew(iadev->rfL.pcq_rd, iadev->reass_reg+PCQ_RD_PTR);  
1113       
1114     	/* get the buffer desc entry.  
1115     		update stuff. - doesn't seem to be any update necessary  
1116     	*/  
1117     	buf_desc_ptr = (struct rx_buf_desc *)iadev->RX_DESC_BASE_ADDR;
1118     	/* make the ptr point to the corresponding buffer desc entry */  
1119     	buf_desc_ptr += desc;	  
1120             if (!desc || (desc > iadev->num_rx_desc) || 
1121                           ((buf_desc_ptr->vc_index & 0xffff) > iadev->num_vc)) { 
1122                 free_desc(dev, desc);
1123                 IF_ERR(printk("IA: bad descriptor desc = %d \n", desc);)
1124                 return -1;
1125             }
1126     	vcc = iadev->rx_open[buf_desc_ptr->vc_index & 0xffff];  
1127     	if (!vcc)  
1128     	{      
1129                     free_desc(dev, desc); 
1130     		printk("IA: null vcc, drop PDU\n");  
1131     		return -1;  
1132     	}  
1133     	  
1134       
1135     	/* might want to check the status bits for errors */  
1136     	status = (u_short) (buf_desc_ptr->desc_mode);  
1137     	if (status & (RX_CER | RX_PTE | RX_OFL))  
1138     	{  
1139                     atomic_inc(&vcc->stats->rx_err);
1140     		IF_ERR(printk("IA: bad packet, dropping it");)  
1141                     if (status & RX_CER) { 
1142                         IF_ERR(printk(" cause: packet CRC error\n");)
1143                     }
1144                     else if (status & RX_PTE) {
1145                         IF_ERR(printk(" cause: packet time out\n");)
1146                     }
1147                     else {
1148                         IF_ERR(printk(" cause: buffer over flow\n");)
1149                     }
1150     		goto out_free_desc;
1151     	}  
1152       
1153     	/*  
1154     		build DLE.	  
1155     	*/  
1156       
1157     	buf_addr = (buf_desc_ptr->buf_start_hi << 16) | buf_desc_ptr->buf_start_lo;  
1158     	dma_addr = (buf_desc_ptr->dma_start_hi << 16) | buf_desc_ptr->dma_start_lo;  
1159     	len = dma_addr - buf_addr;  
1160             if (len > iadev->rx_buf_sz) {
1161                printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
1162                atomic_inc(&vcc->stats->rx_err);
1163     	   goto out_free_desc;
1164             }
1165     		  
1166     #if LINUX_VERSION_CODE >= 0x20312
1167             if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) {
1168     #else
1169             if (atm_charge(vcc, atm_pdu2truesize(len))) {
1170     	   /* lets allocate an skb for now */  
1171     	   skb = alloc_skb(len, GFP_ATOMIC);  
1172     	   if (!skb)  
1173     	   {  
1174                   IF_ERR(printk("can't allocate memory for recv, drop pkt!\n");)  
1175                   atomic_inc(&vcc->stats->rx_drop);
1176                   atm_return(vcc, atm_pdu2truesize(len));
1177     	      goto out_free_desc;
1178     	   }  
1179             }
1180             else {
1181                IF_EVENT(printk("IA: Rx over the rx_quota %ld\n", vcc->rx_quota);)
1182     #endif
1183                if (vcc->vci < 32)
1184                   printk("Drop control packets\n");
1185     	      goto out_free_desc;
1186             }
1187     	skb_put(skb,len);  
1188             // pwang_test
1189             ATM_SKB(skb)->vcc = vcc;
1190             ATM_SKB(skb)->iovcnt = 0;
1191             ATM_DESC(skb) = desc;        
1192     	skb_queue_tail(&iadev->rx_dma_q, skb);  
1193     
1194     	/* Build the DLE structure */  
1195     	wr_ptr = iadev->rx_dle_q.write;  
1196     	wr_ptr->sys_pkt_addr = virt_to_bus(skb->data);	  
1197     	wr_ptr->local_pkt_addr = buf_addr;  
1198     	wr_ptr->bytes = len;	/* We don't know this do we ?? */  
1199     	wr_ptr->mode = DMA_INT_ENABLE;  
1200       
1201     	/* shud take care of wrap around here too. */  
1202             if(++wr_ptr == iadev->rx_dle_q.end)
1203                  wr_ptr = iadev->rx_dle_q.start;
1204     	iadev->rx_dle_q.write = wr_ptr;  
1205     	udelay(1);  
1206     	/* Increment transaction counter */  
1207     	writel(1, iadev->dma+IPHASE5575_RX_COUNTER);   
1208     out:	return 0;  
1209     out_free_desc:
1210             free_desc(dev, desc);
1211             goto out;
1212     }  
1213       
1214     static void rx_intr(struct atm_dev *dev)  
1215     {  
1216       IADEV *iadev;  
1217       u_short status;  
1218       u_short state, i;  
1219       
1220       iadev = INPH_IA_DEV(dev);  
1221       status = readl(iadev->reass_reg+REASS_INTR_STATUS_REG) & 0xffff;  
1222       IF_EVENT(printk("rx_intr: status = 0x%x\n", status);)
1223       if (status & RX_PKT_RCVD)  
1224       {  
1225     	/* do something */  
1226     	/* Basically recvd an interrupt for receving a packet.  
1227     	A descriptor would have been written to the packet complete   
1228     	queue. Get all the descriptors and set up dma to move the   
1229     	packets till the packet complete queue is empty..  
1230     	*/  
1231     	state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
1232             IF_EVENT(printk("Rx intr status: RX_PKT_RCVD %08x\n", status);) 
1233     	while(!(state & PCQ_EMPTY))  
1234     	{  
1235                  rx_pkt(dev);  
1236     	     state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
1237     	}  
1238             iadev->rxing = 1;
1239       }  
1240       if (status & RX_FREEQ_EMPT)  
1241       {   
1242          if (iadev->rxing) {
1243             iadev->rx_tmp_cnt = iadev->rx_pkt_cnt;
1244             iadev->rx_tmp_jif = jiffies; 
1245             iadev->rxing = 0;
1246          } 
1247          else if (((jiffies - iadev->rx_tmp_jif) > 50) && 
1248                    ((iadev->rx_pkt_cnt - iadev->rx_tmp_cnt) == 0)) {
1249             for (i = 1; i <= iadev->num_rx_desc; i++)
1250                    free_desc(dev, i);
1251     printk("Test logic RUN!!!!\n");
1252             writew( ~(RX_FREEQ_EMPT|RX_EXCP_RCVD),iadev->reass_reg+REASS_MASK_REG);
1253             iadev->rxing = 1;
1254          }
1255          IF_EVENT(printk("Rx intr status: RX_FREEQ_EMPT %08x\n", status);)  
1256       }  
1257     
1258       if (status & RX_EXCP_RCVD)  
1259       {  
1260     	/* probably need to handle the exception queue also. */  
1261     	IF_EVENT(printk("Rx intr status: RX_EXCP_RCVD %08x\n", status);)  
1262     	rx_excp_rcvd(dev);  
1263       }  
1264     
1265     
1266       if (status & RX_RAW_RCVD)  
1267       {  
1268     	/* need to handle the raw incoming cells. This deepnds on   
1269     	whether we have programmed to receive the raw cells or not.  
1270     	Else ignore. */  
1271     	IF_EVENT(printk("Rx intr status:  RX_RAW_RCVD %08x\n", status);)  
1272       }  
1273     }  
1274       
1275       
1276     static void rx_dle_intr(struct atm_dev *dev)  
1277     {  
1278       IADEV *iadev;  
1279       struct atm_vcc *vcc;   
1280       struct sk_buff *skb;  
1281       int desc;  
1282       u_short state;   
1283       struct dle *dle, *cur_dle;  
1284       u_int dle_lp;  
1285       int len;
1286       iadev = INPH_IA_DEV(dev);  
1287      
1288       /* free all the dles done, that is just update our own dle read pointer   
1289     	- do we really need to do this. Think not. */  
1290       /* DMA is done, just get all the recevie buffers from the rx dma queue  
1291     	and push them up to the higher layer protocol. Also free the desc  
1292     	associated with the buffer. */  
1293       dle = iadev->rx_dle_q.read;  
1294       dle_lp = readl(iadev->dma+IPHASE5575_RX_LIST_ADDR) & (sizeof(struct dle)*DLE_ENTRIES - 1);  
1295       cur_dle = (struct dle*)(iadev->rx_dle_q.start + (dle_lp >> 4));  
1296       while(dle != cur_dle)  
1297       {  
1298           /* free the DMAed skb */  
1299           skb = skb_dequeue(&iadev->rx_dma_q);  
1300           if (!skb)  
1301              goto INCR_DLE;
1302           desc = ATM_DESC(skb);
1303           free_desc(dev, desc);  
1304                    
1305           if (!(len = skb->len))
1306           {  
1307               printk("rx_dle_intr: skb len 0\n");  
1308     	  dev_kfree_skb_any(skb);  
1309           }  
1310           else  
1311           {  
1312               struct cpcs_trailer *trailer;
1313               u_short length;
1314               struct ia_vcc *ia_vcc;
1315               /* no VCC related housekeeping done as yet. lets see */  
1316               vcc = ATM_SKB(skb)->vcc;
1317     	  if (!vcc) {
1318     	      printk("IA: null vcc\n");  
1319                   dev_kfree_skb_any(skb);
1320                   goto INCR_DLE;
1321               }
1322               ia_vcc = INPH_IA_VCC(vcc);
1323               if (ia_vcc == NULL)
1324               {
1325                  atomic_inc(&vcc->stats->rx_err);
1326                  dev_kfree_skb_any(skb);
1327     #if LINUX_VERSION_CODE >= 0x20312
1328                  atm_return(vcc, atm_guess_pdu2truesize(len));
1329     #else
1330                  atm_return(vcc, atm_pdu2truesize(len));
1331     #endif
1332                  goto INCR_DLE;
1333                }
1334               // get real pkt length  pwang_test
1335               trailer = (struct cpcs_trailer*)((u_char *)skb->data +
1336                                      skb->len - sizeof(*trailer));
1337               length =  swap(trailer->length);
1338               if ((length > iadev->rx_buf_sz) || (length > 
1339                                   (skb->len - sizeof(struct cpcs_trailer))))
1340               {
1341                  atomic_inc(&vcc->stats->rx_err);
1342                  IF_ERR(printk("rx_dle_intr: Bad  AAL5 trailer %d (skb len %d)", 
1343                                                                 length, skb->len);)
1344                  dev_kfree_skb_any(skb);
1345     #if LINUX_VERSION_CODE >= 0x20312
1346                  atm_return(vcc, atm_guess_pdu2truesize(len));
1347     #else
1348                  atm_return(vcc, atm_pdu2truesize(len));
1349     #endif 
1350                  goto INCR_DLE;
1351               }
1352               skb_trim(skb, length);
1353               
1354     	  /* Display the packet */  
1355     	  IF_RXPKT(printk("\nDmad Recvd data: len = %d \n", skb->len);  
1356               xdump(skb->data, skb->len, "RX: ");
1357               printk("\n");)
1358     
1359     	  IF_RX(printk("rx_dle_intr: skb push");)  
1360     	  vcc->push(vcc,skb);  
1361     	  atomic_inc(&vcc->stats->rx);
1362               iadev->rx_pkt_cnt++;
1363           }  
1364     INCR_DLE:
1365           if (++dle == iadev->rx_dle_q.end)  
1366         	  dle = iadev->rx_dle_q.start;  
1367       }  
1368       iadev->rx_dle_q.read = dle;  
1369       
1370       /* if the interrupts are masked because there were no free desc available,  
1371     		unmask them now. */ 
1372       if (!iadev->rxing) {
1373          state = readl(iadev->reass_reg + STATE_REG) & 0xffff;
1374          if (!(state & FREEQ_EMPTY)) {
1375             state = readl(iadev->reass_reg + REASS_MASK_REG) & 0xffff;
1376             writel(state & ~(RX_FREEQ_EMPT |/* RX_EXCP_RCVD |*/ RX_PKT_RCVD),
1377                                           iadev->reass_reg+REASS_MASK_REG);
1378             iadev->rxing++; 
1379          }
1380       }
1381     }  
1382       
1383       
1384     static int open_rx(struct atm_vcc *vcc)  
1385     {  
1386     	IADEV *iadev;  
1387     	u_short *vc_table;  
1388     	u_short *reass_ptr;  
1389     	IF_EVENT(printk("iadev: open_rx %d.%d\n", vcc->vpi, vcc->vci);)
1390     
1391     	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;    
1392     	iadev = INPH_IA_DEV(vcc->dev);  
1393             if (vcc->qos.rxtp.traffic_class == ATM_ABR) {  
1394                if (iadev->phy_type & FE_25MBIT_PHY) {
1395                    printk("IA:  ABR not support\n");
1396                    return -EINVAL; 
1397                }
1398             }
1399     	/* Make only this VCI in the vc table valid and let all   
1400     		others be invalid entries */  
1401     	vc_table = (u_short *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);  
1402     	vc_table += vcc->vci;  
1403     	/* mask the last 6 bits and OR it with 3 for 1K VCs */  
1404     
1405             *vc_table = vcc->vci << 6;
1406     	/* Also keep a list of open rx vcs so that we can attach them with  
1407     		incoming PDUs later. */  
1408     	if ((vcc->qos.rxtp.traffic_class == ATM_ABR) || 
1409                                     (vcc->qos.txtp.traffic_class == ATM_ABR))  
1410     	{  
1411                     srv_cls_param_t srv_p;
1412                     init_abr_vc(iadev, &srv_p);
1413                     ia_open_abr_vc(iadev, &srv_p, vcc, 0);
1414     	} 
1415            	else {  /* for UBR  later may need to add CBR logic */
1416             	reass_ptr = (u_short *)
1417                                (iadev->reass_ram+REASS_TABLE*iadev->memSize);
1418                	reass_ptr += vcc->vci;  
1419                	*reass_ptr = NO_AAL5_PKT;
1420            	}
1421     	
1422     	if (iadev->rx_open[vcc->vci])  
1423     		printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d already open\n",  
1424     			vcc->dev->number, vcc->vci);  
1425     	iadev->rx_open[vcc->vci] = vcc;  
1426     	return 0;  
1427     }  
1428       
1429     static int rx_init(struct atm_dev *dev)  
1430     {  
1431     	IADEV *iadev;  
1432     	struct rx_buf_desc *buf_desc_ptr;  
1433     	unsigned long rx_pkt_start = 0;  
1434     	u32 *odle_addr, *dle_addr;  
1435     	struct abr_vc_table  *abr_vc_table; 
1436     	u16 *vc_table;  
1437     	u16 *reass_table;  
1438             u16 *ptr16;
1439     	int i,j, vcsize_sel;  
1440     	u_short freeq_st_adr;  
1441     	u_short *freeq_start;  
1442       
1443     	iadev = INPH_IA_DEV(dev);  
1444       //    spin_lock_init(&iadev->rx_lock); 
1445     	/* I need to initialize the DLEs somewhere. Lets see what I   
1446     		need to do for this, hmmm...  
1447     		- allocate memory for 256 DLEs. make sure that it starts  
1448     		on a 4k byte address boundary. Program the start address   
1449     		in Receive List address register.  ..... to do for TX also  
1450     	   To make sure that it is a 4k byte boundary - allocate 8k and find   
1451     		4k byte boundary within.  
1452     		( (addr + (4k-1)) & ~(4k-1) )  
1453     	*/   
1454       
1455     	/* allocate 8k bytes */  
1456     	odle_addr = kmalloc(2*sizeof(struct dle)*DLE_ENTRIES, GFP_KERNEL);  
1457     	if (!odle_addr)  
1458     	{  
1459     		printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");  
1460     		return -ENOMEM;
1461     	}  
1462     	/* find 4k byte boundary within the 8k allocated */  
1463     	dle_addr = (u32*)( ((u32)odle_addr+(4096-1)) & ~(4096-1) );  
1464     	iadev->rx_dle_q.start = (struct dle*)dle_addr;  
1465     	iadev->rx_dle_q.read = iadev->rx_dle_q.start;  
1466     	iadev->rx_dle_q.write = iadev->rx_dle_q.start;  
1467     	iadev->rx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES);  
1468     	/* the end of the dle q points to the entry after the last  
1469     	DLE that can be used. */  
1470       
1471     	/* write the upper 20 bits of the start address to rx list address register */  
1472     	writel(virt_to_bus(dle_addr) & 0xfffff000, iadev->dma+IPHASE5575_RX_LIST_ADDR);  
1473     	IF_INIT(printk("Tx Dle list addr: 0x%08x value: 0x%0x\n", 
1474                           (u32)(iadev->dma+IPHASE5575_TX_LIST_ADDR), 
1475                           *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR));  
1476     	printk("Rx Dle list addr: 0x%08x value: 0x%0x\n", 
1477                           (u32)(iadev->dma+IPHASE5575_RX_LIST_ADDR), 
1478                           *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));)  
1479       
1480     	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
1481     	writew(0, iadev->reass_reg+MODE_REG);  
1482     	writew(RESET_REASS, iadev->reass_reg+REASS_COMMAND_REG);  
1483       
1484     	/* Receive side control memory map  
1485     	   -------------------------------  
1486       
1487     		Buffer descr	0x0000 (736 - 23K)  
1488     		VP Table	0x5c00 (256 - 512)  
1489     		Except q	0x5e00 (128 - 512)  
1490     		Free buffer q	0x6000 (1K - 2K)  
1491     		Packet comp q	0x6800 (1K - 2K)  
1492     		Reass Table	0x7000 (1K - 2K)  
1493     		VC Table	0x7800 (1K - 2K)  
1494     		ABR VC Table	0x8000 (1K - 32K)  
1495     	*/  
1496     	  
1497     	/* Base address for Buffer Descriptor Table */  
1498     	writew(RX_DESC_BASE >> 16, iadev->reass_reg+REASS_DESC_BASE);  
1499     	/* Set the buffer size register */  
1500     	writew(iadev->rx_buf_sz, iadev->reass_reg+BUF_SIZE);  
1501       
1502     	/* Initialize each entry in the Buffer Descriptor Table */  
1503             iadev->RX_DESC_BASE_ADDR = iadev->reass_ram+RX_DESC_BASE*iadev->memSize;
1504     	buf_desc_ptr =(struct rx_buf_desc *)iadev->RX_DESC_BASE_ADDR;
1505     	memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
1506     	buf_desc_ptr++;  
1507     	rx_pkt_start = iadev->rx_pkt_ram;  
1508     	for(i=1; i<=iadev->num_rx_desc; i++)  
1509     	{  
1510     		memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
1511     		buf_desc_ptr->buf_start_hi = rx_pkt_start >> 16;  
1512     		buf_desc_ptr->buf_start_lo = rx_pkt_start & 0x0000ffff;  
1513     		buf_desc_ptr++;		  
1514     		rx_pkt_start += iadev->rx_buf_sz;  
1515     	}  
1516     	IF_INIT(printk("Rx Buffer desc ptr: 0x%0x\n", (u32)(buf_desc_ptr));)  
1517             i = FREE_BUF_DESC_Q*iadev->memSize; 
1518     	writew(i >> 16,  iadev->reass_reg+REASS_QUEUE_BASE); 
1519             writew(i, iadev->reass_reg+FREEQ_ST_ADR);
1520             writew(i+iadev->num_rx_desc*sizeof(u_short), 
1521                                              iadev->reass_reg+FREEQ_ED_ADR);
1522             writew(i, iadev->reass_reg+FREEQ_RD_PTR);
1523             writew(i+iadev->num_rx_desc*sizeof(u_short), 
1524                                             iadev->reass_reg+FREEQ_WR_PTR);    
1525     	/* Fill the FREEQ with all the free descriptors. */  
1526     	freeq_st_adr = readw(iadev->reass_reg+FREEQ_ST_ADR);  
1527     	freeq_start = (u_short *)(iadev->reass_ram+freeq_st_adr);  
1528     	for(i=1; i<=iadev->num_rx_desc; i++)  
1529     	{  
1530     		*freeq_start = (u_short)i;  
1531     		freeq_start++;  
1532     	}  
1533     	IF_INIT(printk("freeq_start: 0x%0x\n", (u32)freeq_start);)  
1534             /* Packet Complete Queue */
1535             i = (PKT_COMP_Q * iadev->memSize) & 0xffff;
1536             writew(i, iadev->reass_reg+PCQ_ST_ADR);
1537             writew(i+iadev->num_vc*sizeof(u_short), iadev->reass_reg+PCQ_ED_ADR);
1538             writew(i, iadev->reass_reg+PCQ_RD_PTR);
1539             writew(i, iadev->reass_reg+PCQ_WR_PTR);
1540     
1541             /* Exception Queue */
1542             i = (EXCEPTION_Q * iadev->memSize) & 0xffff;
1543             writew(i, iadev->reass_reg+EXCP_Q_ST_ADR);
1544             writew(i + NUM_RX_EXCP * sizeof(RX_ERROR_Q), 
1545                                                  iadev->reass_reg+EXCP_Q_ED_ADR);
1546             writew(i, iadev->reass_reg+EXCP_Q_RD_PTR);
1547             writew(i, iadev->reass_reg+EXCP_Q_WR_PTR); 
1548      
1549         	/* Load local copy of FREEQ and PCQ ptrs */
1550             iadev->rfL.fdq_st = readw(iadev->reass_reg+FREEQ_ST_ADR) & 0xffff;
1551            	iadev->rfL.fdq_ed = readw(iadev->reass_reg+FREEQ_ED_ADR) & 0xffff ;
1552     	iadev->rfL.fdq_rd = readw(iadev->reass_reg+FREEQ_RD_PTR) & 0xffff;
1553     	iadev->rfL.fdq_wr = readw(iadev->reass_reg+FREEQ_WR_PTR) & 0xffff;
1554             iadev->rfL.pcq_st = readw(iadev->reass_reg+PCQ_ST_ADR) & 0xffff;
1555     	iadev->rfL.pcq_ed = readw(iadev->reass_reg+PCQ_ED_ADR) & 0xffff;
1556     	iadev->rfL.pcq_rd = readw(iadev->reass_reg+PCQ_RD_PTR) & 0xffff;
1557     	iadev->rfL.pcq_wr = readw(iadev->reass_reg+PCQ_WR_PTR) & 0xffff;
1558     	
1559             IF_INIT(printk("INIT:pcq_st:0x%x pcq_ed:0x%x pcq_rd:0x%x pcq_wr:0x%x", 
1560                   iadev->rfL.pcq_st, iadev->rfL.pcq_ed, iadev->rfL.pcq_rd, 
1561                   iadev->rfL.pcq_wr);)		  
1562     	/* just for check - no VP TBL */  
1563     	/* VP Table */  
1564     	/* writew(0x0b80, iadev->reass_reg+VP_LKUP_BASE); */  
1565     	/* initialize VP Table for invalid VPIs  
1566     		- I guess we can write all 1s or 0x000f in the entire memory  
1567     		  space or something similar.  
1568     	*/  
1569       
1570     	/* This seems to work and looks right to me too !!! */  
1571             i =  REASS_TABLE * iadev->memSize;
1572     	writew((i >> 3), iadev->reass_reg+REASS_TABLE_BASE);   
1573      	/* initialize Reassembly table to I don't know what ???? */  
1574     	reass_table = (u16 *)(iadev->reass_ram+i);  
1575             j = REASS_TABLE_SZ * iadev->memSize;
1576     	for(i=0; i < j; i++)  
1577     		*reass_table++ = NO_AAL5_PKT;  
1578            i = 8*1024;
1579            vcsize_sel =  0;
1580            while (i != iadev->num_vc) {
1581               i /= 2;
1582               vcsize_sel++;
1583            }
1584            i = RX_VC_TABLE * iadev->memSize;
1585            writew(((i>>3) & 0xfff8) | vcsize_sel, iadev->reass_reg+VC_LKUP_BASE);
1586            vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);  
1587             j = RX_VC_TABLE_SZ * iadev->memSize;
1588     	for(i = 0; i < j; i++)  
1589     	{  
1590     		/* shift the reassembly pointer by 3 + lower 3 bits of   
1591     		vc_lkup_base register (=3 for 1K VCs) and the last byte   
1592     		is those low 3 bits.   
1593     		Shall program this later.  
1594     		*/  
1595     		*vc_table = (i << 6) | 15;	/* for invalid VCI */  
1596     		vc_table++;  
1597     	}  
1598             /* ABR VC table */
1599             i =  ABR_VC_TABLE * iadev->memSize;
1600             writew(i >> 3, iadev->reass_reg+ABR_LKUP_BASE);
1601                        
1602             i = ABR_VC_TABLE * iadev->memSize;
1603     	abr_vc_table = (struct abr_vc_table *)(iadev->reass_ram+i);  
1604             j = REASS_TABLE_SZ * iadev->memSize;
1605             memset ((char*)abr_vc_table, 0, j * sizeof(*abr_vc_table));
1606         	for(i = 0; i < j; i++) {   		
1607     		abr_vc_table->rdf = 0x0003;
1608                  	abr_vc_table->air = 0x5eb1;
1609     	       	abr_vc_table++;   	
1610             }  
1611     
1612     	/* Initialize other registers */  
1613       
1614     	/* VP Filter Register set for VC Reassembly only */  
1615     	writew(0xff00, iadev->reass_reg+VP_FILTER);  
1616             writew(0, iadev->reass_reg+XTRA_RM_OFFSET);
1617     	writew(0x1,  iadev->reass_reg+PROTOCOL_ID);
1618     
1619     	/* Packet Timeout Count  related Registers : 
1620     	   Set packet timeout to occur in about 3 seconds
1621     	   Set Packet Aging Interval count register to overflow in about 4 us
1622      	*/  
1623             writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT );
1624             ptr16 = (u16*)j;
1625             i = ((u32)ptr16 >> 6) & 0xff;
1626     	ptr16  += j - 1;
1627     	i |=(((u32)ptr16 << 2) & 0xff00);
1628             writew(i, iadev->reass_reg+TMOUT_RANGE);
1629             /* initiate the desc_tble */
1630             for(i=0; i<iadev->num_tx_desc;i++)
1631                 iadev->desc_tbl[i].timestamp = 0;
1632     
1633     	/* to clear the interrupt status register - read it */  
1634     	readw(iadev->reass_reg+REASS_INTR_STATUS_REG);   
1635       
1636     	/* Mask Register - clear it */  
1637     	writew(~(RX_FREEQ_EMPT|RX_PKT_RCVD), iadev->reass_reg+REASS_MASK_REG);  
1638       
1639     	skb_queue_head_init(&iadev->rx_dma_q);  
1640     	iadev->rx_free_desc_qhead = NULL;   
1641     	iadev->rx_open = kmalloc(4*iadev->num_vc,GFP_KERNEL);
1642     	if (!iadev->rx_open)  
1643     	{  
1644     		printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n",
1645     		dev->number);  
1646     		kfree(odle_addr);
1647     		return -ENOMEM;  
1648     	}  
1649     	memset(iadev->rx_open, 0, 4*iadev->num_vc);  
1650             iadev->rxing = 1;
1651             iadev->rx_pkt_cnt = 0;
1652     	/* Mode Register */  
1653     	writew(R_ONLINE, iadev->reass_reg+MODE_REG);  
1654     	return 0;  
1655     }  
1656       
1657     
1658     /*  
1659     	The memory map suggested in appendix A and the coding for it.   
1660     	Keeping it around just in case we change our mind later.  
1661       
1662     		Buffer descr	0x0000 (128 - 4K)  
1663     		UBR sched	0x1000 (1K - 4K)  
1664     		UBR Wait q	0x2000 (1K - 4K)  
1665     		Commn queues	0x3000 Packet Ready, Trasmit comp(0x3100)  
1666     					(128 - 256) each  
1667     		extended VC	0x4000 (1K - 8K)  
1668     		ABR sched	0x6000	and ABR wait queue (1K - 2K) each  
1669     		CBR sched	0x7000 (as needed)  
1670     		VC table	0x8000 (1K - 32K)  
1671     */  
1672       
1673     static void tx_intr(struct atm_dev *dev)  
1674     {  
1675     	IADEV *iadev;  
1676     	unsigned short status;  
1677             unsigned long flags;
1678     
1679     	iadev = INPH_IA_DEV(dev);  
1680       
1681     	status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);  
1682             if (status & TRANSMIT_DONE){
1683     
1684                IF_EVENT(printk("Tansmit Done Intr logic run\n");)
1685                spin_lock_irqsave(&iadev->tx_lock, flags);
1686                ia_tx_poll(iadev);
1687                spin_unlock_irqrestore(&iadev->tx_lock, flags);
1688                writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
1689                if (iadev->close_pending)  
1690                    wake_up(&iadev->close_wait);
1691             }     	  
1692     	if (status & TCQ_NOT_EMPTY)  
1693     	{  
1694     	    IF_EVENT(printk("TCQ_NOT_EMPTY int received\n");)  
1695     	}  
1696     }  
1697       
1698     static void tx_dle_intr(struct atm_dev *dev)
1699     {
1700             IADEV *iadev;
1701             struct dle *dle, *cur_dle; 
1702             struct sk_buff *skb;
1703             struct atm_vcc *vcc;
1704             struct ia_vcc  *iavcc;
1705             u_int dle_lp;
1706             unsigned long flags;
1707     
1708             iadev = INPH_IA_DEV(dev);
1709             spin_lock_irqsave(&iadev->tx_lock, flags);   
1710             dle = iadev->tx_dle_q.read;
1711             dle_lp = readl(iadev->dma+IPHASE5575_TX_LIST_ADDR) & 
1712                                             (sizeof(struct dle)*DLE_ENTRIES - 1);
1713             cur_dle = (struct dle*)(iadev->tx_dle_q.start + (dle_lp >> 4));
1714             while (dle != cur_dle)
1715             {
1716                 /* free the DMAed skb */ 
1717                 skb = skb_dequeue(&iadev->tx_dma_q); 
1718                 if (!skb) break;
1719                 vcc = ATM_SKB(skb)->vcc;
1720                 if (!vcc) {
1721                       printk("tx_dle_intr: vcc is null\n");
1722     		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
1723                       dev_kfree_skb_any(skb);
1724     
1725                       return;
1726                 }
1727                 iavcc = INPH_IA_VCC(vcc);
1728                 if (!iavcc) {
1729                       printk("tx_dle_intr: iavcc is null\n");
1730     		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
1731                       dev_kfree_skb_any(skb);
1732                       return;
1733                 }
1734                 if (vcc->qos.txtp.pcr >= iadev->rate_limit) {
1735                    if ((vcc->pop) && (skb->len != 0))
1736                    {     
1737                      vcc->pop(vcc, skb);
1738                    } 
1739                    else {
1740                      dev_kfree_skb_any(skb);
1741                    }
1742                 }
1743                 else { /* Hold the rate-limited skb for flow control */
1744                    IA_SKB_STATE(skb) |= IA_DLED;
1745                    skb_queue_tail(&iavcc->txing_skb, skb);
1746                 }
1747                 IF_EVENT(printk("tx_dle_intr: enque skb = 0x%x \n", (u32)skb);)
1748                 if (++dle == iadev->tx_dle_q.end)
1749                      dle = iadev->tx_dle_q.start;
1750             }
1751             iadev->tx_dle_q.read = dle;
1752             spin_unlock_irqrestore(&iadev->tx_lock, flags);
1753     }
1754       
1755     static int open_tx(struct atm_vcc *vcc)  
1756     {  
1757     	struct ia_vcc *ia_vcc;  
1758     	IADEV *iadev;  
1759     	struct main_vc *vc;  
1760     	struct ext_vc *evc;  
1761             int ret;
1762     	IF_EVENT(printk("iadev: open_tx entered vcc->vci = %d\n", vcc->vci);)  
1763     	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;  
1764     	iadev = INPH_IA_DEV(vcc->dev);  
1765             
1766             if (iadev->phy_type & FE_25MBIT_PHY) {
1767                if (vcc->qos.txtp.traffic_class == ATM_ABR) {
1768                    printk("IA:  ABR not support\n");
1769                    return -EINVAL; 
1770                }
1771     	  if (vcc->qos.txtp.traffic_class == ATM_CBR) {
1772                    printk("IA:  CBR not support\n");
1773                    return -EINVAL; 
1774               }
1775             }
1776             ia_vcc =  INPH_IA_VCC(vcc);
1777             memset((caddr_t)ia_vcc, 0, sizeof(*ia_vcc));
1778             if (vcc->qos.txtp.max_sdu > 
1779                              (iadev->tx_buf_sz - sizeof(struct cpcs_trailer))){
1780                printk("IA:  SDU size over the configured SDU size %d\n",
1781                                                               iadev->tx_buf_sz);
1782                kfree(ia_vcc);
1783                return -EINVAL; 
1784             }
1785     	ia_vcc->vc_desc_cnt = 0;
1786             ia_vcc->txing = 1;
1787     
1788             /* find pcr */
1789             if (vcc->qos.txtp.max_pcr == ATM_MAX_PCR) 
1790                vcc->qos.txtp.pcr = iadev->LineRate;
1791             else if ((vcc->qos.txtp.max_pcr == 0)&&( vcc->qos.txtp.pcr <= 0))
1792                vcc->qos.txtp.pcr = iadev->LineRate;
1793             else if ((vcc->qos.txtp.max_pcr > vcc->qos.txtp.pcr) && (vcc->qos.txtp.max_pcr> 0)) 
1794                vcc->qos.txtp.pcr = vcc->qos.txtp.max_pcr;
1795             if (vcc->qos.txtp.pcr > iadev->LineRate)
1796                  vcc->qos.txtp.pcr = iadev->LineRate;
1797             ia_vcc->pcr = vcc->qos.txtp.pcr;
1798     
1799             if (ia_vcc->pcr > (iadev->LineRate / 6) ) ia_vcc->ltimeout = HZ / 10;
1800             else if (ia_vcc->pcr > (iadev->LineRate / 130)) ia_vcc->ltimeout = HZ;
1801             else if (ia_vcc->pcr <= 170) ia_vcc->ltimeout = 16 * HZ;
1802             else ia_vcc->ltimeout = 2700 * HZ  / ia_vcc->pcr;
1803             if (ia_vcc->pcr < iadev->rate_limit)
1804                skb_queue_head_init (&ia_vcc->txing_skb);
1805             if (ia_vcc->pcr < iadev->rate_limit) {
1806                if (vcc->qos.txtp.max_sdu != 0) {
1807                    if (ia_vcc->pcr > 60000)
1808                       vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 5;
1809                    else if (ia_vcc->pcr > 2000)
1810                       vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 4;
1811                    else
1812                      vcc->sk->sndbuf = 3*vcc->qos.txtp.max_sdu;
1813                }
1814                else
1815                  vcc->sk->sndbuf = 24576;
1816             }
1817                
1818     	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
1819     	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
1820     	vc += vcc->vci;  
1821     	evc += vcc->vci;  
1822     	memset((caddr_t)vc, 0, sizeof(*vc));  
1823     	memset((caddr_t)evc, 0, sizeof(*evc));  
1824     	  
1825     	/* store the most significant 4 bits of vci as the last 4 bits   
1826     		of first part of atm header.  
1827     	   store the last 12 bits of vci as first 12 bits of the second  
1828     		part of the atm header.  
1829     	*/  
1830     	evc->atm_hdr1 = (vcc->vci >> 12) & 0x000f;  
1831     	evc->atm_hdr2 = (vcc->vci & 0x0fff) << 4;  
1832      
1833     	/* check the following for different traffic classes */  
1834     	if (vcc->qos.txtp.traffic_class == ATM_UBR)  
1835     	{  
1836     		vc->type = UBR;  
1837                     vc->status = CRC_APPEND;
1838     		vc->acr = cellrate_to_float(iadev->LineRate);  
1839                     if (vcc->qos.txtp.pcr > 0) 
1840                        vc->acr = cellrate_to_float(vcc->qos.txtp.pcr);  
1841                     IF_UBR(printk("UBR: txtp.pcr = 0x%x f_rate = 0x%x\n", 
1842                                                  vcc->qos.txtp.max_pcr,vc->acr);)
1843     	}  
1844     	else if (vcc->qos.txtp.traffic_class == ATM_ABR)  
1845     	{       srv_cls_param_t srv_p;
1846     		IF_ABR(printk("Tx ABR VCC\n");)  
1847                     init_abr_vc(iadev, &srv_p);
1848                     if (vcc->qos.txtp.pcr > 0) 
1849                        srv_p.pcr = vcc->qos.txtp.pcr;
1850                     if (vcc->qos.txtp.min_pcr > 0) {
1851                        int tmpsum = iadev->sum_mcr+iadev->sum_cbr+vcc->qos.txtp.min_pcr;
1852                        if (tmpsum > iadev->LineRate)
1853                            return -EBUSY;
1854                        srv_p.mcr = vcc->qos.txtp.min_pcr;
1855                        iadev->sum_mcr += vcc->qos.txtp.min_pcr;
1856                     } 
1857                     else srv_p.mcr = 0;
1858                     if (vcc->qos.txtp.icr)
1859                        srv_p.icr = vcc->qos.txtp.icr;
1860                     if (vcc->qos.txtp.tbe)
1861                        srv_p.tbe = vcc->qos.txtp.tbe;
1862                     if (vcc->qos.txtp.frtt)
1863                        srv_p.frtt = vcc->qos.txtp.frtt;
1864                     if (vcc->qos.txtp.rif)
1865                        srv_p.rif = vcc->qos.txtp.rif;
1866                     if (vcc->qos.txtp.rdf)
1867                        srv_p.rdf = vcc->qos.txtp.rdf;
1868                     if (vcc->qos.txtp.nrm_pres)
1869                        srv_p.nrm = vcc->qos.txtp.nrm;
1870                     if (vcc->qos.txtp.trm_pres)
1871                        srv_p.trm = vcc->qos.txtp.trm;
1872                     if (vcc->qos.txtp.adtf_pres)
1873                        srv_p.adtf = vcc->qos.txtp.adtf;
1874                     if (vcc->qos.txtp.cdf_pres)
1875                        srv_p.cdf = vcc->qos.txtp.cdf;    
1876                     if (srv_p.icr > srv_p.pcr)
1877                        srv_p.icr = srv_p.pcr;    
1878                     IF_ABR(printk("ABR:vcc->qos.txtp.max_pcr = %d  mcr = %d\n", 
1879                                                           srv_p.pcr, srv_p.mcr);)
1880     		ia_open_abr_vc(iadev, &srv_p, vcc, 1);
1881     	} else if (vcc->qos.txtp.traffic_class == ATM_CBR) {
1882                     if (iadev->phy_type & FE_25MBIT_PHY) {
1883                         printk("IA:  CBR not support\n");
1884                         return -EINVAL; 
1885                     }
1886                     if (vcc->qos.txtp.max_pcr > iadev->LineRate) {
1887                        IF_CBR(printk("PCR is not availble\n");)
1888                        return -1;
1889                     }
1890                     vc->type = CBR;
1891                     vc->status = CRC_APPEND;
1892                     if ((ret = ia_cbr_setup (iadev, vcc)) < 0) {     
1893                         return ret;
1894                     }
1895            } 
1896     	else  
1897                printk("iadev:  Non UBR, ABR and CBR traffic not supportedn"); 
1898             
1899             iadev->testTable[vcc->vci]->vc_status |= VC_ACTIVE;
1900     	IF_EVENT(printk("ia open_tx returning \n");)  
1901     	return 0;  
1902     }  
1903       
1904       
1905     static int tx_init(struct atm_dev *dev)  
1906     {  
1907     	IADEV *iadev;  
1908     	struct tx_buf_desc *buf_desc_ptr;
1909     	unsigned int tx_pkt_start;  
1910     	u32 *dle_addr;  
1911     	int i;  
1912     	u_short tcq_st_adr;  
1913     	u_short *tcq_start;  
1914     	u_short prq_st_adr;  
1915     	u_short *prq_start;  
1916     	struct main_vc *vc;  
1917     	struct ext_vc *evc;   
1918             u_short tmp16;
1919             u32 vcsize_sel;
1920      
1921     	iadev = INPH_IA_DEV(dev);  
1922             spin_lock_init(&iadev->tx_lock);
1923      
1924     	IF_INIT(printk("Tx MASK REG: 0x%0x\n", 
1925                                     readw(iadev->seg_reg+SEG_MASK_REG));)  
1926     	/*---------- Initializing Transmit DLEs ----------*/  
1927     	/* allocating 8k memory for transmit DLEs */  
1928     	dle_addr = kmalloc(2*sizeof(struct dle)*DLE_ENTRIES, GFP_KERNEL);  
1929     	if (!dle_addr)  
1930     	{  
1931     		printk(KERN_ERR DEV_LABEL "can't allocate TX DLEs\n");  
1932     		return -ENOMEM;
1933     	}  
1934       
1935     	/* find 4k byte boundary within the 8k allocated */  
1936     	dle_addr = (u32*)(((u32)dle_addr+(4096-1)) & ~(4096-1));  
1937     	iadev->tx_dle_q.start = (struct dle*)dle_addr;  
1938     	iadev->tx_dle_q.read = iadev->tx_dle_q.start;  
1939     	iadev->tx_dle_q.write = iadev->tx_dle_q.start;  
1940     	iadev->tx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES);  
1941     
1942     	/* write the upper 20 bits of the start address to tx list address register */  
1943     	writel(virt_to_bus(dle_addr) & 0xfffff000, iadev->dma+IPHASE5575_TX_LIST_ADDR);  
1944     	writew(0xffff, iadev->seg_reg+SEG_MASK_REG);  
1945     	writew(0, iadev->seg_reg+MODE_REG_0);  
1946     	writew(RESET_SEG, iadev->seg_reg+SEG_COMMAND_REG);  
1947             iadev->MAIN_VC_TABLE_ADDR = iadev->seg_ram+MAIN_VC_TABLE*iadev->memSize;
1948             iadev->EXT_VC_TABLE_ADDR = iadev->seg_ram+EXT_VC_TABLE*iadev->memSize;
1949             iadev->ABR_SCHED_TABLE_ADDR=iadev->seg_ram+ABR_SCHED_TABLE*iadev->memSize;
1950       
1951     	/*  
1952     	   Transmit side control memory map  
1953     	   --------------------------------    
1954     	 Buffer descr 	0x0000 (128 - 4K)  
1955     	 Commn queues	0x1000	Transmit comp, Packet ready(0x1400)   
1956     					(512 - 1K) each  
1957     					TCQ - 4K, PRQ - 5K  
1958     	 CBR Table 	0x1800 (as needed) - 6K  
1959     	 UBR Table	0x3000 (1K - 4K) - 12K  
1960     	 UBR Wait queue	0x4000 (1K - 4K) - 16K  
1961     	 ABR sched	0x5000	and ABR wait queue (1K - 2K) each  
1962     				ABR Tbl - 20K, ABR Wq - 22K   
1963     	 extended VC	0x6000 (1K - 8K) - 24K  
1964     	 VC Table	0x8000 (1K - 32K) - 32K  
1965     	  
1966     	Between 0x2000 (8K) and 0x3000 (12K) there is 4K space left for VBR Tbl  
1967     	and Wait q, which can be allotted later.  
1968     	*/  
1969          
1970     	/* Buffer Descriptor Table Base address */  
1971     	writew(TX_DESC_BASE, iadev->seg_reg+SEG_DESC_BASE);  
1972       
1973     	/* initialize each entry in the buffer descriptor table */  
1974     	buf_desc_ptr =(struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE);  
1975     	memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
1976     	buf_desc_ptr++;  
1977     	tx_pkt_start = TX_PACKET_RAM;  
1978     	for(i=1; i<=iadev->num_tx_desc; i++)  
1979     	{  
1980     		memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
1981     		buf_desc_ptr->desc_mode = AAL5;  
1982     		buf_desc_ptr->buf_start_hi = tx_pkt_start >> 16;  
1983     		buf_desc_ptr->buf_start_lo = tx_pkt_start & 0x0000ffff;  
1984     		buf_desc_ptr++;		  
1985     		tx_pkt_start += iadev->tx_buf_sz;  
1986     	}  
1987             iadev->tx_buf = kmalloc(iadev->num_tx_desc*sizeof(caddr_t), GFP_KERNEL);
1988             if (!iadev->tx_buf) {
1989                 printk(KERN_ERR DEV_LABEL " couldn't get mem\n");
1990                 return -EAGAIN;
1991             }
1992            	for (i= 0; i< iadev->num_tx_desc; i++)
1993            	{
1994      
1995            	    iadev->tx_buf[i] = kmalloc(sizeof(struct cpcs_trailer),
1996                                                                GFP_KERNEL|GFP_DMA);
1997                 if(!iadev->tx_buf[i]) {                
1998     		printk(KERN_ERR DEV_LABEL " couldn't get freepage\n"); 
1999              	return -EAGAIN;
2000                 }
2001             }
2002             iadev->desc_tbl = kmalloc(iadev->num_tx_desc *
2003                                        sizeof(struct desc_tbl_t), GFP_KERNEL);
2004       
2005     	/* Communication Queues base address */  
2006             i = TX_COMP_Q * iadev->memSize;
2007     	writew(i >> 16, iadev->seg_reg+SEG_QUEUE_BASE);  
2008       
2009     	/* Transmit Complete Queue */  
2010     	writew(i, iadev->seg_reg+TCQ_ST_ADR);  
2011     	writew(i, iadev->seg_reg+TCQ_RD_PTR);  
2012     	writew(i+iadev->num_tx_desc*sizeof(u_short),iadev->seg_reg+TCQ_WR_PTR); 
2013     	iadev->host_tcq_wr = i + iadev->num_tx_desc*sizeof(u_short);
2014             writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
2015                                                   iadev->seg_reg+TCQ_ED_ADR); 
2016     	/* Fill the TCQ with all the free descriptors. */  
2017     	tcq_st_adr = readw(iadev->seg_reg+TCQ_ST_ADR);  
2018     	tcq_start = (u_short *)(iadev->seg_ram+tcq_st_adr);  
2019     	for(i=1; i<=iadev->num_tx_desc; i++)  
2020     	{  
2021     		*tcq_start = (u_short)i;  
2022     		tcq_start++;  
2023     	}  
2024       
2025     	/* Packet Ready Queue */  
2026             i = PKT_RDY_Q * iadev->memSize; 
2027     	writew(i, iadev->seg_reg+PRQ_ST_ADR);  
2028     	writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
2029                                                   iadev->seg_reg+PRQ_ED_ADR);
2030     	writew(i, iadev->seg_reg+PRQ_RD_PTR);  
2031     	writew(i, iadev->seg_reg+PRQ_WR_PTR);  
2032     	 
2033             /* Load local copy of PRQ and TCQ ptrs */
2034             iadev->ffL.prq_st = readw(iadev->seg_reg+PRQ_ST_ADR) & 0xffff;
2035     	iadev->ffL.prq_ed = readw(iadev->seg_reg+PRQ_ED_ADR) & 0xffff;
2036      	iadev->ffL.prq_wr = readw(iadev->seg_reg+PRQ_WR_PTR) & 0xffff;
2037     
2038     	iadev->ffL.tcq_st = readw(iadev->seg_reg+TCQ_ST_ADR) & 0xffff;
2039     	iadev->ffL.tcq_ed = readw(iadev->seg_reg+TCQ_ED_ADR) & 0xffff;
2040     	iadev->ffL.tcq_rd = readw(iadev->seg_reg+TCQ_RD_PTR) & 0xffff;
2041     
2042     	/* Just for safety initializing the queue to have desc 1 always */  
2043     	/* Fill the PRQ with all the free descriptors. */  
2044     	prq_st_adr = readw(iadev->seg_reg+PRQ_ST_ADR);  
2045     	prq_start = (u_short *)(iadev->seg_ram+prq_st_adr);  
2046     	for(i=1; i<=iadev->num_tx_desc; i++)  
2047     	{  
2048     		*prq_start = (u_short)0;	/* desc 1 in all entries */  
2049     		prq_start++;  
2050     	}  
2051     	/* CBR Table */  
2052             IF_INIT(printk("Start CBR Init\n");)
2053     #if 1  /* for 1K VC board, CBR_PTR_BASE is 0 */
2054             writew(0,iadev->seg_reg+CBR_PTR_BASE);
2055     #else /* Charlie's logic is wrong ? */
2056             tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize)>>17;
2057             IF_INIT(printk("cbr_ptr_base = 0x%x ", tmp16);)
2058             writew(tmp16,iadev->seg_reg+CBR_PTR_BASE);
2059     #endif
2060     
2061             IF_INIT(printk("value in register = 0x%x\n",
2062                                        readw(iadev->seg_reg+CBR_PTR_BASE));)
2063             tmp16 = (CBR_SCHED_TABLE*iadev->memSize) >> 1;
2064             writew(tmp16, iadev->seg_reg+CBR_TAB_BEG);
2065             IF_INIT(printk("cbr_tab_beg = 0x%x in reg = 0x%x \n", tmp16,
2066                                             readw(iadev->seg_reg+CBR_TAB_BEG));)
2067             writew(tmp16, iadev->seg_reg+CBR_TAB_END+1); // CBR_PTR;
2068             tmp16 = (CBR_SCHED_TABLE*iadev->memSize + iadev->num_vc*6 - 2) >> 1;
2069             writew(tmp16, iadev->seg_reg+CBR_TAB_END);
2070             IF_INIT(printk("iadev->seg_reg = 0x%x CBR_PTR_BASE = 0x%x\n",
2071                    (u32)iadev->seg_reg, readw(iadev->seg_reg+CBR_PTR_BASE));)
2072             IF_INIT(printk("CBR_TAB_BEG = 0x%x, CBR_TAB_END = 0x%x, CBR_PTR = 0x%x\n",
2073               readw(iadev->seg_reg+CBR_TAB_BEG), readw(iadev->seg_reg+CBR_TAB_END),
2074               readw(iadev->seg_reg+CBR_TAB_END+1));)
2075             tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize);
2076     
2077             /* Initialize the CBR Schedualing Table */
2078             memset((caddr_t)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize), 
2079                                                               0, iadev->num_vc*6); 
2080             iadev->CbrRemEntries = iadev->CbrTotEntries = iadev->num_vc*3;
2081             iadev->CbrEntryPt = 0;
2082             iadev->Granularity = MAX_ATM_155 / iadev->CbrTotEntries;
2083             iadev->NumEnabledCBR = 0;
2084     
2085     	/* UBR scheduling Table and wait queue */  
2086     	/* initialize all bytes of UBR scheduler table and wait queue to 0   
2087     		- SCHEDSZ is 1K (# of entries).  
2088     		- UBR Table size is 4K  
2089     		- UBR wait queue is 4K  
2090     	   since the table and wait queues are contiguous, all the bytes   
2091     	   can be intialized by one memeset.  
2092     	*/  
2093             
2094             vcsize_sel = 0;
2095             i = 8*1024;
2096             while (i != iadev->num_vc) {
2097               i /= 2;
2098               vcsize_sel++;
2099             }
2100      
2101             i = MAIN_VC_TABLE * iadev->memSize;
2102             writew(vcsize_sel | ((i >> 8) & 0xfff8),iadev->seg_reg+VCT_BASE);
2103             i =  EXT_VC_TABLE * iadev->memSize;
2104             writew((i >> 8) & 0xfffe, iadev->seg_reg+VCTE_BASE);
2105             i = UBR_SCHED_TABLE * iadev->memSize;
2106             writew((i & 0xffff) >> 11,  iadev->seg_reg+UBR_SBPTR_BASE);
2107             i = UBR_WAIT_Q * iadev->memSize; 
2108             writew((i >> 7) & 0xffff,  iadev->seg_reg+UBRWQ_BASE);
2109      	memset((caddr_t)(iadev->seg_ram+UBR_SCHED_TABLE*iadev->memSize),
2110                                                            0, iadev->num_vc*8);
2111     	/* ABR scheduling Table(0x5000-0x57ff) and wait queue(0x5800-0x5fff)*/  
2112     	/* initialize all bytes of ABR scheduler table and wait queue to 0   
2113     		- SCHEDSZ is 1K (# of entries).  
2114     		- ABR Table size is 2K  
2115     		- ABR wait queue is 2K  
2116     	   since the table and wait queues are contiguous, all the bytes   
2117     	   can be intialized by one memeset.  
2118     	*/  
2119             i = ABR_SCHED_TABLE * iadev->memSize;
2120             writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE);
2121             i = ABR_WAIT_Q * iadev->memSize;
2122             writew((i >> 7) & 0xffff, iadev->seg_reg+ABRWQ_BASE);
2123      
2124             i = ABR_SCHED_TABLE*iadev->memSize;
2125     	memset((caddr_t)(iadev->seg_ram+i),  0, iadev->num_vc*4);
2126     	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
2127     	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
2128             iadev->testTable = kmalloc(sizeof(long)*iadev->num_vc, GFP_KERNEL); 
2129             if (!iadev->testTable) {
2130                printk("Get freepage  failed\n");
2131                return -EAGAIN; 
2132             }
2133     	for(i=0; i<iadev->num_vc; i++)  
2134     	{  
2135     		memset((caddr_t)vc, 0, sizeof(*vc));  
2136     		memset((caddr_t)evc, 0, sizeof(*evc));  
2137                     iadev->testTable[i] = kmalloc(sizeof(struct testTable_t),
2138     						GFP_KERNEL);
2139     		if (!iadev->testTable[i])
2140     			return -ENOMEM;
2141                   	iadev->testTable[i]->lastTime = 0;
2142      		iadev->testTable[i]->fract = 0;
2143                     iadev->testTable[i]->vc_status = VC_UBR;
2144     		vc++;  
2145     		evc++;  
2146     	}  
2147       
2148     	/* Other Initialization */  
2149     	  
2150     	/* Max Rate Register */  
2151             if (iadev->phy_type & FE_25MBIT_PHY) {
2152     	   writew(RATE25, iadev->seg_reg+MAXRATE);  
2153     	   writew((UBR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
2154             }
2155             else {
2156     	   writew(cellrate_to_float(iadev->LineRate),iadev->seg_reg+MAXRATE);
2157     	   writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
2158             }
2159     	/* Set Idle Header Reigisters to be sure */  
2160     	writew(0, iadev->seg_reg+IDLEHEADHI);  
2161     	writew(0, iadev->seg_reg+IDLEHEADLO);  
2162       
2163     	/* Program ABR UBR Priority Register  as  PRI_ABR_UBR_EQUAL */
2164             writew(0xaa00, iadev->seg_reg+ABRUBR_ARB); 
2165     
2166             iadev->close_pending = 0;
2167     #if LINUX_VERSION_CODE >= 0x20303
2168             init_waitqueue_head(&iadev->close_wait);
2169             init_waitqueue_head(&iadev->timeout_wait);
2170     #else
2171             iadev->close_wait = NULL;
2172             iadev->timeout_wait = NULL;
2173     #endif 
2174     	skb_queue_head_init(&iadev->tx_dma_q);  
2175     	ia_init_rtn_q(&iadev->tx_return_q);  
2176     
2177     	/* RM Cell Protocol ID and Message Type */  
2178     	writew(RM_TYPE_4_0, iadev->seg_reg+RM_TYPE);  
2179             skb_queue_head_init (&iadev->tx_backlog);
2180       
2181     	/* Mode Register 1 */  
2182     	writew(MODE_REG_1_VAL, iadev->seg_reg+MODE_REG_1);  
2183       
2184     	/* Mode Register 0 */  
2185     	writew(T_ONLINE, iadev->seg_reg+MODE_REG_0);  
2186       
2187     	/* Interrupt Status Register - read to clear */  
2188     	readw(iadev->seg_reg+SEG_INTR_STATUS_REG);  
2189       
2190     	/* Interrupt Mask Reg- don't mask TCQ_NOT_EMPTY interrupt generation */  
2191             writew(~(TRANSMIT_DONE | TCQ_NOT_EMPTY), iadev->seg_reg+SEG_MASK_REG);
2192             writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);  
2193             iadev->tx_pkt_cnt = 0;
2194             iadev->rate_limit = iadev->LineRate / 3;
2195       
2196     	return 0;  
2197     }   
2198        
2199     static void ia_int(int irq, void *dev_id, struct pt_regs *regs)  
2200     {  
2201        struct atm_dev *dev;  
2202        IADEV *iadev;  
2203        unsigned int status;  
2204     
2205        dev = dev_id;  
2206        iadev = INPH_IA_DEV(dev);  
2207        while( (status = readl(iadev->reg+IPHASE5575_BUS_STATUS_REG) & 0x7f))  
2208        { 
2209             IF_EVENT(printk("ia_int: status = 0x%x\n", status);) 
2210     	if (status & STAT_REASSINT)  
2211     	{  
2212     	   /* do something */  
2213     	   IF_EVENT(printk("REASSINT Bus status reg: %08x\n", status);) 
2214     	   rx_intr(dev);  
2215     	}  
2216     	if (status & STAT_DLERINT)  
2217     	{  
2218     	   /* Clear this bit by writing a 1 to it. */  
2219     	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT;
2220     	   rx_dle_intr(dev);  
2221     	}  
2222     	if (status & STAT_SEGINT)  
2223     	{  
2224     	   /* do something */ 
2225                IF_EVENT(printk("IA: tx_intr \n");) 
2226     	   tx_intr(dev);  
2227     	}  
2228     	if (status & STAT_DLETINT)  
2229     	{  
2230     	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT;  
2231     	   tx_dle_intr(dev);  
2232     	}  
2233     	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
2234     	{  
2235                if (status & STAT_FEINT) 
2236                    IaFrontEndIntr(iadev);
2237     	}  
2238        }  
2239     }  
2240     	  
2241     	  
2242     	  
2243     /*----------------------------- entries --------------------------------*/  
2244     static int get_esi(struct atm_dev *dev)  
2245     {  
2246     	IADEV *iadev;  
2247     	int i;  
2248     	u32 mac1;  
2249     	u16 mac2;  
2250     	  
2251     	iadev = INPH_IA_DEV(dev);  
2252     	mac1 = cpu_to_be32(le32_to_cpu(readl(  
2253     				iadev->reg+IPHASE5575_MAC1)));  
2254     	mac2 = cpu_to_be16(le16_to_cpu(readl(iadev->reg+IPHASE5575_MAC2)));  
2255     	IF_INIT(printk("ESI: 0x%08x%04x\n", mac1, mac2);)  
2256     	for (i=0; i<MAC1_LEN; i++)  
2257     		dev->esi[i] = mac1 >>(8*(MAC1_LEN-1-i));  
2258     	  
2259     	for (i=0; i<MAC2_LEN; i++)  
2260     		dev->esi[i+MAC1_LEN] = mac2 >>(8*(MAC2_LEN - 1 -i));  
2261     	return 0;  
2262     }  
2263     	  
2264     static int reset_sar(struct atm_dev *dev)  
2265     {  
2266     	IADEV *iadev;  
2267     	int i, error = 1;  
2268     	unsigned int pci[64];  
2269     	  
2270     	iadev = INPH_IA_DEV(dev);  
2271     	for(i=0; i<64; i++)  
2272     	  if ((error = pci_read_config_dword(iadev->pci,  
2273     				i*4, &pci[i])) != PCIBIOS_SUCCESSFUL)  
2274       	      return error;  
2275     	writel(0, iadev->reg+IPHASE5575_EXT_RESET);  
2276     	for(i=0; i<64; i++)  
2277     	  if ((error = pci_write_config_dword(iadev->pci,  
2278     					i*4, pci[i])) != PCIBIOS_SUCCESSFUL)  
2279     	    return error;  
2280     	udelay(5);  
2281     	return 0;  
2282     }  
2283     	  
2284     	  
2285     #if LINUX_VERSION_CODE >= 0x20312
2286     static int __init ia_init(struct atm_dev *dev)
2287     #else
2288     __initfunc(static int ia_init(struct atm_dev *dev))
2289     #endif  
2290     {  
2291     	IADEV *iadev;  
2292     	unsigned long real_base, base;  
2293     	unsigned short command;  
2294     	unsigned char revision;  
2295     	int error, i; 
2296     	  
2297     	/* The device has been identified and registered. Now we read   
2298     	   necessary configuration info like memory base address,   
2299     	   interrupt number etc */  
2300     	  
2301     	IF_INIT(printk(">ia_init\n");)  
2302     	dev->ci_range.vpi_bits = 0;  
2303     	dev->ci_range.vci_bits = NR_VCI_LD;  
2304     
2305     	iadev = INPH_IA_DEV(dev);  
2306     	real_base = pci_resource_start (iadev->pci, 0);
2307     	iadev->irq = iadev->pci->irq;
2308     		  
2309     	if ((error = pci_read_config_word(iadev->pci, PCI_COMMAND,&command))   
2310     		    || (error = pci_read_config_byte(iadev->pci,   
2311     				PCI_REVISION_ID,&revision)))   
2312     	{  
2313     		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%x\n",  
2314     				dev->number,error);  
2315     		return -EINVAL;  
2316     	}  
2317     	IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%lx,irq=%d\n",  
2318     			dev->number, revision, real_base, iadev->irq);)  
2319     	  
2320     	/* find mapping size of board */  
2321     	  
2322     	iadev->pci_map_size = pci_resource_len(iadev->pci, 0);
2323     
2324             if (iadev->pci_map_size == 0x100000){
2325               iadev->num_vc = 4096;
2326     	  dev->ci_range.vci_bits = NR_VCI_4K_LD;  
2327               iadev->memSize = 4;
2328             }
2329             else if (iadev->pci_map_size == 0x40000) {
2330               iadev->num_vc = 1024;
2331               iadev->memSize = 1;
2332             }
2333             else {
2334                printk("Unknown pci_map_size = 0x%x\n", iadev->pci_map_size);
2335                return -EINVAL;
2336             }
2337     	IF_INIT(printk (DEV_LABEL "map size: %i\n", iadev->pci_map_size);)  
2338     	  
2339     	/* enable bus mastering */
2340     	pci_set_master(iadev->pci);
2341     
2342     	/*  
2343     	 * Delay at least 1us before doing any mem accesses (how 'bout 10?)  
2344     	 */  
2345     	udelay(10);  
2346     	  
2347     	/* mapping the physical address to a virtual address in address space */  
2348     	base=(unsigned long)ioremap((unsigned long)real_base,iadev->pci_map_size);  /* ioremap is not resolved ??? */  
2349     	  
2350     	if (!base)  
2351     	{  
2352     		printk(DEV_LABEL " (itf %d): can't set up page mapping\n",  
2353     			    dev->number);  
2354     		return error;  
2355     	}  
2356     	IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=0x%lx,irq=%d\n",  
2357     			dev->number, revision, base, iadev->irq);)  
2358     	  
2359     	/* filling the iphase dev structure */  
2360     	iadev->mem = iadev->pci_map_size /2;  
2361     	iadev->base_diff = real_base - base;  
2362     	iadev->real_base = real_base;  
2363     	iadev->base = base;  
2364     		  
2365     	/* Bus Interface Control Registers */  
2366     	iadev->reg = (u32 *) (base + REG_BASE);  
2367     	/* Segmentation Control Registers */  
2368     	iadev->seg_reg = (u32 *) (base + SEG_BASE);  
2369     	/* Reassembly Control Registers */  
2370     	iadev->reass_reg = (u32 *) (base + REASS_BASE);  
2371     	/* Front end/ DMA control registers */  
2372     	iadev->phy = (u32 *) (base + PHY_BASE);  
2373     	iadev->dma = (u32 *) (base + PHY_BASE);  
2374     	/* RAM - Segmentation RAm and Reassembly RAM */  
2375     	iadev->ram = (u32 *) (base + ACTUAL_RAM_BASE);  
2376     	iadev->seg_ram =  (base + ACTUAL_SEG_RAM_BASE);  
2377     	iadev->reass_ram = (base + ACTUAL_REASS_RAM_BASE);  
2378       
2379     	/* lets print out the above */  
2380     	IF_INIT(printk("Base addrs: %08x %08x %08x \n %08x %08x %08x %08x\n", 
2381               (u32)iadev->reg,(u32)iadev->seg_reg,(u32)iadev->reass_reg, 
2382               (u32)iadev->phy, (u32)iadev->ram, (u32)iadev->seg_ram, 
2383               (u32)iadev->reass_ram);) 
2384     	  
2385     	/* lets try reading the MAC address */  
2386     	error = get_esi(dev);  
2387     	if (error) {
2388     	  iounmap((void *) iadev->base);
2389     	  return error;  
2390     	}
2391             printk("IA: ");
2392     	for (i=0; i < ESI_LEN; i++)  
2393                     printk("%s%02X",i ? "-" : "",dev->esi[i]);  
2394             printk("\n");  
2395       
2396             /* reset SAR */  
2397             if (reset_sar(dev)) {
2398     	   iounmap((void *) iadev->base);
2399                printk("IA: reset SAR fail, please try again\n");
2400                return 1;
2401             }
2402     	return 0;  
2403     }  
2404     
2405     static void ia_update_stats(IADEV *iadev) {
2406         if (!iadev->carrier_detect)
2407             return;
2408         iadev->rx_cell_cnt += readw(iadev->reass_reg+CELL_CTR0)&0xffff;
2409         iadev->rx_cell_cnt += (readw(iadev->reass_reg+CELL_CTR1) & 0xffff) << 16;
2410         iadev->drop_rxpkt +=  readw(iadev->reass_reg + DRP_PKT_CNTR ) & 0xffff;
2411         iadev->drop_rxcell += readw(iadev->reass_reg + ERR_CNTR) & 0xffff;
2412         iadev->tx_cell_cnt += readw(iadev->seg_reg + CELL_CTR_LO_AUTO)&0xffff;
2413         iadev->tx_cell_cnt += (readw(iadev->seg_reg+CELL_CTR_HIGH_AUTO)&0xffff)<<16;
2414         return;
2415     }
2416       
2417     static void ia_led_timer(unsigned long arg) {
2418      	unsigned long flags;
2419       	static u_char blinking[8] = {0, 0, 0, 0, 0, 0, 0, 0};
2420             u_char i;
2421             static u32 ctrl_reg; 
2422             for (i = 0; i < iadev_count; i++) {
2423                if (ia_dev[i]) {
2424     	      ctrl_reg = readl(ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
2425     	      if (blinking[i] == 0) {
2426     		 blinking[i]++;
2427                      ctrl_reg &= (~CTRL_LED);
2428                      writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
2429                      ia_update_stats(ia_dev[i]);
2430                   }
2431                   else {
2432     		 blinking[i] = 0;
2433     		 ctrl_reg |= CTRL_LED;
2434                      writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
2435                      spin_lock_irqsave(&ia_dev[i]->tx_lock, flags);
2436                      if (ia_dev[i]->close_pending)  
2437                         wake_up(&ia_dev[i]->close_wait);
2438                      ia_tx_poll(ia_dev[i]);
2439                      spin_unlock_irqrestore(&ia_dev[i]->tx_lock, flags);
2440                   }
2441                }
2442             }
2443     	mod_timer(&ia_timer, jiffies + HZ / 4);
2444      	return;
2445     }
2446     
2447     static void ia_phy_put(struct atm_dev *dev, unsigned char value,   
2448     	unsigned long addr)  
2449     {  
2450     	writel(value, INPH_IA_DEV(dev)->phy+addr);  
2451     }  
2452       
2453     static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr)  
2454     {  
2455     	return readl(INPH_IA_DEV(dev)->phy+addr);  
2456     }  
2457     
2458     #if LINUX_VERSION_CODE >= 0x20312
2459     static int __init ia_start(struct atm_dev *dev)
2460     #else
2461     __initfunc(static int ia_start(struct atm_dev *dev))
2462     #endif  
2463     {  
2464     	IADEV *iadev;  
2465     	int error = 1;  
2466     	unsigned char phy;  
2467     	u32 ctrl_reg;  
2468     	IF_EVENT(printk(">ia_start\n");)  
2469     	iadev = INPH_IA_DEV(dev);  
2470             if (request_irq(iadev->irq, &ia_int, SA_SHIRQ, DEV_LABEL, dev)) {  
2471                     printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",  
2472                         dev->number, iadev->irq);  
2473                     return -EAGAIN;  
2474             }  
2475             /* @@@ should release IRQ on error */  
2476     	/* enabling memory + master */  
2477             if ((error = pci_write_config_word(iadev->pci,   
2478     				PCI_COMMAND,   
2479     				PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER )))   
2480     	{  
2481                     printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"  
2482                         "master (0x%x)\n",dev->number, error);  
2483                     free_irq(iadev->irq, dev); 
2484                     return -EIO;  
2485             }  
2486     	udelay(10);  
2487       
2488     	/* Maybe we should reset the front end, initialize Bus Interface Control   
2489     		Registers and see. */  
2490       
2491     	IF_INIT(printk("Bus ctrl reg: %08x\n", 
2492                                 readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
2493     	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
2494     	ctrl_reg = (ctrl_reg & (CTRL_LED | CTRL_FE_RST))  
2495     			| CTRL_B8  
2496     			| CTRL_B16  
2497     			| CTRL_B32  
2498     			| CTRL_B48  
2499     			| CTRL_B64  
2500     			| CTRL_B128  
2501     			| CTRL_ERRMASK  
2502     			| CTRL_DLETMASK		/* shud be removed l8r */  
2503     			| CTRL_DLERMASK  
2504     			| CTRL_SEGMASK  
2505     			| CTRL_REASSMASK 	  
2506     			| CTRL_FEMASK  
2507     			| CTRL_CSPREEMPT;  
2508       
2509            writel(ctrl_reg, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
2510       
2511     	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
2512                                readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));  
2513     	   printk("Bus status reg after init: %08x\n", 
2514                                 readl(iadev->reg+IPHASE5575_BUS_STATUS_REG));)  
2515         
2516             ia_hw_type(iadev); 
2517     	error = tx_init(dev);  
2518     	if (error) {
2519                free_irq(iadev->irq, dev);  
2520                return error;
2521             }  
2522     	error = rx_init(dev);  
2523     	if (error) {
2524               free_irq(iadev->irq, dev); 
2525               return error;  
2526             }
2527       
2528     	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
2529            	writel(ctrl_reg | CTRL_FE_RST, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
2530     	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
2531                                    readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
2532             phy = 0; /* resolve compiler complaint */
2533             IF_INIT ( 
2534     	if ((phy=ia_phy_get(dev,0)) == 0x30)  
2535     		printk("IA: pm5346,rev.%d\n",phy&0x0f);  
2536     	else  
2537     		printk("IA: utopia,rev.%0x\n",phy);) 
2538     
2539             if (iadev->phy_type &  FE_25MBIT_PHY) {
2540                ia_mb25_init(iadev);
2541                return 0;
2542             }
2543             if (iadev->phy_type & (FE_DS3_PHY | FE_E3_PHY)) {
2544                ia_suni_pm7345_init(iadev);
2545                return 0;
2546             }
2547     
2548     	error = suni_init(dev);  
2549     	if (error) {
2550               free_irq(iadev->irq, dev); 
2551               return error;  
2552             }
2553     
2554             /* Enable interrupt on loss of signal SUNI_RSOP_CIE 0x10
2555                SUNI_RSOP_CIE_LOSE - 0x04
2556             */
2557             ia_phy_put(dev, ia_phy_get(dev,0x10) | 0x04, 0x10);         
2558     #ifndef MODULE
2559     	error = dev->phy->start(dev);  
2560     	if (error) {
2561               free_irq(iadev->irq, dev);
2562               return error;
2563             }   
2564     #endif
2565             /* Get iadev->carrier_detect status */
2566             IaFrontEndIntr(iadev);
2567     	return 0;  
2568     }  
2569       
2570     static void ia_close(struct atm_vcc *vcc)  
2571     {  
2572             u16 *vc_table;
2573             IADEV *iadev;
2574             struct ia_vcc *ia_vcc;
2575             struct sk_buff *skb = NULL;
2576             struct sk_buff_head tmp_tx_backlog, tmp_vcc_backlog;
2577             unsigned long closetime, flags;
2578             int ctimeout;
2579     
2580             iadev = INPH_IA_DEV(vcc->dev);
2581             ia_vcc = INPH_IA_VCC(vcc);
2582     	if (!ia_vcc) return;  
2583     
2584             IF_EVENT(printk("ia_close: ia_vcc->vc_desc_cnt = %d  vci = %d\n", 
2585                                                   ia_vcc->vc_desc_cnt,vcc->vci);)
2586     	clear_bit(ATM_VF_READY,&vcc->flags);
2587             skb_queue_head_init (&tmp_tx_backlog);
2588             skb_queue_head_init (&tmp_vcc_backlog); 
2589             if (vcc->qos.txtp.traffic_class != ATM_NONE) {
2590                iadev->close_pending++;
2591                sleep_on_timeout(&iadev->timeout_wait, 50);
2592                spin_lock_irqsave(&iadev->tx_lock, flags); 
2593                while((skb = skb_dequeue(&iadev->tx_backlog))) {
2594                   if (ATM_SKB(skb)->vcc == vcc){ 
2595                      if (vcc->pop) vcc->pop(vcc, skb);
2596                      else dev_kfree_skb_any(skb);
2597                   }
2598                   else 
2599                      skb_queue_tail(&tmp_tx_backlog, skb);
2600                } 
2601                while((skb = skb_dequeue(&tmp_tx_backlog))) 
2602                  skb_queue_tail(&iadev->tx_backlog, skb);
2603                IF_EVENT(printk("IA TX Done decs_cnt = %d\n", ia_vcc->vc_desc_cnt);) 
2604                closetime = jiffies;
2605                ctimeout = 300000 / ia_vcc->pcr;
2606                if (ctimeout == 0)
2607                   ctimeout = 1;
2608                while (ia_vcc->vc_desc_cnt > 0){
2609                   if ((jiffies - closetime) >= ctimeout) 
2610                      break;
2611                   spin_unlock_irqrestore(&iadev->tx_lock, flags);
2612                   sleep_on(&iadev->close_wait);
2613                   spin_lock_irqsave(&iadev->tx_lock, flags);
2614                }    
2615                iadev->close_pending--;
2616                iadev->testTable[vcc->vci]->lastTime = 0;
2617                iadev->testTable[vcc->vci]->fract = 0; 
2618                iadev->testTable[vcc->vci]->vc_status = VC_UBR; 
2619                if (vcc->qos.txtp.traffic_class == ATM_ABR) {
2620                   if (vcc->qos.txtp.min_pcr > 0)
2621                      iadev->sum_mcr -= vcc->qos.txtp.min_pcr;
2622                }
2623                if (vcc->qos.txtp.traffic_class == ATM_CBR) {
2624                   ia_vcc = INPH_IA_VCC(vcc); 
2625                   iadev->sum_mcr -= ia_vcc->NumCbrEntry*iadev->Granularity;
2626                   ia_cbrVc_close (vcc);
2627                }
2628                spin_unlock_irqrestore(&iadev->tx_lock, flags);
2629             }
2630             
2631             if (vcc->qos.rxtp.traffic_class != ATM_NONE) {   
2632                // reset reass table
2633                vc_table = (u16 *)(iadev->reass_ram+REASS_TABLE*iadev->memSize);
2634                vc_table += vcc->vci; 
2635                *vc_table = NO_AAL5_PKT;
2636                // reset vc table
2637                vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);
2638                vc_table += vcc->vci;
2639                *vc_table = (vcc->vci << 6) | 15;
2640                if (vcc->qos.rxtp.traffic_class == ATM_ABR) {
2641                   struct abr_vc_table *abr_vc_table = (struct abr_vc_table *)
2642                                     (iadev->reass_ram+ABR_VC_TABLE*iadev->memSize);
2643                   abr_vc_table +=  vcc->vci;
2644                   abr_vc_table->rdf = 0x0003;
2645                   abr_vc_table->air = 0x5eb1;
2646                }                                 
2647                // Drain the packets
2648                rx_dle_intr(vcc->dev); 
2649                iadev->rx_open[vcc->vci] = 0;
2650             }
2651     	kfree(INPH_IA_VCC(vcc));  
2652             ia_vcc = NULL;
2653             INPH_IA_VCC(vcc) = NULL;  
2654             clear_bit(ATM_VF_ADDR,&vcc->flags);
2655             return;        
2656     }  
2657       
2658     static int ia_open(struct atm_vcc *vcc, short vpi, int vci)  
2659     {  
2660     	IADEV *iadev;  
2661     	struct ia_vcc *ia_vcc;  
2662     	int error;  
2663     	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))  
2664     	{  
2665     		IF_EVENT(printk("ia: not partially allocated resources\n");)  
2666     		INPH_IA_VCC(vcc) = NULL;  
2667     	}  
2668     	iadev = INPH_IA_DEV(vcc->dev);  
2669     	error = atm_find_ci(vcc, &vpi, &vci);  
2670     	if (error)   
2671     	{  
2672     	    printk("iadev: atm_find_ci returned error %d\n", error);  
2673     	    return error;  
2674     	}  
2675     	vcc->vpi = vpi;  
2676     	vcc->vci = vci;  
2677     	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)  
2678     	{  
2679     		IF_EVENT(printk("iphase open: unspec part\n");)  
2680     		set_bit(ATM_VF_ADDR,&vcc->flags);
2681     	}  
2682     	if (vcc->qos.aal != ATM_AAL5)  
2683     		return -EINVAL;  
2684     	IF_EVENT(printk(DEV_LABEL "(itf %d): open %d.%d\n", 
2685                                      vcc->dev->number, vcc->vpi, vcc->vci);)  
2686       
2687     	/* Device dependent initialization */  
2688     	ia_vcc = kmalloc(sizeof(*ia_vcc), GFP_KERNEL);  
2689     	if (!ia_vcc) return -ENOMEM;  
2690     	INPH_IA_VCC(vcc) = ia_vcc;  
2691       
2692     	if ((error = open_rx(vcc)))  
2693     	{  
2694     		IF_EVENT(printk("iadev: error in open_rx, closing\n");)  
2695     		ia_close(vcc);  
2696     		return error;  
2697     	}  
2698       
2699     	if ((error = open_tx(vcc)))  
2700     	{  
2701     		IF_EVENT(printk("iadev: error in open_tx, closing\n");)  
2702     		ia_close(vcc);  
2703     		return error;  
2704     	}  
2705       
2706     	set_bit(ATM_VF_READY,&vcc->flags);
2707     
2708     #ifndef MODULE
2709             {
2710                static u8 first = 1; 
2711                if (first) {
2712                   ia_timer.expires = jiffies + 3*HZ;
2713                   add_timer(&ia_timer);
2714                   first = 0;
2715                }           
2716             }
2717     #endif
2718     	IF_EVENT(printk("ia open returning\n");)  
2719     	return 0;  
2720     }  
2721       
2722     static int ia_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)  
2723     {  
2724     	IF_EVENT(printk(">ia_change_qos\n");)  
2725     	return 0;  
2726     }  
2727       
2728     static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg)  
2729     {  
2730        IA_CMDBUF ia_cmds;
2731        IADEV *iadev;
2732        int i, board;
2733        u16 *tmps;
2734        IF_EVENT(printk(">ia_ioctl\n");)  
2735        if (cmd != IA_CMD) {
2736           if (!dev->phy->ioctl) return -EINVAL;
2737           return dev->phy->ioctl(dev,cmd,arg);
2738        }
2739        if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; 
2740        board = ia_cmds.status;
2741        if ((board < 0) || (board > iadev_count))
2742              board = 0;    
2743        iadev = ia_dev[board];
2744        switch (ia_cmds.cmd) {
2745        case MEMDUMP:
2746        {
2747     	switch (ia_cmds.sub_cmd) {
2748            	  case MEMDUMP_DEV:     
2749     	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
2750     	     if (copy_to_user(ia_cmds.buf, iadev, sizeof(IADEV)))
2751                     return -EFAULT;
2752                  ia_cmds.status = 0;
2753                  break;
2754               case MEMDUMP_SEGREG:
2755     	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
2756                  tmps = (u16 *)ia_cmds.buf;
2757                  for(i=0; i<0x80; i+=2, tmps++)
2758                     if(put_user(*(u16*)(iadev->seg_reg+i), tmps)) return -EFAULT;
2759                  ia_cmds.status = 0;
2760                  ia_cmds.len = 0x80;
2761                  break;
2762               case MEMDUMP_REASSREG:
2763     	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
2764                  tmps = (u16 *)ia_cmds.buf;
2765                  for(i=0; i<0x80; i+=2, tmps++)
2766                     if(put_user(*(u16*)(iadev->reass_reg+i), tmps)) return -EFAULT;
2767                  ia_cmds.status = 0;
2768                  ia_cmds.len = 0x80;
2769                  break;
2770               case MEMDUMP_FFL:
2771               {  
2772                  ia_regs_t       regs_local;
2773                  ffredn_t        *ffL = &regs_local.ffredn;
2774                  rfredn_t        *rfL = &regs_local.rfredn;
2775                          
2776     	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
2777                  /* Copy real rfred registers into the local copy */
2778      	     for (i=0; i<(sizeof (rfredn_t))/4; i++)
2779                     ((u_int *)rfL)[i] = ((u_int *)iadev->reass_reg)[i] & 0xffff;
2780                  	/* Copy real ffred registers into the local copy */
2781     	     for (i=0; i<(sizeof (ffredn_t))/4; i++)
2782                     ((u_int *)ffL)[i] = ((u_int *)iadev->seg_reg)[i] & 0xffff;
2783     
2784                  if (copy_to_user(ia_cmds.buf, &regs_local,sizeof(ia_regs_t)))
2785                     return -EFAULT;
2786                  printk("Board %d registers dumped\n", board);
2787                  ia_cmds.status = 0;                  
2788     	 }	
2789         	     break;        
2790              case READ_REG:
2791              {  
2792     	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
2793                  desc_dbg(iadev); 
2794                  ia_cmds.status = 0; 
2795              }
2796                  break;
2797              case 0x6:
2798              {  
2799                  ia_cmds.status = 0; 
2800                  printk("skb = 0x%lx\n", (long)skb_peek(&iadev->tx_backlog));
2801                  printk("rtn_q: 0x%lx\n",(long)ia_deque_rtn_q(&iadev->tx_return_q));
2802              }
2803                  break;
2804              case 0x8:
2805              {
2806                  struct k_sonet_stats *stats;
2807                  stats = &PRIV(_ia_dev[board])->sonet_stats;
2808                  printk("section_bip: %d\n", atomic_read(&stats->section_bip));
2809                  printk("line_bip   : %d\n", atomic_read(&stats->line_bip));
2810                  printk("path_bip   : %d\n", atomic_read(&stats->path_bip));
2811                  printk("line_febe  : %d\n", atomic_read(&stats->line_febe));
2812                  printk("path_febe  : %d\n", atomic_read(&stats->path_febe));
2813                  printk("corr_hcs   : %d\n", atomic_read(&stats->corr_hcs));
2814                  printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
2815                  printk("tx_cells   : %d\n", atomic_read(&stats->tx_cells));
2816                  printk("rx_cells   : %d\n", atomic_read(&stats->rx_cells));
2817              }
2818                 ia_cmds.status = 0;
2819                 break;
2820              case 0x9:
2821     	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
2822                 for (i = 1; i <= iadev->num_rx_desc; i++)
2823                    free_desc(_ia_dev[board], i);
2824                 writew( ~(RX_FREEQ_EMPT | RX_EXCP_RCVD), 
2825                                                 iadev->reass_reg+REASS_MASK_REG);
2826                 iadev->rxing = 1;
2827                 
2828                 ia_cmds.status = 0;
2829                 break;
2830     
2831              case 0xb:
2832     	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
2833                 IaFrontEndIntr(iadev);
2834                 break;
2835              case 0xa:
2836     	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
2837              {  
2838                  ia_cmds.status = 0; 
2839                  IADebugFlag = ia_cmds.maddr;
2840                  printk("New debug option loaded\n");
2841              }
2842                  break;
2843              default:
2844                  ia_cmds.status = 0;
2845                  break;
2846           }	
2847        }
2848           break;
2849        default:
2850           break;
2851     
2852        }	
2853        return 0;  
2854     }  
2855       
2856     static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,   
2857     	void *optval, int optlen)  
2858     {  
2859     	IF_EVENT(printk(">ia_getsockopt\n");)  
2860     	return -EINVAL;  
2861     }  
2862       
2863     static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,   
2864     	void *optval, int optlen)  
2865     {  
2866     	IF_EVENT(printk(">ia_setsockopt\n");)  
2867     	return -EINVAL;  
2868     }  
2869       
2870     static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
2871             IADEV *iadev;
2872             struct dle *wr_ptr;
2873             struct tx_buf_desc *buf_desc_ptr;
2874             int desc;
2875             int comp_code;
2876             unsigned int addr;
2877             int total_len, pad, last;
2878             struct cpcs_trailer *trailer;
2879             struct ia_vcc *iavcc;
2880             iadev = INPH_IA_DEV(vcc->dev);  
2881             iavcc = INPH_IA_VCC(vcc);
2882             if (!iavcc->txing) {
2883                printk("discard packet on closed VC\n");
2884                if (vcc->pop)
2885     		vcc->pop(vcc, skb);
2886                else
2887     		dev_kfree_skb_any(skb);
2888     	   return 0;
2889             }
2890     
2891             if (skb->len > iadev->tx_buf_sz - 8) {
2892                printk("Transmit size over tx buffer size\n");
2893                if (vcc->pop)
2894                      vcc->pop(vcc, skb);
2895                else
2896                      dev_kfree_skb_any(skb);
2897               return 0;
2898             }
2899             if ((u32)skb->data & 3) {
2900                printk("Misaligned SKB\n");
2901                if (vcc->pop)
2902                      vcc->pop(vcc, skb);
2903                else
2904                      dev_kfree_skb_any(skb);
2905                return 0;
2906             }       
2907     	/* Get a descriptor number from our free descriptor queue  
2908     	   We get the descr number from the TCQ now, since I am using  
2909     	   the TCQ as a free buffer queue. Initially TCQ will be   
2910     	   initialized with all the descriptors and is hence, full.  
2911     	*/
2912     	desc = get_desc (iadev, iavcc);
2913     	if (desc == 0xffff) 
2914     	    return 1;
2915     	comp_code = desc >> 13;  
2916     	desc &= 0x1fff;  
2917       
2918     	if ((desc == 0) || (desc > iadev->num_tx_desc))  
2919     	{  
2920     		IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) 
2921                     atomic_inc(&vcc->stats->tx);
2922     		if (vcc->pop)   
2923     		    vcc->pop(vcc, skb);   
2924     		else  
2925     		    dev_kfree_skb_any(skb);
2926     		return 0;   /* return SUCCESS */
2927     	}  
2928       
2929     	if (comp_code)  
2930     	{  
2931     	    IF_ERR(printk(DEV_LABEL "send desc:%d completion code %d error\n", 
2932                                                                 desc, comp_code);)  
2933     	}  
2934            
2935             /* remember the desc and vcc mapping */
2936             iavcc->vc_desc_cnt++;
2937             iadev->desc_tbl[desc-1].iavcc = iavcc;
2938             iadev->desc_tbl[desc-1].txskb = skb;
2939             IA_SKB_STATE(skb) = 0;
2940     
2941             iadev->ffL.tcq_rd += 2;
2942             if (iadev->ffL.tcq_rd > iadev->ffL.tcq_ed)
2943     	  	iadev->ffL.tcq_rd  = iadev->ffL.tcq_st;
2944     	writew(iadev->ffL.tcq_rd, iadev->seg_reg+TCQ_RD_PTR);
2945       
2946     	/* Put the descriptor number in the packet ready queue  
2947     		and put the updated write pointer in the DLE field   
2948     	*/   
2949     	*(u16*)(iadev->seg_ram+iadev->ffL.prq_wr) = desc; 
2950     
2951      	iadev->ffL.prq_wr += 2;
2952             if (iadev->ffL.prq_wr > iadev->ffL.prq_ed)
2953                     iadev->ffL.prq_wr = iadev->ffL.prq_st;
2954     	  
2955     	/* Figure out the exact length of the packet and padding required to 
2956                make it  aligned on a 48 byte boundary.  */
2957     	total_len = skb->len + sizeof(struct cpcs_trailer);  
2958     	last = total_len - (total_len/48)*48;  
2959     	pad = 48 - last;  
2960     	total_len = pad + total_len;  
2961     	IF_TX(printk("ia packet len:%d padding:%d\n", total_len, pad);)  
2962      
2963     	/* Put the packet in a tx buffer */   
2964     	if (!iadev->tx_buf[desc-1])  
2965     		printk("couldn't get free page\n");  
2966     
2967             IF_TX(printk("Sent: skb = 0x%x skb->data: 0x%x len: %d, desc: %d\n",
2968                       (u32)skb, (u32)skb->data, skb->len, desc);)
2969             addr = virt_to_bus(skb->data);
2970     	trailer = (struct cpcs_trailer*)iadev->tx_buf[desc-1];  
2971     	trailer->control = 0; 
2972             /*big endian*/ 
2973     	trailer->length = ((skb->len & 0xff) << 8) | ((skb->len & 0xff00) >> 8);
2974     	trailer->crc32 = 0;	/* not needed - dummy bytes */  
2975     
2976     	/* Display the packet */  
2977     	IF_TXPKT(printk("Sent data: len = %d MsgNum = %d\n", 
2978                                                             skb->len, tcnter++);  
2979             xdump(skb->data, skb->len, "TX: ");
2980             printk("\n");)
2981     
2982     	/* Build the buffer descriptor */  
2983     	buf_desc_ptr = (struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE);  
2984     	buf_desc_ptr += desc;	/* points to the corresponding entry */  
2985     	buf_desc_ptr->desc_mode = AAL5 | EOM_EN | APP_CRC32 | CMPL_INT;   
2986             writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
2987     	buf_desc_ptr->vc_index = vcc->vci;
2988     	buf_desc_ptr->bytes = total_len;  
2989     
2990             if (vcc->qos.txtp.traffic_class == ATM_ABR)  
2991     	   clear_lockup (vcc, iadev);
2992     
2993     	/* Build the DLE structure */  
2994     	wr_ptr = iadev->tx_dle_q.write;  
2995     	memset((caddr_t)wr_ptr, 0, sizeof(*wr_ptr));  
2996     	wr_ptr->sys_pkt_addr = addr;  
2997     	wr_ptr->local_pkt_addr = (buf_desc_ptr->buf_start_hi << 16) | 
2998                                                       buf_desc_ptr->buf_start_lo;  
2999     	/* wr_ptr->bytes = swap(total_len);	didn't seem to affect ?? */  
3000     	wr_ptr->bytes = skb->len;  
3001     
3002             /* hw bug - DLEs of 0x2d, 0x2e, 0x2f cause DMA lockup */
3003             if ((wr_ptr->bytes >> 2) == 0xb)
3004                wr_ptr->bytes = 0x30;
3005     
3006     	wr_ptr->mode = TX_DLE_PSI; 
3007     	wr_ptr->prq_wr_ptr_data = 0;
3008       
3009     	/* end is not to be used for the DLE q */  
3010     	if (++wr_ptr == iadev->tx_dle_q.end)  
3011     		wr_ptr = iadev->tx_dle_q.start;  
3012             
3013             /* Build trailer dle */
3014             wr_ptr->sys_pkt_addr = virt_to_bus(iadev->tx_buf[desc-1]);
3015             wr_ptr->local_pkt_addr = ((buf_desc_ptr->buf_start_hi << 16) | 
3016               buf_desc_ptr->buf_start_lo) + total_len - sizeof(struct cpcs_trailer);
3017     
3018             wr_ptr->bytes = sizeof(struct cpcs_trailer);
3019             wr_ptr->mode = DMA_INT_ENABLE; 
3020             wr_ptr->prq_wr_ptr_data = iadev->ffL.prq_wr;
3021             
3022             /* end is not to be used for the DLE q */
3023             if (++wr_ptr == iadev->tx_dle_q.end)  
3024                     wr_ptr = iadev->tx_dle_q.start;
3025     
3026     	iadev->tx_dle_q.write = wr_ptr;  
3027             ATM_DESC(skb) = vcc->vci;
3028             skb_queue_tail(&iadev->tx_dma_q, skb);
3029     
3030             atomic_inc(&vcc->stats->tx);
3031             iadev->tx_pkt_cnt++;
3032     	/* Increment transaction counter */  
3033     	writel(2, iadev->dma+IPHASE5575_TX_COUNTER);  
3034             
3035     #if 0        
3036             /* add flow control logic */ 
3037             if (atomic_read(&vcc->stats->tx) % 20 == 0) {
3038               if (iavcc->vc_desc_cnt > 10) {
3039                  vcc->tx_quota =  vcc->tx_quota * 3 / 4;
3040                 printk("Tx1:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
3041                   iavcc->flow_inc = -1;
3042                   iavcc->saved_tx_quota = vcc->tx_quota;
3043                } else if ((iavcc->flow_inc < 0) && (iavcc->vc_desc_cnt < 3)) {
3044                  // vcc->tx_quota = 3 * iavcc->saved_tx_quota / 4;
3045                  printk("Tx2:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); 
3046                   iavcc->flow_inc = 0;
3047                }
3048             }
3049     #endif
3050     	IF_TX(printk("ia send done\n");)  
3051     	return 0;  
3052     }  
3053     
3054     static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
3055     {
3056             IADEV *iadev; 
3057             struct ia_vcc *iavcc;
3058             unsigned long flags;
3059     
3060             iadev = INPH_IA_DEV(vcc->dev);
3061             iavcc = INPH_IA_VCC(vcc); 
3062             if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
3063             {
3064                 if (!skb)
3065                     printk(KERN_CRIT "null skb in ia_send\n");
3066                 else dev_kfree_skb_any(skb);
3067                 return -EINVAL;
3068             }                         
3069             spin_lock_irqsave(&iadev->tx_lock, flags); 
3070             if (!test_bit(ATM_VF_READY,&vcc->flags)){ 
3071                 dev_kfree_skb_any(skb);
3072                 spin_unlock_irqrestore(&iadev->tx_lock, flags);
3073                 return -EINVAL; 
3074             }
3075             ATM_SKB(skb)->vcc = vcc;
3076      
3077             if (skb_peek(&iadev->tx_backlog)) {
3078                skb_queue_tail(&iadev->tx_backlog, skb);
3079             }
3080             else {
3081                if (ia_pkt_tx (vcc, skb)) {
3082                   skb_queue_tail(&iadev->tx_backlog, skb);
3083                }
3084             }
3085             spin_unlock_irqrestore(&iadev->tx_lock, flags);
3086             return 0;
3087     
3088     }
3089     
3090     static int ia_sg_send(struct atm_vcc *vcc, unsigned long start,   
3091     	unsigned long size)  
3092     {  
3093     	IF_EVENT(printk(">ia_sg_send\n");)  
3094     	return 0;  
3095     }  
3096       
3097       
3098     static int ia_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
3099     { 
3100       int   left = *pos, n;   
3101       char  *tmpPtr;
3102       IADEV *iadev = INPH_IA_DEV(dev);
3103       if(!left--) {
3104          if (iadev->phy_type == FE_25MBIT_PHY) {
3105            n = sprintf(page, "  Board Type         :  Iphase5525-1KVC-128K\n");
3106            return n;
3107          }
3108          if (iadev->phy_type == FE_DS3_PHY)
3109             n = sprintf(page, "  Board Type         :  Iphase-ATM-DS3");
3110          else if (iadev->phy_type == FE_E3_PHY)
3111             n = sprintf(page, "  Board Type         :  Iphase-ATM-E3");
3112          else if (iadev->phy_type == FE_UTP_OPTION)
3113              n = sprintf(page, "  Board Type         :  Iphase-ATM-UTP155"); 
3114          else
3115             n = sprintf(page, "  Board Type         :  Iphase-ATM-OC3");
3116          tmpPtr = page + n;
3117          if (iadev->pci_map_size == 0x40000)
3118             n += sprintf(tmpPtr, "-1KVC-");
3119          else
3120             n += sprintf(tmpPtr, "-4KVC-");  
3121          tmpPtr = page + n; 
3122          if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_1M)
3123             n += sprintf(tmpPtr, "1M  \n");
3124          else if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_512K)
3125             n += sprintf(tmpPtr, "512K\n");
3126          else
3127            n += sprintf(tmpPtr, "128K\n");
3128          return n;
3129       }
3130       if (!left) {
3131          return  sprintf(page, "  Number of Tx Buffer:  %u\n"
3132                                "  Size of Tx Buffer  :  %u\n"
3133                                "  Number of Rx Buffer:  %u\n"
3134                                "  Size of Rx Buffer  :  %u\n"
3135                                "  Packets Receiverd  :  %u\n"
3136                                "  Packets Transmitted:  %u\n"
3137                                "  Cells Received     :  %u\n"
3138                                "  Cells Transmitted  :  %u\n"
3139                                "  Board Dropped Cells:  %u\n"
3140                                "  Board Dropped Pkts :  %u\n",
3141                                iadev->num_tx_desc,  iadev->tx_buf_sz,
3142                                iadev->num_rx_desc,  iadev->rx_buf_sz,
3143                                iadev->rx_pkt_cnt,   iadev->tx_pkt_cnt,
3144                                iadev->rx_cell_cnt, iadev->tx_cell_cnt,
3145                                iadev->drop_rxcell, iadev->drop_rxpkt);                        
3146       }
3147       return 0;
3148     }
3149       
3150     static const struct atmdev_ops ops = {  
3151     	open:		ia_open,  
3152     	close:		ia_close,  
3153     	ioctl:		ia_ioctl,  
3154     	getsockopt:	ia_getsockopt,  
3155     	setsockopt:	ia_setsockopt,  
3156     	send:		ia_send,  
3157     	sg_send:	ia_sg_send,  
3158     	phy_put:	ia_phy_put,  
3159     	phy_get:	ia_phy_get,  
3160     	change_qos:	ia_change_qos,  
3161     	proc_read:	ia_proc_read,
3162     	owner:		THIS_MODULE,
3163     };  
3164     	  
3165       
3166     #if LINUX_VERSION_CODE >= 0x20312
3167     int __init ia_detect(void)
3168     #else
3169     __initfunc(int ia_detect(void)) 
3170     #endif 
3171     {  
3172     	struct atm_dev *dev;  
3173     	IADEV *iadev;  
3174             unsigned long flags;
3175             int index = 0;  
3176     	struct pci_dev *prev_dev;       
3177     	if (!pci_present()) {  
3178     		printk(KERN_ERR DEV_LABEL " driver but no PCI BIOS ?\n");  
3179     		return 0;  
3180     	}  
3181     	iadev = kmalloc(sizeof(*iadev), GFP_KERNEL); 
3182     	if (!iadev) return -ENOMEM;  
3183             memset((char*)iadev, 0, sizeof(*iadev));
3184     	prev_dev = NULL;  
3185     	while((iadev->pci = pci_find_device(PCI_VENDOR_ID_IPHASE,  
3186     		PCI_DEVICE_ID_IPHASE_5575,  prev_dev))) {  
3187     		IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n",
3188                          iadev->pci->bus->number, PCI_SLOT(iadev->pci->devfn), 
3189                                                      PCI_FUNC(iadev->pci->devfn));)  
3190     		if (pci_enable_device(iadev->pci)) break;
3191     		dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
3192     		if (!dev) break;  
3193     		IF_INIT(printk(DEV_LABEL "registered at (itf :%d)\n", 
3194                                                                  dev->number);)  
3195     		INPH_IA_DEV(dev) = iadev; 
3196                     // TODO: multi_board using ia_boards logic in cleanup_module
3197     		ia_dev[index] = iadev;
3198     		_ia_dev[index] = dev;
3199                     IF_INIT(printk("dev_id = 0x%x iadev->LineRate = %d \n", 
3200                                             (u32)dev, iadev->LineRate);)
3201                     iadev_count++;
3202                     spin_lock_init(&iadev->misc_lock);
3203                     spin_lock_irqsave(&iadev->misc_lock, flags); 
3204     		if (ia_init(dev) || ia_start(dev)) {  
3205     			atm_dev_deregister(dev);  
3206                             IF_INIT(printk("IA register failed!\n");)
3207                             ia_dev[index] = NULL;
3208                             _ia_dev[index] = NULL;
3209                             iadev_count--;
3210                             spin_unlock_irqrestore(&iadev->misc_lock, flags); 
3211     			return -EINVAL;  
3212     		}  
3213                     spin_unlock_irqrestore(&iadev->misc_lock, flags);
3214                     IF_EVENT(printk("iadev_count = %d\n", iadev_count);)
3215     		prev_dev = iadev->pci;  
3216     		iadev->next_board = ia_boards;  
3217     		ia_boards = dev;  
3218     		iadev = kmalloc(sizeof(*iadev), GFP_KERNEL);  
3219     		if (!iadev) break;   
3220                     memset((char*)iadev, 0, sizeof(*iadev)); 
3221     		index++;  
3222                     dev = NULL;
3223     	}  
3224     	return index;  
3225     }  
3226       
3227     
3228     #ifdef MODULE  
3229       
3230     int init_module(void)  
3231     {  
3232     	IF_EVENT(printk(">ia init_module\n");)  
3233     	if (!ia_detect()) {  
3234     		printk(KERN_ERR DEV_LABEL ": no adapter found\n");  
3235     		return -ENXIO;  
3236     	}  
3237        	ia_timer.expires = jiffies + 3*HZ;
3238        	add_timer(&ia_timer); 
3239        
3240     	return 0;  
3241     }  
3242       
3243       
3244     void cleanup_module(void)  
3245     {  
3246     	struct atm_dev *dev;  
3247     	IADEV *iadev;  
3248     	unsigned short command;  
3249             int i, j= 0;
3250      
3251     	IF_EVENT(printk(">ia cleanup_module\n");)  
3252     	if (MOD_IN_USE)  
3253     		printk("ia: module in use\n");  
3254             del_timer(&ia_timer);
3255     	while(ia_dev[j])  
3256     	{  
3257     		dev = ia_boards;  
3258     		iadev = INPH_IA_DEV(dev);  
3259     		ia_boards = iadev->next_board;  
3260                     
3261             	/* disable interrupt of lost signal */
3262             	ia_phy_put(dev, ia_phy_get(dev,0x10) & ~(0x4), 0x10); 
3263             	udelay(1);
3264     
3265           		/* De-register device */  
3266           		atm_dev_deregister(dev);  
3267     		IF_EVENT(printk("iav deregistered at (itf:%d)\n", dev->number);)
3268     		for (i= 0; i< iadev->num_tx_desc; i++)
3269                             kfree(iadev->tx_buf[i]);
3270                     kfree(iadev->tx_buf);
3271           		/* Disable memory mapping and busmastering */  
3272     		if (pci_read_config_word(iadev->pci,  
3273     					     PCI_COMMAND, &command) != 0)  
3274           		{  
3275              		printk("ia: can't read PCI_COMMAND.\n");  
3276           		}  
3277           		command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);  
3278           		if (pci_write_config_word(iadev->pci,  
3279     					      PCI_COMMAND, command) != 0)  
3280           		{  
3281              		printk("ia: can't write PCI_COMMAND.\n");  
3282           		}  
3283           		free_irq(iadev->irq, dev);  
3284           		iounmap((void *) iadev->base);  
3285           		kfree(iadev);  
3286                     j++;
3287     	}  
3288     	/* and voila whatever we tried seems to work. I don't know if it will  
3289     		fix suni errors though. Really doubt that. */  
3290             for (i = 0; i<8; i++) {
3291                    ia_dev[i] =  NULL;
3292                   _ia_dev[i] = NULL;
3293             }
3294     }  
3295     
3296     #endif  
3297     
3298