Deleted Added
sdiff udiff text old ( 66006 ) new ( 66007 )
full compact
1/*
2 * Copyright (c) 1995, David Greenman
3 * All rights reserved.
4 *
5 * Modifications to support NetBSD and media selection:
6 * Copyright (c) 1997 Jason R. Thorpe. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 13 unchanged lines hidden (view full) ---

22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD: head/sys/dev/fxp/if_fxp.c 66007 2000-09-17 22:12:12Z dg $
31 */
32
33/*
34 * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>

--- 177 unchanged lines hidden (view full) ---

216 FXP_MEDIA_DEFAULT_DEFMEDIA },
217};
218#define NFXPMEDIA (sizeof(fxp_media) / sizeof(fxp_media[0]))
219
220static int fxp_mediachange __P((struct ifnet *));
221static void fxp_mediastatus __P((struct ifnet *, struct ifmediareq *));
222static void fxp_set_media __P((struct fxp_softc *, int));
223static __inline void fxp_scb_wait __P((struct fxp_softc *));
224static __inline void fxp_dma_wait __P((volatile u_int16_t *, struct fxp_softc *sc));
225static FXP_INTR_TYPE fxp_intr __P((void *));
226static void fxp_start __P((struct ifnet *));
227static int fxp_ioctl __P((struct ifnet *,
228 FXP_IOCTLCMD_TYPE, caddr_t));
229static void fxp_init __P((void *));
230static void fxp_stop __P((struct fxp_softc *));
231static void fxp_watchdog __P((struct ifnet *));
232static int fxp_add_rfabuf __P((struct fxp_softc *, struct mbuf *));

--- 53 unchanged lines hidden (view full) ---

286 * completed).
287 */
288static __inline void
289fxp_scb_wait(sc)
290 struct fxp_softc *sc;
291{
292 int i = 10000;
293
294 while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
295 DELAY(2);
296 if (i == 0)
297 printf(FXP_FORMAT ": SCB timeout\n", FXP_ARGS(sc));
298}
299
300static __inline void
301fxp_dma_wait(status, sc)
302 volatile u_int16_t *status;
303 struct fxp_softc *sc;
304{
305 int i = 10000;
306
307 while (!(*status & FXP_CB_STATUS_C) && --i)
308 DELAY(2);
309 if (i == 0)
310 printf(FXP_FORMAT ": DMA timeout\n", FXP_ARGS(sc));
311}
312
313/*************************************************************
314 * Operating system-specific autoconfiguration glue
315 *************************************************************/
316
317#if defined(__NetBSD__)
318
319#ifdef __BROKEN_INDIRECT_CONFIG
320static int fxp_match __P((struct device *, void *, void *));

--- 378 unchanged lines hidden (view full) ---

