if_hme.c (164866) | if_hme.c (164932) |
---|---|
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.35 2003/02/27 14:58:22 pk 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.35 2003/02/27 14:58:22 pk Exp 38 */ 39 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 164866 2006-12-04 01:53:40Z marius $"); | 41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 164932 2006-12-06 02:07:20Z marius $"); |
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 --- 49 unchanged lines hidden (view full) --- 99#include <dev/hme/if_hmereg.h> 100#include <dev/hme/if_hmevar.h> 101 102static void hme_start(struct ifnet *); 103static void hme_start_locked(struct ifnet *); 104static void hme_stop(struct hme_softc *); 105static int hme_ioctl(struct ifnet *, u_long, caddr_t); 106static void hme_tick(void *); | 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 --- 49 unchanged lines hidden (view full) --- 99#include <dev/hme/if_hmereg.h> 100#include <dev/hme/if_hmevar.h> 101 102static void hme_start(struct ifnet *); 103static void hme_start_locked(struct ifnet *); 104static void hme_stop(struct hme_softc *); 105static int hme_ioctl(struct ifnet *, u_long, caddr_t); 106static void hme_tick(void *); |
107static void hme_watchdog(struct ifnet *); | 107static int hme_watchdog(struct hme_softc *); |
108static void hme_init(void *); 109static void hme_init_locked(struct hme_softc *); 110static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 111static int hme_meminit(struct hme_softc *); 112static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 113 u_int32_t, u_int32_t); 114static void hme_mifinit(struct hme_softc *); 115static void hme_setladrf(struct hme_softc *, int); --- 93 unchanged lines hidden (view full) --- 209 * Allocate DMA capable memory 210 * Buffer descriptors must be aligned on a 2048 byte boundary; 211 * take this into account when calculating the size. Note that 212 * the maximum number of descriptors (256) occupies 2048 bytes, 213 * so we allocate that much regardless of HME_N*DESC. 214 */ 215 size = 4096; 216 | 108static void hme_init(void *); 109static void hme_init_locked(struct hme_softc *); 110static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 111static int hme_meminit(struct hme_softc *); 112static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 113 u_int32_t, u_int32_t); 114static void hme_mifinit(struct hme_softc *); 115static void hme_setladrf(struct hme_softc *, int); --- 93 unchanged lines hidden (view full) --- 209 * Allocate DMA capable memory 210 * Buffer descriptors must be aligned on a 2048 byte boundary; 211 * take this into account when calculating the size. Note that 212 * the maximum number of descriptors (256) occupies 2048 bytes, 213 * so we allocate that much regardless of HME_N*DESC. 214 */ 215 size = 4096; 216 |
217 error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, 218 BUS_SPACE_MAXADDR, NULL, NULL, size, HME_NTXDESC + HME_NRXDESC + 1, 219 BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->sc_pdmatag); | 217 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 218 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 219 HME_NTXDESC + HME_NRXDESC + 1, BUS_SPACE_MAXSIZE_32BIT, 0, 220 NULL, NULL, &sc->sc_pdmatag); |
220 if (error) 221 goto fail_ifnet; 222 223 error = bus_dma_tag_create(sc->sc_pdmatag, 2048, 0, 224 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 225 1, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, busdma_lock_mutex, 226 &sc->sc_lock, &sc->sc_cdmatag); 227 if (error) --- 57 unchanged lines hidden (view full) --- 285 goto fail_txdesc; 286 } 287 288 sc->sc_csum_features = HME_CSUM_FEATURES; 289 /* Initialize ifnet structure. */ 290 ifp->if_softc = sc; 291 if_initname(ifp, device_get_name(sc->sc_dev), 292 device_get_unit(sc->sc_dev)); | 221 if (error) 222 goto fail_ifnet; 223 224 error = bus_dma_tag_create(sc->sc_pdmatag, 2048, 0, 225 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 226 1, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, busdma_lock_mutex, 227 &sc->sc_lock, &sc->sc_cdmatag); 228 if (error) --- 57 unchanged lines hidden (view full) --- 286 goto fail_txdesc; 287 } 288 289 sc->sc_csum_features = HME_CSUM_FEATURES; 290 /* Initialize ifnet structure. */ 291 ifp->if_softc = sc; 292 if_initname(ifp, device_get_name(sc->sc_dev), 293 device_get_unit(sc->sc_dev)); |
293 ifp->if_mtu = ETHERMTU; | |
294 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 295 ifp->if_start = hme_start; 296 ifp->if_ioctl = hme_ioctl; 297 ifp->if_init = hme_init; | 294 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 295 ifp->if_start = hme_start; 296 ifp->if_ioctl = hme_ioctl; 297 ifp->if_init = hme_init; |
298 ifp->if_watchdog = hme_watchdog; | |
299 IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ); 300 ifp->if_snd.ifq_drv_maxlen = HME_NTXQ; 301 IFQ_SET_READY(&ifp->if_snd); 302 303 hme_mifinit(sc); 304 305 if ((error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, hme_mediachange, 306 hme_mediastatus)) != 0) { --- 155 unchanged lines hidden (view full) --- 462 */ 463 HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); 464 HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); 465 HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); 466 HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); 467 468 mii_tick(sc->sc_mii); 469 | 298 IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ); 299 ifp->if_snd.ifq_drv_maxlen = HME_NTXQ; 300 IFQ_SET_READY(&ifp->if_snd); 301 302 hme_mifinit(sc); 303 304 if ((error = mii_phy_probe(sc->sc_dev, &sc->sc_miibus, hme_mediachange, 305 hme_mediastatus)) != 0) { --- 155 unchanged lines hidden (view full) --- 461 */ 462 HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); 463 HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); 464 HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); 465 HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); 466 467 mii_tick(sc->sc_mii); 468 |
469 if (hme_watchdog(sc) == EJUSTRETURN) 470 return; 471 |
|
470 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 471} 472 473static void 474hme_stop(struct hme_softc *sc) 475{ 476 u_int32_t v; 477 int n; 478 479 callout_stop(&sc->sc_tick_ch); | 472 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 473} 474 475static void 476hme_stop(struct hme_softc *sc) 477{ 478 u_int32_t v; 479 int n; 480 481 callout_stop(&sc->sc_tick_ch); |
482 sc->sc_wdog_timer = 0; |
|
480 sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 481 482 /* Mask all interrupts */ 483 HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff); 484 485 /* Reset transmitter and receiver */ 486 HME_SEB_WRITE_4(sc, HME_SEBI_RESET, HME_SEB_RESET_ETX | 487 HME_SEB_RESET_ERX); --- 383 unchanged lines hidden (view full) --- 871 HME_MAC_READ_4(sc, HME_MACI_RXCFG), 872 HME_MAC_READ_4(sc, HME_MACI_TXCFG)); 873#endif 874 875 /* Set the current media. */ 876 hme_mediachange_locked(sc); 877 878 /* Start the one second timer. */ | 483 sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 484 485 /* Mask all interrupts */ 486 HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff); 487 488 /* Reset transmitter and receiver */ 489 HME_SEB_WRITE_4(sc, HME_SEBI_RESET, HME_SEB_RESET_ETX | 490 HME_SEB_RESET_ERX); --- 383 unchanged lines hidden (view full) --- 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. */ 879 hme_mediachange_locked(sc); 880 881 /* Start the one second timer. */ |
882 sc->sc_wdog_timer = 0; |
|
879 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 880 881 ifp->if_drv_flags |= IFF_DRV_RUNNING; 882 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | 883 callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc); 884 885 ifp->if_drv_flags |= IFF_DRV_RUNNING; 886 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; |
883 ifp->if_timer = 0; | |
884 hme_start_locked(ifp); 885} 886 887/* TX TCP/UDP checksum */ 888static void 889hme_txcksum(struct mbuf *m, u_int32_t *cflags) 890{ 891 struct ip *ip; --- 215 unchanged lines hidden (view full) --- 1107 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1108 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1109 break; 1110 } 1111 enq++; 1112 BPF_MTAP(ifp, m); 1113 } 1114 | 887 hme_start_locked(ifp); 888} 889 890/* TX TCP/UDP checksum */ 891static void 892hme_txcksum(struct mbuf *m, u_int32_t *cflags) 893{ 894 struct ip *ip; --- 215 unchanged lines hidden (view full) --- 1110 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1111 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1112 break; 1113 } 1114 enq++; 1115 BPF_MTAP(ifp, m); 1116 } 1117 |
1115 /* Set watchdog timer if a packet was queued */ | |
1116 if (enq > 0) { 1117 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, 1118 BUS_DMASYNC_PREWRITE); | 1118 if (enq > 0) { 1119 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, 1120 BUS_DMASYNC_PREWRITE); |
1119 ifp->if_timer = 5; | 1121 sc->sc_wdog_timer = 5; |
1120 } 1121} 1122 1123/* 1124 * Transmit interrupt. 1125 */ 1126static void 1127hme_tint(struct hme_softc *sc) --- 36 unchanged lines hidden (view full) --- 1164 1165 ifp->if_opackets++; 1166 m_freem(htx->htx_m); 1167 htx->htx_m = NULL; 1168 STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txbusyq, htx_q); 1169 STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, htx, htx_q); 1170 htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq); 1171 } | 1122 } 1123} 1124 1125/* 1126 * Transmit interrupt. 1127 */ 1128static void 1129hme_tint(struct hme_softc *sc) --- 36 unchanged lines hidden (view full) --- 1166 1167 ifp->if_opackets++; 1168 m_freem(htx->htx_m); 1169 htx->htx_m = NULL; 1170 STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txbusyq, htx_q); 1171 STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, htx, htx_q); 1172 htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq); 1173 } |
1172 /* Turn off watchdog if hme(4) transmitted queued packet */ 1173 ifp->if_timer = sc->sc_rb.rb_td_nbusy > 0 ? 5 : 0; | 1174 sc->sc_wdog_timer = sc->sc_rb.rb_td_nbusy > 0 ? 5 : 0; |
1174 1175 /* Update ring */ 1176 sc->sc_rb.rb_tdtail = ri; 1177 1178 if (ifp->if_drv_flags & IFF_DRV_RUNNING && 1179 !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1180 hme_start_locked(ifp); 1181} --- 139 unchanged lines hidden (view full) --- 1321 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0) 1322 hme_tint(sc); 1323 1324 if ((status & HME_SEB_STAT_RXTOHOST) != 0) 1325 hme_rint(sc); 1326 HME_UNLOCK(sc); 1327} 1328 | 1175 1176 /* Update ring */ 1177 sc->sc_rb.rb_tdtail = ri; 1178 1179 if (ifp->if_drv_flags & IFF_DRV_RUNNING && 1180 !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1181 hme_start_locked(ifp); 1182} --- 139 unchanged lines hidden (view full) --- 1322 if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0) 1323 hme_tint(sc); 1324 1325 if ((status & HME_SEB_STAT_RXTOHOST) != 0) 1326 hme_rint(sc); 1327 HME_UNLOCK(sc); 1328} 1329 |
1329static void 1330hme_watchdog(struct ifnet *ifp) | 1330static int 1331hme_watchdog(struct hme_softc *sc) |
1331{ | 1332{ |
1332 struct hme_softc *sc = ifp->if_softc; | |
1333#ifdef HMEDEBUG 1334 u_int32_t status; 1335#endif 1336 | 1333#ifdef HMEDEBUG 1334 u_int32_t status; 1335#endif 1336 |
1337 HME_LOCK(sc); | 1337 HME_LOCK_ASSERT(sc, MA_OWNED); |
1338#ifdef HMEDEBUG 1339 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1340 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status); 1341#endif | 1338#ifdef HMEDEBUG 1339 status = HME_SEB_READ_4(sc, HME_SEBI_STAT); 1340 CTR1(KTR_HME, "hme_watchdog: status %x", (u_int)status); 1341#endif |
1342 1343 if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0) 1344 return (0); 1345 |
|
1342 device_printf(sc->sc_dev, "device timeout\n"); | 1346 device_printf(sc->sc_dev, "device timeout\n"); |
1343 ++ifp->if_oerrors; | 1347 ++sc->sc_ifp->if_oerrors; |
1344 1345 hme_init_locked(sc); | 1348 1349 hme_init_locked(sc); |
1346 HME_UNLOCK(sc); | 1350 return (EJUSTRETURN); |
1347} 1348 1349/* 1350 * Initialize the MII Management Interface 1351 */ 1352static void 1353hme_mifinit(struct hme_softc *sc) 1354{ --- 349 unchanged lines hidden --- | 1351} 1352 1353/* 1354 * Initialize the MII Management Interface 1355 */ 1356static void 1357hme_mifinit(struct hme_softc *sc) 1358{ --- 349 unchanged lines hidden --- |