if_hme.c (133688) | if_hme.c (137982) |
---|---|
1/*- 2 * Copyright (c) 1999 The NetBSD Foundation, Inc. 3 * Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Paul Kranenburg. 8 * --- 24 unchanged lines hidden (view full) --- 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 * from: NetBSD: hme.c,v 1.29 2002/05/05 03:02:38 thorpej Exp 38 */ 39 40#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1999 The NetBSD Foundation, Inc. 3 * Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Paul Kranenburg. 8 * --- 24 unchanged lines hidden (view full) --- 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 * from: NetBSD: hme.c,v 1.29 2002/05/05 03:02:38 thorpej Exp 38 */ 39 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 133688 2004-08-13 23:14:50Z rwatson $"); | 41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 137982 2004-11-22 06:46:30Z yongari $"); |
42 43/* 44 * HME Ethernet module driver. 45 * 46 * The HME is e.g. part of the PCIO PCI multi function device. 47 * It supports TX gathering and TX and RX checksum offloading. 48 * RX buffers must be aligned at a programmable offset modulo 16. We choose 2 49 * for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes --- 44 unchanged lines hidden (view full) --- 94#include <dev/mii/miivar.h> 95 96#include <machine/bus.h> 97 98#include <dev/hme/if_hmereg.h> 99#include <dev/hme/if_hmevar.h> 100 101static void hme_start(struct ifnet *); | 42 43/* 44 * HME Ethernet module driver. 45 * 46 * The HME is e.g. part of the PCIO PCI multi function device. 47 * It supports TX gathering and TX and RX checksum offloading. 48 * RX buffers must be aligned at a programmable offset modulo 16. We choose 2 49 * for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes --- 44 unchanged lines hidden (view full) --- 94#include <dev/mii/miivar.h> 95 96#include <machine/bus.h> 97 98#include <dev/hme/if_hmereg.h> 99#include <dev/hme/if_hmevar.h> 100 101static void hme_start(struct ifnet *); |
102static void hme_start_locked(struct ifnet *); |
|
102static void hme_stop(struct hme_softc *); 103static int hme_ioctl(struct ifnet *, u_long, caddr_t); 104static void hme_tick(void *); 105static void hme_watchdog(struct ifnet *); 106static void hme_init(void *); | 103static void hme_stop(struct hme_softc *); 104static int hme_ioctl(struct ifnet *, u_long, caddr_t); 105static void hme_tick(void *); 106static void hme_watchdog(struct ifnet *); 107static void hme_init(void *); |
108static void hme_init_locked(void *); |
|
107static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 108static int hme_meminit(struct hme_softc *); 109static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 110 u_int32_t, u_int32_t); 111static void hme_mifinit(struct hme_softc *); 112static void hme_reset(struct hme_softc *); 113static void hme_setladrf(struct hme_softc *, int); 114 --- 75 unchanged lines hidden (view full) --- 190 * sc_mac{t,h,o} (MAC registers) 191 * sc_mif{t,h,o} (Management Interface registers) 192 * 193 * the maximum bus burst size: 194 * sc_burst 195 * 196 */ 197 | 109static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 110static int hme_meminit(struct hme_softc *); 111static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 112 u_int32_t, u_int32_t); 113static void hme_mifinit(struct hme_softc *); 114static void hme_reset(struct hme_softc *); 115static void hme_setladrf(struct hme_softc *, int); 116 --- 75 unchanged lines hidden (view full) --- 192 * sc_mac{t,h,o} (MAC registers) 193 * sc_mif{t,h,o} (Management Interface registers) 194 * 195 * the maximum bus burst size: 196 * sc_burst 197 * 198 */ 199 |
200 HME_LOCK_ASSERT(sc, MA_NOTOWNED); |
|
198 /* Make sure the chip is stopped. */ | 201 /* Make sure the chip is stopped. */ |
202 HME_LOCK(sc); |
|
199 hme_stop(sc); | 203 hme_stop(sc); |
204 HME_UNLOCK(sc); |
|
200 201 /* 202 * Allocate DMA capable memory 203 * Buffer descriptors must be aligned on a 2048 byte boundary; 204 * take this into account when calculating the size. Note that 205 * the maximum number of descriptors (256) occupies 2048 bytes, 206 * so we allocate that much regardless of HME_N*DESC. 207 */ --- 71 unchanged lines hidden (view full) --- 279 } 280 281 sc->sc_csum_features = HME_CSUM_FEATURES; 282 /* Initialize ifnet structure. */ 283 ifp->if_softc = sc; 284 if_initname(ifp, device_get_name(sc->sc_dev), 285 device_get_unit(sc->sc_dev)); 286 ifp->if_mtu = ETHERMTU; | 205 206 /* 207 * Allocate DMA capable memory 208 * Buffer descriptors must be aligned on a 2048 byte boundary; 209 * take this into account when calculating the size. Note that 210 * the maximum number of descriptors (256) occupies 2048 bytes, 211 * so we allocate that much regardless of HME_N*DESC. 212 */ --- 71 unchanged lines hidden (view full) --- 284 } 285 286 sc->sc_csum_features = HME_CSUM_FEATURES; 287 /* Initialize ifnet structure. */ 288 ifp->if_softc = sc; 289 if_initname(ifp, device_get_name(sc->sc_dev), 290 device_get_unit(sc->sc_dev)); 291 ifp->if_mtu = ETHERMTU; |
287 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 288 IFF_NEEDSGIANT; | 292 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; |
289 ifp->if_start = hme_start; 290 ifp->if_ioctl = hme_ioctl; 291 ifp->if_init = hme_init; 292 ifp->if_watchdog = hme_watchdog; 293 IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ); 294 ifp->if_snd.ifq_drv_maxlen = HME_NTXQ; 295 IFQ_SET_READY(&ifp->if_snd); 296 | 293 ifp->if_start = hme_start; 294 ifp->if_ioctl = hme_ioctl; 295 ifp->if_init = hme_init; 296 ifp->if_watchdog = hme_watchdog; 297 IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ); 298 ifp->if_snd.ifq_drv_maxlen = HME_NTXQ; 299 IFQ_SET_READY(&ifp->if_snd); 300 |
301 HME_LOCK(sc); |
|
297 hme_mifinit(sc); | 302 hme_mifinit(sc); |
303 HME_UNLOCK(sc); |
|
298 299 if ((error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, hme_mediachange, 300 hme_mediastatus)) != 0) { 301 device_printf(sc->sc_dev, "phy probe failed: %d\n", error); 302 goto fail_rxdesc; 303 } 304 sc->sc_mii = device_get_softc(sc->sc_miibus); 305 --- 28 unchanged lines hidden (view full) --- 334 /* 335 * Tell the upper layer(s) we support long frames/checksum offloads. 336 */ 337 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 338 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 339 ifp->if_hwassist |= sc->sc_csum_features; 340 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 341 | 304 305 if ((error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, hme_mediachange, 306 hme_mediastatus)) != 0) { 307 device_printf(sc->sc_dev, "phy probe failed: %d\n", error); 308 goto fail_rxdesc; 309 } 310 sc->sc_mii = device_get_softc(sc->sc_miibus); 311 --- 28 unchanged lines hidden (view full) --- 340 /* 341 * Tell the upper layer(s) we support long frames/checksum offloads. 342 */ 343 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 344 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 345 ifp->if_hwassist |= sc->sc_csum_features; 346 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 347 |
342 callout_init(&sc->sc_tick_ch, 0); | 348 callout_init(&sc->sc_tick_ch, CALLOUT_MPSAFE); |
343 return (0); 344 345fail_txdesc: 346 for (i = 0; i < tdesc; i++) { 347 bus_dmamap_destroy(sc->sc_tdmatag, 348 sc->sc_rb.rb_txdesc[i].htx_dmamap); 349 } 350 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap); --- 17 unchanged lines hidden (view full) --- 368} 369 370void 371hme_detach(struct hme_softc *sc) 372{ 373 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 374 int i; 375 | 349 return (0); 350 351fail_txdesc: 352 for (i = 0; i < tdesc; i++) { 353 bus_dmamap_destroy(sc->sc_tdmatag, 354 sc->sc_rb.rb_txdesc[i].htx_dmamap); 355 } 356 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap); --- 17 unchanged lines hidden (view full) --- 374} 375 376void 377hme_detach(struct hme_softc *sc) 378{ 379 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 380 int i; 381 |
382 HME_LOCK_ASSERT(sc, MA_NOTOWNED); 383 |
|
376 ether_ifdetach(ifp); | 384 ether_ifdetach(ifp); |
385 HME_LOCK(sc); |
|
377 hme_stop(sc); | 386 hme_stop(sc); |
387 HME_UNLOCK(sc); |
|
378 device_delete_child(sc->sc_dev, sc->sc_miibus); 379 380 for (i = 0; i < HME_NTXQ; i++) { 381 bus_dmamap_destroy(sc->sc_tdmatag, 382 sc->sc_rb.rb_txdesc[i].htx_dmamap); 383 } 384 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap); 385 for (i = 0; i < HME_NRXDESC; i++) { --- 9 unchanged lines hidden (view full) --- 395 bus_dma_tag_destroy(sc->sc_cdmatag); 396 bus_dma_tag_destroy(sc->sc_pdmatag); 397} 398 399void 400hme_suspend(struct hme_softc *sc) 401{ 402 | 388 device_delete_child(sc->sc_dev, sc->sc_miibus); 389 390 for (i = 0; i < HME_NTXQ; i++) { 391 bus_dmamap_destroy(sc->sc_tdmatag, 392 sc->sc_rb.rb_txdesc[i].htx_dmamap); 393 } 394 bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap); 395 for (i = 0; i < HME_NRXDESC; i++) { --- 9 unchanged lines hidden (view full) --- 405 bus_dma_tag_destroy(sc->sc_cdmatag); 406 bus_dma_tag_destroy(sc->sc_pdmatag); 407} 408 409void 410hme_suspend(struct hme_softc *sc) 411{ 412 |
413 HME_LOCK(sc); |
|
403 hme_stop(sc); | 414 hme_stop(sc); |
415 HME_UNLOCK(sc); |
|
404} 405 406void 407hme_resume(struct hme_softc *sc) 408{ 409 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 410 | 416} 417 418void 419hme_resume(struct hme_softc *sc) 420{ 421 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 422 |
423 HME_LOCK(sc); |
|
411 if ((ifp->if_flags & IFF_UP) != 0) | 424 if ((ifp->if_flags & IFF_UP) != 0) |
412 hme_init(ifp); | 425 hme_init_locked(ifp); 426 HME_UNLOCK(sc); |
413} 414 415static void 416hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 417{ 418 struct hme_softc *sc = (struct hme_softc *)xsc; 419 420 if (error != 0) --- 15 unchanged lines hidden (view full) --- 436 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 437} 438 439static void 440hme_reset(struct hme_softc *sc) 441{ 442 int s; 443 | 427} 428 429static void 430hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 431{ 432 struct hme_softc *sc = (struct hme_softc *)xsc; 433 434 if (error != 0) --- 15 unchanged lines hidden (view full) --- 450 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 451} 452 453static void 454hme_reset(struct hme_softc *sc) 455{ 456 int s; 457 |
458 HME_LOCK(sc); |
|
444 s = splnet(); | 459 s = splnet(); |
445 hme_init(sc); | 460 hme_init_locked(sc); |
446 splx(s); | 461 splx(s); |
462 HME_UNLOCK(sc); |
|
447} 448 449static void 450hme_stop(struct hme_softc *sc) 451{ 452 u_int32_t v; 453 int n; 454 --- 211 unchanged lines hidden (view full) --- 666/* 667 * Initialization of interface; set up initialization block 668 * and transmit/receive descriptor rings. 669 */ 670static void 671hme_init(void *xsc) 672{ 673 struct hme_softc *sc = (struct hme_softc *)xsc; | 463} 464 465static void 466hme_stop(struct hme_softc *sc) 467{ 468 u_int32_t v; 469 int n; 470 --- 211 unchanged lines hidden (view full) --- 682/* 683 * Initialization of interface; set up initialization block 684 * and transmit/receive descriptor rings. 685 */ 686static void 687hme_init(void *xsc) 688{ 689 struct hme_softc *sc = (struct hme_softc *)xsc; |
690 691 HME_LOCK(sc); 692 hme_init_locked(sc); 693 HME_UNLOCK(sc); 694} 695 696static void 697hme_init_locked(void *xsc) 698{ 699 struct hme_softc *sc = (struct hme_softc *)xsc; |
|
674 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 675 u_int8_t *ea; 676 u_int32_t n, v; 677 | 700 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 701 u_int8_t *ea; 702 u_int32_t n, v; 703 |
704 HME_LOCK_ASSERT(sc, MA_OWNED); |
|
678 /* 679 * Initialization sequence. The numbered steps below correspond 680 * to the sequence outlined in section 6.3.5.1 in the Ethernet 681 * Channel Engine manual (part of the PCIO manual). 682 * See also the STP2002-STQ document from Sun Microsystems. 683 */ 684 685 /* step 1 & 2. Reset the Ethernet Channel */ --- 158 unchanged lines hidden (view full) --- 844 HME_ERX_READ_4(sc, HME_ERXI_CFG), 845 HME_ETX_READ_4(sc, HME_ETXI_CFG)); 846 CTR2(KTR_HME, "hme_init: mac rxcfg %#x, maci txcfg %#x", 847 HME_MAC_READ_4(sc, HME_MACI_RXCFG), 848 HME_MAC_READ_4(sc, HME_MACI_TXCFG)); 849#endif 850 851 /* Set the current media. */ | 705 /* 706 * Initialization sequence. The numbered steps below correspond 707 * to the sequence outlined in section 6.3.5.1 in the Ethernet 708 * Channel Engine manual (part of the PCIO manual). 709 * See also the STP2002-STQ document from Sun Microsystems. 710 */ 711 712 /* step 1 & 2. Reset the Ethernet Channel */ --- 158 unchanged lines hidden (view full) --- 871 HME_ERX_READ_4(sc, HME_ERXI_CFG), 872 HME_ETX_READ_4(sc, HME_ETXI_CFG)); 873 CTR2(KTR_HME, "hme_init: mac rxcfg %#x, maci txcfg %#x", 874 HME_MAC_READ_4(sc, HME_MACI_RXCFG), 875 HME_MAC_READ_4(sc, HME_MACI_TXCFG)); 876#endif 877 878 /* Set the current media. */ |
852 /* mii_mediachg(sc->sc_mii); */ | 879 /* 880 * HME_UNLOCK(sc); 881 * mii_mediachg(sc->sc_mii); 882 * HME_LOCK(sc); 883 */ |
853 854 /* Start the one second timer. */ 855 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 856 857 ifp->if_flags |= IFF_RUNNING; 858 ifp->if_flags &= ~IFF_OACTIVE; 859 ifp->if_timer = 0; | 884 885 /* Start the one second timer. */ 886 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 887 888 ifp->if_flags |= IFF_RUNNING; 889 ifp->if_flags &= ~IFF_OACTIVE; 890 ifp->if_timer = 0; |
860 hme_start(ifp); | 891 hme_start_locked(ifp); |
861} 862 863struct hme_txdma_arg { 864 struct hme_softc *hta_sc; 865 struct hme_txdesc *hta_htx; 866 int hta_ndescs; 867}; 868 --- 185 unchanged lines hidden (view full) --- 1054 1055 m->m_pkthdr.rcvif = ifp; 1056 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS; 1057 m_adj(m, HME_RXOFFS); 1058 /* RX TCP/UDP checksum */ 1059 if (ifp->if_capenable & IFCAP_RXCSUM) 1060 hme_rxcksum(m, flags); 1061 /* Pass the packet up. */ | 892} 893 894struct hme_txdma_arg { 895 struct hme_softc *hta_sc; 896 struct hme_txdesc *hta_htx; 897 int hta_ndescs; 898}; 899 --- 185 unchanged lines hidden (view full) --- 1085 1086 m->m_pkthdr.rcvif = ifp; 1087 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS; 1088 m_adj(m, HME_RXOFFS); 1089 /* RX TCP/UDP checksum */ 1090 if (ifp->if_capenable & IFCAP_RXCSUM) 1091 hme_rxcksum(m, flags); 1092 /* Pass the packet up. */ |
1093 HME_UNLOCK(sc); |
|
1062 (*ifp->if_input)(ifp, m); | 1094 (*ifp->if_input)(ifp, m); |
1095 HME_LOCK(sc); |
|
1063} 1064 1065static void 1066hme_start(struct ifnet *ifp) 1067{ | 1096} 1097 1098static void 1099hme_start(struct ifnet *ifp) 1100{ |
1101 struct hme_softc *sc = ifp->if_softc; 1102 1103 HME_LOCK(sc); 1104 hme_start_locked(ifp); 1105 HME_UNLOCK(sc); 1106} 1107 1108static void 1109hme_start_locked(struct ifnet *ifp) 1110{ |
|
1068 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc; 1069 struct mbuf *m; 1070 int error, enq = 0; 1071 1072 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1073 return; 1074 1075 error = 0; --- 92 unchanged lines hidden (view full) --- 1168 } 1169 /* Turn off watchdog */ 1170 if (sc->sc_rb.rb_td_nbusy == 0) 1171 ifp->if_timer = 0; 1172 1173 /* Update ring */ 1174 sc->sc_rb.rb_tdtail = ri; 1175 | 1111 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc; 1112 struct mbuf *m; 1113 int error, enq = 0; 1114 1115 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1116 return; 1117 1118 error = 0; --- 92 unchanged lines hidden (view full) --- 1211 } 1212 /* Turn off watchdog */ 1213 if (sc->sc_rb.rb_td_nbusy == 0) 1214 ifp->if_timer = 0; 1215 1216 /* Update ring */ 1217 sc->sc_rb.rb_tdtail = ri; 1218 |
1176 hme_start(ifp); | 1219 hme_start_locked(ifp); |
1177 1178 if (sc->sc_rb.rb_td_nbusy == 0) 1179 ifp->if_timer = 0; 1180} 1181 1182/* 1183 * RX TCP/UDP checksum 1184 */ --- 112 unchanged lines hidden (view full) --- 1297} 1298 1299void 1300hme_intr(void *v) 1301{ 1302 struct hme_softc *sc = (struct hme_softc *)v; 1303 u_int32_t status; 1304 | 1220 1221 if (sc->sc_rb.rb_td_nbusy == 0) 1222 ifp->if_timer = 0; 1223} 1224 1225/* 1226 * RX TCP/UDP checksum 1227 */ --- 112 unchanged lines hidden (view full) --- 1340} 1341 1342void 1343hme_intr(void *v) 1344{ 1345 struct hme_softc *sc = (struct hme_softc *)v; 1346 u_int32_t status; 1347 |
1348 HME_LOCK(sc); |
|
1305 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1306 CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status); 1307 1308 if ((status & HME_SEB_STAT_ALL_ERRORS) != 0) 1309 hme_eint(sc, status); 1310 1311 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0) 1312 hme_tint(sc); 1313 1314 if ((status & HME_SEB_STAT_RXTOHOST) != 0) 1315 hme_rint(sc); | 1349 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1350 CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status); 1351 1352 if ((status & HME_SEB_STAT_ALL_ERRORS) != 0) 1353 hme_eint(sc, status); 1354 1355 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0) 1356 hme_tint(sc); 1357 1358 if ((status & HME_SEB_STAT_RXTOHOST) != 0) 1359 hme_rint(sc); |
1360 HME_UNLOCK(sc); |
|
1316} 1317 1318 1319static void 1320hme_watchdog(struct ifnet *ifp) 1321{ 1322 struct hme_softc *sc = ifp->if_softc; 1323#ifdef HMEDEBUG 1324 u_int32_t status; | 1361} 1362 1363 1364static void 1365hme_watchdog(struct ifnet *ifp) 1366{ 1367 struct hme_softc *sc = ifp->if_softc; 1368#ifdef HMEDEBUG 1369 u_int32_t status; |
1370#endif |
|
1325 | 1371 |
1372 HME_LOCK(sc); 1373#ifdef HMEDEBUG |
|
1326 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1327 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status); 1328#endif 1329 device_printf(sc->sc_dev, "device timeout\n"); 1330 ++ifp->if_oerrors; | 1374 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1375 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status); 1376#endif 1377 device_printf(sc->sc_dev, "device timeout\n"); 1378 ++ifp->if_oerrors; |
1379 HME_UNLOCK(sc); |
|
1331 1332 hme_reset(sc); 1333} 1334 1335/* 1336 * Initialize the MII Management Interface 1337 */ 1338static void 1339hme_mifinit(struct hme_softc *sc) 1340{ 1341 u_int32_t v; 1342 | 1380 1381 hme_reset(sc); 1382} 1383 1384/* 1385 * Initialize the MII Management Interface 1386 */ 1387static void 1388hme_mifinit(struct hme_softc *sc) 1389{ 1390 u_int32_t v; 1391 |
1392 HME_LOCK_ASSERT(sc, MA_OWNED); 1393 |
|
1343 /* Configure the MIF in frame mode */ 1344 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1345 v &= ~HME_MIF_CFG_BBMODE; 1346 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); 1347} 1348 1349/* 1350 * MII interface 1351 */ 1352int 1353hme_mii_readreg(device_t dev, int phy, int reg) 1354{ 1355 struct hme_softc *sc = device_get_softc(dev); 1356 int n; 1357 u_int32_t v; 1358 | 1394 /* Configure the MIF in frame mode */ 1395 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1396 v &= ~HME_MIF_CFG_BBMODE; 1397 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); 1398} 1399 1400/* 1401 * MII interface 1402 */ 1403int 1404hme_mii_readreg(device_t dev, int phy, int reg) 1405{ 1406 struct hme_softc *sc = device_get_softc(dev); 1407 int n; 1408 u_int32_t v; 1409 |
1410 HME_LOCK(sc); |
|
1359 /* Select the desired PHY in the MIF configuration register */ 1360 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1361 /* Clear PHY select bit */ 1362 v &= ~HME_MIF_CFG_PHY; 1363 if (phy == HME_PHYAD_EXTERNAL) 1364 /* Set PHY select bit to get at external device */ 1365 v |= HME_MIF_CFG_PHY; 1366 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); --- 4 unchanged lines hidden (view full) --- 1371 (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) | 1372 (phy << HME_MIF_FO_PHYAD_SHIFT) | 1373 (reg << HME_MIF_FO_REGAD_SHIFT); 1374 1375 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v); 1376 for (n = 0; n < 100; n++) { 1377 DELAY(1); 1378 v = HME_MIF_READ_4(sc, HME_MIFI_FO); | 1411 /* Select the desired PHY in the MIF configuration register */ 1412 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1413 /* Clear PHY select bit */ 1414 v &= ~HME_MIF_CFG_PHY; 1415 if (phy == HME_PHYAD_EXTERNAL) 1416 /* Set PHY select bit to get at external device */ 1417 v |= HME_MIF_CFG_PHY; 1418 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); --- 4 unchanged lines hidden (view full) --- 1423 (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) | 1424 (phy << HME_MIF_FO_PHYAD_SHIFT) | 1425 (reg << HME_MIF_FO_REGAD_SHIFT); 1426 1427 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v); 1428 for (n = 0; n < 100; n++) { 1429 DELAY(1); 1430 v = HME_MIF_READ_4(sc, HME_MIFI_FO); |
1379 if (v & HME_MIF_FO_TALSB) | 1431 if (v & HME_MIF_FO_TALSB) { 1432 HME_UNLOCK(sc); |
1380 return (v & HME_MIF_FO_DATA); | 1433 return (v & HME_MIF_FO_DATA); |
1434 } |
|
1381 } 1382 1383 device_printf(sc->sc_dev, "mii_read timeout\n"); | 1435 } 1436 1437 device_printf(sc->sc_dev, "mii_read timeout\n"); |
1438 HME_UNLOCK(sc); |
|
1384 return (0); 1385} 1386 1387int 1388hme_mii_writereg(device_t dev, int phy, int reg, int val) 1389{ 1390 struct hme_softc *sc = device_get_softc(dev); 1391 int n; 1392 u_int32_t v; 1393 | 1439 return (0); 1440} 1441 1442int 1443hme_mii_writereg(device_t dev, int phy, int reg, int val) 1444{ 1445 struct hme_softc *sc = device_get_softc(dev); 1446 int n; 1447 u_int32_t v; 1448 |
1449 HME_LOCK(sc); |
|
1394 /* Select the desired PHY in the MIF configuration register */ 1395 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1396 /* Clear PHY select bit */ 1397 v &= ~HME_MIF_CFG_PHY; 1398 if (phy == HME_PHYAD_EXTERNAL) 1399 /* Set PHY select bit to get at external device */ 1400 v |= HME_MIF_CFG_PHY; 1401 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); --- 5 unchanged lines hidden (view full) --- 1407 (phy << HME_MIF_FO_PHYAD_SHIFT) | 1408 (reg << HME_MIF_FO_REGAD_SHIFT) | 1409 (val & HME_MIF_FO_DATA); 1410 1411 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v); 1412 for (n = 0; n < 100; n++) { 1413 DELAY(1); 1414 v = HME_MIF_READ_4(sc, HME_MIFI_FO); | 1450 /* Select the desired PHY in the MIF configuration register */ 1451 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1452 /* Clear PHY select bit */ 1453 v &= ~HME_MIF_CFG_PHY; 1454 if (phy == HME_PHYAD_EXTERNAL) 1455 /* Set PHY select bit to get at external device */ 1456 v |= HME_MIF_CFG_PHY; 1457 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); --- 5 unchanged lines hidden (view full) --- 1463 (phy << HME_MIF_FO_PHYAD_SHIFT) | 1464 (reg << HME_MIF_FO_REGAD_SHIFT) | 1465 (val & HME_MIF_FO_DATA); 1466 1467 HME_MIF_WRITE_4(sc, HME_MIFI_FO, v); 1468 for (n = 0; n < 100; n++) { 1469 DELAY(1); 1470 v = HME_MIF_READ_4(sc, HME_MIFI_FO); |
1415 if (v & HME_MIF_FO_TALSB) | 1471 if (v & HME_MIF_FO_TALSB) { 1472 HME_UNLOCK(sc); |
1416 return (1); | 1473 return (1); |
1474 } |
|
1417 } 1418 1419 device_printf(sc->sc_dev, "mii_write timeout\n"); | 1475 } 1476 1477 device_printf(sc->sc_dev, "mii_write timeout\n"); |
1478 HME_UNLOCK(sc); |
|
1420 return (0); 1421} 1422 1423void 1424hme_mii_statchg(device_t dev) 1425{ 1426 struct hme_softc *sc = device_get_softc(dev); | 1479 return (0); 1480} 1481 1482void 1483hme_mii_statchg(device_t dev) 1484{ 1485 struct hme_softc *sc = device_get_softc(dev); |
1427 int instance = IFM_INST(sc->sc_mii->mii_media.ifm_cur->ifm_media); 1428 int phy = sc->sc_phys[instance]; | 1486 int instance; 1487 int phy; |
1429 u_int32_t v; 1430 | 1488 u_int32_t v; 1489 |
1490 HME_LOCK(sc); 1491 instance = IFM_INST(sc->sc_mii->mii_media.ifm_cur->ifm_media); 1492 phy = sc->sc_phys[instance]; |
|
1431#ifdef HMEDEBUG 1432 if (sc->sc_debug) 1433 printf("hme_mii_statchg: status change: phy = %d\n", phy); 1434#endif 1435 1436 /* Select the current PHY in the MIF configuration register */ 1437 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1438 v &= ~HME_MIF_CFG_PHY; 1439 if (phy == HME_PHYAD_EXTERNAL) 1440 v |= HME_MIF_CFG_PHY; 1441 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); 1442 1443 /* Set the MAC Full Duplex bit appropriately */ 1444 v = HME_MAC_READ_4(sc, HME_MACI_TXCFG); | 1493#ifdef HMEDEBUG 1494 if (sc->sc_debug) 1495 printf("hme_mii_statchg: status change: phy = %d\n", phy); 1496#endif 1497 1498 /* Select the current PHY in the MIF configuration register */ 1499 v = HME_MIF_READ_4(sc, HME_MIFI_CFG); 1500 v &= ~HME_MIF_CFG_PHY; 1501 if (phy == HME_PHYAD_EXTERNAL) 1502 v |= HME_MIF_CFG_PHY; 1503 HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v); 1504 1505 /* Set the MAC Full Duplex bit appropriately */ 1506 v = HME_MAC_READ_4(sc, HME_MACI_TXCFG); |
1445 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, HME_MAC_TXCFG_ENABLE, 0)) | 1507 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, HME_MAC_TXCFG_ENABLE, 0)) { 1508 HME_UNLOCK(sc); |
1446 return; | 1509 return; |
1510 } |
|
1447 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0) 1448 v |= HME_MAC_TXCFG_FULLDPLX; 1449 else 1450 v &= ~HME_MAC_TXCFG_FULLDPLX; 1451 HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, v); | 1511 if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0) 1512 v |= HME_MAC_TXCFG_FULLDPLX; 1513 else 1514 v &= ~HME_MAC_TXCFG_FULLDPLX; 1515 HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, v); |
1452 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, 0, HME_MAC_TXCFG_ENABLE)) | 1516 if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, v, 0, HME_MAC_TXCFG_ENABLE)) { 1517 HME_UNLOCK(sc); |
1453 return; | 1518 return; |
1519 } 1520 HME_UNLOCK(sc); |
|
1454} 1455 1456static int 1457hme_mediachange(struct ifnet *ifp) 1458{ 1459 struct hme_softc *sc = ifp->if_softc; 1460 1461 return (mii_mediachg(sc->sc_mii)); 1462} 1463 1464static void 1465hme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1466{ 1467 struct hme_softc *sc = ifp->if_softc; 1468 | 1521} 1522 1523static int 1524hme_mediachange(struct ifnet *ifp) 1525{ 1526 struct hme_softc *sc = ifp->if_softc; 1527 1528 return (mii_mediachg(sc->sc_mii)); 1529} 1530 1531static void 1532hme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1533{ 1534 struct hme_softc *sc = ifp->if_softc; 1535 |
1469 if ((ifp->if_flags & IFF_UP) == 0) | 1536 HME_LOCK(sc); 1537 if ((ifp->if_flags & IFF_UP) == 0) { 1538 HME_UNLOCK(sc); |
1470 return; | 1539 return; |
1540 } |
|
1471 | 1541 |
1542 HME_UNLOCK(sc); |
|
1472 mii_pollstat(sc->sc_mii); | 1543 mii_pollstat(sc->sc_mii); |
1544 HME_LOCK(sc); |
|
1473 ifmr->ifm_active = sc->sc_mii->mii_media_active; 1474 ifmr->ifm_status = sc->sc_mii->mii_media_status; | 1545 ifmr->ifm_active = sc->sc_mii->mii_media_active; 1546 ifmr->ifm_status = sc->sc_mii->mii_media_status; |
1547 HME_UNLOCK(sc); |
|
1475} 1476 1477/* 1478 * Process an ioctl request. 1479 */ 1480static int 1481hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1482{ 1483 struct hme_softc *sc = ifp->if_softc; 1484 struct ifreq *ifr = (struct ifreq *)data; 1485 int s, error = 0; 1486 | 1548} 1549 1550/* 1551 * Process an ioctl request. 1552 */ 1553static int 1554hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1555{ 1556 struct hme_softc *sc = ifp->if_softc; 1557 struct ifreq *ifr = (struct ifreq *)data; 1558 int s, error = 0; 1559 |
1560 HME_LOCK(sc); |
|
1487 s = splnet(); 1488 1489 switch (cmd) { 1490 case SIOCSIFFLAGS: 1491 if ((ifp->if_flags & IFF_UP) == 0 && 1492 (ifp->if_flags & IFF_RUNNING) != 0) { 1493 /* 1494 * If interface is marked down and it is running, then 1495 * stop it. 1496 */ 1497 hme_stop(sc); 1498 ifp->if_flags &= ~IFF_RUNNING; 1499 } else if ((ifp->if_flags & IFF_UP) != 0 && 1500 (ifp->if_flags & IFF_RUNNING) == 0) { 1501 /* 1502 * If interface is marked up and it is stopped, then 1503 * start it. 1504 */ | 1561 s = splnet(); 1562 1563 switch (cmd) { 1564 case SIOCSIFFLAGS: 1565 if ((ifp->if_flags & IFF_UP) == 0 && 1566 (ifp->if_flags & IFF_RUNNING) != 0) { 1567 /* 1568 * If interface is marked down and it is running, then 1569 * stop it. 1570 */ 1571 hme_stop(sc); 1572 ifp->if_flags &= ~IFF_RUNNING; 1573 } else if ((ifp->if_flags & IFF_UP) != 0 && 1574 (ifp->if_flags & IFF_RUNNING) == 0) { 1575 /* 1576 * If interface is marked up and it is stopped, then 1577 * start it. 1578 */ |
1505 hme_init(sc); | 1579 hme_init_locked(sc); |
1506 } else if ((ifp->if_flags & IFF_UP) != 0) { 1507 /* 1508 * Reset the interface to pick up changes in any other 1509 * flags that affect hardware registers. 1510 */ | 1580 } else if ((ifp->if_flags & IFF_UP) != 0) { 1581 /* 1582 * Reset the interface to pick up changes in any other 1583 * flags that affect hardware registers. 1584 */ |
1511 hme_init(sc); | 1585 hme_init_locked(sc); |
1512 } 1513 if ((ifp->if_flags & IFF_LINK0) != 0) 1514 sc->sc_csum_features |= CSUM_UDP; 1515 else 1516 sc->sc_csum_features &= ~CSUM_UDP; 1517 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) 1518 ifp->if_hwassist = sc->sc_csum_features; 1519#ifdef HMEDEBUG 1520 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0; 1521#endif 1522 break; 1523 1524 case SIOCADDMULTI: 1525 case SIOCDELMULTI: 1526 hme_setladrf(sc, 1); 1527 error = 0; 1528 break; 1529 case SIOCGIFMEDIA: 1530 case SIOCSIFMEDIA: | 1586 } 1587 if ((ifp->if_flags & IFF_LINK0) != 0) 1588 sc->sc_csum_features |= CSUM_UDP; 1589 else 1590 sc->sc_csum_features &= ~CSUM_UDP; 1591 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) 1592 ifp->if_hwassist = sc->sc_csum_features; 1593#ifdef HMEDEBUG 1594 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0; 1595#endif 1596 break; 1597 1598 case SIOCADDMULTI: 1599 case SIOCDELMULTI: 1600 hme_setladrf(sc, 1); 1601 error = 0; 1602 break; 1603 case SIOCGIFMEDIA: 1604 case SIOCSIFMEDIA: |
1605 HME_UNLOCK(sc); |
|
1531 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd); | 1606 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd); |
1607 HME_LOCK(sc); |
|
1532 break; 1533 case SIOCSIFCAP: 1534 ifp->if_capenable = ifr->ifr_reqcap; 1535 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) 1536 ifp->if_hwassist = sc->sc_csum_features; 1537 else 1538 ifp->if_hwassist = 0; 1539 break; 1540 default: | 1608 break; 1609 case SIOCSIFCAP: 1610 ifp->if_capenable = ifr->ifr_reqcap; 1611 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) 1612 ifp->if_hwassist = sc->sc_csum_features; 1613 else 1614 ifp->if_hwassist = 0; 1615 break; 1616 default: |
1617 HME_UNLOCK(sc); |
|
1541 error = ether_ioctl(ifp, cmd, data); | 1618 error = ether_ioctl(ifp, cmd, data); |
1619 HME_LOCK(sc); |
|
1542 break; 1543 } 1544 1545 splx(s); | 1620 break; 1621 } 1622 1623 splx(s); |
1624 HME_UNLOCK(sc); |
|
1546 return (error); 1547} 1548 1549/* 1550 * Set up the logical address filter. 1551 */ 1552static void 1553hme_setladrf(struct hme_softc *sc, int reenable) 1554{ 1555 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 1556 struct ifmultiaddr *inm; 1557 u_int32_t crc; 1558 u_int32_t hash[4]; 1559 u_int32_t macc; 1560 | 1625 return (error); 1626} 1627 1628/* 1629 * Set up the logical address filter. 1630 */ 1631static void 1632hme_setladrf(struct hme_softc *sc, int reenable) 1633{ 1634 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 1635 struct ifmultiaddr *inm; 1636 u_int32_t crc; 1637 u_int32_t hash[4]; 1638 u_int32_t macc; 1639 |
1640 HME_LOCK_ASSERT(sc, MA_OWNED); |
|
1561 /* Clear hash table */ 1562 hash[3] = hash[2] = hash[1] = hash[0] = 0; 1563 1564 /* Get current RX configuration */ 1565 macc = HME_MAC_READ_4(sc, HME_MACI_RXCFG); 1566 1567 /* 1568 * Disable the receiver while changing it's state as the documentation --- 60 unchanged lines hidden --- | 1641 /* Clear hash table */ 1642 hash[3] = hash[2] = hash[1] = hash[0] = 0; 1643 1644 /* Get current RX configuration */ 1645 macc = HME_MAC_READ_4(sc, HME_MACI_RXCFG); 1646 1647 /* 1648 * Disable the receiver while changing it's state as the documentation --- 60 unchanged lines hidden --- |