aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/bfe
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>2004-02-13 21:36:34 +0000
committerJulian Elischer <julian@FreeBSD.org>2004-02-13 21:36:34 +0000
commitf557dfe09af18af48868053e1775f8c691481240 (patch)
tree639044f6a0920f6baf47df112ac4c8f9b1c6977d /sys/dev/bfe
parent5bade38b08a39ba43b0eee280a9f63b44bad5daf (diff)
Notes
Diffstat (limited to 'sys/dev/bfe')
-rw-r--r--sys/dev/bfe/if_bfe.c192
-rw-r--r--sys/dev/bfe/if_bfereg.h12
2 files changed, 113 insertions, 91 deletions
diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c
index 95914f62d096..269f4c10a47b 100644
--- a/sys/dev/bfe/if_bfe.c
+++ b/sys/dev/bfe/if_bfe.c
@@ -1,6 +1,9 @@
/*
* Copyright (c) 2003 Stuart Walsh<stu@ipng.org.uk>
* and Duncan Barclay<dmlb@dmlb.org>
+ * Modifications for FreeBSD-stable by Edwin Groothuis
+ * <edwin at mavetju.org
+ * < http://lists.freebsd.org/mailman/listinfo/freebsd-bugs>>
*/
/*
@@ -24,12 +27,11 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
@@ -71,12 +73,7 @@
#include <dev/mii/miivar.h>
#if __FreeBSD_version > 500000
#include "miidevs.h"
-#else
-#include "miibus_if.h"
-#endif
-#include <dev/mii/brgphyreg.h>
-#if __FreeBSD_version > 500000
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#endif
@@ -87,18 +84,11 @@ MODULE_DEPEND(bfe, pci, 1, 1, 1);
MODULE_DEPEND(bfe, ether, 1, 1, 1);
MODULE_DEPEND(bfe, miibus, 1, 1, 1);
-#if __FreeBSD_version < 500000
/* "controller miibus0" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
-#endif
#define BFE_DEVDESC_MAX 64 /* Maximum device description length */
-#if __FreeBSD_version < 500000
-#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
-#define ETHER_ALIGN 2
-#endif
-
static struct bfe_type bfe_devs[] = {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM4401,
"Broadcom BCM4401 Fast Ethernet" },
@@ -241,7 +231,7 @@ bfe_dma_alloc(device_t dev)
&sc->bfe_tx_tag);
if (error) {
- device_printf(dev, "count not allocate dma tag\n");
+ device_printf(dev, "could not allocate dma tag\n");
return(ENOMEM);
}
@@ -256,7 +246,7 @@ bfe_dma_alloc(device_t dev)
&sc->bfe_rx_tag);
if (error) {
- device_printf(dev, "count not allocate dma tag\n");
+ device_printf(dev, "could not allocate dma tag\n");
return(ENOMEM);
}
@@ -330,41 +320,45 @@ bfe_dma_alloc(device_t dev)
static int
bfe_attach(device_t dev)
{
- int s;
struct ifnet *ifp;
struct bfe_softc *sc;
int unit, error = 0, rid;
- u_int32_t command;
-
- s = splimp ();
-
+
sc = device_get_softc(dev);
- bzero (sc, sizeof (struct bfe_softc));
-#if __FreeBSD_version > 500000
mtx_init(&sc->bfe_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
-#endif
unit = device_get_unit(dev);
sc->bfe_dev = dev;
sc->bfe_unit = unit;
- /*
- * Map control/status registers.
+ /*
+ * Handle power management nonsense.
*/
- /*pci_enable_busmaster(dev);*/
- command = pci_read_config(dev, PCIR_COMMAND, 4);
- command |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
- pci_write_config(dev, PCIR_COMMAND, command, 4);
- command = pci_read_config(dev, PCIR_COMMAND, 4);
-
- if (!(command & PCIM_CMD_MEMEN)) {
- printf("bfe%d: failed to enable memory mapping!\n", unit);
- error = ENXIO;
- goto fail;
+ if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
+ u_int32_t membase, irq;
+
+ /* Save important PCI config data. */
+ membase = pci_read_config(dev, BFE_PCI_MEMLO, 4);
+ irq = pci_read_config(dev, BFE_PCI_INTLINE, 4);
+
+ /* Reset the power state. */
+ printf("bfe%d: chip is is in D%d power mode -- setting to D0\n",
+ sc->bfe_unit, pci_get_powerstate(dev));
+
+ pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+
+ /* Restore PCI config data. */
+ pci_write_config(dev, BFE_PCI_MEMLO, membase, 4);
+ pci_write_config(dev, BFE_PCI_INTLINE, irq, 4);
}
+ /*
+ * Map control/status registers.
+ */
+ pci_enable_busmaster(dev);
+
rid = BFE_PCI_MEMLO;
sc->bfe_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1,
RF_ACTIVE);
@@ -444,8 +438,6 @@ bfe_attach(device_t dev)
goto fail;
}
fail:
- splx (s);
-
if(error)
bfe_release_resources(sc);
return(error);
@@ -456,7 +448,7 @@ bfe_detach(device_t dev)
{
struct bfe_softc *sc;
struct ifnet *ifp;
- int s;
+ BFE_VAR(s);
sc = device_get_softc(dev);
@@ -465,15 +457,14 @@ bfe_detach(device_t dev)
ifp = &sc->arpcom.ac_if;
-#if __FreeBSD_version > 500000
if (device_is_attached(dev)) {
bfe_stop(sc);
+#if __FreeBSD_version > 500000
ether_ifdetach(ifp);
- }
#else
- bfe_stop(sc);
- ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
+ ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
#endif
+ }
bfe_chip_reset(sc);
@@ -483,9 +474,7 @@ bfe_detach(device_t dev)
bfe_release_resources(sc);
BFE_UNLOCK(sc);
-#if __FreeBSD_version > 500000
mtx_destroy(&sc->bfe_mtx);
-#endif
return(0);
}
@@ -498,7 +487,7 @@ static void
bfe_shutdown(device_t dev)
{
struct bfe_softc *sc;
- int s;
+ BFE_VAR(s);
sc = device_get_softc(dev);
BFE_LOCK(sc);
@@ -542,6 +531,25 @@ bfe_miibus_statchg(device_t dev)
}
static void
+bfe_tx_ring_free(struct bfe_softc *sc)
+{
+ int i;
+
+ for(i = 0; i < BFE_TX_LIST_CNT; i++) {
+ if(sc->bfe_tx_ring[i].bfe_mbuf != NULL) {
+ m_freem(sc->bfe_tx_ring[i].bfe_mbuf);
+ sc->bfe_tx_ring[i].bfe_mbuf = NULL;
+ bus_dmamap_unload(sc->bfe_tag,
+ sc->bfe_tx_ring[i].bfe_map);
+ bus_dmamap_destroy(sc->bfe_tag,
+ sc->bfe_tx_ring[i].bfe_map);
+ }
+ }
+ bzero(sc->bfe_tx_list, BFE_TX_LIST_SIZE);
+ bus_dmamap_sync(sc->bfe_tx_tag, sc->bfe_tx_map, BUS_DMASYNC_PREREAD);
+}
+
+static void
bfe_rx_ring_free(struct bfe_softc *sc)
{
int i;
@@ -667,7 +675,7 @@ static void
bfe_clear_stats(struct bfe_softc *sc)
{
u_long reg;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -684,7 +692,7 @@ static int
bfe_resetphy(struct bfe_softc *sc)
{
u_int32_t val;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
bfe_writephy(sc, 0, BMCR_RESET);
@@ -702,7 +710,7 @@ bfe_resetphy(struct bfe_softc *sc)
static void
bfe_chip_halt(struct bfe_softc *sc)
{
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
/* disable interrupts - not that it actually does..*/
@@ -723,7 +731,7 @@ static void
bfe_chip_reset(struct bfe_softc *sc)
{
u_int32_t val;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -1022,7 +1030,7 @@ static int
bfe_readphy(struct bfe_softc *sc, u_int32_t reg, u_int32_t *val)
{
int err;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
/* Clear MII ISR */
@@ -1043,7 +1051,7 @@ static int
bfe_writephy(struct bfe_softc *sc, u_int32_t reg, u_int32_t val)
{
int status;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
CSR_WRITE_4(sc, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII);
@@ -1067,7 +1075,7 @@ static int
bfe_setupphy(struct bfe_softc *sc)
{
u_int32_t val;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
/* Enable activity LED */
@@ -1103,34 +1111,28 @@ static void
bfe_txeof(struct bfe_softc *sc)
{
struct ifnet *ifp;
- int i, cnt;
- int s;
+ int i, chipidx;
+ BFE_VAR(s);
BFE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
- cnt = CSR_READ_4(sc, BFE_DMATX_STAT) & BFE_STAT_CDMASK;
- cnt /= sizeof(struct bfe_desc);
+ chipidx = CSR_READ_4(sc, BFE_DMATX_STAT) & BFE_STAT_CDMASK;
+ chipidx /= sizeof(struct bfe_desc);
+ i = sc->bfe_tx_cons;
/* Go through the mbufs and free those that have been transmitted */
- for(i = sc->bfe_tx_cons; sc->bfe_tx_cnt > 0; sc->bfe_tx_cnt--) {
+ while(i != chipidx) {
struct bfe_data *r = &sc->bfe_tx_ring[i];
-
- if (i == cnt)
- break;
-
if(r->bfe_mbuf != NULL) {
ifp->if_opackets++;
- m_free(r->bfe_mbuf);
+ m_freem(r->bfe_mbuf);
r->bfe_mbuf = NULL;
bus_dmamap_unload(sc->bfe_tag, r->bfe_map);
}
-
- if(i == BFE_TX_LIST_CNT - 1)
- i = 0;
- else
- i++;
+ sc->bfe_tx_cnt--;
+ BFE_INC(i, BFE_TX_LIST_CNT);
}
if(i != sc->bfe_tx_cons) {
@@ -1156,7 +1158,7 @@ bfe_rxeof(struct bfe_softc *sc)
struct bfe_data *r;
int cons;
u_int32_t status, current, len, flags;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
cons = sc->bfe_rx_cons;
@@ -1203,13 +1205,9 @@ bfe_rxeof(struct bfe_softc *sc)
#if __FreeBSD_version > 500000
(*ifp->if_input)(ifp, m);
#else
- ether_input(ifp, (struct ether_header *)rxheader, m);
+ ether_input(ifp, NULL, m);
#endif
-
- if (cons == BFE_RX_LIST_CNT - 1)
- cons = 0;
- else
- cons++;
+ BFE_INC(cons, BFE_RX_LIST_CNT);
}
sc->bfe_rx_cons = cons;
BFE_UNLOCK(sc);
@@ -1221,7 +1219,7 @@ bfe_intr(void *xsc)
struct bfe_softc *sc = xsc;
struct ifnet *ifp;
u_int32_t istat, imask, flag;
- int s;
+ BFE_VAR(s);
ifp = &sc->arpcom.ac_if;
@@ -1335,10 +1333,7 @@ bfe_encap(struct bfe_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
bus_dmamap_sync(sc->bfe_tag, r->bfe_map, BUS_DMASYNC_PREREAD);
frag = cur;
- if (cur == BFE_TX_LIST_CNT - 1)
- cur = 0;
- else
- cur++;
+ BFE_INC(cur, BFE_TX_LIST_CNT);
cnt++;
}
}
@@ -1364,8 +1359,7 @@ bfe_start(struct ifnet *ifp)
struct bfe_softc *sc;
struct mbuf *m_head = NULL;
int idx;
- int done = 0;
- int s;
+ BFE_VAR(s);
sc = ifp->if_softc;
idx = sc->bfe_tx_prod;
@@ -1386,7 +1380,7 @@ bfe_start(struct ifnet *ifp)
return;
}
- while(!done) {
+ while(sc->bfe_tx_ring[idx].bfe_mbuf == NULL) {
IF_DEQUEUE(&ifp->if_snd, m_head);
if(m_head == NULL)
break;
@@ -1398,7 +1392,6 @@ bfe_start(struct ifnet *ifp)
if(bfe_encap(sc, m_head, &idx)) {
IF_PREPEND(&ifp->if_snd, m_head);
ifp->if_flags |= IFF_OACTIVE;
- done = 1;
break;
}
@@ -1426,7 +1419,7 @@ bfe_init(void *xsc)
{
struct bfe_softc *sc = (struct bfe_softc*)xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -1468,7 +1461,7 @@ bfe_ifmedia_upd(struct ifnet *ifp)
{
struct bfe_softc *sc;
struct mii_data *mii;
- int s;
+ BFE_VAR(s);
sc = ifp->if_softc;
@@ -1496,7 +1489,7 @@ bfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct bfe_softc *sc = ifp->if_softc;
struct mii_data *mii;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -1515,7 +1508,7 @@ bfe_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct ifreq *ifr = (struct ifreq *) data;
struct mii_data *mii;
int error = 0;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -1539,9 +1532,21 @@ bfe_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
mii = device_get_softc(sc->bfe_miibus);
error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
break;
+#if __FreeBSD_version > 500000
default:
error = ether_ioctl(ifp, command, data);
break;
+#else
+ case SIOCSIFADDR:
+ case SIOCGIFADDR:
+ case SIOCSIFMTU:
+ error = ether_ioctl(ifp, command, data);
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+#endif
}
BFE_UNLOCK(sc);
@@ -1552,7 +1557,7 @@ static void
bfe_watchdog(struct ifnet *ifp)
{
struct bfe_softc *sc;
- int s;
+ BFE_VAR(s);
sc = ifp->if_softc;
@@ -1573,7 +1578,7 @@ bfe_tick(void *xsc)
{
struct bfe_softc *sc = xsc;
struct mii_data *mii;
- int s;
+ BFE_VAR(s);
if (sc == NULL)
return;
@@ -1594,6 +1599,10 @@ bfe_tick(void *xsc)
if (!sc->bfe_link && mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
sc->bfe_link++;
+#ifdef FALSE
+ if (!sc->bfe_link)
+ sc->bfe_link++;
+#endif
BFE_UNLOCK(sc);
}
@@ -1606,7 +1615,7 @@ static void
bfe_stop(struct bfe_softc *sc)
{
struct ifnet *ifp;
- int s;
+ BFE_VAR(s);
BFE_LOCK(sc);
@@ -1615,6 +1624,7 @@ bfe_stop(struct bfe_softc *sc)
ifp = &sc->arpcom.ac_if;
bfe_chip_halt(sc);
+ bfe_tx_ring_free(sc);
bfe_rx_ring_free(sc);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
diff --git a/sys/dev/bfe/if_bfereg.h b/sys/dev/bfe/if_bfereg.h
index a672455bee58..66c2a3b414d9 100644
--- a/sys/dev/bfe/if_bfereg.h
+++ b/sys/dev/bfe/if_bfereg.h
@@ -425,11 +425,23 @@
#if __FreeBSD_version > 500000
#define BFE_LOCK(scp) mtx_lock(&sc->bfe_mtx)
#define BFE_UNLOCK(scp) mtx_unlock(&sc->bfe_mtx)
+#define BFE_VAR(s)
#else
#define BFE_LOCK(scp) s=splimp()
#define BFE_UNLOCK(scp) splx(s)
+#define BFE_VAR(s) int s
+#define BPF_MTAP(_ifp,_m) do { \
+ if ((_ifp)->if_bpf) \
+ bpf_mtap((_ifp), (_m)); \
+ } while (0)
+#define ETHER_ALIGN 2
+#define mtx_destroy(a)
+#define mtx_init(a,b,c,d)
+#define device_is_attached(a) 1
#endif
+#define BFE_INC(x, y) (x) = ((x) == ((y)-1)) ? 0 : (x)+1
+
struct bfe_data {
struct mbuf *bfe_mbuf;
bus_dmamap_t bfe_map;