| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: midway.c,v 1.86 2009/03/14 15:36:17 dsl Exp $ */ | | 1 | /* $NetBSD: midway.c,v 1.87 2009/03/15 15:52:12 cegger Exp $ */ |
2 | /* (sync'd to midway.c 1.68) */ | | 2 | /* (sync'd to midway.c 1.68) */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * | | 5 | * |
6 | * Copyright (c) 1996 Charles D. Cranor and Washington University. | | 6 | * Copyright (c) 1996 Charles D. Cranor and Washington University. |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | * - support pvc sub interface | | 58 | * - support pvc sub interface |
59 | * | | 59 | * |
60 | * initial work on per-pvc-interface for ipv6 was done | | 60 | * initial work on per-pvc-interface for ipv6 was done |
61 | * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project. | | 61 | * by Katsushi Kobayashi <ikob@cc.uec.ac.jp> of the WIDE Project. |
62 | * some of the extensions for pvc subinterfaces are merged from | | 62 | * some of the extensions for pvc subinterfaces are merged from |
63 | * the CAIRN project written by Suresh Bhogavilli (suresh@isi.edu). | | 63 | * the CAIRN project written by Suresh Bhogavilli (suresh@isi.edu). |
64 | * | | 64 | * |
65 | * code cleanup: | | 65 | * code cleanup: |
66 | * - remove WMAYBE related code. ENI WMAYBE DMA doesn't work. | | 66 | * - remove WMAYBE related code. ENI WMAYBE DMA doesn't work. |
67 | * - remove updating if_lastchange for every packet. | | 67 | * - remove updating if_lastchange for every packet. |
68 | */ | | 68 | */ |
69 | | | 69 | |
70 | #include <sys/cdefs.h> | | 70 | #include <sys/cdefs.h> |
71 | __KERNEL_RCSID(0, "$NetBSD: midway.c,v 1.86 2009/03/14 15:36:17 dsl Exp $"); | | 71 | __KERNEL_RCSID(0, "$NetBSD: midway.c,v 1.87 2009/03/15 15:52:12 cegger Exp $"); |
72 | | | 72 | |
73 | #include "opt_natm.h" | | 73 | #include "opt_natm.h" |
74 | | | 74 | |
75 | #undef EN_DEBUG | | 75 | #undef EN_DEBUG |
76 | #undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */ | | 76 | #undef EN_DEBUG_RANGE /* check ranges on en_read/en_write's? */ |
77 | #define EN_MBUF_OPT /* try and put more stuff in mbuf? */ | | 77 | #define EN_MBUF_OPT /* try and put more stuff in mbuf? */ |
78 | #define EN_DIAG | | 78 | #define EN_DIAG |
79 | #define EN_STAT | | 79 | #define EN_STAT |
80 | #ifndef EN_DMA | | 80 | #ifndef EN_DMA |
81 | #define EN_DMA 1 /* use DMA? */ | | 81 | #define EN_DMA 1 /* use DMA? */ |
82 | #endif | | 82 | #endif |
83 | #define EN_NOTXDMA 0 /* hook to disable tx DMA only */ | | 83 | #define EN_NOTXDMA 0 /* hook to disable tx DMA only */ |
84 | #define EN_NORXDMA 0 /* hook to disable rx DMA only */ | | 84 | #define EN_NORXDMA 0 /* hook to disable rx DMA only */ |
| @@ -485,141 +485,119 @@ static struct ifnet *en_vci2ifp(struct e | | | @@ -485,141 +485,119 @@ static struct ifnet *en_vci2ifp(struct e |
485 | * [2] autoconfig stuff | | 485 | * [2] autoconfig stuff |
486 | * [3] ioctl stuff | | 486 | * [3] ioctl stuff |
487 | * [4] reset -> init -> transmit -> intr -> receive functions | | 487 | * [4] reset -> init -> transmit -> intr -> receive functions |
488 | * | | 488 | * |
489 | */ | | 489 | */ |
490 | | | 490 | |
491 | /***********************************************************************/ | | 491 | /***********************************************************************/ |
492 | | | 492 | |
493 | /* | | 493 | /* |
494 | * en_read: read a word from the card. this is the only function | | 494 | * en_read: read a word from the card. this is the only function |
495 | * that reads from the card. | | 495 | * that reads from the card. |
496 | */ | | 496 | */ |
497 | | | 497 | |
498 | STATIC INLINE u_int32_t en_read(sc, r) | | 498 | STATIC INLINE u_int32_t en_read(struct en_softc *sc, uint32_t r) |
499 | | | | |
500 | struct en_softc *sc; | | | |
501 | u_int32_t r; | | | |
502 | | | | |
503 | { | | 499 | { |
504 | | | 500 | |
505 | #ifdef EN_DEBUG_RANGE | | 501 | #ifdef EN_DEBUG_RANGE |
506 | if (r > MID_MAXOFF || (r % 4)) | | 502 | if (r > MID_MAXOFF || (r % 4)) |
507 | panic("en_read out of range, r=0x%x", r); | | 503 | panic("en_read out of range, r=0x%x", r); |
508 | #endif | | 504 | #endif |
509 | | | 505 | |
510 | return(bus_space_read_4(sc->en_memt, sc->en_base, r)); | | 506 | return(bus_space_read_4(sc->en_memt, sc->en_base, r)); |
511 | } | | 507 | } |
512 | | | 508 | |
513 | /* | | 509 | /* |
514 | * en_write: write a word to the card. this is the only function that | | 510 | * en_write: write a word to the card. this is the only function that |
515 | * writes to the card. | | 511 | * writes to the card. |
516 | */ | | 512 | */ |
517 | | | 513 | |
518 | STATIC INLINE void en_write(sc, r, v) | | 514 | STATIC INLINE void en_write(struct en_softc *sc, uint32_t r, uint32_t v) |
519 | | | | |
520 | struct en_softc *sc; | | | |
521 | u_int32_t r, v; | | | |
522 | | | | |
523 | { | | 515 | { |
524 | #ifdef EN_DEBUG_RANGE | | 516 | #ifdef EN_DEBUG_RANGE |
525 | if (r > MID_MAXOFF || (r % 4)) | | 517 | if (r > MID_MAXOFF || (r % 4)) |
526 | panic("en_write out of range, r=0x%x", r); | | 518 | panic("en_write out of range, r=0x%x", r); |
527 | #endif | | 519 | #endif |
528 | | | 520 | |
529 | bus_space_write_4(sc->en_memt, sc->en_base, r, v); | | 521 | bus_space_write_4(sc->en_memt, sc->en_base, r, v); |
530 | } | | 522 | } |
531 | | | 523 | |
532 | /* | | 524 | /* |
533 | * en_k2sz: convert KBytes to a size parameter (a log2) | | 525 | * en_k2sz: convert KBytes to a size parameter (a log2) |
534 | */ | | 526 | */ |
535 | | | 527 | |
536 | STATIC INLINE int en_k2sz(k) | | 528 | STATIC INLINE int en_k2sz(int k) |
537 | | | | |
538 | int k; | | | |
539 | | | | |
540 | { | | 529 | { |
541 | switch(k) { | | 530 | switch(k) { |
542 | case 1: return(0); | | 531 | case 1: return(0); |
543 | case 2: return(1); | | 532 | case 2: return(1); |
544 | case 4: return(2); | | 533 | case 4: return(2); |
545 | case 8: return(3); | | 534 | case 8: return(3); |
546 | case 16: return(4); | | 535 | case 16: return(4); |
547 | case 32: return(5); | | 536 | case 32: return(5); |
548 | case 64: return(6); | | 537 | case 64: return(6); |
549 | case 128: return(7); | | 538 | case 128: return(7); |
550 | default: panic("en_k2sz"); | | 539 | default: panic("en_k2sz"); |
551 | } | | 540 | } |
552 | return(0); | | 541 | return(0); |
553 | } | | 542 | } |
554 | #define en_log2(X) en_k2sz(X) | | 543 | #define en_log2(X) en_k2sz(X) |
555 | | | 544 | |
556 | | | 545 | |
557 | /* | | 546 | /* |
558 | * en_b2sz: convert a DMA burst code to its byte size | | 547 | * en_b2sz: convert a DMA burst code to its byte size |
559 | */ | | 548 | */ |
560 | | | 549 | |
561 | STATIC INLINE int en_b2sz(b) | | 550 | STATIC INLINE int en_b2sz(int b) |
562 | | | | |
563 | int b; | | | |
564 | | | | |
565 | { | | 551 | { |
566 | switch (b) { | | 552 | switch (b) { |
567 | case MIDDMA_WORD: return(1*4); | | 553 | case MIDDMA_WORD: return(1*4); |
568 | case MIDDMA_2WMAYBE: | | 554 | case MIDDMA_2WMAYBE: |
569 | case MIDDMA_2WORD: return(2*4); | | 555 | case MIDDMA_2WORD: return(2*4); |
570 | case MIDDMA_4WMAYBE: | | 556 | case MIDDMA_4WMAYBE: |
571 | case MIDDMA_4WORD: return(4*4); | | 557 | case MIDDMA_4WORD: return(4*4); |
572 | case MIDDMA_8WMAYBE: | | 558 | case MIDDMA_8WMAYBE: |
573 | case MIDDMA_8WORD: return(8*4); | | 559 | case MIDDMA_8WORD: return(8*4); |
574 | case MIDDMA_16WMAYBE: | | 560 | case MIDDMA_16WMAYBE: |
575 | case MIDDMA_16WORD: return(16*4); | | 561 | case MIDDMA_16WORD: return(16*4); |
576 | default: panic("en_b2sz"); | | 562 | default: panic("en_b2sz"); |
577 | } | | 563 | } |
578 | return(0); | | 564 | return(0); |
579 | } | | 565 | } |
580 | | | 566 | |
581 | | | 567 | |
582 | /* | | 568 | /* |
583 | * en_sz2b: convert a burst size (bytes) to DMA burst code | | 569 | * en_sz2b: convert a burst size (bytes) to DMA burst code |
584 | */ | | 570 | */ |
585 | | | 571 | |
586 | STATIC INLINE int en_sz2b(sz) | | 572 | STATIC INLINE int en_sz2b(int sz) |
587 | | | | |
588 | int sz; | | | |
589 | | | | |
590 | { | | 573 | { |
591 | switch (sz) { | | 574 | switch (sz) { |
592 | case 1*4: return(MIDDMA_WORD); | | 575 | case 1*4: return(MIDDMA_WORD); |
593 | case 2*4: return(MIDDMA_2WORD); | | 576 | case 2*4: return(MIDDMA_2WORD); |
594 | case 4*4: return(MIDDMA_4WORD); | | 577 | case 4*4: return(MIDDMA_4WORD); |
595 | case 8*4: return(MIDDMA_8WORD); | | 578 | case 8*4: return(MIDDMA_8WORD); |
596 | case 16*4: return(MIDDMA_16WORD); | | 579 | case 16*4: return(MIDDMA_16WORD); |
597 | default: panic("en_sz2b"); | | 580 | default: panic("en_sz2b"); |
598 | } | | 581 | } |
599 | return(0); | | 582 | return(0); |
600 | } | | 583 | } |
601 | | | 584 | |
602 | | | 585 | |
603 | /* | | 586 | /* |
604 | * en_dqneed: calculate number of DTQ/DRQ's needed for a buffer | | 587 | * en_dqneed: calculate number of DTQ/DRQ's needed for a buffer |
605 | */ | | 588 | */ |
606 | | | 589 | |
607 | STATIC INLINE int en_dqneed(sc, data, len, tx) | | 590 | STATIC INLINE int en_dqneed(struct en_softc *sc, void *data, u_int len, u_int tx) |
608 | | | | |
609 | struct en_softc *sc; | | | |
610 | void *data; | | | |
611 | u_int len, tx; | | | |
612 | | | | |
613 | { | | 591 | { |
614 | int result, needalign, sz; | | 592 | int result, needalign, sz; |
615 | | | 593 | |
616 | #if !defined(MIDWAY_ENIONLY) | | 594 | #if !defined(MIDWAY_ENIONLY) |
617 | #if !defined(MIDWAY_ADPONLY) | | 595 | #if !defined(MIDWAY_ADPONLY) |
618 | if (sc->is_adaptec) | | 596 | if (sc->is_adaptec) |
619 | #endif /* !MIDWAY_ADPONLY */ | | 597 | #endif /* !MIDWAY_ADPONLY */ |
620 | return(1); /* adaptec can DMA anything in one go */ | | 598 | return(1); /* adaptec can DMA anything in one go */ |
621 | #endif | | 599 | #endif |
622 | | | 600 | |
623 | #if !defined(MIDWAY_ADPONLY) | | 601 | #if !defined(MIDWAY_ADPONLY) |
624 | result = 0; | | 602 | result = 0; |
625 | if (len < EN_MINDMA) { | | 603 | if (len < EN_MINDMA) { |
| @@ -660,31 +638,27 @@ u_int len, tx; | | | @@ -660,31 +638,27 @@ u_int len, tx; |
660 | } | | 638 | } |
661 | | | 639 | |
662 | return(result); | | 640 | return(result); |
663 | #endif /* !MIDWAY_ADPONLY */ | | 641 | #endif /* !MIDWAY_ADPONLY */ |
664 | } | | 642 | } |
665 | | | 643 | |
666 | | | 644 | |
667 | /* | | 645 | /* |
668 | * en_mget: get an mbuf chain that can hold totlen bytes and return it | | 646 | * en_mget: get an mbuf chain that can hold totlen bytes and return it |
669 | * (for recv) [based on am7990_get from if_le and ieget from if_ie] | | 647 | * (for recv) [based on am7990_get from if_le and ieget from if_ie] |
670 | * after this call the sum of all the m_len's in the chain will be totlen. | | 648 | * after this call the sum of all the m_len's in the chain will be totlen. |
671 | */ | | 649 | */ |
672 | | | 650 | |
673 | STATIC INLINE struct mbuf *en_mget(sc, totlen, drqneed) | | 651 | STATIC INLINE struct mbuf *en_mget(struct en_softc *sc, u_int totlen, u_int *drqneed) |
674 | | | | |
675 | struct en_softc *sc; | | | |
676 | u_int totlen, *drqneed; | | | |
677 | | | | |
678 | { | | 652 | { |
679 | struct mbuf *m; | | 653 | struct mbuf *m; |
680 | struct mbuf *top, **mp; | | 654 | struct mbuf *top, **mp; |
681 | *drqneed = 0; | | 655 | *drqneed = 0; |
682 | | | 656 | |
683 | MGETHDR(m, M_DONTWAIT, MT_DATA); | | 657 | MGETHDR(m, M_DONTWAIT, MT_DATA); |
684 | if (m == NULL) | | 658 | if (m == NULL) |
685 | return(NULL); | | 659 | return(NULL); |
686 | m->m_pkthdr.rcvif = &sc->enif; | | 660 | m->m_pkthdr.rcvif = &sc->enif; |
687 | m->m_pkthdr.len = totlen; | | 661 | m->m_pkthdr.len = totlen; |
688 | m->m_len = MHLEN; | | 662 | m->m_len = MHLEN; |
689 | top = NULL; | | 663 | top = NULL; |
690 | mp = ⊤ | | 664 | mp = ⊤ |
| @@ -715,30 +689,27 @@ u_int totlen, *drqneed; | | | @@ -715,30 +689,27 @@ u_int totlen, *drqneed; |
715 | | | 689 | |
716 | *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0); | | 690 | *drqneed += en_dqneed(sc, m->m_data, m->m_len, 0); |
717 | | | 691 | |
718 | } | | 692 | } |
719 | return(top); | | 693 | return(top); |
720 | } | | 694 | } |
721 | | | 695 | |
722 | /***********************************************************************/ | | 696 | /***********************************************************************/ |
723 | | | 697 | |
724 | /* | | 698 | /* |
725 | * autoconfig stuff | | 699 | * autoconfig stuff |
726 | */ | | 700 | */ |
727 | | | 701 | |
728 | void en_attach(sc) | | 702 | void en_attach(struct en_softc *sc) |
729 | | | | |
730 | struct en_softc *sc; | | | |
731 | | | | |
732 | { | | 703 | { |
733 | struct ifnet *ifp = &sc->enif; | | 704 | struct ifnet *ifp = &sc->enif; |
734 | int sz; | | 705 | int sz; |
735 | u_int32_t reg, lcv, check, ptr, sav, midvloc; | | 706 | u_int32_t reg, lcv, check, ptr, sav, midvloc; |
736 | | | 707 | |
737 | /* | | 708 | /* |
738 | * probe card to determine memory size. the stupid ENI card always | | 709 | * probe card to determine memory size. the stupid ENI card always |
739 | * reports to PCI that it needs 4MB of space (2MB regs and 2MB RAM). | | 710 | * reports to PCI that it needs 4MB of space (2MB regs and 2MB RAM). |
740 | * if it has less than 2MB RAM the addresses wrap in the RAM address space. | | 711 | * if it has less than 2MB RAM the addresses wrap in the RAM address space. |
741 | * (i.e. on a 512KB card addresses 0x3ffffc, 0x37fffc, and 0x2ffffc | | 712 | * (i.e. on a 512KB card addresses 0x3ffffc, 0x37fffc, and 0x2ffffc |
742 | * are aliases for 0x27fffc [note that RAM starts at offset 0x200000]). | | 713 | * are aliases for 0x27fffc [note that RAM starts at offset 0x200000]). |
743 | */ | | 714 | */ |
744 | | | 715 | |
| @@ -924,30 +895,27 @@ done_probe: | | | @@ -924,30 +895,27 @@ done_probe: |
924 | * en_dmaprobe: helper function for en_attach. | | 895 | * en_dmaprobe: helper function for en_attach. |
925 | * | | 896 | * |
926 | * see how the card handles DMA by running a few DMA tests. we need | | 897 | * see how the card handles DMA by running a few DMA tests. we need |
927 | * to figure out the largest number of bytes we can DMA in one burst | | 898 | * to figure out the largest number of bytes we can DMA in one burst |
928 | * ("bestburstlen"), and if the starting address for a burst needs to | | 899 | * ("bestburstlen"), and if the starting address for a burst needs to |
929 | * be aligned on any sort of boundary or not ("alburst"). | | 900 | * be aligned on any sort of boundary or not ("alburst"). |
930 | * | | 901 | * |
931 | * typical findings: | | 902 | * typical findings: |
932 | * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!) | | 903 | * sparc1: bestburstlen=4, alburst=0 (ick, broken DMA!) |
933 | * sparc2: bestburstlen=64, alburst=1 | | 904 | * sparc2: bestburstlen=64, alburst=1 |
934 | * p166: bestburstlen=64, alburst=0 | | 905 | * p166: bestburstlen=64, alburst=0 |
935 | */ | | 906 | */ |
936 | | | 907 | |
937 | STATIC void en_dmaprobe(sc) | | 908 | STATIC void en_dmaprobe(struct en_softc *sc) |
938 | | | | |
939 | struct en_softc *sc; | | | |
940 | | | | |
941 | { | | 909 | { |
942 | u_int32_t srcbuf[64], dstbuf[64]; | | 910 | u_int32_t srcbuf[64], dstbuf[64]; |
943 | u_int8_t *sp, *dp; | | 911 | u_int8_t *sp, *dp; |
944 | int bestalgn, bestnotalgn, lcv, try, fail; | | 912 | int bestalgn, bestnotalgn, lcv, try, fail; |
945 | | | 913 | |
946 | sc->alburst = 0; | | 914 | sc->alburst = 0; |
947 | | | 915 | |
948 | sp = (u_int8_t *) srcbuf; | | 916 | sp = (u_int8_t *) srcbuf; |
949 | while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0) | | 917 | while ((((unsigned long) sp) % MIDDMA_MAXBURST) != 0) |
950 | sp += 4; | | 918 | sp += 4; |
951 | dp = (u_int8_t *) dstbuf; | | 919 | dp = (u_int8_t *) dstbuf; |
952 | while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0) | | 920 | while ((((unsigned long) dp) % MIDDMA_MAXBURST) != 0) |
953 | dp += 4; | | 921 | dp += 4; |
| @@ -999,32 +967,27 @@ struct en_softc *sc; | | | @@ -999,32 +967,27 @@ struct en_softc *sc; |
999 | aprint_error_dev(&sc->sc_dev, "WARNING: WMAYBE DMA test failed %d time(s)\n", | | 967 | aprint_error_dev(&sc->sc_dev, "WARNING: WMAYBE DMA test failed %d time(s)\n", |
1000 | fail); | | 968 | fail); |
1001 | en_dmaplan = en_dma_planB; /* fall back to plan B */ | | 969 | en_dmaplan = en_dma_planB; /* fall back to plan B */ |
1002 | } | | 970 | } |
1003 | | | 971 | |
1004 | } | | 972 | } |
1005 | | | 973 | |
1006 | | | 974 | |
1007 | /* | | 975 | /* |
1008 | * en_dmaprobe_doit: do actual testing | | 976 | * en_dmaprobe_doit: do actual testing |
1009 | */ | | 977 | */ |
1010 | | | 978 | |
1011 | int | | 979 | int |
1012 | en_dmaprobe_doit(sc, sp, dp, wmtry) | | 980 | en_dmaprobe_doit(struct en_softc *sc, uint8_t *sp, uint8_t *dp, int wmtry) |
1013 | | | | |
1014 | struct en_softc *sc; | | | |
1015 | u_int8_t *sp, *dp; | | | |
1016 | int wmtry; | | | |
1017 | | | | |
1018 | { | | 981 | { |
1019 | int lcv, retval = 4, cnt, count; | | 982 | int lcv, retval = 4, cnt, count; |
1020 | u_int32_t reg, bcode, midvloc; | | 983 | u_int32_t reg, bcode, midvloc; |
1021 | | | 984 | |
1022 | /* | | 985 | /* |
1023 | * set up a 1k buffer at MID_BUFOFF | | 986 | * set up a 1k buffer at MID_BUFOFF |
1024 | */ | | 987 | */ |
1025 | | | 988 | |
1026 | if (sc->en_busreset) | | 989 | if (sc->en_busreset) |
1027 | sc->en_busreset(sc); | | 990 | sc->en_busreset(sc); |
1028 | EN_WRITE(sc, MID_RESID, 0x0); /* reset card before touching RAM */ | | 991 | EN_WRITE(sc, MID_RESID, 0x0); /* reset card before touching RAM */ |
1029 | | | 992 | |
1030 | midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT; | | 993 | midvloc = ((MID_BUFOFF - MID_RAMOFF) / sizeof(u_int32_t)) >> MIDV_LOCTOPSHFT; |
| @@ -1135,32 +1098,27 @@ int wmtry; | | | @@ -1135,32 +1098,27 @@ int wmtry; |
1135 | | | 1098 | |
1136 | /***********************************************************************/ | | 1099 | /***********************************************************************/ |
1137 | | | 1100 | |
1138 | /* | | 1101 | /* |
1139 | * en_ioctl: handle ioctl requests | | 1102 | * en_ioctl: handle ioctl requests |
1140 | * | | 1103 | * |
1141 | * NOTE: if you add an ioctl to set txspeed, you should choose a new | | 1104 | * NOTE: if you add an ioctl to set txspeed, you should choose a new |
1142 | * TX channel/slot. Choose the one with the lowest sc->txslot[slot].nref | | 1105 | * TX channel/slot. Choose the one with the lowest sc->txslot[slot].nref |
1143 | * value, subtract one from sc->txslot[0].nref, add one to the | | 1106 | * value, subtract one from sc->txslot[0].nref, add one to the |
1144 | * sc->txslot[slot].nref, set sc->txvc2slot[vci] = slot, and then set | | 1107 | * sc->txslot[slot].nref, set sc->txvc2slot[vci] = slot, and then set |
1145 | * txspeed[vci]. | | 1108 | * txspeed[vci]. |
1146 | */ | | 1109 | */ |
1147 | | | 1110 | |
1148 | STATIC int en_ioctl(ifp, cmd, data) | | 1111 | STATIC int en_ioctl(struct ifnet *ifp, EN_IOCTL_CMDT cmd, void *data) |
1149 | | | | |
1150 | struct ifnet *ifp; | | | |
1151 | EN_IOCTL_CMDT cmd; | | | |
1152 | void *data; | | | |
1153 | | | | |
1154 | { | | 1112 | { |
1155 | #ifdef MISSING_IF_SOFTC | | 1113 | #ifdef MISSING_IF_SOFTC |
1156 | struct en_softc *sc = (struct en_softc *)device_lookup_private(&en_cd, ifp->if_unit); | | 1114 | struct en_softc *sc = (struct en_softc *)device_lookup_private(&en_cd, ifp->if_unit); |
1157 | #else | | 1115 | #else |
1158 | struct en_softc *sc = (struct en_softc *) ifp->if_softc; | | 1116 | struct en_softc *sc = (struct en_softc *) ifp->if_softc; |
1159 | #endif | | 1117 | #endif |
1160 | struct ifaddr *ifa = (struct ifaddr *) data; | | 1118 | struct ifaddr *ifa = (struct ifaddr *) data; |
1161 | struct ifreq *ifr = (struct ifreq *) data; | | 1119 | struct ifreq *ifr = (struct ifreq *) data; |
1162 | struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data; | | 1120 | struct atm_pseudoioctl *api = (struct atm_pseudoioctl *)data; |
1163 | #ifdef NATM | | 1121 | #ifdef NATM |
1164 | struct atm_rawioctl *ario = (struct atm_rawioctl *)data; | | 1122 | struct atm_rawioctl *ario = (struct atm_rawioctl *)data; |
1165 | int slot; | | 1123 | int slot; |
1166 | #endif | | 1124 | #endif |
| @@ -1337,32 +1295,27 @@ void *data; | | | @@ -1337,32 +1295,27 @@ void *data; |
1337 | default: | | 1295 | default: |
1338 | error = ifioctl_common(ifp, cmd, data); | | 1296 | error = ifioctl_common(ifp, cmd, data); |
1339 | break; | | 1297 | break; |
1340 | } | | 1298 | } |
1341 | splx(s); | | 1299 | splx(s); |
1342 | return error; | | 1300 | return error; |
1343 | } | | 1301 | } |
1344 | | | 1302 | |
1345 | | | 1303 | |
1346 | /* | | 1304 | /* |
1347 | * en_rxctl: turn on and off VCs for recv. | | 1305 | * en_rxctl: turn on and off VCs for recv. |
1348 | */ | | 1306 | */ |
1349 | | | 1307 | |
1350 | STATIC int en_rxctl(sc, pi, on) | | 1308 | STATIC int en_rxctl(struct en_softc *sc, struct atm_pseudoioctl *pi, int on) |
1351 | | | | |
1352 | struct en_softc *sc; | | | |
1353 | struct atm_pseudoioctl *pi; | | | |
1354 | int on; | | | |
1355 | | | | |
1356 | { | | 1309 | { |
1357 | u_int s, vci, flags, slot; | | 1310 | u_int s, vci, flags, slot; |
1358 | u_int32_t oldmode, newmode; | | 1311 | u_int32_t oldmode, newmode; |
1359 | | | 1312 | |
1360 | vci = ATM_PH_VCI(&pi->aph); | | 1313 | vci = ATM_PH_VCI(&pi->aph); |
1361 | flags = ATM_PH_FLAGS(&pi->aph); | | 1314 | flags = ATM_PH_FLAGS(&pi->aph); |
1362 | | | 1315 | |
1363 | #ifdef EN_DEBUG | | 1316 | #ifdef EN_DEBUG |
1364 | printf("%s: %s vpi=%d, vci=%d, flags=%d\n", device_xname(&sc->sc_dev), | | 1317 | printf("%s: %s vpi=%d, vci=%d, flags=%d\n", device_xname(&sc->sc_dev), |
1365 | (on) ? "enable" : "disable", ATM_PH_VPI(&pi->aph), vci, flags); | | 1318 | (on) ? "enable" : "disable", ATM_PH_VPI(&pi->aph), vci, flags); |
1366 | #endif | | 1319 | #endif |
1367 | | | 1320 | |
1368 | if (ATM_PH_VPI(&pi->aph) || vci >= MID_N_VC) | | 1321 | if (ATM_PH_VPI(&pi->aph) || vci >= MID_N_VC) |
| @@ -1435,30 +1388,27 @@ int on; | | | @@ -1435,30 +1388,27 @@ int on; |
1435 | printf("%s: rx%d: VCI %d is now %s\n", device_xname(&sc->sc_dev), slot, vci, | | 1388 | printf("%s: rx%d: VCI %d is now %s\n", device_xname(&sc->sc_dev), slot, vci, |
1436 | (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) ? "draining" : "free"); | | 1389 | (sc->rxslot[slot].oth_flags & ENOTHER_DRAIN) ? "draining" : "free"); |
1437 | #endif | | 1390 | #endif |
1438 | return(0); | | 1391 | return(0); |
1439 | } | | 1392 | } |
1440 | | | 1393 | |
1441 | /***********************************************************************/ | | 1394 | /***********************************************************************/ |
1442 | | | 1395 | |
1443 | /* | | 1396 | /* |
1444 | * en_reset: reset the board, throw away work in progress. | | 1397 | * en_reset: reset the board, throw away work in progress. |
1445 | * must en_init to recover. | | 1398 | * must en_init to recover. |
1446 | */ | | 1399 | */ |
1447 | | | 1400 | |
1448 | void en_reset(sc) | | 1401 | void en_reset(struct en_softc *sc) |
1449 | | | | |
1450 | struct en_softc *sc; | | | |
1451 | | | | |
1452 | { | | 1402 | { |
1453 | struct mbuf *m; | | 1403 | struct mbuf *m; |
1454 | int lcv, slot; | | 1404 | int lcv, slot; |
1455 | | | 1405 | |
1456 | #ifdef EN_DEBUG | | 1406 | #ifdef EN_DEBUG |
1457 | printf("%s: reset\n", device_xname(&sc->sc_dev)); | | 1407 | printf("%s: reset\n", device_xname(&sc->sc_dev)); |
1458 | #endif | | 1408 | #endif |
1459 | | | 1409 | |
1460 | if (sc->en_busreset) | | 1410 | if (sc->en_busreset) |
1461 | sc->en_busreset(sc); | | 1411 | sc->en_busreset(sc); |
1462 | EN_WRITE(sc, MID_RESID, 0x0); /* reset hardware */ | | 1412 | EN_WRITE(sc, MID_RESID, 0x0); /* reset hardware */ |
1463 | | | 1413 | |
1464 | /* | | 1414 | /* |
| @@ -1510,30 +1460,27 @@ struct en_softc *sc; | | | @@ -1510,30 +1460,27 @@ struct en_softc *sc; |
1510 | m_freem(m); | | 1460 | m_freem(m); |
1511 | } | | 1461 | } |
1512 | sc->txslot[lcv].mbsize = 0; | | 1462 | sc->txslot[lcv].mbsize = 0; |
1513 | } | | 1463 | } |
1514 | | | 1464 | |
1515 | return; | | 1465 | return; |
1516 | } | | 1466 | } |
1517 | | | 1467 | |
1518 | | | 1468 | |
1519 | /* | | 1469 | /* |
1520 | * en_init: init board and sync the card with the data in the softc. | | 1470 | * en_init: init board and sync the card with the data in the softc. |
1521 | */ | | 1471 | */ |
1522 | | | 1472 | |
1523 | STATIC void en_init(sc) | | 1473 | STATIC void en_init(struct en_softc *sc) |
1524 | | | | |
1525 | struct en_softc *sc; | | | |
1526 | | | | |
1527 | { | | 1474 | { |
1528 | int vc, slot; | | 1475 | int vc, slot; |
1529 | u_int32_t loc; | | 1476 | u_int32_t loc; |
1530 | #ifdef ATM_PVCEXT | | 1477 | #ifdef ATM_PVCEXT |
1531 | struct pvcsif *pvcsif; | | 1478 | struct pvcsif *pvcsif; |
1532 | #endif | | 1479 | #endif |
1533 | | | 1480 | |
1534 | if ((sc->enif.if_flags & IFF_UP) == 0) { | | 1481 | if ((sc->enif.if_flags & IFF_UP) == 0) { |
1535 | #ifdef ATM_PVCEXT | | 1482 | #ifdef ATM_PVCEXT |
1536 | LIST_FOREACH(pvcsif, &sc->sif_list, sif_links) { | | 1483 | LIST_FOREACH(pvcsif, &sc->sif_list, sif_links) { |
1537 | if (pvcsif->sif_if.if_flags & IFF_UP) { | | 1484 | if (pvcsif->sif_if.if_flags & IFF_UP) { |
1538 | /* | | 1485 | /* |
1539 | * down the device only when there is no active pvc subinterface. | | 1486 | * down the device only when there is no active pvc subinterface. |
| @@ -1631,31 +1578,27 @@ struct en_softc *sc; | | | @@ -1631,31 +1578,27 @@ struct en_softc *sc; |
1631 | EN_WRITE(sc, MID_INTENA, MID_INT_TX|MID_INT_DMA_OVR|MID_INT_IDENT| | | 1578 | EN_WRITE(sc, MID_INTENA, MID_INT_TX|MID_INT_DMA_OVR|MID_INT_IDENT| |
1632 | MID_INT_LERR|MID_INT_DMA_ERR|MID_INT_DMA_RX|MID_INT_DMA_TX| | | 1579 | MID_INT_LERR|MID_INT_DMA_ERR|MID_INT_DMA_RX|MID_INT_DMA_TX| |
1633 | MID_INT_SERVICE| /* >>> MID_INT_SUNI| XXXCDC<<< */ MID_INT_STATS); | | 1580 | MID_INT_SERVICE| /* >>> MID_INT_SUNI| XXXCDC<<< */ MID_INT_STATS); |
1634 | EN_WRITE(sc, MID_MAST_CSR, MID_SETIPL(sc->ipl)|MID_MCSR_ENDMA| | | 1581 | EN_WRITE(sc, MID_MAST_CSR, MID_SETIPL(sc->ipl)|MID_MCSR_ENDMA| |
1635 | MID_MCSR_ENTX|MID_MCSR_ENRX); | | 1582 | MID_MCSR_ENTX|MID_MCSR_ENRX); |
1636 | | | 1583 | |
1637 | } | | 1584 | } |
1638 | | | 1585 | |
1639 | | | 1586 | |
1640 | /* | | 1587 | /* |
1641 | * en_loadvc: load a vc tab entry from a slot | | 1588 | * en_loadvc: load a vc tab entry from a slot |
1642 | */ | | 1589 | */ |
1643 | | | 1590 | |
1644 | STATIC void en_loadvc(sc, vc) | | 1591 | STATIC void en_loadvc(struct en_softc *sc, int vc) |
1645 | | | | |
1646 | struct en_softc *sc; | | | |
1647 | int vc; | | | |
1648 | | | | |
1649 | { | | 1592 | { |
1650 | int slot; | | 1593 | int slot; |
1651 | u_int32_t reg = EN_READ(sc, MID_VC(vc)); | | 1594 | u_int32_t reg = EN_READ(sc, MID_VC(vc)); |
1652 | | | 1595 | |
1653 | reg = MIDV_SETMODE(reg, MIDV_TRASH); | | 1596 | reg = MIDV_SETMODE(reg, MIDV_TRASH); |
1654 | EN_WRITE(sc, MID_VC(vc), reg); | | 1597 | EN_WRITE(sc, MID_VC(vc), reg); |
1655 | DELAY(27); | | 1598 | DELAY(27); |
1656 | | | 1599 | |
1657 | if ((slot = sc->rxvc2slot[vc]) == RX_NONE) | | 1600 | if ((slot = sc->rxvc2slot[vc]) == RX_NONE) |
1658 | return; | | 1601 | return; |
1659 | | | 1602 | |
1660 | /* no need to set CRC */ | | 1603 | /* no need to set CRC */ |
1661 | EN_WRITE(sc, MID_DST_RP(vc), 0); /* read pointer = 0, desc. start = 0 */ | | 1604 | EN_WRITE(sc, MID_DST_RP(vc), 0); /* read pointer = 0, desc. start = 0 */ |
| @@ -1664,30 +1607,27 @@ int vc; | | | @@ -1664,30 +1607,27 @@ int vc; |
1664 | sc->rxslot[slot].cur = sc->rxslot[slot].start; | | 1607 | sc->rxslot[slot].cur = sc->rxslot[slot].start; |
1665 | | | 1608 | |
1666 | #ifdef EN_DEBUG | | 1609 | #ifdef EN_DEBUG |
1667 | printf("%s: rx%d: assigned to VCI %d\n", device_xname(&sc->sc_dev), slot, vc); | | 1610 | printf("%s: rx%d: assigned to VCI %d\n", device_xname(&sc->sc_dev), slot, vc); |
1668 | #endif | | 1611 | #endif |
1669 | } | | 1612 | } |
1670 | | | 1613 | |
1671 | | | 1614 | |
1672 | /* | | 1615 | /* |
1673 | * en_start: start transmitting the next packet that needs to go out | | 1616 | * en_start: start transmitting the next packet that needs to go out |
1674 | * if there is one. note that atm_output() has already splnet()'d us. | | 1617 | * if there is one. note that atm_output() has already splnet()'d us. |
1675 | */ | | 1618 | */ |
1676 | | | 1619 | |
1677 | STATIC void en_start(ifp) | | 1620 | STATIC void en_start(struct ifnet *ifp) |
1678 | | | | |
1679 | struct ifnet *ifp; | | | |
1680 | | | | |
1681 | { | | 1621 | { |
1682 | #ifdef MISSING_IF_SOFTC | | 1622 | #ifdef MISSING_IF_SOFTC |
1683 | struct en_softc *sc = (struct en_softc *)device_lookup_private(&en_cd, ifp->if_unit); | | 1623 | struct en_softc *sc = (struct en_softc *)device_lookup_private(&en_cd, ifp->if_unit); |
1684 | #else | | 1624 | #else |
1685 | struct en_softc *sc = (struct en_softc *) ifp->if_softc; | | 1625 | struct en_softc *sc = (struct en_softc *) ifp->if_softc; |
1686 | #endif | | 1626 | #endif |
1687 | struct mbuf *m, *lastm, *prev; | | 1627 | struct mbuf *m, *lastm, *prev; |
1688 | struct atm_pseudohdr *ap, *new_ap; | | 1628 | struct atm_pseudohdr *ap, *new_ap; |
1689 | int txchan, mlen, got, need, toadd, cellcnt, first; | | 1629 | int txchan, mlen, got, need, toadd, cellcnt, first; |
1690 | u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal; | | 1630 | u_int32_t atm_vpi, atm_vci, atm_flags, *dat, aal; |
1691 | u_int8_t *cp; | | 1631 | u_int8_t *cp; |
1692 | | | 1632 | |
1693 | if ((ifp->if_flags & IFF_RUNNING) == 0) | | 1633 | if ((ifp->if_flags & IFF_RUNNING) == 0) |
| @@ -1858,31 +1798,27 @@ struct ifnet *ifp; | | | @@ -1858,31 +1798,27 @@ struct ifnet *ifp; |
1858 | en_txdma(sc, txchan); | | 1798 | en_txdma(sc, txchan); |
1859 | | | 1799 | |
1860 | } | | 1800 | } |
1861 | /*NOTREACHED*/ | | 1801 | /*NOTREACHED*/ |
1862 | } | | 1802 | } |
1863 | | | 1803 | |
1864 | | | 1804 | |
1865 | /* | | 1805 | /* |
1866 | * en_mfix: fix a stupid mbuf | | 1806 | * en_mfix: fix a stupid mbuf |
1867 | */ | | 1807 | */ |
1868 | | | 1808 | |
1869 | #ifndef __FreeBSD__ | | 1809 | #ifndef __FreeBSD__ |
1870 | | | 1810 | |
1871 | STATIC int en_mfix(sc, mm, prev) | | 1811 | STATIC int en_mfix(struct en_softc *sc, struct mbuf **mm, struct mbuf *prev) |
1872 | | | | |
1873 | struct en_softc *sc; | | | |
1874 | struct mbuf **mm, *prev; | | | |
1875 | | | | |
1876 | { | | 1812 | { |
1877 | struct mbuf *m, *new; | | 1813 | struct mbuf *m, *new; |
1878 | u_char *d, *cp; | | 1814 | u_char *d, *cp; |
1879 | int off; | | 1815 | int off; |
1880 | struct mbuf *nxt; | | 1816 | struct mbuf *nxt; |
1881 | | | 1817 | |
1882 | m = *mm; | | 1818 | m = *mm; |
1883 | | | 1819 | |
1884 | EN_COUNT(sc->mfix); /* count # of calls */ | | 1820 | EN_COUNT(sc->mfix); /* count # of calls */ |
1885 | #ifdef EN_DEBUG | | 1821 | #ifdef EN_DEBUG |
1886 | printf("%s: mfix mbuf m_data=%p, m_len=%d\n", device_xname(&sc->sc_dev), | | 1822 | printf("%s: mfix mbuf m_data=%p, m_len=%d\n", device_xname(&sc->sc_dev), |
1887 | m->m_data, m->m_len); | | 1823 | m->m_data, m->m_len); |
1888 | #endif | | 1824 | #endif |
| @@ -2066,31 +2002,27 @@ struct mbuf **mm, *prev; | | | @@ -2066,31 +2002,27 @@ struct mbuf **mm, *prev; |
2066 | nxt->m_data = (void *)cp; | | 2002 | nxt->m_data = (void *)cp; |
2067 | } | | 2003 | } |
2068 | if (nxt != NULL && nxt->m_len == 0) | | 2004 | if (nxt != NULL && nxt->m_len == 0) |
2069 | m->m_next = m_free(nxt); | | 2005 | m->m_next = m_free(nxt); |
2070 | return(1); | | 2006 | return(1); |
2071 | } | | 2007 | } |
2072 | | | 2008 | |
2073 | #endif /* __FreeBSD__ */ | | 2009 | #endif /* __FreeBSD__ */ |
2074 | | | 2010 | |
2075 | /* | | 2011 | /* |
2076 | * en_txdma: start transmit DMA, if possible | | 2012 | * en_txdma: start transmit DMA, if possible |
2077 | */ | | 2013 | */ |
2078 | | | 2014 | |
2079 | STATIC void en_txdma(sc, chan) | | 2015 | STATIC void en_txdma(struct en_softc *sc, int chan) |
2080 | | | | |
2081 | struct en_softc *sc; | | | |
2082 | int chan; | | | |
2083 | | | | |
2084 | { | | 2016 | { |
2085 | struct mbuf *tmp; | | 2017 | struct mbuf *tmp; |
2086 | struct atm_pseudohdr *ap; | | 2018 | struct atm_pseudohdr *ap; |
2087 | struct en_launch launch; | | 2019 | struct en_launch launch; |
2088 | int datalen = 0, dtqneed, len, ncells; | | 2020 | int datalen = 0, dtqneed, len, ncells; |
2089 | u_int8_t *cp; | | 2021 | u_int8_t *cp; |
2090 | struct ifnet *ifp; | | 2022 | struct ifnet *ifp; |
2091 | | | 2023 | |
2092 | memset(&launch, 0, sizeof launch); /* XXX gcc */ | | 2024 | memset(&launch, 0, sizeof launch); /* XXX gcc */ |
2093 | | | 2025 | |
2094 | #ifdef EN_DEBUG | | 2026 | #ifdef EN_DEBUG |
2095 | printf("%s: tx%d: starting...\n", device_xname(&sc->sc_dev), chan); | | 2027 | printf("%s: tx%d: starting...\n", device_xname(&sc->sc_dev), chan); |
2096 | #endif | | 2028 | #endif |
| @@ -2297,32 +2229,27 @@ dequeue_drop: | | | @@ -2297,32 +2229,27 @@ dequeue_drop: |
2297 | IF_DEQUEUE(&sc->txslot[chan].q, tmp); | | 2229 | IF_DEQUEUE(&sc->txslot[chan].q, tmp); |
2298 | if (launch.t != tmp) | | 2230 | if (launch.t != tmp) |
2299 | panic("en dequeue drop"); | | 2231 | panic("en dequeue drop"); |
2300 | m_freem(launch.t); | | 2232 | m_freem(launch.t); |
2301 | sc->txslot[chan].mbsize -= launch.mlen; | | 2233 | sc->txslot[chan].mbsize -= launch.mlen; |
2302 | goto again; | | 2234 | goto again; |
2303 | } | | 2235 | } |
2304 | | | 2236 | |
2305 | | | 2237 | |
2306 | /* | | 2238 | /* |
2307 | * en_txlaunch: launch an mbuf into the DMA pool! | | 2239 | * en_txlaunch: launch an mbuf into the DMA pool! |
2308 | */ | | 2240 | */ |
2309 | | | 2241 | |
2310 | STATIC void en_txlaunch(sc, chan, l) | | 2242 | STATIC void en_txlaunch(struct en_softc *sc, int chan, struct en_launch *l) |
2311 | | | | |
2312 | struct en_softc *sc; | | | |
2313 | int chan; | | | |
2314 | struct en_launch *l; | | | |
2315 | | | | |
2316 | { | | 2243 | { |
2317 | struct mbuf *tmp; | | 2244 | struct mbuf *tmp; |
2318 | u_int32_t cur = sc->txslot[chan].cur, | | 2245 | u_int32_t cur = sc->txslot[chan].cur, |
2319 | start = sc->txslot[chan].start, | | 2246 | start = sc->txslot[chan].start, |
2320 | stop = sc->txslot[chan].stop, | | 2247 | stop = sc->txslot[chan].stop, |
2321 | dma, *data, *datastop, count, bcode; | | 2248 | dma, *data, *datastop, count, bcode; |
2322 | int pad, addtail, need, len, needalign, cnt, end, mx; | | 2249 | int pad, addtail, need, len, needalign, cnt, end, mx; |
2323 | | | 2250 | |
2324 | | | 2251 | |
2325 | /* | | 2252 | /* |
2326 | * vars: | | 2253 | * vars: |
2327 | * need = # bytes card still needs (decr. to zero) | | 2254 | * need = # bytes card still needs (decr. to zero) |
2328 | * len = # of bytes left in current mbuf | | 2255 | * len = # of bytes left in current mbuf |
| @@ -2654,30 +2581,27 @@ done: | | | @@ -2654,30 +2581,27 @@ done: |
2654 | #ifdef EN_DEBUG | | 2581 | #ifdef EN_DEBUG |
2655 | printf("%s: tx%d: DONE! cur now = 0x%x\n", | | 2582 | printf("%s: tx%d: DONE! cur now = 0x%x\n", |
2656 | device_xname(&sc->sc_dev), chan, cur); | | 2583 | device_xname(&sc->sc_dev), chan, cur); |
2657 | #endif | | 2584 | #endif |
2658 | | | 2585 | |
2659 | return; | | 2586 | return; |
2660 | } | | 2587 | } |
2661 | | | 2588 | |
2662 | | | 2589 | |
2663 | /* | | 2590 | /* |
2664 | * interrupt handler | | 2591 | * interrupt handler |
2665 | */ | | 2592 | */ |
2666 | | | 2593 | |
2667 | EN_INTR_TYPE en_intr(arg) | | 2594 | EN_INTR_TYPE en_intr(void *arg) |
2668 | | | | |
2669 | void *arg; | | | |
2670 | | | | |
2671 | { | | 2595 | { |
2672 | struct en_softc *sc = (struct en_softc *) arg; | | 2596 | struct en_softc *sc = (struct en_softc *) arg; |
2673 | struct mbuf *m; | | 2597 | struct mbuf *m; |
2674 | struct atm_pseudohdr ah; | | 2598 | struct atm_pseudohdr ah; |
2675 | struct ifnet *ifp; | | 2599 | struct ifnet *ifp; |
2676 | u_int32_t reg, kick, val, mask, chip, vci, slot, dtq, drq; | | 2600 | u_int32_t reg, kick, val, mask, chip, vci, slot, dtq, drq; |
2677 | int lcv, idx, need_softserv = 0; | | 2601 | int lcv, idx, need_softserv = 0; |
2678 | | | 2602 | |
2679 | reg = EN_READ(sc, MID_INTACK); | | 2603 | reg = EN_READ(sc, MID_INTACK); |
2680 | | | 2604 | |
2681 | if ((reg & MID_INT_ANY) == 0) | | 2605 | if ((reg & MID_INT_ANY) == 0) |
2682 | EN_INTR_RET(0); /* not us */ | | 2606 | EN_INTR_RET(0); /* not us */ |
2683 | | | 2607 | |
| @@ -2960,30 +2884,27 @@ void *arg; | | | @@ -2960,30 +2884,27 @@ void *arg; |
2960 | * A: if we remove a VCI from the hardware list and we find that we are | | 2884 | * A: if we remove a VCI from the hardware list and we find that we are |
2961 | * out of DRQs we must defer processing until some DRQs become free. | | 2885 | * out of DRQs we must defer processing until some DRQs become free. |
2962 | * so we must remember to look at this RX VCI/slot later, but we can't | | 2886 | * so we must remember to look at this RX VCI/slot later, but we can't |
2963 | * put it back on the hardware service list (since that isn't allowed). | | 2887 | * put it back on the hardware service list (since that isn't allowed). |
2964 | * so we instead save it on the software service list. it would be nice | | 2888 | * so we instead save it on the software service list. it would be nice |
2965 | * if we could peek at the VCI on top of the hwservice list without removing | | 2889 | * if we could peek at the VCI on top of the hwservice list without removing |
2966 | * it, however this leads to a race condition: if we peek at it and | | 2890 | * it, however this leads to a race condition: if we peek at it and |
2967 | * decide we are done with it new data could come in before we have a | | 2891 | * decide we are done with it new data could come in before we have a |
2968 | * chance to remove it from the hwslist. by the time we get it out of | | 2892 | * chance to remove it from the hwslist. by the time we get it out of |
2969 | * the list the interrupt for the new data will be lost. oops! | | 2893 | * the list the interrupt for the new data will be lost. oops! |
2970 | * | | 2894 | * |
2971 | */ | | 2895 | */ |
2972 | | | 2896 | |
2973 | STATIC void en_service(sc) | | 2897 | STATIC void en_service(struct en_softc *sc) |
2974 | | | | |
2975 | struct en_softc *sc; | | | |
2976 | | | | |
2977 | { | | 2898 | { |
2978 | struct mbuf *m, *tmp; | | 2899 | struct mbuf *m, *tmp; |
2979 | u_int32_t cur, dstart, rbd, pdu, *sav, dma, bcode, count, *data, *datastop; | | 2900 | u_int32_t cur, dstart, rbd, pdu, *sav, dma, bcode, count, *data, *datastop; |
2980 | u_int32_t start, stop, cnt, needalign; | | 2901 | u_int32_t start, stop, cnt, needalign; |
2981 | int slot, raw, aal5, vci, fill, mlen, tlen, drqneed, need, needfill, end; | | 2902 | int slot, raw, aal5, vci, fill, mlen, tlen, drqneed, need, needfill, end; |
2982 | | | 2903 | |
2983 | aal5 = 0; /* Silence gcc */ | | 2904 | aal5 = 0; /* Silence gcc */ |
2984 | next_vci: | | 2905 | next_vci: |
2985 | if (sc->swsl_size == 0) { | | 2906 | if (sc->swsl_size == 0) { |
2986 | #ifdef EN_DEBUG | | 2907 | #ifdef EN_DEBUG |
2987 | printf("%s: en_service done\n", device_xname(&sc->sc_dev)); | | 2908 | printf("%s: en_service done\n", device_xname(&sc->sc_dev)); |
2988 | #endif | | 2909 | #endif |
2989 | return; /* >>> exit here if swsl now empty <<< */ | | 2910 | return; /* >>> exit here if swsl now empty <<< */ |
| @@ -3393,30 +3314,27 @@ done: | | | @@ -3393,30 +3314,27 @@ done: |
3393 | * en_dump: dump the state | | 3314 | * en_dump: dump the state |
3394 | */ | | 3315 | */ |
3395 | | | 3316 | |
3396 | #define END_SWSL 0x00000040 /* swsl state */ | | 3317 | #define END_SWSL 0x00000040 /* swsl state */ |
3397 | #define END_DRQ 0x00000020 /* drq state */ | | 3318 | #define END_DRQ 0x00000020 /* drq state */ |
3398 | #define END_DTQ 0x00000010 /* dtq state */ | | 3319 | #define END_DTQ 0x00000010 /* dtq state */ |
3399 | #define END_RX 0x00000008 /* rx state */ | | 3320 | #define END_RX 0x00000008 /* rx state */ |
3400 | #define END_TX 0x00000004 /* tx state */ | | 3321 | #define END_TX 0x00000004 /* tx state */ |
3401 | #define END_MREGS 0x00000002 /* registers */ | | 3322 | #define END_MREGS 0x00000002 /* registers */ |
3402 | #define END_STATS 0x00000001 /* dump stats */ | | 3323 | #define END_STATS 0x00000001 /* dump stats */ |
3403 | | | 3324 | |
3404 | #define END_BITS "\20\7SWSL\6DRQ\5DTQ\4RX\3TX\2MREGS\1STATS" | | 3325 | #define END_BITS "\20\7SWSL\6DRQ\5DTQ\4RX\3TX\2MREGS\1STATS" |
3405 | | | 3326 | |
3406 | int en_dump(unit, level) | | 3327 | int en_dump(int unit, int level) |
3407 | | | | |
3408 | int unit, level; | | | |
3409 | | | | |
3410 | { | | 3328 | { |
3411 | struct en_softc *sc; | | 3329 | struct en_softc *sc; |
3412 | int lcv, cnt, slot; | | 3330 | int lcv, cnt, slot; |
3413 | u_int32_t ptr, reg; | | 3331 | u_int32_t ptr, reg; |
3414 | | | 3332 | |
3415 | for (lcv = 0 ; lcv < en_cd.cd_ndevs ; lcv++) { | | 3333 | for (lcv = 0 ; lcv < en_cd.cd_ndevs ; lcv++) { |
3416 | char sbuf[256]; | | 3334 | char sbuf[256]; |
3417 | | | 3335 | |
3418 | sc = device_lookup_private(&en_cd, lcv); | | 3336 | sc = device_lookup_private(&en_cd, lcv); |
3419 | if (sc == NULL) continue; | | 3337 | if (sc == NULL) continue; |
3420 | if (unit != -1 && unit != lcv) | | 3338 | if (unit != -1 && unit != lcv) |
3421 | continue; | | 3339 | continue; |
3422 | | | 3340 | |
| @@ -3563,30 +3481,27 @@ int unit, level; | | | @@ -3563,30 +3481,27 @@ int unit, level; |
3563 | for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ; | | 3481 | for (cnt = sc->swsl_head ; cnt != sc->swsl_tail ; |
3564 | cnt = (cnt + 1) % MID_SL_N) | | 3482 | cnt = (cnt + 1) % MID_SL_N) |
3565 | printf("0x%x ", sc->swslist[cnt]); | | 3483 | printf("0x%x ", sc->swslist[cnt]); |
3566 | printf("\n"); | | 3484 | printf("\n"); |
3567 | } | | 3485 | } |
3568 | } | | 3486 | } |
3569 | return(0); | | 3487 | return(0); |
3570 | } | | 3488 | } |
3571 | | | 3489 | |
3572 | /* | | 3490 | /* |
3573 | * en_dumpmem: dump the memory | | 3491 | * en_dumpmem: dump the memory |
3574 | */ | | 3492 | */ |
3575 | | | 3493 | |
3576 | int en_dumpmem(unit, addr, len) | | 3494 | int en_dumpmem(int unit, int addr, int len) |
3577 | | | | |
3578 | int unit, addr, len; | | | |
3579 | | | | |
3580 | { | | 3495 | { |
3581 | struct en_softc *sc; | | 3496 | struct en_softc *sc; |
3582 | u_int32_t reg; | | 3497 | u_int32_t reg; |
3583 | | | 3498 | |
3584 | sc = device_lookup_private(&en_cd, unit); | | 3499 | sc = device_lookup_private(&en_cd, unit); |
3585 | if (sc == NULL) { | | 3500 | if (sc == NULL) { |
3586 | printf("invalid unit number: %d\n", unit); | | 3501 | printf("invalid unit number: %d\n", unit); |
3587 | return(0); | | 3502 | return(0); |
3588 | } | | 3503 | } |
3589 | addr = addr & ~3; | | 3504 | addr = addr & ~3; |
3590 | if (addr < MID_RAMOFF || addr + len*4 > MID_MAXOFF || len <= 0) { | | 3505 | if (addr < MID_RAMOFF || addr + len*4 > MID_MAXOFF || len <= 0) { |
3591 | printf("invalid addr/len number: %d, %d\n", addr, len); | | 3506 | printf("invalid addr/len number: %d, %d\n", addr, len); |
3592 | return(0); | | 3507 | return(0); |
| @@ -3602,29 +3517,27 @@ int unit, addr, len; | | | @@ -3602,29 +3517,27 @@ int unit, addr, len; |
3602 | #endif | | 3517 | #endif |
3603 | | | 3518 | |
3604 | #ifdef ATM_PVCEXT | | 3519 | #ifdef ATM_PVCEXT |
3605 | /* | | 3520 | /* |
3606 | * ATM PVC extension: shaper control and pvc subinterfaces | | 3521 | * ATM PVC extension: shaper control and pvc subinterfaces |
3607 | */ | | 3522 | */ |
3608 | | | 3523 | |
3609 | /* | | 3524 | /* |
3610 | * the list of the interfaces sharing the physical device. | | 3525 | * the list of the interfaces sharing the physical device. |
3611 | * in order to avoid starvation, the interfaces are scheduled in | | 3526 | * in order to avoid starvation, the interfaces are scheduled in |
3612 | * a round-robin fashion when en_start is called from tx complete | | 3527 | * a round-robin fashion when en_start is called from tx complete |
3613 | * interrupts. | | 3528 | * interrupts. |
3614 | */ | | 3529 | */ |
3615 | static void rrp_add(sc, ifp) | | 3530 | static void rrp_add(struct en_softc *sc, struct ifnet *ifp) |
3616 | struct en_softc *sc; | | | |
3617 | struct ifnet *ifp; | | | |
3618 | { | | 3531 | { |
3619 | struct rrp *head, *p, *new; | | 3532 | struct rrp *head, *p, *new; |
3620 | | | 3533 | |
3621 | head = sc->txrrp; | | 3534 | head = sc->txrrp; |
3622 | if ((p = head) != NULL) { | | 3535 | if ((p = head) != NULL) { |
3623 | while (1) { | | 3536 | while (1) { |
3624 | if (p->ifp == ifp) { | | 3537 | if (p->ifp == ifp) { |
3625 | /* an entry for this ifp already exits */ | | 3538 | /* an entry for this ifp already exits */ |
3626 | p->nref++; | | 3539 | p->nref++; |
3627 | return; | | 3540 | return; |
3628 | } | | 3541 | } |
3629 | if (p->next == head) | | 3542 | if (p->next == head) |
3630 | break; | | 3543 | break; |
| @@ -3645,29 +3558,27 @@ static void rrp_add(sc, ifp) | | | @@ -3645,29 +3558,27 @@ static void rrp_add(sc, ifp) |
3645 | if (p == NULL) { | | 3558 | if (p == NULL) { |
3646 | /* this is the only one in the list */ | | 3559 | /* this is the only one in the list */ |
3647 | new->next = new; | | 3560 | new->next = new; |
3648 | sc->txrrp = new; | | 3561 | sc->txrrp = new; |
3649 | } | | 3562 | } |
3650 | else { | | 3563 | else { |
3651 | /* add the new entry at the tail of the list */ | | 3564 | /* add the new entry at the tail of the list */ |
3652 | new->next = p->next; | | 3565 | new->next = p->next; |
3653 | p->next = new; | | 3566 | p->next = new; |
3654 | } | | 3567 | } |
3655 | } | | 3568 | } |
3656 | | | 3569 | |
3657 | #if 0 /* not used */ | | 3570 | #if 0 /* not used */ |
3658 | static void rrp_delete(sc, ifp) | | 3571 | static void rrp_delete(struct en_softc *sc, struct ifnet *ifp) |
3659 | struct en_softc *sc; | | | |
3660 | struct ifnet *ifp; | | | |
3661 | { | | 3572 | { |
3662 | struct rrp *head, *p, *prev; | | 3573 | struct rrp *head, *p, *prev; |
3663 | | | 3574 | |
3664 | head = sc->txrrp; | | 3575 | head = sc->txrrp; |
3665 | | | 3576 | |
3666 | prev = head; | | 3577 | prev = head; |
3667 | if (prev == NULL) { | | 3578 | if (prev == NULL) { |
3668 | printf("rrp_delete: no list!\n"); | | 3579 | printf("rrp_delete: no list!\n"); |
3669 | return; | | 3580 | return; |
3670 | } | | 3581 | } |
3671 | p = prev->next; | | 3582 | p = prev->next; |
3672 | | | 3583 | |
3673 | while (1) { | | 3584 | while (1) { |
| @@ -3737,28 +3648,27 @@ en_pvcattach(struct ifnet *ifp) | | | @@ -3737,28 +3648,27 @@ en_pvcattach(struct ifnet *ifp) |
3737 | #ifdef ATM_PVCEXT | | 3648 | #ifdef ATM_PVCEXT |
3738 | rrp_add(sc, pvc_ifp); | | 3649 | rrp_add(sc, pvc_ifp); |
3739 | #endif | | 3650 | #endif |
3740 | splx(s); | | 3651 | splx(s); |
3741 | | | 3652 | |
3742 | return (pvc_ifp); | | 3653 | return (pvc_ifp); |
3743 | } | | 3654 | } |
3744 | | | 3655 | |
3745 | | | 3656 | |
3746 | /* txspeed conversion derived from linux drivers/atm/eni.c | | 3657 | /* txspeed conversion derived from linux drivers/atm/eni.c |
3747 | by Werner Almesberger, EPFL LRC */ | | 3658 | by Werner Almesberger, EPFL LRC */ |
3748 | static const int pre_div[] = { 4,16,128,2048 }; | | 3659 | static const int pre_div[] = { 4,16,128,2048 }; |
3749 | | | 3660 | |
3750 | static int en_pcr2txspeed(pcr) | | 3661 | static int en_pcr2txspeed(int pcr) |
3751 | int pcr; | | | |
3752 | { | | 3662 | { |
3753 | int pre, res, div; | | 3663 | int pre, res, div; |
3754 | | | 3664 | |
3755 | if (pcr == 0 || pcr > 347222) | | 3665 | if (pcr == 0 || pcr > 347222) |
3756 | pre = res = 0; /* max rate */ | | 3666 | pre = res = 0; /* max rate */ |
3757 | else { | | 3667 | else { |
3758 | for (pre = 0; pre < 3; pre++) | | 3668 | for (pre = 0; pre < 3; pre++) |
3759 | if (25000000/pre_div[pre]/64 <= pcr) | | 3669 | if (25000000/pre_div[pre]/64 <= pcr) |
3760 | break; | | 3670 | break; |
3761 | div = pre_div[pre]*(pcr); | | 3671 | div = pre_div[pre]*(pcr); |
3762 | #if 1 | | 3672 | #if 1 |
3763 | /* | | 3673 | /* |
3764 | * the shaper value should be rounded down, | | 3674 | * the shaper value should be rounded down, |
| @@ -3767,48 +3677,43 @@ static int en_pcr2txspeed(pcr) | | | @@ -3767,48 +3677,43 @@ static int en_pcr2txspeed(pcr) |
3767 | */ | | 3677 | */ |
3768 | res = (25000000 + div -1)/div - 1; | | 3678 | res = (25000000 + div -1)/div - 1; |
3769 | #else | | 3679 | #else |
3770 | res = 25000000/div-1; | | 3680 | res = 25000000/div-1; |
3771 | #endif | | 3681 | #endif |
3772 | if (res < 0) | | 3682 | if (res < 0) |
3773 | res = 0; | | 3683 | res = 0; |
3774 | if (res > 63) | | 3684 | if (res > 63) |
3775 | res = 63; | | 3685 | res = 63; |
3776 | } | | 3686 | } |
3777 | return ((pre << 6) + res); | | 3687 | return ((pre << 6) + res); |
3778 | } | | 3688 | } |
3779 | | | 3689 | |
3780 | static int en_txspeed2pcr(txspeed) | | 3690 | static int en_txspeed2pcr(int txspeed) |
3781 | int txspeed; | | | |
3782 | { | | 3691 | { |
3783 | int pre, res, pcr; | | 3692 | int pre, res, pcr; |
3784 | | | 3693 | |
3785 | pre = (txspeed >> 6) & 0x3; | | 3694 | pre = (txspeed >> 6) & 0x3; |
3786 | res = txspeed & 0x3f; | | 3695 | res = txspeed & 0x3f; |
3787 | pcr = 25000000 / pre_div[pre] / (res+1); | | 3696 | pcr = 25000000 / pre_div[pre] / (res+1); |
3788 | return (pcr); | | 3697 | return (pcr); |
3789 | } | | 3698 | } |
3790 | | | 3699 | |
3791 | /* | | 3700 | /* |
3792 | * en_txctl selects a hardware transmit channel and sets the shaper value. | | 3701 | * en_txctl selects a hardware transmit channel and sets the shaper value. |
3793 | * en_txctl should be called after enabling the vc by en_rxctl | | 3702 | * en_txctl should be called after enabling the vc by en_rxctl |
3794 | * since it assumes a transmit channel is already assigned by en_rxctl | | 3703 | * since it assumes a transmit channel is already assigned by en_rxctl |
3795 | * to the vc. | | 3704 | * to the vc. |
3796 | */ | | 3705 | */ |
3797 | static int en_txctl(sc, vci, joint_vci, pcr) | | 3706 | static int en_txctl(struct en_softc *sc, int vci, int joint_vci, int pcr) |
3798 | struct en_softc *sc; | | | |
3799 | int vci; | | | |
3800 | int joint_vci; | | | |
3801 | int pcr; | | | |
3802 | { | | 3707 | { |
3803 | int txspeed, txchan, s; | | 3708 | int txspeed, txchan, s; |
3804 | | | 3709 | |
3805 | if (pcr) | | 3710 | if (pcr) |
3806 | txspeed = en_pcr2txspeed(pcr); | | 3711 | txspeed = en_pcr2txspeed(pcr); |
3807 | else | | 3712 | else |
3808 | txspeed = 0; | | 3713 | txspeed = 0; |
3809 | | | 3714 | |
3810 | s = splnet(); | | 3715 | s = splnet(); |
3811 | txchan = sc->txvc2slot[vci]; | | 3716 | txchan = sc->txvc2slot[vci]; |
3812 | sc->txslot[txchan].nref--; | | 3717 | sc->txslot[txchan].nref--; |
3813 | | | 3718 | |
3814 | /* select a slot */ | | 3719 | /* select a slot */ |
| @@ -3846,29 +3751,27 @@ static int en_txctl(sc, vci, joint_vci, | | | @@ -3846,29 +3751,27 @@ static int en_txctl(sc, vci, joint_vci, |
3846 | | | 3751 | |
3847 | /* set the shaper parameter */ | | 3752 | /* set the shaper parameter */ |
3848 | sc->txspeed[vci] = (u_int8_t)txspeed; | | 3753 | sc->txspeed[vci] = (u_int8_t)txspeed; |
3849 | | | 3754 | |
3850 | splx(s); | | 3755 | splx(s); |
3851 | #ifdef EN_DEBUG | | 3756 | #ifdef EN_DEBUG |
3852 | printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan); | | 3757 | printf("VCI:%d PCR set to %d, tx channel %d\n", vci, pcr, txchan); |
3853 | if (joint_vci != 0) | | 3758 | if (joint_vci != 0) |
3854 | printf(" slot shared with VCI:%d\n", joint_vci); | | 3759 | printf(" slot shared with VCI:%d\n", joint_vci); |
3855 | #endif | | 3760 | #endif |
3856 | return (0); | | 3761 | return (0); |
3857 | } | | 3762 | } |
3858 | | | 3763 | |
3859 | static int en_pvctx(sc, pvcreq) | | 3764 | static int en_pvctx(struct en_softc *sc, struct pvctxreq *pvcreq) |
3860 | struct en_softc *sc; | | | |
3861 | struct pvctxreq *pvcreq; | | | |
3862 | { | | 3765 | { |
3863 | struct ifnet *ifp; | | 3766 | struct ifnet *ifp; |
3864 | struct atm_pseudoioctl api; | | 3767 | struct atm_pseudoioctl api; |
3865 | struct atm_pseudohdr *pvc_aph, *pvc_joint; | | 3768 | struct atm_pseudohdr *pvc_aph, *pvc_joint; |
3866 | int vci, joint_vci, pcr; | | 3769 | int vci, joint_vci, pcr; |
3867 | int error = 0; | | 3770 | int error = 0; |
3868 | | | 3771 | |
3869 | /* check vpi:vci values */ | | 3772 | /* check vpi:vci values */ |
3870 | pvc_aph = &pvcreq->pvc_aph; | | 3773 | pvc_aph = &pvcreq->pvc_aph; |
3871 | pvc_joint = &pvcreq->pvc_joint; | | 3774 | pvc_joint = &pvcreq->pvc_joint; |
3872 | | | 3775 | |
3873 | vci = ATM_PH_VCI(pvc_aph); | | 3776 | vci = ATM_PH_VCI(pvc_aph); |
3874 | joint_vci = ATM_PH_VCI(pvc_joint); | | 3777 | joint_vci = ATM_PH_VCI(pvc_joint); |
| @@ -3953,29 +3856,27 @@ static int en_pvctx(sc, pvcreq) | | | @@ -3953,29 +3856,27 @@ static int en_pvctx(sc, pvcreq) |
3953 | | | 3856 | |
3954 | error = en_txctl(sc, vci, joint_vci, pcr); | | 3857 | error = en_txctl(sc, vci, joint_vci, pcr); |
3955 | | | 3858 | |
3956 | if (error == 0) { | | 3859 | if (error == 0) { |
3957 | if (sc->txspeed[vci] != 0) | | 3860 | if (sc->txspeed[vci] != 0) |
3958 | pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); | | 3861 | pvcreq->pvc_pcr = en_txspeed2pcr(sc->txspeed[vci]); |
3959 | else | | 3862 | else |
3960 | pvcreq->pvc_pcr = 0; | | 3863 | pvcreq->pvc_pcr = 0; |
3961 | } | | 3864 | } |
3962 | | | 3865 | |
3963 | return error; | | 3866 | return error; |
3964 | } | | 3867 | } |
3965 | | | 3868 | |
3966 | static int en_pvctxget(sc, pvcreq) | | 3869 | static int en_pvctxget(struct en_softc *sc, struct pvctxreq *pvcreq) |
3967 | struct en_softc *sc; | | | |
3968 | struct pvctxreq *pvcreq; | | | |
3969 | { | | 3870 | { |
3970 | struct pvcsif *pvcsif; | | 3871 | struct pvcsif *pvcsif; |
3971 | struct ifnet *ifp; | | 3872 | struct ifnet *ifp; |
3972 | int vci, slot; | | 3873 | int vci, slot; |
3973 | | | 3874 | |
3974 | if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL) | | 3875 | if ((ifp = ifunit(pvcreq->pvc_ifname)) == NULL) |
3975 | return (ENXIO); | | 3876 | return (ENXIO); |
3976 | | | 3877 | |
3977 | if (ifp == &sc->enif) { | | 3878 | if (ifp == &sc->enif) { |
3978 | /* physical interface: assume vci is specified */ | | 3879 | /* physical interface: assume vci is specified */ |
3979 | struct atm_pseudohdr *pvc_aph; | | 3880 | struct atm_pseudohdr *pvc_aph; |
3980 | | | 3881 | |
3981 | pvc_aph = &pvcreq->pvc_aph; | | 3882 | pvc_aph = &pvcreq->pvc_aph; |