Completely rewrite the transmit logic, making it look more like the

EPIC/100 driver's.  Also, fix the "all multicast" logic.  Also do some
general cleanup.
This commit is contained in:
thorpej 1999-08-03 22:43:28 +00:00
parent e0c8203cb3
commit 3012cf91af
3 changed files with 551 additions and 448 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* $NetBSD: i82557reg.h,v 1.1 1999/06/20 16:33:28 thorpej Exp $ */
/* $NetBSD: i82557reg.h,v 1.2 1999/08/03 22:43:28 thorpej Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -133,34 +133,33 @@
#define FXP_SCB_COMMAND_RU_BASE 6
#define FXP_SCB_COMMAND_RU_RBDRESUME 7
/*
* Software-use only part of the command block.
*/
struct fxp_cb_soft {
void *next; /* pointer to next command block */
struct mbuf *mb_head; /* pointer to data for this command */
bus_dmamap_t dmamap; /* our DMA map */
};
/*
* Command block definitions
*/
/*
* NOP command.
*/
struct fxp_cb_nop {
struct fxp_cb_soft cb_soft;
volatile u_int16_t cb_status;
volatile u_int16_t cb_command;
volatile u_int32_t link_addr;
};
/*
* Individual Address command.
*/
struct fxp_cb_ias {
struct fxp_cb_soft cb_soft;
volatile u_int16_t cb_status;
volatile u_int16_t cb_command;
volatile u_int32_t link_addr;
volatile u_int8_t macaddr[6];
};
/* I hate bit-fields :-( */
/*
* Configure command.
*/
struct fxp_cb_config {
struct fxp_cb_soft cb_soft;
volatile u_int16_t cb_status;
volatile u_int16_t cb_command;
volatile u_int32_t link_addr;
@ -220,15 +219,10 @@ struct fxp_cb_config {
};
/*
* Size of the hardware portion of a given transmit descriptor, including
* the DMA segment array.
* Multicast setup command.
*/
#define FXP_MCSDESCSIZE \
(sizeof(struct fxp_cb_mcs) - offsetof(struct fxp_cb_mcs, cb_status))
#define MAXMCADDR 80
struct fxp_cb_mcs {
struct fxp_cb_soft cb_soft;
volatile u_int16_t cb_status;
volatile u_int16_t cb_command;
volatile u_int32_t link_addr;
@ -237,19 +231,9 @@ struct fxp_cb_mcs {
};
/*
* Number of DMA segments in a TxCB. The TxCB must map to a
* contiguous region from the DMA engine's perspective. Since
* we allocate memory conforming to those contraints, we can
* arbitrarily choose the number of segments.
* Transmit command.
*/
#define FXP_NTXSEG 32
struct fxp_tbd {
volatile u_int32_t tb_addr;
volatile u_int32_t tb_size;
};
struct fxp_cb_tx {
struct fxp_cb_soft cb_soft;
volatile u_int16_t cb_status;
volatile u_int16_t cb_command;
volatile u_int32_t link_addr;
@ -257,28 +241,15 @@ struct fxp_cb_tx {
volatile u_int16_t byte_count;
volatile u_int8_t tx_threshold;
volatile u_int8_t tbd_number;
/*
* The following isn't actually part of the TxCB, but we
* allocate it here for convenience.
*/
volatile struct fxp_tbd tbd[FXP_NTXSEG];
};
/*
* Offset of the hardware portion of a given transmit descriptor from the
* base of the control data DMA mapping.
* Transmit buffer descriptors.
*/
#define FXP_TXDESCOFF(sc, txd) \
(FXP_CDOFF(fcd_txcbs[0]) + \
(((u_long)(txd)) - ((u_long)&(sc)->control_data->fcd_txcbs[0])) + \
offsetof(struct fxp_cb_tx, cb_status))
/*
* Size of the hardware portion of a given transmit descriptor, including
* the DMA segment array.
*/
#define FXP_TXDESCSIZE \
(sizeof(struct fxp_cb_tx) - offsetof(struct fxp_cb_tx, cb_status))
struct fxp_tbd {
volatile u_int32_t tb_addr;
volatile u_int32_t tb_size;
};
/*
* Control Block (CB) definitions
@ -287,6 +258,7 @@ struct fxp_cb_tx {
/* status */
#define FXP_CB_STATUS_OK 0x2000
#define FXP_CB_STATUS_C 0x8000
/* commands */
#define FXP_CB_COMMAND_NOP 0x0
#define FXP_CB_COMMAND_IAS 0x1
@ -296,6 +268,7 @@ struct fxp_cb_tx {
#define FXP_CB_COMMAND_RESRV 0x5
#define FXP_CB_COMMAND_DUMP 0x6
#define FXP_CB_COMMAND_DIAG 0x7
/* command flags */
#define FXP_CB_COMMAND_SF 0x0008 /* simple/flexible mode */
#define FXP_CB_COMMAND_I 0x2000 /* generate interrupt on completion */
@ -303,13 +276,13 @@ struct fxp_cb_tx {
#define FXP_CB_COMMAND_EL 0x8000 /* end of list */
/*
* RFA definitions
* Receive Frame Area.
*
* NOTE! The RFA will NOT be aligned on a 4-byte boundary in the DMA
* area! To prevent EGCS from optimizing the copy of link_addr and
* rbd_addr (which would cause an unaligned access fault on RISC systems),
* we must make them an array of bytes!
*/
struct fxp_rfa {
volatile u_int16_t rfa_status;
volatile u_int16_t rfa_control;
@ -318,6 +291,7 @@ struct fxp_rfa {
volatile u_int16_t actual_size;
volatile u_int16_t size;
};
#define FXP_RFA_STATUS_RCOL 0x0001 /* receive collision */
#define FXP_RFA_STATUS_IAMATCH 0x0002 /* 0 = matches station address */
#define FXP_RFA_STATUS_S4 0x0010 /* receive error from PHY */
@ -329,8 +303,9 @@ struct fxp_rfa {
#define FXP_RFA_STATUS_CRC 0x0800 /* CRC error */
#define FXP_RFA_STATUS_OK 0x2000 /* packet received okay */
#define FXP_RFA_STATUS_C 0x8000 /* packet reception complete */
#define FXP_RFA_CONTROL_SF 0x08 /* simple/flexible memory mode */
#define FXP_RFA_CONTROL_H 0x10 /* header RFD */
#define FXP_RFA_CONTROL_SF 0x0008 /* simple/flexible memory mode */
#define FXP_RFA_CONTROL_H 0x0010 /* header RFD */
#define FXP_RFA_CONTROL_S 0x4000 /* suspend after reception */
#define FXP_RFA_CONTROL_EL 0x8000 /* end of list */
@ -362,14 +337,10 @@ struct fxp_stats {
/*
* Serial EEPROM control register bits
*/
/* shift clock */
#define FXP_EEPROM_EESK 0x01
/* chip select */
#define FXP_EEPROM_EECS 0x02
/* data in */
#define FXP_EEPROM_EEDI 0x04
/* data out */
#define FXP_EEPROM_EEDO 0x08
#define FXP_EEPROM_EESK 0x01 /* shift clock */
#define FXP_EEPROM_EECS 0x02 /* chip select */
#define FXP_EEPROM_EEDI 0x04 /* data in */
#define FXP_EEPROM_EEDO 0x08 /* data out */
/*
* Serial EEPROM opcodes, including start bit
@ -385,7 +356,7 @@ struct fxp_stats {
#define FXP_MDI_READ 0x2
/*
* PHY device types
* PHY device types (from EEPROM)
*/
#define FXP_PHY_NONE 0
#define FXP_PHY_82553A 1

View File

@ -1,7 +1,7 @@
/* $NetBSD: i82557var.h,v 1.1 1999/06/20 16:33:29 thorpej Exp $ */
/* $NetBSD: i82557var.h,v 1.2 1999/08/03 22:43:28 thorpej Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -72,22 +72,18 @@
*/
/*
* Number of transmit control blocks. This determines the number
* of transmit buffers that can be chained in the CB list. This
* must be a power of two.
* Transmit descriptor list size.
*/
#define FXP_NTXCB 128
/*
* TxCB list index mask. This is used to do list wrap-around.
*/
#define FXP_TXCB_MASK (FXP_NTXCB - 1)
#define FXP_NTXCB 128
#define FXP_NTXCB_MASK (FXP_NTXCB - 1)
#define FXP_NEXTTX(x) ((x + 1) & FXP_NTXCB_MASK)
#define FXP_NTXSEG 16
/*
* Number of receive frame area buffers. These are large, so
* choose wisely.
*/
#define FXP_NRFABUFS 64
#define FXP_NRFABUFS 64
/*
* Maximum number of seconds that the reciever can be idle before we
@ -109,6 +105,23 @@ struct fxp_control_data {
*/
struct fxp_cb_tx fcd_txcbs[FXP_NTXCB];
/*
* The transmit buffer descriptors.
*/
struct fxp_tbdlist {
struct fxp_tbd tbd_d[FXP_NTXSEG];
} fcd_tbdl[FXP_NTXCB];
/*
* The configuration CB.
*/
struct fxp_cb_config fcd_configcb;
/*
* The Individual Address CB.
*/
struct fxp_cb_ias fcd_iascb;
/*
* The multicast setup CB.
*/
@ -121,10 +134,23 @@ struct fxp_control_data {
};
#define FXP_CDOFF(x) offsetof(struct fxp_control_data, x)
#define FXP_CDTXOFF(x) FXP_CDOFF(fcd_txcbs[(x)])
#define FXP_CDTBDOFF(x) FXP_CDOFF(fcd_tbdl[(x)])
#define FXP_CDCONFIGOFF FXP_CDOFF(fcd_configcb)
#define FXP_CDIASOFF FXP_CDOFF(fcd_iascb)
#define FXP_CDMCSOFF FXP_CDOFF(fcd_mcscb)
#define FXP_CDSTATSOFF FXP_CDOFF(fcd_stats)
/*
* Receive buffer descriptor (software only). This is the analog of
* the software portion of the fxp_cb_tx.
* Software state for transmit descriptors.
*/
struct fxp_txsoft {
struct mbuf *txs_mbuf; /* head of mbuf chain */
bus_dmamap_t txs_dmamap; /* our DMA map */
};
/*
* Software state for receive descriptors.
*/
struct fxp_rxdesc {
struct fxp_rxdesc *fr_next; /* next in the chain */
@ -132,15 +158,19 @@ struct fxp_rxdesc {
bus_dmamap_t fr_dmamap; /* our DMA map */
};
/*
* Software state per device.
*/
struct fxp_softc {
struct device sc_dev; /* generic device structures */
void *sc_ih; /* interrupt handler cookie */
void *sc_sdhook; /* shutdown hook */
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus dma tag */
struct ethercom sc_ethercom; /* ethernet common part */
#define sc_if sc_ethercom.ec_if
void *sc_sdhook; /* shutdown hook */
void *sc_ih; /* interrupt handler cookie */
struct mii_data sc_mii; /* MII/media information */
/*
* We create a single DMA map that maps all data structure
@ -151,28 +181,31 @@ struct fxp_softc {
#define sc_cddma sc_dmamap->dm_segs[0].ds_addr
/*
* These DMA maps map transmit and recieve buffers.
* Software state for transmit and receive descriptors.
*/
bus_dmamap_t sc_tx_dmamaps[FXP_NTXCB];
struct fxp_txsoft sc_txsoft[FXP_NTXCB];
bus_dmamap_t sc_rx_dmamaps[FXP_NRFABUFS];
struct fxp_rxdesc sc_rxdescs[FXP_NRFABUFS];
/*
* Control data - TxCBs, stats, etc.
* Control data structures.
*/
struct fxp_control_data *control_data;
struct fxp_control_data *sc_control_data;
int sc_flags; /* misc. flags */
#define FXPF_NEEDMCSETUP 0x01 /* multicast setup needed */
#define FXPF_DOINGMCSETUP 0x02 /* multicast setup in-progress */
int sc_txpending; /* number of TX requests pending */
int sc_txdirty; /* first dirty TX descriptor */
int sc_txlast; /* last used TX descriptor */
/* receive buffer descriptors */
struct fxp_rxdesc sc_rxdescs[FXP_NRFABUFS];
struct mii_data sc_mii; /* MII media information */
struct fxp_cb_tx *cbl_first; /* first active TxCB in list */
struct fxp_cb_tx *cbl_last; /* last active TxCB in list */
int tx_queued; /* # of active TxCB's */
int need_mcsetup; /* multicast filter needs programming */
struct fxp_rxdesc *rfa_head; /* first mbuf in receive frame area */
struct fxp_rxdesc *rfa_tail; /* last mbuf in receive frame area */
int rx_idle_secs; /* # of seconds RX has been idle */
int all_mcasts; /* receive all multicasts */
int promisc_mode; /* promiscuous mode enabled */
int phy_primary_addr; /* address of primary PHY */
int phy_primary_device; /* device type of primary PHY */
int phy_10Mbps_only; /* PHY is 10Mbps-only device */
@ -181,6 +214,34 @@ struct fxp_softc {
#endif
};
#define FXP_CDTXADDR(sc, x) ((sc)->sc_cddma + FXP_CDTXOFF((x)))
#define FXP_CDTBDADDR(sc, x) ((sc)->sc_cddma + FXP_CDTBDOFF((x)))
#define FXP_CDTX(sc, x) (&(sc)->sc_control_data->fcd_txcbs[(x)])
#define FXP_CDTBD(sc, x) (&(sc)->sc_control_data->fcd_tbdl[(x)])
#define FXP_DSTX(sc, x) (&(sc)->sc_txsoft[(x)])
#define FXP_CDTXSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \
FXP_CDTXOFF((x)), sizeof(struct fxp_cb_tx), (ops))
#define FXP_CDTBDSYNC(sc, x, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \
FXP_CDTBDOFF((x)), sizeof(struct fxp_tbdlist), (ops))
#define FXP_CDCONFIGSYNC(sc, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \
FXP_CDCONFIGOFF, sizeof(struct fxp_cb_config), (ops))
#define FXP_CDIASSYNC(sc, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \
FXP_CDIASOFF, sizeof(struct fxp_cb_ias), (ops))
#define FXP_CDMCSSYNC(sc, ops) \
bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, \
FXP_CDMCSOFF, sizeof(struct fxp_cb_mcs), (ops))
/* Macros to ease CSR access. */
#define CSR_READ_1(sc, reg) \
bus_space_read_1((sc)->sc_st, (sc)->sc_sh, (reg))