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:
parent
e0c8203cb3
commit
3012cf91af
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user