The DP83932C manual says the CAM enable register (CER) can't be

accessed on normal operations and the CER should be set up
through the last entry in the CAM desciptor area and loaded
via LCAM command, so make our driver do so, though the previoius
code (writing CER directly) worked without problems.

Tested on sn at jazzio on arc (in 32bit mode) by me and
sn at nubus on mac68k (in 16bit mode) by Paul Ripke on port-mac68k.
This commit is contained in:
tsutsui 2008-04-19 06:59:08 +00:00
parent 12cb822366
commit 74a2e40f00
2 changed files with 36 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dp83932.c,v 1.23 2008/04/08 12:07:26 cegger Exp $ */
/* $NetBSD: dp83932.c,v 1.24 2008/04/19 06:59:08 tsutsui Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.23 2008/04/08 12:07:26 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.24 2008/04/19 06:59:08 tsutsui Exp $");
#include "bpfilter.h"
@ -1204,7 +1204,7 @@ sonic_set_filter(struct sonic_softc *sc)
goto allmulti;
}
if (entry == 16) {
if (entry == SONIC_NCAMENT) {
/*
* Out of CAM slots. Have to enable reception
* of all multicast addresses.
@ -1229,6 +1229,21 @@ sonic_set_filter(struct sonic_softc *sc)
rcr |= RCR_AMC;
setit:
/* set mask for the CAM Enable register */
if (sc->sc_32bit) {
if (entry == SONIC_NCAMENT)
sc->sc_cdaenable32 = htosonic32(sc, camvalid);
else
sc->sc_cda32[entry].cda_entry =
htosonic32(sc, camvalid);
} else {
if (entry == SONIC_NCAMENT)
sc->sc_cdaenable16 = htosonic16(sc, camvalid);
else
sc->sc_cda16[entry].cda_entry =
htosonic16(sc, camvalid);
}
/* Load the CAM. */
SONIC_CDCAMSYNC(sc, BUS_DMASYNC_PREWRITE);
CSR_WRITE(sc, SONIC_CDP, SONIC_CDCAMADDR(sc) & 0xffff);
@ -1243,9 +1258,6 @@ sonic_set_filter(struct sonic_softc *sc)
aprint_error_dev(&sc->sc_dev, "CAM load failed\n");
SONIC_CDCAMSYNC(sc, BUS_DMASYNC_POSTWRITE);
/* Set the CAM enable resgiter. */
CSR_WRITE(sc, SONIC_CER, camvalid);
/* Set the receive control register. */
CSR_WRITE(sc, SONIC_RCR, rcr);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: dp83932var.h,v 1.8 2008/04/19 06:39:43 tsutsui Exp $ */
/* $NetBSD: dp83932var.h,v 1.9 2008/04/19 06:59:08 tsutsui Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -69,6 +69,11 @@
#define SONIC_PREVRX(x) (((x) - 1) & SONIC_NRXDESC_MASK)
#define SONIC_RXSEQ_TO_DESC(x) ((x) & SONIC_NRXDESC_MASK)
/*
* Number of CAM entries.
*/
#define SONIC_NCAMENT 16
/*
* Control structures are DMA'd to the SONIC chip. We allocate them in
* a single clump that maps to a single DMA segment to make several things
@ -93,7 +98,8 @@ struct sonic_control_data16 {
/*
* The CAM descriptors.
*/
struct sonic_cda16 scd_cam[16];
struct sonic_cda16 scd_cam[SONIC_NCAMENT];
uint16_t scd_camenable;
};
#define SONIC_CDOFF16(x) offsetof(struct sonic_control_data16, x)
@ -101,6 +107,8 @@ struct sonic_control_data16 {
#define SONIC_CDRXOFF16(x) SONIC_CDOFF16(scd_rxdescs[(x)])
#define SONIC_CDRROFF16(x) SONIC_CDOFF16(scd_rxbufs[(x)])
#define SONIC_CDCAMOFF16 SONIC_CDOFF16(scd_cam)
#define SONIC_CDCAMSIZE16 \
(sizeof(struct sonic_cda16) * SONIC_NCAMENT + sizeof(uint16_t))
struct sonic_control_data32 {
/*
@ -121,7 +129,8 @@ struct sonic_control_data32 {
/*
* The CAM descriptors.
*/
struct sonic_cda32 scd_cam[16];
struct sonic_cda32 scd_cam[SONIC_NCAMENT];
uint32_t scd_camenable;
};
#define SONIC_CDOFF32(x) offsetof(struct sonic_control_data32, x)
@ -129,6 +138,8 @@ struct sonic_control_data32 {
#define SONIC_CDRXOFF32(x) SONIC_CDOFF32(scd_rxdescs[(x)])
#define SONIC_CDRROFF32(x) SONIC_CDOFF32(scd_rxbufs[(x)])
#define SONIC_CDCAMOFF32 SONIC_CDOFF32(scd_cam)
#define SONIC_CDCAMSIZE32 \
(sizeof(struct sonic_cda32) * SONIC_NCAMENT + sizeof(uint32_t))
/*
* Software state for transmit and receive descriptors.
@ -180,11 +191,13 @@ struct sonic_softc {
#define sc_rda16 sc_cdun.cdun_16->scd_rxdescs
#define sc_rra16 sc_cdun.cdun_16->scd_rxbufs
#define sc_cda16 sc_cdun.cdun_16->scd_cam
#define sc_cdaenable16 sc_cdun.cdun_16->scd_camenable
#define sc_tda32 sc_cdun.cdun_32->scd_txdescs
#define sc_rda32 sc_cdun.cdun_32->scd_rxdescs
#define sc_rra32 sc_cdun.cdun_32->scd_rxbufs
#define sc_cda32 sc_cdun.cdun_32->scd_cam
#define sc_cdaenable32 sc_cdun.cdun_32->scd_camenable
int sc_txpending; /* number of Tx requests pending */
int sc_txdirty; /* first dirty Tx descriptor */
@ -261,11 +274,11 @@ struct sonic_softc {
do { \
if ((sc)->sc_32bit) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
SONIC_CDCAMOFF32, sizeof(struct sonic_cda32) * 16, \
SONIC_CDCAMOFF32, SONIC_CDCAMSIZE32, \
(ops)); \
else \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap, \
SONIC_CDCAMOFF16, sizeof(struct sonic_cda16) * 16, \
SONIC_CDCAMOFF16, SONIC_CDCAMSIZE16, \
(ops)); \
} while (/*CONSTCOND*/0)