4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
36 #define BFE_SUCCESS DDI_SUCCESS
37 #define BFE_FAILURE DDI_FAILURE
39 #define BFE_MAX_MULTICAST_TABLE 64
41 #define BFE_LINK_SPEED_10MBS 1
42 #define BFE_LINK_SPEED_100MBS 2
46 #define BFE_MTU ETHERMTU
49 * Use to increment descriptor slot number.
51 #define BFE_INC_SLOT(i, p2) \
52 (i = ((i + 1) & (p2 - 1)))
54 #define BFE_DEC_SLOT(i, p2) \
55 (i = ((i + p2 - 1) % p2))
60 #define OUTB(bfe, p, v) \
61 ddi_put8((bfe)->bfe_mem_regset.hdl, \
62 (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v)
64 #define OUTW(bfe, p, v) \
65 ddi_put16((bfe)->bfe_mem_regset.hdl, \
66 (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v)
68 #define OUTL(bfe, p, v) \
69 ddi_put32((bfe)->bfe_mem_regset.hdl, \
70 (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v)
73 ddi_get8((bfe)->bfe_mem_regset.hdl, \
74 (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p)))
76 ddi_get16((bfe)->bfe_mem_regset.hdl, \
77 (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p)))
80 ddi_get32((bfe)->bfe_mem_regset.hdl, \
81 (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p)))
83 #define FLUSH(bfe, reg) \
86 #define OUTL_OR(bfe, reg, v) \
87 OUTL(bfe, reg, (INL(bfe, reg) | v))
89 #define OUTL_AND(bfe, reg, v) \
90 OUTL(bfe, reg, (INL(bfe, reg) & v))
93 * These macros allows use to write to descriptor memory.
95 #define PUT_DESC(r, member, val) \
96 ddi_put32(r->r_desc_acc_handle, (member), (val))
98 #define GET_DESC(r, member) \
99 ddi_get32(r->r_desc_acc_handle, (member))
101 typedef struct bfe_cards
{
112 BFE_CHIP_UNINITIALIZED
= 0,
113 BFE_CHIP_INITIALIZED
,
129 BFE_PHY_RESET_TIMEOUT
,
136 #define BFE_RX_MODE_ENABLE 0x1
137 #define BFE_RX_MODE_PROMISC 0x2
138 #define BFE_RX_MODE_BROADCAST 0x4
139 #define BFE_RX_MODE_ALLMULTI 0x8
142 * Every packet has this header which is put by the card.
144 typedef struct bfe_rx_header
{
150 typedef struct bfe_stats
{
151 uint64_t ether_stat_align_errors
;
152 uint64_t ether_stat_carrier_errors
;
153 uint64_t ether_stat_ex_collisions
;
154 uint64_t ether_stat_fcs_errors
;
155 uint64_t ether_stat_first_collisions
;
156 uint64_t ether_stat_macrcv_errors
;
157 uint64_t ether_stat_macxmt_errors
;
158 uint64_t ether_stat_multi_collisions
;
159 uint64_t ether_stat_toolong_errors
;
160 uint64_t ether_stat_tooshort_errors
;
161 uint64_t ether_stat_tx_late_collisions
;
162 uint64_t ether_stat_defer_xmts
;
178 uint64_t intr_claimed
;
179 uint64_t intr_unclaimed
;
180 uint64_t linkchanges
;
200 * Device registers handle
203 ddi_acc_handle_t hdl
;
210 typedef struct bfe_chip
{
221 * Ring Management framework.
225 * TX and RX descriptor format in the hardware.
227 typedef struct bfe_desc
{
228 volatile uint32_t desc_ctl
;
229 volatile uint32_t desc_addr
;
233 * DMA handle for each descriptor
235 typedef struct bfe_dma
{
236 ddi_dma_handle_t handle
;
237 ddi_acc_handle_t acchdl
;
238 ddi_dma_cookie_t cookie
;
243 /* Keep it power of 2 */
244 #define TX_NUM_DESC 128
245 #define RX_NUM_DESC 128
248 #define BFE_RING_UNALLOCATED 0
249 #define BFE_RING_ALLOCATED 1
253 typedef struct bfe_ring
{
254 /* Lock for the ring */
257 /* Actual lock pointer. It may point to global lock */
260 /* DMA handle for all buffers in descriptor table */
261 bfe_dma_t
*r_buf_dma
;
263 /* DMA buffer holding descriptor table */
266 /* DMA handle for the descriptor table */
267 ddi_dma_handle_t r_desc_dma_handle
;
268 ddi_acc_handle_t r_desc_acc_handle
;
269 ddi_dma_cookie_t r_desc_cookie
;
270 uint32_t r_ndesc
; /* number of descriptors for the ring */
271 size_t r_desc_len
; /* Actual descriptor size */
273 /* DMA buffer length */
276 /* Flags associated to the ring */
279 /* Pointer back to bfe instance */
282 /* Current slot number (or descriptor number) in the ring */
284 /* Consumed descriptor if got the interrupt (only used for TX) */
291 * Device driver's private data per instance.
298 /* PCI Configuration handle */
299 ddi_acc_handle_t bfe_conf_handle
;
301 /* Device registers handle and regset */
302 bfe_acc_t bfe_mem_regset
;
305 ether_addr_t bfe_ether_addr
;
306 ether_addr_t bfe_dev_addr
;
308 /* MAC layer handle */
309 mac_handle_t bfe_machdl
;
311 /* Interrupt management */
312 ddi_intr_handle_t bfe_intrhdl
;
315 /* Ring Management */
316 bfe_ring_t bfe_tx_ring
;
317 bfe_ring_t bfe_rx_ring
;
322 bfe_stats_t bfe_stats
;
323 bfe_chip_state_t bfe_chip_state
;
324 uint_t bfe_chip_mode
;
325 int32_t bfe_phy_addr
;
326 uchar_t bfe_chip_action
;
327 bfe_hw_stats_t bfe_hw_stats
;
329 /* rw lock for chip */
330 krwlock_t bfe_rwlock
;
332 /* Multicast table */
333 uint32_t bfe_mcast_cnt
;
335 /* Timeout and PHY state */
336 ddi_periodic_t bfe_periodic_id
;
337 hrtime_t bfe_tx_stall_time
;
338 bfe_phy_state_t bfe_phy_state
;
341 /* MII register set */
342 uint16_t bfe_mii_exp
;
343 uint16_t bfe_mii_bmsr
;
344 uint16_t bfe_mii_anar
;
345 uint16_t bfe_mii_anlpar
;
346 uint16_t bfe_mii_bmcr
;
348 /* Transceiver fields */
349 uint8_t bfe_adv_aneg
;
350 uint8_t bfe_adv_100T4
;
351 uint8_t bfe_adv_100fdx
;
352 uint8_t bfe_adv_100hdx
;
353 uint8_t bfe_adv_10fdx
;
354 uint8_t bfe_adv_10hdx
;
355 uint8_t bfe_cap_aneg
;
356 uint8_t bfe_cap_100T4
;
357 uint8_t bfe_cap_100fdx
;
358 uint8_t bfe_cap_100hdx
;
359 uint8_t bfe_cap_10fdx
;
360 uint8_t bfe_cap_10hdx
;
363 static int bfe_identify_hardware(bfe_t
*);