Deleted Added
full compact
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 ---