Lines Matching +full:vci +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0-or-later
4 Copyright (C) 1995-1999 Madge Networks Ltd.
8 /* * dedicated to the memory of Graham Gordon 1971-1998 * */
48 This driver is for the PCI ATMizer-based Ambassador card (except
56 Only AAL5 is supported with vpi = 0 and vci in the range 0 to 1023.
58 The cards are big-endian.
66 The cards are reset and the self-test results are checked. The
68 pointer to a descriptor containing details of the host-based queues
81 contents of several other "shared run-time registers" (bad) which
96 1. Driver <-> Adapter Communication
104 All queues are host-based circular queues. They are contiguous and
110 The queue pairs work as follows: one queue is for supply to the
113 been dealt with by the adapter. The host adds items to the supply
131 TX supply items are of variable length (scatter gather support) and
133 Each TX supply item contains a unique, host-supplied handle (the skb
141 RX supply items consist of a unique, host-supplied handle (the skb
149 Each pool should have enough buffers to handle a back-to-back stream
205 All structures that are not accessed using DMA must be 4-byte
208 There is a DMA memory hole at E0000000-E00000FF (groan).
214 include spare trailing bytes up to the next 4-byte boundary; they
228 . Discard non-conforming SKBs (causes TX failure or RX fill delay).
229 . Discard non-conforming TX fragment descriptors (the TX fails).
233 . Relax checks for non-DMA items (ignore hole).
234 . Give scatter-gather (iovec) requirements using ???. (?)
251 . Handle interrupted and/or non-blocking writes - is this a job for
266 . Impose a TX-pending limit (2?) on each VC, help avoid TX q overflow.
275 on the last one (OR only "no-op" or "wait" commands are waited for).
277 . Eliminate need for while-schedule around do_command.
292 static const unsigned long onegigmask = -1 << 30;
297 PRINTD (DBG_FLOW|DBG_REGS, "wr: %08zx <- %08x", addr, data); in wr_plain()
299 dev->membase[addr / sizeof(u32)] = data; in wr_plain()
301 outl (data, dev->iobase + addr); in wr_plain()
307 u32 data = dev->membase[addr / sizeof(u32)]; in rd_plain()
309 u32 data = inl (dev->iobase + addr); in rd_plain()
311 PRINTD (DBG_FLOW|DBG_REGS, "rd: %08zx -> %08x", addr, data); in rd_plain()
317 PRINTD (DBG_FLOW|DBG_REGS, "wr: %08zx <- %08x b[%08x]", addr, data, be); in wr_mem()
319 dev->membase[addr / sizeof(u32)] = be; in wr_mem()
321 outl (be, dev->iobase + addr); in wr_mem()
327 __be32 be = dev->membase[addr / sizeof(u32)]; in rd_mem()
329 __be32 be = inl (dev->iobase + addr); in rd_mem()
332 PRINTD (DBG_FLOW|DBG_REGS, "rd: %08zx -> %08x b[%08x]", addr, data, be); in rd_mem()
362 lb, be32_to_cpu (lb->result), be32_to_cpu (lb->command)); in dump_loader_block()
364 PRINTDM (DBG_LOAD, " %08x", be32_to_cpu (lb->payload.data[i])); in dump_loader_block()
365 PRINTDE (DBG_LOAD, ", vld: %08x", be32_to_cpu (lb->valid)); in dump_loader_block()
376 cmd, /*be32_to_cpu*/ (cmd->request)); in dump_command()
378 PRINTDM (DBG_CMD, " %08x", /*be32_to_cpu*/ (cmd->args.par[i])); in dump_command()
389 unsigned char * data = skb->data; in dump_skb()
391 for (i=0; i<skb->len && i < 256;i++) in dump_skb()
408 const u32 fourmegmask = -1 << 22; in check_area()
409 const u32 twofivesixmask = -1 << 8; in check_area()
412 u32 lastaddress = startaddress+length-1; in check_area()
415 PRINTK (KERN_ERR, "check_area failure: [%x,%x] - mail maintainer!", in check_area()
417 return -1; in check_area()
426 if (ATM_SKB(skb)->vcc->pop) { in amb_kfree_skb()
427 ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb); in amb_kfree_skb()
436 tx_simple * tx_descr = bus_to_virt (tx->handle); in tx_complete()
437 struct sk_buff * skb = tx_descr->skb; in tx_complete()
442 atomic_inc(&ATM_SKB(skb)->vcc->stats->tx); in tx_complete()
450 dev->stats.tx_ok++; in tx_complete()
457 struct sk_buff * skb = bus_to_virt (rx->handle); in rx_complete()
458 u16 vc = be16_to_cpu (rx->vc); in rx_complete()
459 // unused: u16 lec_id = be16_to_cpu (rx->lec_id); in rx_complete()
460 u16 status = be16_to_cpu (rx->status); in rx_complete()
461 u16 rx_len = be16_to_cpu (rx->length); in rx_complete()
467 struct atm_vcc * atm_vcc = dev->rxer[vc]; in rx_complete()
468 dev->stats.rx.ok++; in rx_complete()
472 if (rx_len <= atm_vcc->qos.rxtp.max_sdu) { in rx_complete()
474 if (atm_charge (atm_vcc, skb->truesize)) { in rx_complete()
477 ATM_SKB(skb)->vcc = atm_vcc; in rx_complete()
483 atomic_inc(&atm_vcc->stats->rx); in rx_complete()
486 atm_vcc->push (atm_vcc, skb); in rx_complete()
491 … PRINTD (DBG_INFO|DBG_RX, "dropped thanks to atm_charge (vc %hu, truesize %u)", vc, skb->truesize); in rx_complete()
496 PRINTK (KERN_INFO, "dropped over-size frame"); in rx_complete()
498 atomic_inc(&atm_vcc->stats->rx_drop); in rx_complete()
507 dev->stats.rx.error++; in rx_complete()
509 dev->stats.rx.badcrc++; in rx_complete()
511 dev->stats.rx.toolong++; in rx_complete()
513 dev->stats.rx.aborted++; in rx_complete()
515 dev->stats.rx.unused++; in rx_complete()
539 // sometimes does 16-bit accesses (yuk yuk yuk)
542 amb_cq * cq = &dev->cq; in command_do()
543 volatile amb_cq_ptrs * ptrs = &cq->ptrs; in command_do()
548 if (test_bit (dead, &dev->flags)) in command_do()
551 spin_lock (&cq->lock); in command_do()
554 if (cq->pending < cq->maximum) { in command_do()
556 my_slot = ptrs->in; in command_do()
562 *ptrs->in = *cmd; in command_do()
563 cq->pending++; in command_do()
564 ptrs->in = NEXTQ (ptrs->in, ptrs->start, ptrs->limit); in command_do()
567 wr_mem (dev, offsetof(amb_mem, mb.adapter.cmd_address), virt_to_bus (ptrs->in)); in command_do()
569 if (cq->pending > cq->high) in command_do()
570 cq->high = cq->pending; in command_do()
571 spin_unlock (&cq->lock); in command_do()
573 // these comments were in a while-loop before, msleep removes the loop in command_do()
576 msleep(cq->pending); in command_do()
579 while (ptrs->out != my_slot) { in command_do()
580 PRINTD (DBG_CMD, "wait: command slot (now at %p)", ptrs->out); in command_do()
586 while (ptrs->out->request != cpu_to_be32 (SRB_COMPLETE)) { in command_do()
594 spin_lock (&cq->lock); in command_do()
595 cq->pending--; in command_do()
597 *cmd = *ptrs->out; in command_do()
598 ptrs->out = NEXTQ (ptrs->out, ptrs->start, ptrs->limit); in command_do()
599 spin_unlock (&cq->lock); in command_do()
603 cq->filled++; in command_do()
604 spin_unlock (&cq->lock); in command_do()
605 return -EAGAIN; in command_do()
613 amb_txq * txq = &dev->txq; in tx_give()
618 if (test_bit (dead, &dev->flags)) in tx_give()
621 spin_lock_irqsave (&txq->lock, flags); in tx_give()
623 if (txq->pending < txq->maximum) { in tx_give()
624 PRINTD (DBG_TX, "TX in slot %p", txq->in.ptr); in tx_give()
626 *txq->in.ptr = *tx; in tx_give()
627 txq->pending++; in tx_give()
628 txq->in.ptr = NEXTQ (txq->in.ptr, txq->in.start, txq->in.limit); in tx_give()
630 wr_mem (dev, offsetof(amb_mem, mb.adapter.tx_address), virt_to_bus (txq->in.ptr)); in tx_give()
633 if (txq->pending > txq->high) in tx_give()
634 txq->high = txq->pending; in tx_give()
635 spin_unlock_irqrestore (&txq->lock, flags); in tx_give()
638 txq->filled++; in tx_give()
639 spin_unlock_irqrestore (&txq->lock, flags); in tx_give()
640 return -EAGAIN; in tx_give()
645 amb_txq * txq = &dev->txq; in tx_take()
650 spin_lock_irqsave (&txq->lock, flags); in tx_take()
652 if (txq->pending && txq->out.ptr->handle) { in tx_take()
654 tx_complete (dev, txq->out.ptr); in tx_take()
656 txq->out.ptr->handle = 0; in tx_take()
658 txq->pending--; in tx_take()
659 txq->out.ptr = NEXTQ (txq->out.ptr, txq->out.start, txq->out.limit); in tx_take()
661 spin_unlock_irqrestore (&txq->lock, flags); in tx_take()
665 spin_unlock_irqrestore (&txq->lock, flags); in tx_take()
666 return -1; in tx_take()
673 amb_rxq * rxq = &dev->rxq[pool]; in rx_give()
678 spin_lock_irqsave (&rxq->lock, flags); in rx_give()
680 if (rxq->pending < rxq->maximum) { in rx_give()
681 PRINTD (DBG_RX, "RX in slot %p", rxq->in.ptr); in rx_give()
683 *rxq->in.ptr = *rx; in rx_give()
684 rxq->pending++; in rx_give()
685 rxq->in.ptr = NEXTQ (rxq->in.ptr, rxq->in.start, rxq->in.limit); in rx_give()
687 wr_mem (dev, offsetof(amb_mem, mb.adapter.rx_address[pool]), virt_to_bus (rxq->in.ptr)); in rx_give()
689 spin_unlock_irqrestore (&rxq->lock, flags); in rx_give()
692 spin_unlock_irqrestore (&rxq->lock, flags); in rx_give()
693 return -1; in rx_give()
698 amb_rxq * rxq = &dev->rxq[pool]; in rx_take()
703 spin_lock_irqsave (&rxq->lock, flags); in rx_take()
705 if (rxq->pending && (rxq->out.ptr->status || rxq->out.ptr->length)) { in rx_take()
707 rx_complete (dev, rxq->out.ptr); in rx_take()
709 rxq->out.ptr->status = 0; in rx_take()
710 rxq->out.ptr->length = 0; in rx_take()
712 rxq->pending--; in rx_take()
713 rxq->out.ptr = NEXTQ (rxq->out.ptr, rxq->out.start, rxq->out.limit); in rx_take()
715 if (rxq->pending < rxq->low) in rx_take()
716 rxq->low = rxq->pending; in rx_take()
717 spin_unlock_irqrestore (&rxq->lock, flags); in rx_take()
720 if (!rxq->pending && rxq->buffers_wanted) in rx_take()
721 rxq->emptied++; in rx_take()
722 spin_unlock_irqrestore (&rxq->lock, flags); in rx_take()
723 return -1; in rx_take()
731 amb_rxq * rxq = &dev->rxq[pool]; in drain_rx_pool()
735 if (test_bit (dead, &dev->flags)) in drain_rx_pool()
741 if (rxq->pending > rxq->buffers_wanted) { in drain_rx_pool()
748 while (rxq->pending > rxq->buffers_wanted) in drain_rx_pool()
773 if (test_bit (dead, &dev->flags)) in fill_rx_pool()
776 rxq = &dev->rxq[pool]; in fill_rx_pool()
777 while (rxq->pending < rxq->maximum && rxq->pending < rxq->buffers_wanted) { in fill_rx_pool()
779 struct sk_buff * skb = alloc_skb (rxq->buffer_size, priority); in fill_rx_pool()
784 if (check_area (skb->data, skb->truesize)) { in fill_rx_pool()
790 skb, skb->head, (long) skb_end_offset(skb)); in fill_rx_pool()
792 rx.host_address = cpu_to_be32 (virt_to_bus (skb->data)); in fill_rx_pool()
847 wr_plain (dev, offsetof(amb_mem, interrupt), -1); in interrupt_handler()
876 unsigned char exp = -1; // hush gcc in make_rate()
877 unsigned int man = -1; // hush gcc in make_rate()
881 // rates in cells per second, ITU format (nasty 16-bit floating-point) in make_rate()
882 // given 5-bit e and 9-bit m: in make_rate()
885 // (bit 15 is "reserved", bit 14 "non-zero") in make_rate()
887 // largest rate is (1+511/512)*2^31 = 4290772992 (< 2^32-1) in make_rate()
888 // smallest non-zero rate is (1+0/512)*2^0 = 1 (> 0) in make_rate()
891 // remove top bit and shift (rounding if feeling clever) by 9-e in make_rate()
899 return -EINVAL; in make_rate()
911 // invariant: rate = man*2^(exp-31) in make_rate()
913 exp = exp - 1; in make_rate()
918 // rate = (2^31+(man-2^31))*2^(exp-31) in make_rate()
919 // rate = (1+(man-2^31)/2^31)*2^exp in make_rate()
921 man &= 0xffffffffU; // a nop on 32-bit systems in make_rate()
924 // exp is in the range 0 to 31, man is in the range 0 to 2^32-1 in make_rate()
925 // time to lose significance... we want m in the range 0 to 2^9-1 in make_rate()
933 man = man>>(32-9); in make_rate()
939 man = (man>>(32-9)) + 1; in make_rate()
946 man = (man>>(32-9)); in make_rate()
952 if (man & (1<<(32-9-1))) { in make_rate()
953 man = (man>>(32-9)) + 1; in make_rate()
960 man = (man>>(32-9)); in make_rate()
967 // zero rate - not representable in make_rate()
970 return -EINVAL; in make_rate()
985 ? (1 << exp) + (man << (exp-9)) in make_rate()
986 : (1 << exp) + ((man + (1<<(9-exp-1))) >> (9-exp)); in make_rate()
1005 u16 tx_rate_bits = -1; // hush gcc in amb_open()
1006 u16 tx_vc_bits = -1; // hush gcc in amb_open()
1007 u16 tx_frame_bits = -1; // hush gcc in amb_open()
1009 amb_dev * dev = AMB_DEV(atm_vcc->dev); in amb_open()
1011 unsigned char pool = -1; // hush gcc in amb_open()
1012 short vpi = atm_vcc->vpi; in amb_open()
1013 int vci = atm_vcc->vci; in amb_open() local
1015 PRINTD (DBG_FLOW|DBG_VCC, "amb_open %x %x", vpi, vci); in amb_open()
1019 if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) { in amb_open()
1020 PRINTK (KERN_WARNING, "rejecting open with unspecified VPI/VCI (deprecated)"); in amb_open()
1021 return -EINVAL; in amb_open()
1026 0 <= vci && vci < (1<<NUM_VCI_BITS))) { in amb_open()
1027 PRINTD (DBG_WARN|DBG_VCC, "VPI/VCI out of range: %hd/%d", vpi, vci); in amb_open()
1028 return -EINVAL; in amb_open()
1031 qos = &atm_vcc->qos; in amb_open()
1033 if (qos->aal != ATM_AAL5) { in amb_open()
1035 return -EINVAL; in amb_open()
1041 txtp = &qos->txtp; in amb_open()
1042 if (txtp->traffic_class != ATM_NONE) { in amb_open()
1043 switch (txtp->traffic_class) { in amb_open()
1045 // we take "the PCR" as a rate-cap in amb_open()
1056 pcr = -pcr; in amb_open()
1076 // PRINTD (DBG_QOS, "request for non-UBR/ABR denied"); in amb_open()
1077 PRINTD (DBG_QOS, "request for non-UBR denied"); in amb_open()
1078 return -EINVAL; in amb_open()
1086 rxtp = &qos->rxtp; in amb_open()
1087 if (rxtp->traffic_class == ATM_NONE) { in amb_open()
1092 if ((unsigned int) rxtp->max_sdu <= dev->rxq[pool].buffer_size) { in amb_open()
1094 pool, rxtp->max_sdu, dev->rxq[pool].buffer_size); in amb_open()
1100 rxtp->max_sdu); in amb_open()
1101 return -EINVAL; in amb_open()
1104 switch (rxtp->traffic_class) { in amb_open()
1116 // PRINTD (DBG_QOS, "request for non-UBR/ABR denied"); in amb_open()
1117 PRINTD (DBG_QOS, "request for non-UBR denied"); in amb_open()
1118 return -EINVAL; in amb_open()
1127 return -ENOMEM; in amb_open()
1129 atm_vcc->dev_data = (void *) vcc; in amb_open()
1135 set_bit(ATM_VF_ADDR,&atm_vcc->flags); in amb_open()
1137 if (txtp->traffic_class != ATM_NONE) { in amb_open()
1140 vcc->tx_frame_bits = tx_frame_bits; in amb_open()
1142 mutex_lock(&dev->vcc_sf); in amb_open()
1143 if (dev->rxer[vci]) { in amb_open()
1146 cmd.args.modify_rate.vc = cpu_to_be32 (vci); // vpi 0 in amb_open()
1152 cmd.args.modify_flags.vc = cpu_to_be32 (vci); // vpi 0 in amb_open()
1154 ( (AMB_VCC(dev->rxer[vci])->rx_info.pool << SRB_POOL_SHIFT) in amb_open()
1161 cmd.args.open.vc = cpu_to_be32 (vci); // vpi 0 in amb_open()
1167 dev->txer[vci].tx_present = 1; in amb_open()
1168 mutex_unlock(&dev->vcc_sf); in amb_open()
1171 if (rxtp->traffic_class != ATM_NONE) { in amb_open()
1174 vcc->rx_info.pool = pool; in amb_open()
1176 mutex_lock(&dev->vcc_sf); in amb_open()
1178 if (!dev->rxq[pool].buffers_wanted) in amb_open()
1179 dev->rxq[pool].buffers_wanted = rx_lats; in amb_open()
1180 dev->rxq[pool].buffers_wanted += 1; in amb_open()
1183 if (dev->txer[vci].tx_present) { in amb_open()
1187 cmd.args.modify_flags.vc = cpu_to_be32 (vci); // vpi 0 in amb_open()
1190 | (dev->txer[vci].tx_vc_bits << SRB_FLAGS_SHIFT) ); in amb_open()
1194 cmd.args.open.vc = cpu_to_be32 (vci); // vpi 0 in amb_open()
1201 dev->rxer[vci] = atm_vcc; in amb_open()
1202 mutex_unlock(&dev->vcc_sf); in amb_open()
1206 set_bit(ATM_VF_READY,&atm_vcc->flags); in amb_open()
1214 amb_dev * dev = AMB_DEV (atm_vcc->dev); in amb_close()
1216 u16 vci = atm_vcc->vci; in amb_close() local
1221 clear_bit(ATM_VF_READY,&atm_vcc->flags); in amb_close()
1224 if (atm_vcc->qos.txtp.traffic_class != ATM_NONE) { in amb_close()
1227 mutex_lock(&dev->vcc_sf); in amb_close()
1228 if (dev->rxer[vci]) { in amb_close()
1231 cmd.args.modify_rate.vc = cpu_to_be32 (vci); // vpi 0 in amb_close()
1237 cmd.args.close.vc = cpu_to_be32 (vci); // vpi 0 in amb_close()
1239 dev->txer[vci].tx_present = 0; in amb_close()
1242 mutex_unlock(&dev->vcc_sf); in amb_close()
1246 if (atm_vcc->qos.rxtp.traffic_class != ATM_NONE) { in amb_close()
1250 unsigned char pool = vcc->rx_info.pool; in amb_close()
1252 mutex_lock(&dev->vcc_sf); in amb_close()
1253 if (dev->txer[vci].tx_present) { in amb_close()
1256 cmd.args.modify_flags.vc = cpu_to_be32 (vci); // vpi 0 in amb_close()
1258 (dev->txer[vci].tx_vc_bits << SRB_FLAGS_SHIFT); in amb_close()
1262 cmd.args.close.vc = cpu_to_be32 (vci); // vpi 0 in amb_close()
1264 // forget the rxer - no more skbs will be pushed in amb_close()
1265 if (atm_vcc != dev->rxer[vci]) in amb_close()
1266 PRINTK (KERN_ERR, "%s vcc=%p rxer[vci]=%p", in amb_close()
1268 vcc, dev->rxer[vci]); in amb_close()
1269 dev->rxer[vci] = NULL; in amb_close()
1274 dev->rxq[pool].buffers_wanted -= 1; in amb_close()
1275 if (dev->rxq[pool].buffers_wanted == rx_lats) { in amb_close()
1276 dev->rxq[pool].buffers_wanted = 0; in amb_close()
1279 mutex_unlock(&dev->vcc_sf); in amb_close()
1285 // say the VPI/VCI is free again in amb_close()
1286 clear_bit(ATM_VF_ADDR,&atm_vcc->flags); in amb_close()
1294 amb_dev * dev = AMB_DEV(atm_vcc->dev); in amb_send()
1296 u16 vc = atm_vcc->vci; in amb_send()
1297 unsigned int tx_len = skb->len; in amb_send()
1298 unsigned char * tx_data = skb->data; in amb_send()
1302 if (test_bit (dead, &dev->flags)) in amb_send()
1303 return -EIO; in amb_send()
1310 if (!dev->txer[vc].tx_present) { in amb_send()
1311 PRINTK (KERN_ERR, "attempt to send on RX-only VC %x", vc); in amb_send()
1312 return -EBADFD; in amb_send()
1318 ATM_SKB(skb)->vcc = atm_vcc; in amb_send()
1320 if (skb->len > (size_t) atm_vcc->qos.txtp.max_sdu) { in amb_send()
1322 return -EIO; in amb_send()
1325 if (check_area (skb->data, skb->len)) { in amb_send()
1326 atomic_inc(&atm_vcc->stats->tx_err); in amb_send()
1327 return -ENOMEM; // ? in amb_send()
1334 return -ENOMEM; in amb_send()
1338 return -ENOMEM; in amb_send()
1342 tx_descr->skb = skb; in amb_send()
1344 tx_descr->tx_frag.bytes = cpu_to_be32 (tx_len); in amb_send()
1345 tx_descr->tx_frag.address = cpu_to_be32 (virt_to_bus (tx_data)); in amb_send()
1347 tx_descr->tx_frag_end.handle = virt_to_bus (tx_descr); in amb_send()
1348 tx_descr->tx_frag_end.vc = 0; in amb_send()
1349 tx_descr->tx_frag_end.next_descriptor_length = 0; in amb_send()
1350 tx_descr->tx_frag_end.next_descriptor = 0; in amb_send()
1352 tx_descr->tx_frag_end.cpcs_uu = 0; in amb_send()
1353 tx_descr->tx_frag_end.cpi = 0; in amb_send()
1354 tx_descr->tx_frag_end.pad = 0; in amb_send()
1357 tx.vc = cpu_to_be16 (vcc->tx_frame_bits | vc); in amb_send()
1359 tx.tx_descr_addr = cpu_to_be32 (virt_to_bus (&tx_descr->tx_frag)); in amb_send()
1374 amb_dev * dev = AMB_DEV (atm_vcc->dev);
1376 unsigned char pool = vcc->rx_info.pool;
1388 rx.host_address = cpu_to_be32 (virt_to_bus (skb->data));
1390 skb->data = skb->head;
1392 skb->len = 0;
1418 if (!left--) { in amb_proc_read()
1419 amb_stats * s = &dev->stats; in amb_proc_read()
1423 s->tx_ok, s->rx.ok, s->rx.error, in amb_proc_read()
1424 s->rx.badcrc, s->rx.toolong, in amb_proc_read()
1425 s->rx.aborted, s->rx.unused); in amb_proc_read()
1428 if (!left--) { in amb_proc_read()
1429 amb_cq * c = &dev->cq; in amb_proc_read()
1431 c->pending, c->high, c->maximum); in amb_proc_read()
1434 if (!left--) { in amb_proc_read()
1435 amb_txq * t = &dev->txq; in amb_proc_read()
1437 t->pending, t->maximum, t->high, t->filled); in amb_proc_read()
1440 if (!left--) { in amb_proc_read()
1443 amb_rxq * r = &dev->rxq[pool]; in amb_proc_read()
1445 r->pending, r->maximum, r->buffers_wanted, r->low, r->emptied); in amb_proc_read()
1451 if (!left--) { in amb_proc_read()
1454 amb_rxq * r = &dev->rxq[pool]; in amb_proc_read()
1455 count += sprintf (page+count, " %u", r->buffer_size); in amb_proc_read()
1462 if (!left--) { in amb_proc_read()
1484 // could collect device-specific (not driver/atm-linux) stats here in do_housekeeping()
1488 mod_timer(&dev->housekeeping, jiffies + 10*HZ); in do_housekeeping()
1515 return -ENOMEM; in create_queues()
1520 return -ENOMEM; in create_queues()
1530 amb_cq * cq = &dev->cq; in create_queues()
1532 cq->pending = 0; in create_queues()
1533 cq->high = 0; in create_queues()
1534 cq->maximum = cmds - 1; in create_queues()
1536 cq->ptrs.start = cmd; in create_queues()
1537 cq->ptrs.in = cmd; in create_queues()
1538 cq->ptrs.out = cmd; in create_queues()
1539 cq->ptrs.limit = cmd + cmds; in create_queues()
1541 memory = cq->ptrs.limit; in create_queues()
1549 amb_txq * txq = &dev->txq; in create_queues()
1551 txq->pending = 0; in create_queues()
1552 txq->high = 0; in create_queues()
1553 txq->filled = 0; in create_queues()
1554 txq->maximum = txs - 1; in create_queues()
1556 txq->in.start = in; in create_queues()
1557 txq->in.ptr = in; in create_queues()
1558 txq->in.limit = in + txs; in create_queues()
1560 memory = txq->in.limit; in create_queues()
1563 txq->out.start = out; in create_queues()
1564 txq->out.ptr = out; in create_queues()
1565 txq->out.limit = out + txs; in create_queues()
1567 memory = txq->out.limit; in create_queues()
1575 amb_rxq * rxq = &dev->rxq[pool]; in create_queues()
1577 rxq->buffer_size = rx_buffer_sizes[pool]; in create_queues()
1578 rxq->buffers_wanted = 0; in create_queues()
1580 rxq->pending = 0; in create_queues()
1581 rxq->low = rxs[pool] - 1; in create_queues()
1582 rxq->emptied = 0; in create_queues()
1583 rxq->maximum = rxs[pool] - 1; in create_queues()
1585 rxq->in.start = in; in create_queues()
1586 rxq->in.ptr = in; in create_queues()
1587 rxq->in.limit = in + rxs[pool]; in create_queues()
1589 memory = rxq->in.limit; in create_queues()
1592 rxq->out.start = out; in create_queues()
1593 rxq->out.ptr = out; in create_queues()
1594 rxq->out.limit = out + rxs[pool]; in create_queues()
1596 memory = rxq->out.limit; in create_queues()
1603 kfree (limit - total); in create_queues()
1604 return -ENOMEM; in create_queues()
1613 void * memory = dev->cq.ptrs.start; in destroy_queues()
1625 // centisecond timeouts - guessing away here
1665 res = -EINVAL; in decode_loader_result()
1669 res = -ETIMEDOUT; in decode_loader_result()
1677 res = -EIO; in decode_loader_result()
1685 res = -EINVAL; in decode_loader_result()
1693 res = -EINVAL; in decode_loader_result()
1697 res = -EIO; in decode_loader_result()
1705 res = -EIO; in decode_loader_result()
1709 res = -EINVAL; in decode_loader_result()
1713 res = -EINVAL; in decode_loader_result()
1737 correctly byte-ordered so we leave it alone. Hit the doorbell in do_loader_command()
1742 lb->result = 0; in do_loader_command()
1743 lb->command = cpu_to_be32 (cmd); in do_loader_command()
1744 lb->valid = cpu_to_be32 (DMA_VALID); in do_loader_command()
1751 while (!lb->result || lb->result == cpu_to_be32 (COMMAND_IN_PROGRESS)) in do_loader_command()
1758 return -ETIMEDOUT; in do_loader_command()
1769 be32_to_cpu (lb->result)); in do_loader_command()
1771 return -ETIMEDOUT; in do_loader_command()
1775 return decode_loader_result (cmd, be32_to_cpu (lb->result)); in do_loader_command()
1793 *version = be32_to_cpu (lb->payload.version); in get_loader_version()
1802 transfer_block * tb = &lb->payload.transfer; in loader_write()
1806 tb->address = rec->addr; in loader_write()
1807 tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4); in loader_write()
1808 memcpy(tb->data, rec->data, be16_to_cpu(rec->len)); in loader_write()
1817 transfer_block * tb = &lb->payload.transfer; in loader_verify()
1822 tb->address = rec->addr; in loader_verify()
1823 tb->count = cpu_to_be32(be16_to_cpu(rec->len) / 4); in loader_verify()
1825 if (!res && memcmp(tb->data, rec->data, be16_to_cpu(rec->len))) in loader_verify()
1826 res = -EINVAL; in loader_verify()
1836 lb->payload.start = cpu_to_be32 (address); in loader_start()
1844 PRINTK (KERN_ERR, "self-test failed: %s", msg); in sf()
1861 wr_plain (dev, offsetof(amb_mem, interrupt), -1); in amb_reset()
1863 // clear self-test done flag in amb_reset()
1872 // half second time-out in amb_reset()
1879 return -ETIMEDOUT; in amb_reset()
1882 // get results of self-test in amb_reset()
1883 // XXX double check byte-order in amb_reset()
1899 return -EIO; in amb_reset()
1916 res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); in ucode_init()
1923 rec = (const struct ihex_binrec *)fw->data; in ucode_init()
1924 if (be16_to_cpu(rec->len) != sizeof(__be32) || be32_to_cpu(rec->addr)) { in ucode_init()
1928 start_address = be32_to_cpup((__be32 *)rec->data); in ucode_init()
1935 PRINTD (DBG_LOAD, "starting region (%x, %u)", be32_to_cpu(rec->addr), in ucode_init()
1936 be16_to_cpu(rec->len)); in ucode_init()
1937 if (be16_to_cpu(rec->len) > 4 * MAX_TRANSFER_DATA) { in ucode_init()
1941 if (be16_to_cpu(rec->len) & 3) { in ucode_init()
1962 return -EINVAL; in ucode_init()
1979 a.command_start = bus_addr (dev->cq.ptrs.start); in amb_talk()
1980 a.command_end = bus_addr (dev->cq.ptrs.limit); in amb_talk()
1981 a.tx_start = bus_addr (dev->txq.in.start); in amb_talk()
1982 a.tx_end = bus_addr (dev->txq.in.limit); in amb_talk()
1983 a.txcom_start = bus_addr (dev->txq.out.start); in amb_talk()
1984 a.txcom_end = bus_addr (dev->txq.out.limit); in amb_talk()
1988 a.rec_struct[pool].buffer_start = bus_addr (dev->rxq[pool].in.start); in amb_talk()
1989 a.rec_struct[pool].buffer_end = bus_addr (dev->rxq[pool].in.limit); in amb_talk()
1990 a.rec_struct[pool].rx_start = bus_addr (dev->rxq[pool].out.start); in amb_talk()
1991 a.rec_struct[pool].rx_end = bus_addr (dev->rxq[pool].out.limit); in amb_talk()
1992 a.rec_struct[pool].buffer_size = cpu_to_be32 (dev->rxq[pool].buffer_size); in amb_talk()
2012 return -ETIMEDOUT; in amb_talk()
2058 esi[i] = bitrev8(upper2>>(8*(i-4))); in amb_esi()
2070 // fix up the PLX-mapped window base address to match the block in fixup_plx_window()
2121 return -EINVAL; in amb_init()
2129 dev->pci_dev = pci_dev; in setup_dev()
2132 dev->iobase = pci_resource_start (pci_dev, 1); in setup_dev()
2133 dev->irq = pci_dev->irq; in setup_dev()
2134 dev->membase = bus_to_virt(pci_resource_start(pci_dev, 0)); in setup_dev()
2137 dev->flags = 0; in setup_dev()
2140 // ATM_OC3_PCR = 1555200000/8/270*260/53 - 29/53 in setup_dev()
2142 dev->tx_avail = ATM_OC3_PCR; in setup_dev()
2143 dev->rx_avail = ATM_OC3_PCR; in setup_dev()
2145 // semaphore for txer/rxer modifications - we cannot use a in setup_dev()
2147 mutex_init(&dev->vcc_sf); in setup_dev()
2150 // consider replacing "int pending" -> "atomic_t available" in setup_dev()
2152 spin_lock_init (&dev->cq.lock); in setup_dev()
2153 spin_lock_init (&dev->txq.lock); in setup_dev()
2155 spin_lock_init (&dev->rxq[pool].lock); in setup_dev()
2192 irq = pci_dev->irq; in amb_probe()
2194 if (pci_dev->device == PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD) { in amb_probe()
2196 err = -EINVAL; in amb_probe()
2215 err = -ENOMEM; in amb_probe()
2236 dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1, in amb_probe()
2238 if (!dev->atm_dev) { in amb_probe()
2240 err = -EINVAL; in amb_probe()
2245 dev->atm_dev->number, dev, dev->atm_dev); in amb_probe()
2246 dev->atm_dev->dev_data = (void *) dev; in amb_probe()
2249 amb_esi (dev, dev->atm_dev->esi); in amb_probe()
2251 // 0 bits for vpi, 10 bits for vci in amb_probe()
2252 dev->atm_dev->ci_range.vpi_bits = NUM_VPI_BITS; in amb_probe()
2253 dev->atm_dev->ci_range.vci_bits = NUM_VCI_BITS; in amb_probe()
2255 timer_setup(&dev->housekeeping, do_housekeeping, 0); in amb_probe()
2256 mod_timer(&dev->housekeeping, jiffies); in amb_probe()
2284 PRINTD(DBG_INFO|DBG_INIT, "closing %p (atm_dev = %p)", dev, dev->atm_dev); in amb_remove_one()
2285 del_timer_sync(&dev->housekeeping); in amb_remove_one()
2290 free_irq(dev->irq, dev); in amb_remove_one()
2293 atm_dev_deregister(dev->atm_dev); in amb_remove_one()