bge_impl.h revision a4de4ba2aed9fb0ab6c2bcdb07b7f4fe512c4291
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _BGE_IMPL_H
#define _BGE_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __sparcv9
#endif /* __sparcv9 */
#include <sys/ethernet.h>
#include <sys/dditypes.h>
#include <sys/mac_ether.h>
#ifdef __amd64
#include <sys/x86_archext.h>
#endif
/*
* <sys/ethernet.h> *may* already have provided the typedef ether_addr_t;
* but of course C doesn't provide a way to check this directly. So here
* we rely on the fact that the symbol ETHERTYPE_AT was added to the
* header file (as a #define, which we *can* test for) at the same time
* as the typedef for ether_addr_t ;-!
*/
#ifndef ETHERTYPE_AT
#endif /* ETHERTYPE_AT */
/*
* Reconfiguring the network devices requires the net_config privilege
* in Solaris 10+.
*/
#include "bge.h"
#include "bge_hw.h"
/*
* Compile-time feature switches ...
*/
#define BGE_DO_PPIO 0 /* peek/poke ioctls */
#define BGE_RX_SOFTINT 0 /* softint per receive ring */
#define BGE_CHOOSE_SEND_METHOD 0 /* send by copying only */
/*
* NOTES:
*
* #defines:
*
* BGE_PCI_CONFIG_RNUMBER and BGE_PCI_OPREGS_RNUMBER are the
* register-set numbers to use for the config space registers
* and the operating registers respectively. On an OBP-based
* machine, regset 0 refers to CONFIG space, and regset 1 will
* be the operating registers in MEMORY space. If an expansion
* ROM is fitted, it may appear as a further register set.
*
* BGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
* for the data buffers. The descriptors are always set up
* in CONSISTENT mode.
*
* BGE_HEADROOM defines how much space we'll leave in allocated
* mblks before the first valid data byte. This should be chosen
* to be 2 modulo 4, so that once the ethernet header (14 bytes)
* has been stripped off, the packet data will be 4-byte aligned.
* The remaining space can be used by upstream modules to prepend
* any headers required.
*/
#define BGE_PCI_CONFIG_RNUMBER 0
#define BGE_PCI_OPREGS_RNUMBER 1
#define BGE_DMA_MODE DDI_DMA_STREAMING
#define BGE_HEADROOM 34
/*
* BGE_HALFTICK is half the period of the cyclic callback (in
* nanoseconds), chosen so that 0.5s <= cyclic period <= 1s.
* Other time values are derived as odd multiples of this value
* so that there's little chance of ambiguity w.r.t. which tick
* a timeout expires on.
*
* BGE_PHY_STABLE_TIME is the period for which the contents of the
* PHY's status register must remain unchanging before we accept
* that the link has come up. [Sometimes the link comes up, only
* to go down again within a short time as the autonegotiation
* process cycles through various options before finding the best
* cycles, so we wait until we think it's stable.]
*
* BGE_SERDES_STABLE_TIME is the analogous value for the SerDes
* interface. It's much shorter, 'cos the SerDes doesn't show
* these effects as much as the copper PHY.
*
* BGE_LINK_SETTLE_TIME is the period during which we regard link
* up/down cycles as an normal event after resetting/reprogramming
* the log only, not the console. At any other time, link change
* events are regarded as unexpected and sent to both console & log.
*
* These latter two values have no theoretical justification, but
* are derived from observations and heuristics - the values below
* just seem to work quite well.
*/
/*
* Indices used to identify the different buffer rings internally
*/
#define BGE_STD_BUFF_RING 0
#define BGE_JUMBO_BUFF_RING 1
#define BGE_MINI_BUFF_RING 2
/*
* Current implementation limits
*/
/* for now */
/* for now */
/* for now */
/*
*
* All of the (up to) 16 TX rings & and the corresponding buffers are the
* same size.
*
* Each of the (up to) 3 receive producer (aka buffer) rings is a different
* size and has different sized buffers associated with it too.
*
* The (up to) 16 receive return rings have no buffers associated with them.
* The number of slots per receive return ring must be 2048 if the mini
* ring is enabled, otherwise it may be 1024. See Broadcom document
* 570X-PG102-R page 56.
*
* Note: only the 5700 supported external memory (and therefore the mini
* ring); the 5702/3/4 don't. This driver doesn't support the original
* 5700, so we won't ever use the mini ring capability.
*/
#define BGE_SEND_RINGS_DEFAULT 1
#define BGE_RECV_RINGS_DEFAULT 1
#define BGE_SEND_BUFF_SIZE_DEFAULT 1536
#define BGE_SEND_BUFF_SIZE_JUMBO 9022
#define BGE_SEND_SLOTS_USED 512
#define BGE_STD_SLOTS_USED 512
#define BGE_JUMBO_SLOTS_USED 256
#define BGE_MINI_SLOTS_USED 0 /* must be 0; see above */
#define BGE_RECV_BUFF_SIZE 0
#if BGE_MINI_SLOTS_USED > 0
#else
#endif
#define BGE_SEND_BUF_NUM 512
#define BGE_SEND_BUF_ARRAY 16
#define BGE_SEND_BUF_ARRAY_JUMBO 3
/*
*/
#define BGE_PCI 0
#define BGE_PCI_E 1
#define BGE_PCI_X 2
/*
* Statistic type. There are two type of statistic:
* statistic block and statistic registers
*/
#define BGE_STAT_BLK 1
#define BGE_STAT_REG 2
/*
* MTU.for all chipsets ,the default is 1500 ,and some chipsets
* support 9k jumbo frames size
*/
#define BGE_DEFAULT_MTU 1500
#define BGE_MAXIMUM_MTU 9000
/*
* Pad the h/w defined status block (which can be up to 80 bytes long)
* to a power-of-two boundary
*/
/*
* On platforms which support DVMA, we can simply allocate one big piece
* of memory for all the Tx buffers and another for the Rx buffers, and
* then carve them up as required. It doesn't matter if they aren't just
* one physically contiguous piece each, because both the CPU *and* the
* I/O device can see them *as though they were*.
*
* However, if only physically-addressed DMA is possible, this doesn't
* work; we can't expect to get enough contiguously-addressed memory for
* all the buffers of each type, so in this case we request a number of
* smaller pieces, each still large enough for several buffers but small
* enough to fit within "an I/O page" (e.g. 64K).
*
* The #define below specifies how many pieces of memory are to be used;
* 16 has been shown to work on an i86pc architecture but this could be
* different on other non-DVMA platforms ...
*/
#ifdef _DMA_USES_VIRTADDR
#else
(BGE_RECV_RINGS_USED > 1))
#else
#endif
#endif /* _DMA_USES_VIRTADDR */
/*
* STREAMS parameters
*/
#define BGE_IDNUM 0 /* zero seems to work */
#define BGE_LOWAT (256)
/*
* Basic data types, for clarity in distinguishing 'numbers'
* used for different purposes ...
*
* A <bge_regno_t> is a register 'address' (offset) in any one of
* various address spaces (PCI config space, PCI memory-mapped I/O
* register space, MII registers, etc). None of these exceeds 64K,
* so we could use a 16-bit representation but pointer-sized objects
* are more "natural" in most architectures; they seem to be handled
* more efficiently on SPARC and no worse on x86.
*
* BGE_REGNO_NONE represents the non-existent value in this space.
*/
#define BGE_REGNO_NONE (~(uintptr_t)0u)
/*
* Describes one chunk of allocated DMA-able memory
*
* In some cases, this is a single chunk as allocated from the system;
* but we also use this structure to represent slices carved off such
* a chunk. Even when we don't really need all the information, we
* use this structure as a convenient way of correlating the various
* ways of looking at a piece of memory (kernel VA, IO space DVMA,
* handle+offset, etc).
*/
typedef struct {
void *mem_va; /* CPU VA of memory */
/* >= product of above */
} dma_area_t; /* 0x50 (80) bytes */
typedef struct bge_queue_item {
struct bge_queue_item *next;
void *item;
typedef struct bge_queue {
} bge_queue_t;
/*
* Software version of the Receive Buffer Descriptor
* There's one of these for each receive buffer (up to 256/512/1024 per ring).
*/
typedef struct sw_rbd {
/* buffer area */
} sw_rbd_t; /* 0x50 (80) bytes */
/*
* Software Receive Buffer (Producer) Ring Control Block
* There's one of these for each receiver producer ring (up to 3),
* but each holds buffers of a different size.
*/
typedef struct buff_ring {
/* descriptor area */
/* buffer area(s) */
/* RCB, and used to */
/* driver soft state */
/* initialise same */
/* "consumer index" */
/* (in status block) */
/*
* The rf_lock must be held when updating the h/w producer index
* mailbox register (*chip_mbox_reg), or the s/w producer index
* (rf_next).
*/
/* index mailbox offset */
/* ("producer index") */
} buff_ring_t; /* 0x100 (256) bytes */
/*
* Software Receive (Return) Ring Control Block
* There's one of these for each receiver return ring (up to 16).
*/
typedef struct recv_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
/* descriptor area */
/* RCB, and used to */
/* initialise same */
/* driver soft state */
/* receive callback */
/* "producer index" */
/* (in status block) */
/*
* The rx_lock must be held when updating the h/w consumer index
* mailbox register (*chip_mbox_reg), or the s/w consumer index
* (rx_next).
*/
/* index mailbox offset */
/* ("producer index") */
} recv_ring_t; /* 0x90 (144) bytes */
/*
* Send packet structure
*/
typedef struct send_pkt {
} send_pkt_t;
/*
* Software version of tx buffer structure
*/
typedef struct sw_txbuf {
} sw_txbuf_t;
/*
* Software version of the Send Buffer Descriptor
* There's one of these for each send buffer (up to 512 per ring)
*/
typedef struct sw_sbd {
/* descriptor area */
/* buffer area */
} sw_sbd_t;
/*
* Software Send Ring Control Block
* There's one of these for each of (up to) 16 send rings
*/
typedef struct send_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
/* descriptor area */
/* buffer area(s) */
/* RCB, and used to */
/* initialise same */
/* driver soft state */
/* "consumer index" */
/* (in status block) */
/* index mailbox offset */
/*
* Tx buffer queue
*/
/* ("producer index") */
/*
* path using atomics rather than mutexes for speed
*/
/*
* The tc_lock must be held while manipulating the s/w consumer
* index (tc_next).
*/
/* ("consumer index") */
} send_ring_t; /* 0x100 (256) bytes */
typedef struct {
/*
* The original 5700/01 supported only SEEPROMs. Later chips (5702+)
* the hardware and a backwards-compatible software access method), and
* buffered or unbuffered FLASH devices connected to the 4-wire SPI bus
* and using a new software access method.
*
* The access methods for SEEPROM and Flash are generally similar, with
* the chip handling the serialisation/deserialisation and handshaking,
* but the registers used are different, as are a few details of the
* protocol, and the timing, so we have to determine which (if any) is
* fitted.
*
* The value UNKNOWN means just that; we haven't yet tried to determine
* the device type.
*
* The value NONE can indicate either that a real and definite absence of
* any NVmem has been detected, or that there may be NVmem but we can't
* determine its type, perhaps because the NVconfig pins on the chip have
* been wired up incorrectly. In either case, access to the NVmem (if any)
* is not supported.
*/
enum bge_nvmem_type {
BGE_NVTYPE_UNKNOWN, /* not yet checked */
BGE_NVTYPE_SEEPROM, /* BCM5700/5701 only */
BGE_NVTYPE_LEGACY_SEEPROM, /* 5702+ */
BGE_NVTYPE_UNBUFFERED_FLASH, /* 5702+ */
BGE_NVTYPE_BUFFERED_FLASH /* 5702+ */
};
/*
* Describes the characteristics of a specific chip
*
* Note: elements from <businfo> to <latency> are filled in by during
* the first phase of chip initialisation (see bge_chip_cfg_init()).
* The remaining ones are determined just after the first RESET, in
* bge_poll_firmware(). Thereafter, the entire structure is readonly.
*/
typedef struct {
/* (e.g. 5703/5794/etc) */
} chip_id_t;
#define CHIP_FLAG_SUPPORTED 0x80
#define CHIP_FLAG_SERDES 0x40
#define CHIP_FLAG_PARTIAL_CSUM 0x20
#define CHIP_FLAG_NO_JUMBO 0x1
/*
* Collection of physical-layer functions to:
* (re)initialise the physical layer
* update it to match software settings
* check for link status change
*/
typedef struct {
int (*phys_update)(struct bge *);
} phys_ops_t;
/*
* Named Data (ND) Parameter Management Structure
*/
typedef struct {
int ndp_info;
int ndp_min;
int ndp_max;
int ndp_val;
char *ndp_name;
} nd_param_t; /* 0x18 (24) bytes */
/*
* NDD parameter indexes, divided into:
*
* read-only parameters describing the hardware's capabilities
* read-write parameters controlling the advertised capabilities
* read-only parameters describing the partner's capabilities
* read-only parameters describing the link state
*/
enum {
};
/*
* Actual state of the BCM570x chip
*/
enum bge_chip_state {
BGE_CHIP_ERROR, /* error, want reset */
BGE_CHIP_INITIAL, /* Initial state only */
BGE_CHIP_RESET, /* reset, need init */
BGE_CHIP_STOPPED, /* Tx/Rx stopped */
BGE_CHIP_RUNNING /* with interrupts */
};
enum bge_mac_state {
BGE_MAC_STOPPED = 0,
};
/*
* (Internal) return values from ioctl subroutines
*/
enum ioc_reply {
IOC_DONE, /* OK, reply sent */
IOC_ACK, /* OK, just send ACK */
IOC_REPLY, /* OK, just send reply */
IOC_RESTART_ACK, /* OK, restart & ACK */
IOC_RESTART_REPLY /* OK, restart & reply */
};
/*
* (Internal) return values from send_msg subroutines
*/
enum send_status {
SEND_KEEP, /* OK, msg queued */
SEND_FREE /* OK, free msg */
};
/*
* (Internal) enumeration of this driver's kstats
*/
enum {
BGE_KSTAT_RAW = 0,
};
#define BGE_MAX_RESOURCES 255
/*
* Per-instance soft-state structure
*/
typedef struct bge {
/*
* These fields are set by attach() and unchanged thereafter ...
*/
void *io_regs; /* mapped registers */
int intr_type; /* What type of interrupt */
int intr_cnt; /* # of intrs count returned */
int intr_cap; /* Interrupt capabilities */
const phys_ops_t *physops;
int fm_capabilities; /* FMA capabilities */
/*
* These structures describe the blocks of memory allocated during
* attach(). They remain unchanged thereafter, although the memory
* they describe is carved up into various separate regions and may
* therefore be described by other structures as well.
*/
/* receive descriptors */
/*
* The memory described by the <dma_area> structures above
* is carved up into various pieces, which are described by
* the structures below.
*/
/* statistics area */
/* status block */
/*
* For the BCM5705/5788/5721/5751/5752/5714 and 5715,
* the statistic block is not available,the statistic counter must
* be gotten from statistic registers.And bge_statistics_reg_t record
* the statistic registers value
*/
/*
* Runtime read-write data starts here ...
*
* 16 Receive (Return) Rings
* 16 Send Rings
*
* Note: they're not necessarily all used.
*/
/*
* Locks:
*
* Each buffer ring contains its own <rf_lock> which regulates
* ring refilling.
*
* Each receive (return) ring contains its own <rx_lock> which
* protects the critical cyclic counters etc.
*
* Each send ring contains two locks: <tx_lock> for the send-path
* protocol data and <tc_lock> for send-buffer recycling.
*
* Finally <genlock> is a general lock, protecting most other
* operational data in the state structure and chip register
* accesses. It is acquired by the interrupt handler and
* most "mode-control" routines.
*
* Any of the locks can be acquired singly, but where multiple
* locks are acquired, they *must* be in the order:
*
* genlock >>> rx_lock >>> rf_lock >>> tx_lock >>> tc_lock.
*
* and within any one class of lock the rings must be locked in
* ascending order (send[0].tc_lock >>> send[1].tc_lock), etc.
*
* Note: actually I don't believe there's any need to acquire
* locks on multiple rings, or even locks of all these classes
* concurrently; but I've set out the above order so there is a
* clear definition of lock hierarchy in case it's ever needed.
*
* Note: the combinations of locks that are actually held
* concurrently are:
*
* genlock >>> (bge_chip_interrupt())
* rx_lock[i] >>> (bge_receive())
* rf_lock[n] (bge_refill())
* tc_lock[i] (bge_recycle())
*/
/*
* Current Ethernet addresses and multicast hash (bitmap) and
* refcount tables, protected by <genlock>
*/
/* unused unicst addr slots */
/*
* Link state data (protected by genlock)
*/
const char *link_mode_msg; /* describes link mode */
const char *link_down_msg; /* reason for link DOWN */
const char *link_up_msg; /* comment on link UP */
/*
*/
/*
* Physical layer: copper only
*/
/*
* Physical layer: serdes only
*/
/*
* Driver kstats, protected by <genlock> where necessary
*/
/*
* Miscellaneous operating variables (protected by genlock)
*/
/*
* Miscellaneous operating variables (not synchronised)
*/
/*
* NDD parameters (protected by genlock)
*/
/*
* A flag to prevent excessive config space accesses
* on platforms having BCM5714C/15C
*/
/*
* Spare space, plus guard element used to check data integrity
*/
/*
* Receive rules configure
*/
#ifdef BGE_IPMI_ASF
#endif
} bge_t;
/*
* 'Progress' bit flags ...
*/
/* and mutexen initialised */
/*
* Shorthand for the NDD parameters
*/
/*
* Sync a DMA area described by a dma_area_t
*/
/*
* Find the (kernel virtual) address of block of memory
* described by a dma_area_t
*/
/*
* Zero a block of memory described by a dma_area_t
*/
/*
* Next value of a cyclic index
*/
/*
* Property lookups
*/
DDI_PROP_DONTPASS, (n))
DDI_PROP_DONTPASS, (n), -1)
/*
* Copy an ethernet address
*/
/*
* Endian swap
*/
/* BEGIN CSTYLED */
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
/* END CSTYLED */
/*
* Marker value placed at the end of the driver's state
*/
#define BGE_GUARD 0x1919306009031802
/*
* Bit flags in the 'debug' word ...
*/
/*
* Debugging ...
*/
#ifdef DEBUG
#define BGE_DEBUGGING 1
#else
#define BGE_DEBUGGING 0
#endif /* DEBUG */
/*
* 'Do-if-debugging' macro. The parameter <command> should be one or more
* C statements (but without the *final* semicolon), which will either be
* compiled inline or completely ignored, depending on the BGE_DEBUGGING
* compile-time flag.
*
* You should get a compile-time error (at least on a DEBUG build) if
* your statement isn't actually a statement, rather than unexpected
* run-time behaviour caused by unintended matching of if-then-elses etc.
*
* Note that the BGE_DDB() macro itself can only be used as a statement,
* not an expression, and should always be followed by a semicolon.
*/
#if BGE_DEBUGGING
{ command; } \
} while (0)
#else /* BGE_DEBUGGING */
} while (0)
#endif /* BGE_DEBUGGING */
/*
* These provide the primitive conditional-call capability required.
* Note: the parameter <args> is a parenthesised list of the actual
* printf-style arguments to be passed to the debug function ...
*/
/*
* Conditional-print macros.
*
* Define BGE_DBG to be the relevant member of the set of BGE_DBG_* values
* above before using the BGE_GDEBUG() or BGE_DEBUG() macros. The 'G'
* versions look at the Global debug flag word (bge_debug); the non-G
* versions look in the per-instance data (bgep->debug) and so require a
* variable called 'bgep' to be in scope (and initialised!) before use.
*
* You could redefine BGE_TRC too if you really need two different
* flavours of debugging output in the same area of code, but I don't
* really recommend it.
*
* Note: the parameter <args> is a parenthesised list of the actual
* arguments to be passed to the debug function, usually a printf-style
* format string and corresponding values to be formatted.
*/
/*
* Debug-only action macros
*/
/*
* Inter-source-file linkage ...
*/
/* bge_chip.c */
#ifdef BGE_IPMI_ASF
#pragma inline(bge_nic_put32)
#pragma inline(bge_ind_put32)
#pragma inline(bge_ind_get32)
void bge_asf_heartbeat(void *bgep);
#else
#endif
void bge_chip_cyclic(void *arg);
extern uint32_t bge_rx_ticks_norm;
extern uint32_t bge_tx_ticks_norm;
extern uint32_t bge_rx_count_norm;
extern uint32_t bge_tx_count_norm;
extern boolean_t bge_jumbo_enable;
extern boolean_t bge_relaxed_ordering;
/* bge_kstats.c */
/* bge_log.c */
#if BGE_DEBUGGING
#endif /* BGE_DEBUGGING */
/* bge_main.c */
/* bge_phys.c */
/* bge_ndd.c */
/* bge_recv.c */
/* bge_send.c */
/* bge_atomic.c */
/*
* Reset type
*/
#define BGE_SHUTDOWN_RESET 0
#define BGE_INIT_RESET 1
#define BGE_SUSPEND_RESET 2
/* For asf_status */
#define ASF_STAT_NONE 0
#define ASF_STAT_STOP 1
#define ASF_STAT_RUN 2
/* ASF modes for bge_reset() and bge_chip_reset() */
#define ASF_MODE_NONE 0 /* don't launch asf */
#define BGE_ASF_HEARTBEAT_INTERVAL 1500000
#ifdef __cplusplus
}
#endif
#endif /* _BGE_IMPL_H */