/* * 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 * or http://www.opensolaris.org/os/licensing. * 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 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _BFE_H #define _BFE_H #include "bfe_hw.h" #ifdef __cplusplus extern "C" { #endif #define BFE_SUCCESS DDI_SUCCESS #define BFE_FAILURE DDI_FAILURE #define BFE_MAX_MULTICAST_TABLE 64 #define BFE_LINK_SPEED_10MBS 1 #define BFE_LINK_SPEED_100MBS 2 #define VTAG_SIZE 4 #define BFE_MTU ETHERMTU /* * Use to increment descriptor slot number. */ #define BFE_INC_SLOT(i, p2) \ (i = ((i + 1) & (p2 - 1))) #define BFE_DEC_SLOT(i, p2) \ (i = ((i + p2 - 1) % p2)) /* * I/O instructions */ #define OUTB(bfe, p, v) \ ddi_put8((bfe)->bfe_mem_regset.hdl, \ (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v) #define OUTW(bfe, p, v) \ ddi_put16((bfe)->bfe_mem_regset.hdl, \ (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v) #define OUTL(bfe, p, v) \ ddi_put32((bfe)->bfe_mem_regset.hdl, \ (void *)((caddr_t)((bfe)->bfe_mem_regset.addr) + (p)), v) #define INB(bfe, p) \ ddi_get8((bfe)->bfe_mem_regset.hdl, \ (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p))) #define INW(bfe, p) \ ddi_get16((bfe)->bfe_mem_regset.hdl, \ (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p))) #define INL(bfe, p) \ ddi_get32((bfe)->bfe_mem_regset.hdl, \ (void *)(((caddr_t)(bfe)->bfe_mem_regset.addr) + (p))) #define FLUSH(bfe, reg) \ (void) INL(bfe, reg) #define OUTL_OR(bfe, reg, v) \ OUTL(bfe, reg, (INL(bfe, reg) | v)) #define OUTL_AND(bfe, reg, v) \ OUTL(bfe, reg, (INL(bfe, reg) & v)) /* * These macros allows use to write to descriptor memory. */ #define PUT_DESC(r, member, val) \ ddi_put32(r->r_desc_acc_handle, (member), (val)) #define GET_DESC(r, member) \ ddi_get32(r->r_desc_acc_handle, (member)) typedef struct bfe_cards { uint16_t vendor_id; uint16_t device_id; char *cardname; } bfe_cards_t; /* * Chip's state. */ typedef enum { BFE_CHIP_UNINITIALIZED = 0, BFE_CHIP_INITIALIZED, BFE_CHIP_ACTIVE, BFE_CHIP_STOPPED, BFE_CHIP_HALT, BFE_CHIP_RESUME, BFE_CHIP_SUSPENDED, BFE_CHIP_QUIESCED } bfe_chip_state_t; /* * PHY state. */ typedef enum { BFE_PHY_STARTED = 1, BFE_PHY_STOPPED, BFE_PHY_RESET_DONE, BFE_PHY_RESET_TIMEOUT, BFE_PHY_NOTFOUND } bfe_phy_state_t; /* * Chip's mode */ #define BFE_RX_MODE_ENABLE 0x1 #define BFE_RX_MODE_PROMISC 0x2 #define BFE_RX_MODE_BROADCAST 0x4 #define BFE_RX_MODE_ALLMULTI 0x8 /* * Every packet has this header which is put by the card. */ typedef struct bfe_rx_header { uint16_t len; uint16_t flags; uint16_t pad[12]; } bfe_rx_header_t; typedef struct bfe_stats { uint64_t ether_stat_align_errors; uint64_t ether_stat_carrier_errors; uint64_t ether_stat_ex_collisions; uint64_t ether_stat_fcs_errors; uint64_t ether_stat_first_collisions; uint64_t ether_stat_macrcv_errors; uint64_t ether_stat_macxmt_errors; uint64_t ether_stat_multi_collisions; uint64_t ether_stat_toolong_errors; uint64_t ether_stat_tooshort_errors; uint64_t ether_stat_tx_late_collisions; uint64_t ether_stat_defer_xmts; uint64_t brdcstrcv; uint64_t brdcstxmt; uint64_t multixmt; uint64_t collisions; uint64_t ierrors; uint64_t ipackets; uint64_t multircv; uint64_t norcvbuf; uint64_t noxmtbuf; uint64_t obytes; uint64_t opackets; uint64_t rbytes; uint64_t underflows; uint64_t overflows; uint64_t txchecks; uint64_t intr_claimed; uint64_t intr_unclaimed; uint64_t linkchanges; uint64_t txcpybytes; uint64_t txmapbytes; uint64_t rxcpybytes; uint64_t rxmapbytes; uint64_t txreclaim0; uint64_t txreclaims; uint32_t txstalls; uint32_t resets; } bfe_stats_t; typedef struct { int state; int speed; int duplex; int flowctrl; int mau; } bfe_link_t; /* * Device registers handle */ typedef struct { ddi_acc_handle_t hdl; caddr_t addr; } bfe_acc_t; /* * BCM4401 Chip state */ typedef struct bfe_chip { int link; int state; int speed; int duplex; uint32_t bmsr; uint32_t phyaddr; } bfe_chip_t; /* * Ring Management framework. */ /* * TX and RX descriptor format in the hardware. */ typedef struct bfe_desc { volatile uint32_t desc_ctl; volatile uint32_t desc_addr; } bfe_desc_t; /* * DMA handle for each descriptor */ typedef struct bfe_dma { ddi_dma_handle_t handle; ddi_acc_handle_t acchdl; ddi_dma_cookie_t cookie; caddr_t addr; size_t len; } bfe_dma_t; /* Keep it power of 2 */ #define TX_NUM_DESC 128 #define RX_NUM_DESC 128 #define BFE_RING_UNALLOCATED 0 #define BFE_RING_ALLOCATED 1 struct bfe; typedef struct bfe_ring { /* Lock for the ring */ kmutex_t r_lock; /* Actual lock pointer. It may point to global lock */ kmutex_t *r_lockp; /* DMA handle for all buffers in descriptor table */ bfe_dma_t *r_buf_dma; /* DMA buffer holding descriptor table */ bfe_desc_t *r_desc; /* DMA handle for the descriptor table */ ddi_dma_handle_t r_desc_dma_handle; ddi_acc_handle_t r_desc_acc_handle; ddi_dma_cookie_t r_desc_cookie; uint32_t r_ndesc; /* number of descriptors for the ring */ size_t r_desc_len; /* Actual descriptor size */ /* DMA buffer length */ size_t r_buf_len; /* Flags associated to the ring */ int r_flags; /* Pointer back to bfe instance */ struct bfe *r_bfe; /* Current slot number (or descriptor number) in the ring */ uint_t r_curr_desc; /* Consumed descriptor if got the interrupt (only used for TX) */ uint_t r_cons_desc; uint_t r_avail_desc; } bfe_ring_t; /* * Device driver's private data per instance. */ typedef struct bfe { /* devinfo stuff */ dev_info_t *bfe_dip; int bfe_unit; /* PCI Configuration handle */ ddi_acc_handle_t bfe_conf_handle; /* Device registers handle and regset */ bfe_acc_t bfe_mem_regset; /* Ethernet addr */ ether_addr_t bfe_ether_addr; ether_addr_t bfe_dev_addr; /* MAC layer handle */ mac_handle_t bfe_machdl; /* Interrupt management */ ddi_intr_handle_t bfe_intrhdl; uint_t bfe_intrpri; /* Ring Management */ bfe_ring_t bfe_tx_ring; bfe_ring_t bfe_rx_ring; int bfe_tx_resched; /* Chip details */ bfe_chip_t bfe_chip; bfe_stats_t bfe_stats; bfe_chip_state_t bfe_chip_state; uint_t bfe_chip_mode; int32_t bfe_phy_addr; uchar_t bfe_chip_action; bfe_hw_stats_t bfe_hw_stats; /* rw lock for chip */ krwlock_t bfe_rwlock; /* Multicast table */ uint32_t bfe_mcast_cnt; /* Timeout and PHY state */ ddi_periodic_t bfe_periodic_id; hrtime_t bfe_tx_stall_time; bfe_phy_state_t bfe_phy_state; int bfe_phy_id; /* MII register set */ uint16_t bfe_mii_exp; uint16_t bfe_mii_bmsr; uint16_t bfe_mii_anar; uint16_t bfe_mii_anlpar; uint16_t bfe_mii_bmcr; /* Transceiver fields */ uint8_t bfe_adv_aneg; uint8_t bfe_adv_100T4; uint8_t bfe_adv_100fdx; uint8_t bfe_adv_100hdx; uint8_t bfe_adv_10fdx; uint8_t bfe_adv_10hdx; uint8_t bfe_cap_aneg; uint8_t bfe_cap_100T4; uint8_t bfe_cap_100fdx; uint8_t bfe_cap_100hdx; uint8_t bfe_cap_10fdx; uint8_t bfe_cap_10hdx; } bfe_t; static int bfe_identify_hardware(bfe_t *); #ifdef __cplusplus } #endif #endif /* _BFE_H */