699 * Make sure that DMA is disabled prior to reboot. Not doing
700 * do could allow DMA to corrupt kernel memory during the
701 * reboot before the driver initializes.
702 */
703 fxp_stop((struct fxp_softc *) device_get_softc(dev));
704 return 0;
705}
706
707/*
708 * Device suspend routine. Stop the interface and save some PCI
709 * settings in case the BIOS doesn't restore them properly on
710 * resume.
711 */
712static int
713fxp_suspend(device_t dev)
714{
715 struct fxp_softc *sc = device_get_softc(dev);
716 int i, s;
717
718 s = splimp();
719
720 fxp_stop(sc);
721
722 for (i=0; i<5; i++)
723 sc->saved_maps[i] = pci_read_config(dev, PCIR_MAPS + i*4, 4);
724 sc->saved_biosaddr = pci_read_config(dev, PCIR_BIOS, 4);
725 sc->saved_intline = pci_read_config(dev, PCIR_INTLINE, 1);
726 sc->saved_cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1);
727 sc->saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
728
729 sc->suspended = 1;
730
731 splx(s);
732
733 return 0;
734}
735
736/*
737 * Device resume routine. Restore some PCI settings in case the BIOS
738 * doesn't, re-enable busmastering, and restart the interface if
739 * appropriate.
740 */
741static int
742fxp_resume(device_t dev)
743{
744 struct fxp_softc *sc = device_get_softc(dev);
745 struct ifnet *ifp = &sc->sc_if;
746 u_int16_t pci_command;
747 int i, s;
748
749 s = splimp();
750
751 /* better way to do this? */
752 for (i=0; i<5; i++)
753 pci_write_config(dev, PCIR_MAPS + i*4, sc->saved_maps[i], 4);
754 pci_write_config(dev, PCIR_BIOS, sc->saved_biosaddr, 4);
755 pci_write_config(dev, PCIR_INTLINE, sc->saved_intline, 1);
756 pci_write_config(dev, PCIR_CACHELNSZ, sc->saved_cachelnsz, 1);
757 pci_write_config(dev, PCIR_LATTIMER, sc->saved_lattimer, 1);
758
759 /* reenable busmastering */
760 pci_command = pci_read_config(dev, PCIR_COMMAND, 2);
761 pci_command |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
762 pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
763
764 CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
765 DELAY(10);
766
767 /* reinitialize interface if necessary */
768 if (ifp->if_flags & IFF_UP)
769 fxp_init(sc);
770
771 sc->suspended = 0;
772
773 splx(s);
774
775 return 0;
776}
777
778static device_method_t fxp_methods[] = {
779 /* Device interface */
780 DEVMETHOD(device_probe, fxp_probe),
781 DEVMETHOD(device_attach, fxp_attach),
782 DEVMETHOD(device_detach, fxp_detach),
783 DEVMETHOD(device_shutdown, fxp_shutdown),
784 DEVMETHOD(device_suspend, fxp_suspend),
785 DEVMETHOD(device_resume, fxp_resume),
786
787 { 0, 0 }
788};
789
790static driver_t fxp_driver = {
791 "fxp",
792 fxp_methods,
793 sizeof(struct fxp_softc),

--- 417 unchanged lines hidden (view full) ---

1211 u_int8_t statack;
1212#if defined(__NetBSD__)
1213 int claimed = 0;
1214#else
1215
1216 FXP_LOCK(sc, s);
1217#endif
1218
1219 while (!sc->suspended && (statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
1220#if defined(__NetBSD__)
1221 claimed = 1;
1222#endif
1223 /*
1224 * First ACK all the interrupts in this pass.
1225 */
1226 CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
1227

--- 221 unchanged lines hidden (view full) ---

1449 struct ifnet *ifp = &sc->sc_if;
1450 struct fxp_cb_tx *txp;
1451 int i;
1452
1453#if !defined(__NetBSD__)
1454 FXP_LOCK(sc, s);
1455#endif
1456
1457 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1458 ifp->if_timer = 0;
1459
1460 /*
1461 * Cancel stats updater.
1462 */
1463 untimeout(fxp_stats_update, sc, sc->stat_ch);
1464
1465 /*
1466 * Issue software reset
1467 */

--- 27 unchanged lines hidden (view full) ---

1495 * This "can't happen" - we're at splimp()
1496 * and we just freed all the buffers we need
1497 * above.
1498 */
1499 panic("fxp_stop: no buffers!");
1500 }
1501 }
1502
1503#if !defined(__NetBSD__)
1504 FXP_UNLOCK(sc, s);
1505#endif
1506}
1507
1508/*
1509 * Watchdog/transmission transmit timeout handler. Called when a
1510 * transmission is started on the interface, but no interrupt is

--- 101 unchanged lines hidden (view full) ---

1612
1613 /*
1614 * Start the config command/DMA.
1615 */
1616 fxp_scb_wait(sc);
1617 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
1618 CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
1619 /* ...and wait for it to complete. */
1620 fxp_dma_wait(&cbp->cb_status, sc);
1621
1622 /*
1623 * Now initialize the station address. Temporarily use the TxCB
1624 * memory area like we did above for the config CB.
1625 */
1626 cb_ias = (struct fxp_cb_ias *) sc->cbl_base;
1627 cb_ias->cb_status = 0;
1628 cb_ias->cb_command = FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL;

--- 7 unchanged lines hidden (view full) ---

1636#endif /* __NetBSD__ */
1637
1638 /*
1639 * Start the IAS (Individual Address Setup) command/DMA.
1640 */
1641 fxp_scb_wait(sc);
1642 CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
1643 /* ...and wait for it to complete. */
1644 fxp_dma_wait(&cb_ias->cb_status, sc);
1645
1646 /*
1647 * Initialize transmit control block (TxCB) list.
1648 */
1649
1650 txp = sc->cbl_base;
1651 bzero(txp, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
1652 for (i = 0; i < FXP_NTXCB; i++) {

--- 423 unchanged lines hidden (view full) ---

2076static void
2077fxp_mc_setup(sc)
2078 struct fxp_softc *sc;
2079{
2080 struct fxp_cb_mcs *mcsp = sc->mcsp;
2081 struct ifnet *ifp = &sc->sc_if;
2082 struct ifmultiaddr *ifma;
2083 int nmcasts;
2084 int count;
2085
2086 /*
2087 * If there are queued commands, we must wait until they are all
2088 * completed. If we are already waiting, then add a NOP command
2089 * with interrupt option so that we're notified when all commands
2090 * have been completed - fxp_start() ensures that no additional
2091 * TX commands will be added when need_mcsetup is true.
2092 */

--- 66 unchanged lines hidden (view full) ---

2159 mcsp->mc_cnt = nmcasts * 6;
2160 sc->cbl_first = sc->cbl_last = (struct fxp_cb_tx *) mcsp;
2161 sc->tx_queued = 1;
2162
2163 /*
2164 * Wait until command unit is not active. This should never
2165 * be the case when nothing is queued, but make sure anyway.
2166 */
2167 count = 100;
2168 while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) ==
2169 FXP_SCB_CUS_ACTIVE && --count)
2170 DELAY(10);
2171 if (count == 0) {
2172 printf(FXP_FORMAT ": command queue timeout\n", FXP_ARGS(sc));
2173 return;
2174 }
2175
2176 /*
2177 * Start the multicast setup command.
2178 */
2179 fxp_scb_wait(sc);
2180 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&mcsp->cb_status));
2181 CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
2182
2183 ifp->if_timer = 2;
2184 return;
2185}