Lines Matching defs:lvcc
646 static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,
650 APRINTK(lvcc->vbase != NULL, "cardvcc_read: unbound vcc!\n");
651 val= readl(lvcc->vbase + offset);
653 lvcc->vci, (int) offset, val);
657 static inline void cardvcc_write(const struct lanai_vcc *lvcc,
660 APRINTK(lvcc->vbase != NULL, "cardvcc_write: unbound vcc!\n");
663 (unsigned int) val, lvcc->vci, (unsigned int) offset);
665 lvcc->vci, (unsigned int) offset, (unsigned int) val);
666 writel(val, lvcc->vbase + offset);
693 static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
696 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) {
697 dma_addr_t dmaaddr = lvcc->rx.buf.dmaaddr;
698 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc1);
699 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc2);
700 cardvcc_write(lvcc, 0, vcc_rxwriteptr);
701 cardvcc_write(lvcc, 0, vcc_rxbufstart);
702 cardvcc_write(lvcc, 0, vcc_rxreadptr);
703 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_rxaddr2);
705 RXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->rx.buf))|
714 cardvcc_write(lvcc, addr1, vcc_rxaddr1);
717 static void host_vcc_start_tx(const struct lanai_vcc *lvcc)
719 dma_addr_t dmaaddr = lvcc->tx.buf.dmaaddr;
720 cardvcc_write(lvcc, 0, vcc_txicg);
721 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc1);
722 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc2);
723 cardvcc_write(lvcc, 0, vcc_txreadptr);
724 cardvcc_write(lvcc, 0, vcc_txendptr);
725 cardvcc_write(lvcc, 0, vcc_txwriteptr);
726 cardvcc_write(lvcc,
727 (lvcc->tx.atmvcc->qos.txtp.traffic_class == ATM_CBR) ?
728 TXCBR_NEXT_BOZO | lvcc->vci : 0, vcc_txcbr_next);
729 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_txaddr2);
730 cardvcc_write(lvcc,
732 TXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->tx.buf)),
737 static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)
739 if (lvcc->vbase == NULL) /* We were never bound to a VCI */
742 cardvcc_write(lvcc,
747 cardvcc_write(lvcc, 0, vcc_rxaddr2);
748 cardvcc_write(lvcc, 0, vcc_rxcrc1);
749 cardvcc_write(lvcc, 0, vcc_rxcrc2);
750 cardvcc_write(lvcc, 0, vcc_rxwriteptr);
751 cardvcc_write(lvcc, 0, vcc_rxbufstart);
752 cardvcc_write(lvcc, 0, vcc_rxreadptr);
763 struct lanai_vcc *lvcc)
769 if (lvcc->vbase == NULL) /* We were never bound to a VCI */
772 while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
773 lanai_free_skb(lvcc->tx.atmvcc, skb);
775 __clear_bit(lvcc->vci, lanai->backlog_vccs);
783 (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);
784 write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
786 read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
788 (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
789 (cardvcc_read(lvcc, vcc_txcbr_next) &
799 lvcc->tx.atmvcc->dev->number, lvcc->vci);
806 cardvcc_write(lvcc, 0, vcc_txreadptr);
807 cardvcc_write(lvcc, 0, vcc_txwriteptr);
808 cardvcc_write(lvcc, 0, vcc_txendptr);
809 cardvcc_write(lvcc, 0, vcc_txcrc1);
810 cardvcc_write(lvcc, 0, vcc_txcrc2);
811 cardvcc_write(lvcc, 0, vcc_txaddr2);
812 cardvcc_write(lvcc, 0, vcc_txaddr1);
1133 static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
1137 r -= ((unsigned long) lvcc->tx.buf.ptr) -
1138 ((unsigned long) lvcc->tx.buf.start);
1141 r += lanai_buf_size(&lvcc->tx.buf);
1146 static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
1148 return !skb_queue_empty(&lvcc->tx.backlog);
1158 static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
1162 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,
1163 "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
1164 lvcc->tx.buf.ptr += 4; /* Hope the values REALLY don't matter */
1165 pos = ((unsigned char *) lvcc->tx.buf.ptr) -
1166 (unsigned char *) lvcc->tx.buf.start;
1169 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1170 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1171 pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);
1174 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1175 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1176 lvcc->tx.buf.ptr[-1] =
1178 ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?
1180 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1181 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1185 static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
1188 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
1189 "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);
1190 lvcc->tx.buf.ptr += 2;
1191 lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
1192 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1193 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1196 static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
1201 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1202 m = e - (unsigned char *) lvcc->tx.buf.end;
1205 memcpy(lvcc->tx.buf.ptr, src, n - m);
1207 memcpy(lvcc->tx.buf.start, src + n - m, m);
1208 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1210 lvcc->tx.buf.ptr = (u32 *) e;
1213 static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
1219 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1220 m = e - (unsigned char *) lvcc->tx.buf.end;
1223 memset(lvcc->tx.buf.ptr, 0, n - m);
1225 memset(lvcc->tx.buf.start, 0, m);
1226 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1228 lvcc->tx.buf.ptr = (u32 *) e;
1233 const struct lanai_vcc *lvcc)
1235 int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
1236 (unsigned char *) lvcc->tx.buf.start;
1239 ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
1240 lvcc->tx.buf.end);
1269 reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
1274 * Add one AAL5 PDU to lvcc's transmit buffer. Caller garauntees there's
1278 struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
1284 vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);
1288 vcc_tx_memcpy(lvcc, skb->data, skb->len);
1289 vcc_tx_memzero(lvcc, pad);
1290 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
1291 lanai_endtx(lanai, lvcc);
1292 lanai_free_skb(lvcc->tx.atmvcc, skb);
1293 atomic_inc(&lvcc->tx.atmvcc->stats->tx);
1298 struct lanai_vcc *lvcc, int endptr)
1302 int space = vcc_tx_space(lvcc, endptr);
1303 APRINTK(vcc_is_backlogged(lvcc),
1305 lvcc->vci);
1307 skb = skb_dequeue(&lvcc->tx.backlog);
1313 skb_queue_head(&lvcc->tx.backlog, skb);
1316 lanai_send_one_aal5(lanai, lvcc, skb, n);
1319 if (!vcc_is_backlogged(lvcc)) {
1321 __clear_bit(lvcc->vci, lanai->backlog_vccs);
1326 static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1330 if (vcc_is_backlogged(lvcc)) /* Already backlogged */
1332 space = vcc_tx_space(lvcc,
1333 TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));
1337 __set_bit(lvcc->vci, lanai->backlog_vccs);
1339 skb_queue_tail(&lvcc->tx.backlog, skb);
1342 lanai_send_one_aal5(lanai, lvcc, skb, n);
1346 struct lanai_vcc *lvcc, int endptr)
1352 static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1356 /* Remember to increment lvcc->tx.atmvcc->stats->tx */
1357 lanai_free_skb(lvcc->tx.atmvcc, skb);
1364 const struct lanai_vcc *lvcc, int n)
1366 int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -
1367 ((const unsigned char *) (lvcc->rx.buf.end));
1370 memcpy(dest, lvcc->rx.buf.ptr, n - m);
1371 memcpy(dest + n - m, lvcc->rx.buf.start, m);
1377 static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
1382 u32 *end = &lvcc->rx.buf.start[endptr * 4];
1383 int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
1385 n += lanai_buf_size(&lvcc->rx.buf);
1386 APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),
1388 n, lanai_buf_size(&lvcc->rx.buf));
1390 if ((x = &end[-2]) < lvcc->rx.buf.start)
1391 x = &lvcc->rx.buf.end[-2];
1402 lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);
1403 lvcc->stats.x.aal5.rx_badlen++;
1406 skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);
1408 lvcc->stats.rx_nomem++;
1412 vcc_rx_memcpy(skb->data, lvcc, size);
1413 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
1415 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
1416 atomic_inc(&lvcc->rx.atmvcc->stats->rx);
1418 lvcc->rx.buf.ptr = end;
1419 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
1426 /* Remember to increment lvcc->rx.atmvcc->stats->rx */
1466 struct lanai_vcc *lvcc;
1467 lvcc = kzalloc(sizeof(*lvcc), GFP_KERNEL);
1468 if (likely(lvcc != NULL)) {
1469 skb_queue_head_init(&lvcc->tx.backlog);
1471 lvcc->vci = -1;
1474 return lvcc;
1499 struct lanai_vcc *lvcc, const struct atm_qos *qos)
1501 return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,
1506 static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1511 lvcc->tx.unqueue = vcc_tx_unqueue_aal0;
1515 lvcc->tx.unqueue = vcc_tx_unqueue_aal5;
1519 return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,
1524 struct lanai_vcc *lvcc, vci_t vci)
1526 if (lvcc->vbase != NULL)
1537 lvcc->vbase = cardvcc_addr(lanai, vci);
1538 lanai->vccs[lvcc->vci = vci] = lvcc;
1542 struct lanai_vcc *lvcc)
1544 if (lvcc->vbase == NULL)
1546 DPRINTK("Unbinding vci %d\n", lvcc->vci);
1547 lvcc->vbase = NULL;
1548 lanai->vccs[lvcc->vci] = NULL;
1619 struct lanai_vcc *lvcc;
1621 lvcc = lanai->vccs[vci];
1622 if (unlikely(lvcc == NULL)) {
1633 if (unlikely(lvcc->tx.atmvcc == NULL)) {
1641 lvcc->tx.endptr = SERVICE_GET_END(s);
1645 if (unlikely(lvcc->rx.atmvcc == NULL)) {
1652 if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {
1657 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1661 vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
1669 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1670 lvcc->stats.x.aal5.service_trash++;
1672 (((unsigned long) lvcc->rx.buf.ptr) -
1673 ((unsigned long) lvcc->rx.buf.start)) + 47;
1675 bytes += lanai_buf_size(&lvcc->rx.buf);
1681 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1682 lvcc->stats.x.aal5.service_stream++;
1689 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1690 lvcc->stats.x.aal5.service_rxcrc++;
1691 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
1692 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
1700 struct lanai_vcc *lvcc = lanai->vccs[vci];
1701 if (vcc_is_backlogged(lvcc))
1702 lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
1747 struct lanai_vcc *lvcc = lanai->vccs[vci];
1749 if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||
1750 !vcc_is_backlogged(lvcc)) {
1754 endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
1755 lvcc->tx.unqueue(lanai, lvcc, endptr);
1990 const struct lanai_vcc *lvcc = lanai->vccs[vci];
1993 if (unlikely(lvcc != NULL)) {
1995 lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)
1998 lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)
2275 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2277 if (lvcc == NULL)
2281 if (lvcc->rx.atmvcc == atmvcc) {
2282 lanai_shutdown_rx_vci(lvcc);
2287 lanai_buf_deallocate(&lvcc->rx.buf, lanai->pci);
2288 lvcc->rx.atmvcc = NULL;
2290 if (lvcc->tx.atmvcc == atmvcc) {
2292 if (lvcc->vbase != NULL)
2296 lanai_shutdown_tx_vci(lanai, lvcc);
2297 lanai_buf_deallocate(&lvcc->tx.buf, lanai->pci);
2298 lvcc->tx.atmvcc = NULL;
2300 if (--lvcc->nref == 0) {
2301 host_vcc_unbind(lanai, lvcc);
2302 kfree(lvcc);
2312 struct lanai_vcc *lvcc;
2329 lvcc = lanai->vccs[vci];
2330 if (lvcc == NULL) {
2331 lvcc = new_lanai_vcc();
2332 if (unlikely(lvcc == NULL))
2334 atmvcc->dev_data = lvcc;
2336 lvcc->nref++;
2338 APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",
2345 lanai, lvcc, &atmvcc->qos);
2348 lvcc->rx.atmvcc = atmvcc;
2349 lvcc->stats.rx_nomem = 0;
2350 lvcc->stats.x.aal5.rx_badlen = 0;
2351 lvcc->stats.x.aal5.service_trash = 0;
2352 lvcc->stats.x.aal5.service_stream = 0;
2353 lvcc->stats.x.aal5.service_rxcrc = 0;
2358 APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",
2360 result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos);
2363 lvcc->tx.atmvcc = atmvcc;
2370 host_vcc_bind(lanai, lvcc, vci);
2376 if (atmvcc == lvcc->rx.atmvcc)
2377 host_vcc_start_rx(lvcc);
2378 if (atmvcc == lvcc->tx.atmvcc) {
2379 host_vcc_start_tx(lvcc);
2393 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2396 if (unlikely(lvcc == NULL || lvcc->vbase == NULL ||
2397 lvcc->tx.atmvcc != atmvcc))
2413 vcc_tx_aal5(lanai, lvcc, skb);
2422 vcc_tx_aal0(lanai, lvcc, skb);
2446 struct lanai_vcc *lvcc;
2501 if ((lvcc = lanai->vccs[left]) != NULL)
2507 lvcc->nref, lvcc->stats.rx_nomem);
2508 if (lvcc->rx.atmvcc != NULL) {
2510 lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);
2511 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)
2515 lanai_buf_size(&lvcc->rx.buf),
2516 lvcc->stats.x.aal5.rx_badlen,
2517 lvcc->stats.x.aal5.service_trash,
2518 lvcc->stats.x.aal5.service_stream,
2519 lvcc->stats.x.aal5.service_rxcrc);
2521 if (lvcc->tx.atmvcc != NULL)
2524 lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,
2525 lanai_buf_size(&lvcc->tx.buf),
2526 lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',
2527 vcc_is_backlogged(lvcc) ? 'Y' : 'N');