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)
770 if (lvcc->vbase == NULL) /* We were never bound to a VCI */
773 while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
774 lanai_free_skb(lvcc->tx.atmvcc, skb);
776 __clear_bit(lvcc->vci, lanai->backlog_vccs);
784 (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);
785 write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
787 read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
789 (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
790 (cardvcc_read(lvcc, vcc_txcbr_next) &
800 lvcc->tx.atmvcc->dev->number, lvcc->vci);
807 cardvcc_write(lvcc, 0, vcc_txreadptr);
808 cardvcc_write(lvcc, 0, vcc_txwriteptr);
809 cardvcc_write(lvcc, 0, vcc_txendptr);
810 cardvcc_write(lvcc, 0, vcc_txcrc1);
811 cardvcc_write(lvcc, 0, vcc_txcrc2);
812 cardvcc_write(lvcc, 0, vcc_txaddr2);
813 cardvcc_write(lvcc, 0, vcc_txaddr1);
1134 static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
1138 r -= ((unsigned long) lvcc->tx.buf.ptr) -
1139 ((unsigned long) lvcc->tx.buf.start);
1142 r += lanai_buf_size(&lvcc->tx.buf);
1147 static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
1149 return !skb_queue_empty(&lvcc->tx.backlog);
1159 static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
1163 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,
1164 "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
1165 lvcc->tx.buf.ptr += 4; /* Hope the values REALLY don't matter */
1166 pos = ((unsigned char *) lvcc->tx.buf.ptr) -
1167 (unsigned char *) lvcc->tx.buf.start;
1170 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1171 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1172 pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);
1175 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1176 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1177 lvcc->tx.buf.ptr[-1] =
1179 ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?
1181 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1182 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1186 static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
1189 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
1190 "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);
1191 lvcc->tx.buf.ptr += 2;
1192 lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
1193 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1194 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1197 static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
1202 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1203 m = e - (unsigned char *) lvcc->tx.buf.end;
1206 memcpy(lvcc->tx.buf.ptr, src, n - m);
1208 memcpy(lvcc->tx.buf.start, src + n - m, m);
1209 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1211 lvcc->tx.buf.ptr = (u32 *) e;
1214 static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
1220 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1221 m = e - (unsigned char *) lvcc->tx.buf.end;
1224 memset(lvcc->tx.buf.ptr, 0, n - m);
1226 memset(lvcc->tx.buf.start, 0, m);
1227 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1229 lvcc->tx.buf.ptr = (u32 *) e;
1234 const struct lanai_vcc *lvcc)
1236 int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
1237 (unsigned char *) lvcc->tx.buf.start;
1240 ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
1241 lvcc->tx.buf.end);
1270 reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
1275 * Add one AAL5 PDU to lvcc's transmit buffer. Caller garauntees there's
1279 struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
1285 vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);
1289 vcc_tx_memcpy(lvcc, skb->data, skb->len);
1290 vcc_tx_memzero(lvcc, pad);
1291 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
1292 lanai_endtx(lanai, lvcc);
1293 lanai_free_skb(lvcc->tx.atmvcc, skb);
1294 atomic_inc(&lvcc->tx.atmvcc->stats->tx);
1299 struct lanai_vcc *lvcc, int endptr)
1303 int space = vcc_tx_space(lvcc, endptr);
1304 APRINTK(vcc_is_backlogged(lvcc),
1306 lvcc->vci);
1308 skb = skb_dequeue(&lvcc->tx.backlog);
1314 skb_queue_head(&lvcc->tx.backlog, skb);
1317 lanai_send_one_aal5(lanai, lvcc, skb, n);
1320 if (!vcc_is_backlogged(lvcc)) {
1322 __clear_bit(lvcc->vci, lanai->backlog_vccs);
1327 static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1331 if (vcc_is_backlogged(lvcc)) /* Already backlogged */
1333 space = vcc_tx_space(lvcc,
1334 TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));
1338 __set_bit(lvcc->vci, lanai->backlog_vccs);
1340 skb_queue_tail(&lvcc->tx.backlog, skb);
1343 lanai_send_one_aal5(lanai, lvcc, skb, n);
1347 struct lanai_vcc *lvcc, int endptr)
1353 static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1357 /* Remember to increment lvcc->tx.atmvcc->stats->tx */
1358 lanai_free_skb(lvcc->tx.atmvcc, skb);
1365 const struct lanai_vcc *lvcc, int n)
1367 int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -
1368 ((const unsigned char *) (lvcc->rx.buf.end));
1371 memcpy(dest, lvcc->rx.buf.ptr, n - m);
1372 memcpy(dest + n - m, lvcc->rx.buf.start, m);
1378 static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
1383 u32 *end = &lvcc->rx.buf.start[endptr * 4];
1384 int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
1386 n += lanai_buf_size(&lvcc->rx.buf);
1387 APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),
1389 n, lanai_buf_size(&lvcc->rx.buf));
1391 if ((x = &end[-2]) < lvcc->rx.buf.start)
1392 x = &lvcc->rx.buf.end[-2];
1403 lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);
1404 lvcc->stats.x.aal5.rx_badlen++;
1407 skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);
1409 lvcc->stats.rx_nomem++;
1413 vcc_rx_memcpy(skb->data, lvcc, size);
1414 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
1416 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
1417 atomic_inc(&lvcc->rx.atmvcc->stats->rx);
1419 lvcc->rx.buf.ptr = end;
1420 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
1427 /* Remember to increment lvcc->rx.atmvcc->stats->rx */
1467 struct lanai_vcc *lvcc;
1468 lvcc = kzalloc(sizeof(*lvcc), GFP_KERNEL);
1469 if (likely(lvcc != NULL)) {
1470 skb_queue_head_init(&lvcc->tx.backlog);
1472 lvcc->vci = -1;
1475 return lvcc;
1500 struct lanai_vcc *lvcc, const struct atm_qos *qos)
1502 return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,
1507 static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1512 lvcc->tx.unqueue = vcc_tx_unqueue_aal0;
1516 lvcc->tx.unqueue = vcc_tx_unqueue_aal5;
1520 return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,
1525 struct lanai_vcc *lvcc, vci_t vci)
1527 if (lvcc->vbase != NULL)
1538 lvcc->vbase = cardvcc_addr(lanai, vci);
1539 lanai->vccs[lvcc->vci = vci] = lvcc;
1543 struct lanai_vcc *lvcc)
1545 if (lvcc->vbase == NULL)
1547 DPRINTK("Unbinding vci %d\n", lvcc->vci);
1548 lvcc->vbase = NULL;
1549 lanai->vccs[lvcc->vci] = NULL;
1620 struct lanai_vcc *lvcc;
1622 lvcc = lanai->vccs[vci];
1623 if (unlikely(lvcc == NULL)) {
1634 if (unlikely(lvcc->tx.atmvcc == NULL)) {
1642 lvcc->tx.endptr = SERVICE_GET_END(s);
1646 if (unlikely(lvcc->rx.atmvcc == NULL)) {
1653 if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {
1658 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1662 vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
1670 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1671 lvcc->stats.x.aal5.service_trash++;
1673 (((unsigned long) lvcc->rx.buf.ptr) -
1674 ((unsigned long) lvcc->rx.buf.start)) + 47;
1676 bytes += lanai_buf_size(&lvcc->rx.buf);
1682 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1683 lvcc->stats.x.aal5.service_stream++;
1690 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1691 lvcc->stats.x.aal5.service_rxcrc++;
1692 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
1693 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
1701 struct lanai_vcc *lvcc = lanai->vccs[vci];
1702 if (vcc_is_backlogged(lvcc))
1703 lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
1748 struct lanai_vcc *lvcc = lanai->vccs[vci];
1750 if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||
1751 !vcc_is_backlogged(lvcc)) {
1755 endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
1756 lvcc->tx.unqueue(lanai, lvcc, endptr);
1991 const struct lanai_vcc *lvcc = lanai->vccs[vci];
1994 if (unlikely(lvcc != NULL)) {
1996 lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)
1999 lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)
2276 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2278 if (lvcc == NULL)
2282 if (lvcc->rx.atmvcc == atmvcc) {
2283 lanai_shutdown_rx_vci(lvcc);
2288 lanai_buf_deallocate(&lvcc->rx.buf, lanai->pci);
2289 lvcc->rx.atmvcc = NULL;
2291 if (lvcc->tx.atmvcc == atmvcc) {
2293 if (lvcc->vbase != NULL)
2297 lanai_shutdown_tx_vci(lanai, lvcc);
2298 lanai_buf_deallocate(&lvcc->tx.buf, lanai->pci);
2299 lvcc->tx.atmvcc = NULL;
2301 if (--lvcc->nref == 0) {
2302 host_vcc_unbind(lanai, lvcc);
2303 kfree(lvcc);
2313 struct lanai_vcc *lvcc;
2330 lvcc = lanai->vccs[vci];
2331 if (lvcc == NULL) {
2332 lvcc = new_lanai_vcc();
2333 if (unlikely(lvcc == NULL))
2335 atmvcc->dev_data = lvcc;
2337 lvcc->nref++;
2339 APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",
2346 lanai, lvcc, &atmvcc->qos);
2349 lvcc->rx.atmvcc = atmvcc;
2350 lvcc->stats.rx_nomem = 0;
2351 lvcc->stats.x.aal5.rx_badlen = 0;
2352 lvcc->stats.x.aal5.service_trash = 0;
2353 lvcc->stats.x.aal5.service_stream = 0;
2354 lvcc->stats.x.aal5.service_rxcrc = 0;
2359 APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",
2361 result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos);
2364 lvcc->tx.atmvcc = atmvcc;
2371 host_vcc_bind(lanai, lvcc, vci);
2377 if (atmvcc == lvcc->rx.atmvcc)
2378 host_vcc_start_rx(lvcc);
2379 if (atmvcc == lvcc->tx.atmvcc) {
2380 host_vcc_start_tx(lvcc);
2394 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2397 if (unlikely(lvcc == NULL || lvcc->vbase == NULL ||
2398 lvcc->tx.atmvcc != atmvcc))
2414 vcc_tx_aal5(lanai, lvcc, skb);
2423 vcc_tx_aal0(lanai, lvcc, skb);
2447 struct lanai_vcc *lvcc;
2502 if ((lvcc = lanai->vccs[left]) != NULL)
2508 lvcc->nref, lvcc->stats.rx_nomem);
2509 if (lvcc->rx.atmvcc != NULL) {
2511 lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);
2512 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)
2516 lanai_buf_size(&lvcc->rx.buf),
2517 lvcc->stats.x.aal5.rx_badlen,
2518 lvcc->stats.x.aal5.service_trash,
2519 lvcc->stats.x.aal5.service_stream,
2520 lvcc->stats.x.aal5.service_rxcrc);
2522 if (lvcc->tx.atmvcc != NULL)
2525 lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,
2526 lanai_buf_size(&lvcc->tx.buf),
2527 lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',
2528 vcc_is_backlogged(lvcc) ? 'Y' : 'N');