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