| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: i82596.c,v 1.29 2010/04/05 07:19:35 joerg Exp $ */ | | 1 | /* $NetBSD: i82596.c,v 1.29.20.1 2017/08/18 15:02:11 snj Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2003 Jochen Kunz. | | 4 | * Copyright (c) 2003 Jochen Kunz. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -33,27 +33,27 @@ | | | @@ -33,27 +33,27 @@ |
33 | * Driver for the Intel i82596CA and i82596DX/SX 10MBit/s Ethernet chips. | | 33 | * Driver for the Intel i82596CA and i82596DX/SX 10MBit/s Ethernet chips. |
34 | * | | 34 | * |
35 | * It operates the i82596 in 32-Bit Linear Mode, opposed to the old i82586 | | 35 | * It operates the i82596 in 32-Bit Linear Mode, opposed to the old i82586 |
36 | * ie(4) driver (src/sys/dev/ic/i82586.c), that degrades the i82596 to | | 36 | * ie(4) driver (src/sys/dev/ic/i82586.c), that degrades the i82596 to |
37 | * i82586 compatibility mode. | | 37 | * i82586 compatibility mode. |
38 | * | | 38 | * |
39 | * Documentation about these chips can be found at | | 39 | * Documentation about these chips can be found at |
40 | * | | 40 | * |
41 | * http://developer.intel.com/design/network/datashts/290218.htm | | 41 | * http://developer.intel.com/design/network/datashts/290218.htm |
42 | * http://developer.intel.com/design/network/datashts/290219.htm | | 42 | * http://developer.intel.com/design/network/datashts/290219.htm |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/cdefs.h> | | 45 | #include <sys/cdefs.h> |
46 | __KERNEL_RCSID(0, "$NetBSD: i82596.c,v 1.29 2010/04/05 07:19:35 joerg Exp $"); | | 46 | __KERNEL_RCSID(0, "$NetBSD: i82596.c,v 1.29.20.1 2017/08/18 15:02:11 snj Exp $"); |
47 | | | 47 | |
48 | /* autoconfig and device stuff */ | | 48 | /* autoconfig and device stuff */ |
49 | #include <sys/param.h> | | 49 | #include <sys/param.h> |
50 | #include <sys/device.h> | | 50 | #include <sys/device.h> |
51 | #include <sys/conf.h> | | 51 | #include <sys/conf.h> |
52 | #include "locators.h" | | 52 | #include "locators.h" |
53 | #include "ioconf.h" | | 53 | #include "ioconf.h" |
54 | | | 54 | |
55 | /* bus_space / bus_dma etc. */ | | 55 | /* bus_space / bus_dma etc. */ |
56 | #include <sys/bus.h> | | 56 | #include <sys/bus.h> |
57 | #include <sys/intr.h> | | 57 | #include <sys/intr.h> |
58 | | | 58 | |
59 | /* general system data and functions */ | | 59 | /* general system data and functions */ |
| @@ -744,50 +744,53 @@ iee_start(struct ifnet *ifp) | | | @@ -744,50 +744,53 @@ iee_start(struct ifnet *ifp) |
744 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], | | 744 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], |
745 | sc->sc_tx_mbuf[t], BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { | | 745 | sc->sc_tx_mbuf[t], BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { |
746 | /* | | 746 | /* |
747 | * The packet needs more TBD then we support. | | 747 | * The packet needs more TBD then we support. |
748 | * Copy the packet into a mbuf cluster to get it out. | | 748 | * Copy the packet into a mbuf cluster to get it out. |
749 | */ | | 749 | */ |
750 | printf("%s: iee_start: failed to load DMA map\n", | | 750 | printf("%s: iee_start: failed to load DMA map\n", |
751 | device_xname(sc->sc_dev)); | | 751 | device_xname(sc->sc_dev)); |
752 | MGETHDR(m, M_DONTWAIT, MT_DATA); | | 752 | MGETHDR(m, M_DONTWAIT, MT_DATA); |
753 | if (m == NULL) { | | 753 | if (m == NULL) { |
754 | printf("%s: iee_start: can't allocate mbuf\n", | | 754 | printf("%s: iee_start: can't allocate mbuf\n", |
755 | device_xname(sc->sc_dev)); | | 755 | device_xname(sc->sc_dev)); |
756 | m_freem(sc->sc_tx_mbuf[t]); | | 756 | m_freem(sc->sc_tx_mbuf[t]); |
| | | 757 | sc->sc_tx_mbuf[t] = NULL; |
757 | t--; | | 758 | t--; |
758 | continue; | | 759 | continue; |
759 | } | | 760 | } |
760 | MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner); | | 761 | MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner); |
761 | MCLGET(m, M_DONTWAIT); | | 762 | MCLGET(m, M_DONTWAIT); |
762 | if ((m->m_flags & M_EXT) == 0) { | | 763 | if ((m->m_flags & M_EXT) == 0) { |
763 | printf("%s: iee_start: can't allocate mbuf " | | 764 | printf("%s: iee_start: can't allocate mbuf " |
764 | "cluster\n", device_xname(sc->sc_dev)); | | 765 | "cluster\n", device_xname(sc->sc_dev)); |
765 | m_freem(sc->sc_tx_mbuf[t]); | | 766 | m_freem(sc->sc_tx_mbuf[t]); |
| | | 767 | sc->sc_tx_mbuf[t] = NULL; |
766 | m_freem(m); | | 768 | m_freem(m); |
767 | t--; | | 769 | t--; |
768 | continue; | | 770 | continue; |
769 | } | | 771 | } |
770 | m_copydata(sc->sc_tx_mbuf[t], 0, | | 772 | m_copydata(sc->sc_tx_mbuf[t], 0, |
771 | sc->sc_tx_mbuf[t]->m_pkthdr.len, mtod(m, void *)); | | 773 | sc->sc_tx_mbuf[t]->m_pkthdr.len, mtod(m, void *)); |
772 | m->m_pkthdr.len = sc->sc_tx_mbuf[t]->m_pkthdr.len; | | 774 | m->m_pkthdr.len = sc->sc_tx_mbuf[t]->m_pkthdr.len; |
773 | m->m_len = sc->sc_tx_mbuf[t]->m_pkthdr.len; | | 775 | m->m_len = sc->sc_tx_mbuf[t]->m_pkthdr.len; |
774 | m_freem(sc->sc_tx_mbuf[t]); | | 776 | m_freem(sc->sc_tx_mbuf[t]); |
775 | sc->sc_tx_mbuf[t] = m; | | 777 | sc->sc_tx_mbuf[t] = m; |
776 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], | | 778 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_tx_map[t], |
777 | m, BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { | | 779 | m, BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { |
778 | printf("%s: iee_start: can't load TX DMA map\n", | | 780 | printf("%s: iee_start: can't load TX DMA map\n", |
779 | device_xname(sc->sc_dev)); | | 781 | device_xname(sc->sc_dev)); |
780 | m_freem(sc->sc_tx_mbuf[t]); | | 782 | m_freem(sc->sc_tx_mbuf[t]); |
| | | 783 | sc->sc_tx_mbuf[t] = NULL; |
781 | t--; | | 784 | t--; |
782 | continue; | | 785 | continue; |
783 | } | | 786 | } |
784 | } | | 787 | } |
785 | for (n = 0 ; n < sc->sc_tx_map[t]->dm_nsegs ; n++) { | | 788 | for (n = 0 ; n < sc->sc_tx_map[t]->dm_nsegs ; n++) { |
786 | tbd = SC_TBD(sc, sc->sc_next_tbd + n); | | 789 | tbd = SC_TBD(sc, sc->sc_next_tbd + n); |
787 | tbd->tbd_tb_addr = | | 790 | tbd->tbd_tb_addr = |
788 | IEE_SWAPA32(sc->sc_tx_map[t]->dm_segs[n].ds_addr); | | 791 | IEE_SWAPA32(sc->sc_tx_map[t]->dm_segs[n].ds_addr); |
789 | tbd->tbd_size = | | 792 | tbd->tbd_size = |
790 | sc->sc_tx_map[t]->dm_segs[n].ds_len; | | 793 | sc->sc_tx_map[t]->dm_segs[n].ds_len; |
791 | tbd->tbd_link_addr = | | 794 | tbd->tbd_link_addr = |
792 | IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_tbd_off + | | 795 | IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_tbd_off + |
793 | sc->sc_tbd_sz * (sc->sc_next_tbd + n + 1))); | | 796 | sc->sc_tbd_sz * (sc->sc_next_tbd + n + 1))); |
| @@ -917,48 +920,51 @@ iee_init(struct ifnet *ifp) | | | @@ -917,48 +920,51 @@ iee_init(struct ifnet *ifp) |
917 | MGETHDR(sc->sc_rx_mbuf[r], M_DONTWAIT, MT_DATA); | | 920 | MGETHDR(sc->sc_rx_mbuf[r], M_DONTWAIT, MT_DATA); |
918 | if (sc->sc_rx_mbuf[r] == NULL) { | | 921 | if (sc->sc_rx_mbuf[r] == NULL) { |
919 | printf("%s: iee_init: can't allocate mbuf\n", | | 922 | printf("%s: iee_init: can't allocate mbuf\n", |
920 | device_xname(sc->sc_dev)); | | 923 | device_xname(sc->sc_dev)); |
921 | err = 1; | | 924 | err = 1; |
922 | break; | | 925 | break; |
923 | } | | 926 | } |
924 | MCLAIM(sc->sc_rx_mbuf[r],&sc->sc_ethercom.ec_rx_mowner); | | 927 | MCLAIM(sc->sc_rx_mbuf[r],&sc->sc_ethercom.ec_rx_mowner); |
925 | MCLGET(sc->sc_rx_mbuf[r], M_DONTWAIT); | | 928 | MCLGET(sc->sc_rx_mbuf[r], M_DONTWAIT); |
926 | if ((sc->sc_rx_mbuf[r]->m_flags & M_EXT) == 0) { | | 929 | if ((sc->sc_rx_mbuf[r]->m_flags & M_EXT) == 0) { |
927 | printf("%s: iee_init: can't allocate mbuf" | | 930 | printf("%s: iee_init: can't allocate mbuf" |
928 | " cluster\n", device_xname(sc->sc_dev)); | | 931 | " cluster\n", device_xname(sc->sc_dev)); |
929 | m_freem(sc->sc_rx_mbuf[r]); | | 932 | m_freem(sc->sc_rx_mbuf[r]); |
| | | 933 | sc->sc_rx_mbuf[r] = NULL; |
930 | err = 1; | | 934 | err = 1; |
931 | break; | | 935 | break; |
932 | } | | 936 | } |
933 | sc->sc_rx_mbuf[r]->m_len = | | 937 | sc->sc_rx_mbuf[r]->m_len = |
934 | sc->sc_rx_mbuf[r]->m_pkthdr.len = MCLBYTES - 2; | | 938 | sc->sc_rx_mbuf[r]->m_pkthdr.len = MCLBYTES - 2; |
935 | sc->sc_rx_mbuf[r]->m_data += 2; | | 939 | sc->sc_rx_mbuf[r]->m_data += 2; |
936 | } | | 940 | } |
937 | if (sc->sc_rx_map[r] == NULL && bus_dmamap_create(sc->sc_dmat, | | 941 | if (sc->sc_rx_map[r] == NULL && bus_dmamap_create(sc->sc_dmat, |
938 | MCLBYTES, 1, MCLBYTES , 0, BUS_DMA_NOWAIT, | | 942 | MCLBYTES, 1, MCLBYTES , 0, BUS_DMA_NOWAIT, |
939 | &sc->sc_rx_map[r]) != 0) { | | 943 | &sc->sc_rx_map[r]) != 0) { |
940 | printf("%s: iee_init: can't create RX " | | 944 | printf("%s: iee_init: can't create RX " |
941 | "DMA map\n", device_xname(sc->sc_dev)); | | 945 | "DMA map\n", device_xname(sc->sc_dev)); |
942 | m_freem(sc->sc_rx_mbuf[r]); | | 946 | m_freem(sc->sc_rx_mbuf[r]); |
| | | 947 | sc->sc_rx_mbuf[r] = NULL; |
943 | err = 1; | | 948 | err = 1; |
944 | break; | | 949 | break; |
945 | } | | 950 | } |
946 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rx_map[r], | | 951 | if (bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rx_map[r], |
947 | sc->sc_rx_mbuf[r], BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) { | | 952 | sc->sc_rx_mbuf[r], BUS_DMA_READ | BUS_DMA_NOWAIT) != 0) { |
948 | printf("%s: iee_init: can't load RX DMA map\n", | | 953 | printf("%s: iee_init: can't load RX DMA map\n", |
949 | device_xname(sc->sc_dev)); | | 954 | device_xname(sc->sc_dev)); |
950 | bus_dmamap_destroy(sc->sc_dmat, sc->sc_rx_map[r]); | | 955 | bus_dmamap_destroy(sc->sc_dmat, sc->sc_rx_map[r]); |
951 | m_freem(sc->sc_rx_mbuf[r]); | | 956 | m_freem(sc->sc_rx_mbuf[r]); |
| | | 957 | sc->sc_rx_mbuf[r] = NULL; |
952 | err = 1; | | 958 | err = 1; |
953 | break; | | 959 | break; |
954 | } | | 960 | } |
955 | bus_dmamap_sync(sc->sc_dmat, sc->sc_rx_map[r], 0, | | 961 | bus_dmamap_sync(sc->sc_dmat, sc->sc_rx_map[r], 0, |
956 | sc->sc_rx_map[r]->dm_mapsize, BUS_DMASYNC_PREREAD); | | 962 | sc->sc_rx_map[r]->dm_mapsize, BUS_DMASYNC_PREREAD); |
957 | SC_RBD(sc, r)->rbd_size = sc->sc_rx_map[r]->dm_segs[0].ds_len; | | 963 | SC_RBD(sc, r)->rbd_size = sc->sc_rx_map[r]->dm_segs[0].ds_len; |
958 | SC_RBD(sc, r)->rbd_rb_addr = | | 964 | SC_RBD(sc, r)->rbd_rb_addr = |
959 | IEE_SWAPA32(sc->sc_rx_map[r]->dm_segs[0].ds_addr); | | 965 | IEE_SWAPA32(sc->sc_rx_map[r]->dm_segs[0].ds_addr); |
960 | } | | 966 | } |
961 | SC_RFD(sc, 0)->rfd_rbd_addr = | | 967 | SC_RFD(sc, 0)->rfd_rbd_addr = |
962 | IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_rbd_off)); | | 968 | IEE_SWAPA32(IEE_PHYS_SHMEM(sc->sc_rbd_off)); |
963 | if (err != 0) { | | 969 | if (err != 0) { |
964 | for (n = 0 ; n < r; n++) { | | 970 | for (n = 0 ; n < r; n++) { |