if_rl.c (112839) | if_rl.c (112872) |
---|---|
1/* 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 114 unchanged lines hidden (view full) --- 123 * can hang the bus. I'm inclined to blame this on crummy design/construction 124 * on the part of RealTek. Memory mapped mode does appear to work on 125 * uniprocessor systems though. 126 */ 127#define RL_USEIOSPACE 128 129#include <pci/if_rlreg.h> 130 | 1/* 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 114 unchanged lines hidden (view full) --- 123 * can hang the bus. I'm inclined to blame this on crummy design/construction 124 * on the part of RealTek. Memory mapped mode does appear to work on 125 * uniprocessor systems though. 126 */ 127#define RL_USEIOSPACE 128 129#include <pci/if_rlreg.h> 130 |
131__FBSDID("$FreeBSD: head/sys/pci/if_rl.c 112839 2003-03-30 03:45:28Z silby $"); | 131__FBSDID("$FreeBSD: head/sys/pci/if_rl.c 112872 2003-03-31 17:29:43Z njl $"); |
132 133/* 134 * Various supported device vendors/types and their names. 135 */ 136static struct rl_type rl_devs[] = { 137 { RT_VENDORID, RT_DEVICEID_8129, 138 "RealTek 8129 10/100BaseTX" }, 139 { RT_VENDORID, RT_DEVICEID_8139, --- 723 unchanged lines hidden (view full) --- 863 u_int16_t as[3]; 864 struct rl_softc *sc; 865 struct ifnet *ifp; 866 u_int16_t rl_did = 0; 867 int unit, error = 0, rid, i; 868 869 sc = device_get_softc(dev); 870 unit = device_get_unit(dev); | 132 133/* 134 * Various supported device vendors/types and their names. 135 */ 136static struct rl_type rl_devs[] = { 137 { RT_VENDORID, RT_DEVICEID_8129, 138 "RealTek 8129 10/100BaseTX" }, 139 { RT_VENDORID, RT_DEVICEID_8139, --- 723 unchanged lines hidden (view full) --- 863 u_int16_t as[3]; 864 struct rl_softc *sc; 865 struct ifnet *ifp; 866 u_int16_t rl_did = 0; 867 int unit, error = 0, rid, i; 868 869 sc = device_get_softc(dev); 870 unit = device_get_unit(dev); |
871 bzero(sc, sizeof(struct rl_softc)); | |
872 873 mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 874 MTX_DEF | MTX_RECURSE); 875 876 /* 877 * Handle power management nonsense. 878 */ 879 --- 58 unchanged lines hidden (view full) --- 938 939 if ((rman_get_end(sc->rl_res)-rman_get_start(sc->rl_res))==0xff) { 940 printf("rl%d: Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n", unit); 941 } 942 943 sc->rl_btag = rman_get_bustag(sc->rl_res); 944 sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 945 | 871 872 mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 873 MTX_DEF | MTX_RECURSE); 874 875 /* 876 * Handle power management nonsense. 877 */ 878 --- 58 unchanged lines hidden (view full) --- 937 938 if ((rman_get_end(sc->rl_res)-rman_get_start(sc->rl_res))==0xff) { 939 printf("rl%d: Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n", unit); 940 } 941 942 sc->rl_btag = rman_get_bustag(sc->rl_res); 943 sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 944 |
945 /* Allocate interrupt */ |
|
946 rid = 0; 947 sc->rl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 948 RF_SHAREABLE | RF_ACTIVE); 949 950 if (sc->rl_irq == NULL) { 951 printf("rl%d: couldn't map interrupt\n", unit); | 946 rid = 0; 947 sc->rl_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 948 RF_SHAREABLE | RF_ACTIVE); 949 950 if (sc->rl_irq == NULL) { 951 printf("rl%d: couldn't map interrupt\n", unit); |
952 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); | |
953 error = ENXIO; 954 goto fail; 955 } 956 957 /* Reset the adapter. */ 958 rl_reset(sc); 959 sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 960 rl_read_eeprom(sc, (caddr_t)&rl_did, 0, 1, 0); --- 30 unchanged lines hidden (view full) --- 991 rl_did == COREGA_DEVICEID_FETHERCBTXD || 992 rl_did == COREGA_DEVICEID_FETHERIICBTXD || 993 rl_did == PLANEX_DEVICEID_FNW3800TX) 994 sc->rl_type = RL_8139; 995 else if (rl_did == RT_DEVICEID_8129) 996 sc->rl_type = RL_8129; 997 else { 998 printf("rl%d: unknown device ID: %x\n", unit, rl_did); | 952 error = ENXIO; 953 goto fail; 954 } 955 956 /* Reset the adapter. */ 957 rl_reset(sc); 958 sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 959 rl_read_eeprom(sc, (caddr_t)&rl_did, 0, 1, 0); --- 30 unchanged lines hidden (view full) --- 990 rl_did == COREGA_DEVICEID_FETHERCBTXD || 991 rl_did == COREGA_DEVICEID_FETHERIICBTXD || 992 rl_did == PLANEX_DEVICEID_FNW3800TX) 993 sc->rl_type = RL_8139; 994 else if (rl_did == RT_DEVICEID_8129) 995 sc->rl_type = RL_8129; 996 else { 997 printf("rl%d: unknown device ID: %x\n", unit, rl_did); |
999 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1000 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); | |
1001 error = ENXIO; 1002 goto fail; 1003 } 1004 1005 /* 1006 * Allocate the parent bus DMA tag appropriate for PCI. 1007 */ 1008#define RL_NSEG_NEW 32 1009 error = bus_dma_tag_create(NULL, /* parent */ 1010 1, 0, /* alignment, boundary */ 1011 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 1012 BUS_SPACE_MAXADDR, /* highaddr */ 1013 NULL, NULL, /* filter, filterarg */ 1014 MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 1015 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 1016 BUS_DMA_ALLOCNOW, /* flags */ 1017 &sc->rl_parent_tag); | 998 error = ENXIO; 999 goto fail; 1000 } 1001 1002 /* 1003 * Allocate the parent bus DMA tag appropriate for PCI. 1004 */ 1005#define RL_NSEG_NEW 32 1006 error = bus_dma_tag_create(NULL, /* parent */ 1007 1, 0, /* alignment, boundary */ 1008 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 1009 BUS_SPACE_MAXADDR, /* highaddr */ 1010 NULL, NULL, /* filter, filterarg */ 1011 MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 1012 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 1013 BUS_DMA_ALLOCNOW, /* flags */ 1014 &sc->rl_parent_tag); |
1015 if (error) 1016 goto fail; |
|
1018 1019 /* 1020 * Now allocate a tag for the DMA descriptor lists. 1021 * All of our lists are allocated as a contiguous block 1022 * of memory. 1023 */ 1024 error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 1025 1, 0, /* alignment, boundary */ 1026 BUS_SPACE_MAXADDR, /* lowaddr */ 1027 BUS_SPACE_MAXADDR, /* highaddr */ 1028 NULL, NULL, /* filter, filterarg */ 1029 RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 1030 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 1031 0, /* flags */ 1032 &sc->rl_tag); | 1017 1018 /* 1019 * Now allocate a tag for the DMA descriptor lists. 1020 * All of our lists are allocated as a contiguous block 1021 * of memory. 1022 */ 1023 error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 1024 1, 0, /* alignment, boundary */ 1025 BUS_SPACE_MAXADDR, /* lowaddr */ 1026 BUS_SPACE_MAXADDR, /* highaddr */ 1027 NULL, NULL, /* filter, filterarg */ 1028 RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 1029 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 1030 0, /* flags */ 1031 &sc->rl_tag); |
1032 if (error) 1033 goto fail; |
|
1033 1034 /* 1035 * Now allocate a chunk of DMA-able memory based on the 1036 * tag we just created. 1037 */ 1038 error = bus_dmamem_alloc(sc->rl_tag, 1039 (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT, 1040 &sc->rl_cdata.rl_rx_dmamap); 1041 | 1034 1035 /* 1036 * Now allocate a chunk of DMA-able memory based on the 1037 * tag we just created. 1038 */ 1039 error = bus_dmamem_alloc(sc->rl_tag, 1040 (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT, 1041 &sc->rl_cdata.rl_rx_dmamap); 1042 |
1042 if (sc->rl_cdata.rl_rx_buf == NULL) { | 1043 if (error) { |
1043 printf("rl%d: no memory for list buffers!\n", unit); | 1044 printf("rl%d: no memory for list buffers!\n", unit); |
1044 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1045 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); | |
1046 bus_dma_tag_destroy(sc->rl_tag); | 1045 bus_dma_tag_destroy(sc->rl_tag); |
1047 error = ENXIO; | 1046 sc->rl_tag = NULL; |
1048 goto fail; 1049 } 1050 1051 /* Leave a few bytes before the start of the RX ring buffer. */ 1052 sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 1053 sc->rl_cdata.rl_rx_buf += sizeof(u_int64_t); 1054 1055 /* Do MII setup */ 1056 if (mii_phy_probe(dev, &sc->rl_miibus, 1057 rl_ifmedia_upd, rl_ifmedia_sts)) { 1058 printf("rl%d: MII without any phy!\n", sc->rl_unit); | 1047 goto fail; 1048 } 1049 1050 /* Leave a few bytes before the start of the RX ring buffer. */ 1051 sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 1052 sc->rl_cdata.rl_rx_buf += sizeof(u_int64_t); 1053 1054 /* Do MII setup */ 1055 if (mii_phy_probe(dev, &sc->rl_miibus, 1056 rl_ifmedia_upd, rl_ifmedia_sts)) { 1057 printf("rl%d: MII without any phy!\n", sc->rl_unit); |
1059 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1060 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 1061 bus_dmamem_free(sc->rl_tag, 1062 sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap); 1063 bus_dma_tag_destroy(sc->rl_tag); | |
1064 error = ENXIO; 1065 goto fail; 1066 } 1067 1068 ifp = &sc->arpcom.ac_if; 1069 ifp->if_softc = sc; 1070 ifp->if_unit = unit; 1071 ifp->if_name = "rl"; 1072 ifp->if_mtu = ETHERMTU; 1073 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1074 ifp->if_ioctl = rl_ioctl; 1075 ifp->if_output = ether_output; 1076 ifp->if_start = rl_start; 1077 ifp->if_watchdog = rl_watchdog; 1078 ifp->if_init = rl_init; 1079 ifp->if_baudrate = 10000000; 1080 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 1081 | 1058 error = ENXIO; 1059 goto fail; 1060 } 1061 1062 ifp = &sc->arpcom.ac_if; 1063 ifp->if_softc = sc; 1064 ifp->if_unit = unit; 1065 ifp->if_name = "rl"; 1066 ifp->if_mtu = ETHERMTU; 1067 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1068 ifp->if_ioctl = rl_ioctl; 1069 ifp->if_output = ether_output; 1070 ifp->if_start = rl_start; 1071 ifp->if_watchdog = rl_watchdog; 1072 ifp->if_init = rl_init; 1073 ifp->if_baudrate = 10000000; 1074 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 1075 |
1076 callout_handle_init(&sc->rl_stat_ch); 1077 |
|
1082 /* 1083 * Call MI attach routine. 1084 */ 1085 ether_ifattach(ifp, eaddr); 1086 1087 error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET, 1088 rl_intr, sc, &sc->rl_intrhand); 1089 1090 if (error) { 1091 printf("rl%d: couldn't set up irq\n", unit); | 1078 /* 1079 * Call MI attach routine. 1080 */ 1081 ether_ifattach(ifp, eaddr); 1082 1083 error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET, 1084 rl_intr, sc, &sc->rl_intrhand); 1085 1086 if (error) { 1087 printf("rl%d: couldn't set up irq\n", unit); |
1092 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1093 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 1094 bus_dmamem_free(sc->rl_tag, 1095 sc->rl_cdata.rl_rx_buf, sc->rl_cdata.rl_rx_dmamap); 1096 bus_dma_tag_destroy(sc->rl_tag); | |
1097 goto fail; 1098 } 1099 | 1088 goto fail; 1089 } 1090 |
1100 callout_handle_init(&sc->rl_stat_ch); | |
1101fail: | 1091fail: |
1102 if (error != 0) 1103 mtx_destroy(&sc->rl_mtx); | 1092 if (error) 1093 rl_detach(dev); 1094 |
1104 return (error); 1105} 1106 1107static int 1108rl_detach(dev) 1109 device_t dev; 1110{ 1111 struct rl_softc *sc; 1112 struct ifnet *ifp; 1113 1114 sc = device_get_softc(dev); | 1095 return (error); 1096} 1097 1098static int 1099rl_detach(dev) 1100 device_t dev; 1101{ 1102 struct rl_softc *sc; 1103 struct ifnet *ifp; 1104 1105 sc = device_get_softc(dev); |
1106 KASSERT(mtx_initialized(&sc->rl_mtx), "rl mutex not initialized"); |
|
1115 RL_LOCK(sc); 1116 ifp = &sc->arpcom.ac_if; 1117 | 1107 RL_LOCK(sc); 1108 ifp = &sc->arpcom.ac_if; 1109 |
1118 ether_ifdetach(ifp); 1119 rl_stop(sc); | 1110 if (device_is_alive(dev)) { 1111 if (bus_child_present(dev)) 1112 rl_stop(sc); 1113 ether_ifdetach(ifp); 1114 device_delete_child(dev, sc->rl_miibus); 1115 bus_generic_detach(dev); 1116 } |
1120 | 1117 |
1121 bus_generic_detach(dev); 1122 device_delete_child(dev, sc->rl_miibus); | 1118 if (sc->rl_intrhand) 1119 bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1120 if (sc->rl_irq) 1121 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1122 if (sc->rl_res) 1123 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); |
1123 | 1124 |
1124 bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1125 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1126 bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); | 1125 if (sc->rl_tag) { 1126 bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1127 bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1128 sc->rl_cdata.rl_rx_dmamap); 1129 bus_dma_tag_destroy(sc->rl_tag); 1130 } 1131 if (sc->rl_parent_tag) 1132 bus_dma_tag_destroy(sc->rl_parent_tag); |
1127 | 1133 |
1128 bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1129 bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1130 sc->rl_cdata.rl_rx_dmamap); 1131 bus_dma_tag_destroy(sc->rl_tag); 1132 bus_dma_tag_destroy(sc->rl_parent_tag); 1133 | |
1134 RL_UNLOCK(sc); 1135 mtx_destroy(&sc->rl_mtx); 1136 1137 return(0); 1138} 1139 1140/* 1141 * Initialize the transmit descriptors. --- 787 unchanged lines hidden --- | 1134 RL_UNLOCK(sc); 1135 mtx_destroy(&sc->rl_mtx); 1136 1137 return(0); 1138} 1139 1140/* 1141 * Initialize the transmit descriptors. --- 787 unchanged lines hidden --- |