dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * CDDL HEADER START
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * The contents of this file are subject to the terms of the
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Common Development and Distribution License (the "License").
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * You may not use this file except in compliance with the License.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * or http://www.opensolaris.org/os/licensing.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * See the License for the specific language governing permissions
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * and limitations under the License.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * When distributing Covered Code, include this CDDL HEADER in each
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * If applicable, add the following below this CDDL HEADER, with the
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * fields enclosed by brackets "[]" replaced with your own identifying
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * information: Portions Copyright [yyyy] [name of copyright owner]
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * CDDL HEADER END
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
7a0c1e298cab158fe4113f2e75e46140eb4825e9Crisson Guanghao Hu * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/stream.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/strsun.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/stat.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/pci.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/modctl.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/kstat.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/ethernet.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/devops.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/debug.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/conf.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/sysmacros.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/dditypes.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/ddi.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/sunddi.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/miiregs.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/byteorder.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/cyclic.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/note.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/crc32.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/mac_provider.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/mac_ether.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/vlan.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/errno.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/sdt.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include <sys/strsubr.h>
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include "bfe.h"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#include "bfe_hw.h"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Broadcom BCM4401 chipsets use two rings :
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * - One TX : For sending packets down the wire.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * - One RX : For receving packets.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Each ring can have any number of descriptors (configured during attach).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * As of now we configure only 128 descriptor per ring (TX/RX). Each descriptor
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * has address (desc_addr) and control (desc_ctl) which holds a DMA buffer for
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * the packet and control information (like start/end of frame or end of table).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * The descriptor table is allocated first and then a DMA buffer (for a packet)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * is allocated and linked to each descriptor.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Each descriptor entry is bfe_desc_t structure in bfe. During TX/RX
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * interrupt, the stat register will point to current descriptor being
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * processed.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Here's an example of TX and RX ring :
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * TX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Base of the descriptor table is programmed using BFE_DMATX_CTRL control
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * register. Each 'addr' points to DMA buffer (or packet data buffer) to
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * be transmitted and 'ctl' has the length of the packet (usually MTU).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descriptor 0 |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descriptor 1 | SOF (start of the frame)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ... |Descriptor... | EOF (end of the frame)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ... | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descritor 127 |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | EOT | EOT (End of Table)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * 'r_curr_desc' : pointer to current descriptor which can be used to transmit
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * a packet.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * 'r_avail_desc' : decremented whenever a packet is being sent.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * 'r_cons_desc' : incremented whenever a packet is sent down the wire and
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * notified by an interrupt to bfe driver.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * RX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Base of the descriptor table is programmed using BFE_DMARX_CTRL control
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * register. Each 'addr' points to DMA buffer (or packet data buffer). 'ctl'
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * contains the size of the DMA buffer and all the DMA buffers are
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * pre-allocated during attach and hence the maxmium size of the packet is
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * also known (r_buf_len from the bfe_rint_t structure). During RX interrupt
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * the packet length is embedded in bfe_header_t which is added by the
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * chip in the beginning of the packet.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descriptor 0 |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descriptor 1 |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ... |Descriptor... |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ... | |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | addr |Descriptor 127|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * | ctl | EOT | EOT (End of Table)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ----------------------|
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * 'r_curr_desc' : pointer to current descriptor while receving a packet.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define MODULE_NAME "bfe"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Used for checking PHY (link state, speed)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define BFE_TIMEOUT_INTERVAL (1000 * 1000 * 1000)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Chip restart action and reason for restart
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define BFE_ACTION_RESTART 0x1 /* For restarting the chip */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define BFE_ACTION_RESTART_SETPROP 0x2 /* restart due to setprop */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define BFE_ACTION_RESTART_FAULT 0x4 /* restart due to fault */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define BFE_ACTION_RESTART_PKT 0x8 /* restart due to pkt timeout */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic char bfe_ident[] = "bfe driver for Broadcom BCM4401 chipsets";
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Function Prototypes for bfe driver.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int bfe_check_link(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_report_link(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_chip_halt(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_chip_reset(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_tx_desc_init(bfe_ring_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_rx_desc_init(bfe_ring_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_set_rx_mode(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_enable_chip_intrs(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_chip_restart(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_init_vars(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_clear_stats(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_gather_stats(bfe_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void bfe_error(dev_info_t *, char *, ...);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int bfe_mac_getprop(void *, const char *, mac_prop_id_t, uint_t,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer void *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int bfe_mac_setprop(void *, const char *, mac_prop_id_t, uint_t,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra const void *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int bfe_tx_reclaim(bfe_ring_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint bfe_mac_set_ether_addr(void *, const uint8_t *);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Macros for ddi_dma_sync().
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define SYNC_DESC(r, s, l, d) \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_sync(r->r_desc_dma_handle, \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (off_t)(s * sizeof (bfe_desc_t)), \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (size_t)(l * sizeof (bfe_desc_t)), \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra d)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define SYNC_BUF(r, s, b, l, d) \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_sync(r->r_buf_dma[s].handle, \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (off_t)(b), (size_t)(l), d)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Supported Broadcom BCM4401 Cards.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic bfe_cards_t bfe_cards[] = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra { 0x14e4, 0x170c, "BCM4401 100Base-TX"},
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA attributes for device registers, packet data (buffer) and
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * descriptor table.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct ddi_device_acc_attr bfe_dev_attr = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DEVICE_ATTR_V0,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_STRUCTURE_LE_ACC,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_STRICTORDER_ACC
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct ddi_device_acc_attr bfe_buf_attr = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DEVICE_ATTR_V0,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_NEVERSWAP_ACC, /* native endianness */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_STRICTORDER_ACC
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic ddi_dma_attr_t bfe_dma_attr_buf = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DMA_ATTR_V0, /* dma_attr_version */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* dma_attr_addr_lo */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_addr_hi */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0x1fff, /* dma_attr_count_max */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 8, /* dma_attr_align */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* dma_attr_burstsizes */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_minxfer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0x1fff, /* dma_attr_maxxfer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_seg */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_sgllen */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_granular */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0 /* dma_attr_flags */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic ddi_dma_attr_t bfe_dma_attr_desc = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DMA_ATTR_V0, /* dma_attr_version */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* dma_attr_addr_lo */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_addr_hi */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_count_max */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_DESC_ALIGN, /* dma_attr_align */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* dma_attr_burstsizes */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_minxfer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_maxxfer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_PCI_DMA - 1, /* dma_attr_seg */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_sgllen */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* dma_attr_granular */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0 /* dma_attr_flags */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Ethernet broadcast addresses.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic uchar_t bfe_broadcast[ETHERADDRL] = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra#define ASSERT_ALL_LOCKS(bfe) { \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(mutex_owned(&bfe->bfe_tx_ring.r_lock)); \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(rw_write_held(&bfe->bfe_rwlock)); \
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Debugging and error reproting code.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_error(dev_info_t *dip, char *fmt, ...)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra va_list ap;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra char buf[256];
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra va_start(ap, fmt);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) vsnprintf(buf, sizeof (buf), fmt, ap);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra va_end(ap);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (dip) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra cmn_err(CE_WARN, "%s%d: %s",
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_driver_name(dip), ddi_get_instance(dip), buf);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra cmn_err(CE_WARN, "bfe: %s", buf);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Grabs all necessary locks to block any other operation on the chip.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_grab_locks(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *tx = &bfe->bfe_tx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Grab all the locks.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * - bfe_rwlock : locks down whole chip including RX.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * - tx's r_lock : locks down only TX side.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_enter(&bfe->bfe_rwlock, RW_WRITER);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_enter(&tx->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Note that we don't use RX's r_lock.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Release lock on chip/drver.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_release_locks(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *tx = &bfe->bfe_tx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Release all the locks in the order in which they were grabbed.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_exit(&tx->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It's used to make sure that the write to device register was successful.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_wait_bit(bfe_t *bfe, uint32_t reg, uint32_t bit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ulong_t t, const int clear)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ulong_t i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < t; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = INL(bfe, reg);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (clear && !(v & bit))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (!clear && (v & bit))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(10);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* if device still didn't see the value */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (i == t)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (-1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * PHY functions (read, write, stop, reset and startup)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_read_phy(bfe_t *bfe, uint32_t reg)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_MDIO_DATA, (BFE_MDIO_SB_START |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_MDIO_OP_READ << BFE_MDIO_OP_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (bfe->bfe_phy_addr << BFE_MDIO_PMD_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (reg << BFE_MDIO_RA_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_MDIO_TA_VALID << BFE_MDIO_TA_SHIFT)));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII, 10, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return ((INL(bfe, BFE_MDIO_DATA) & BFE_MDIO_DATA_DATA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_write_phy(bfe_t *bfe, uint32_t reg, uint32_t val)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_MDIO_DATA, (BFE_MDIO_SB_START |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_MDIO_OP_WRITE << BFE_MDIO_OP_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (bfe->bfe_phy_addr << BFE_MDIO_PMD_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (reg << BFE_MDIO_RA_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_MDIO_TA_VALID << BFE_MDIO_TA_SHIFT) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (val & BFE_MDIO_DATA_DATA)));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII, 10, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It resets the PHY layer.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_reset_phy(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_CONTROL, MII_CONTROL_RESET);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(100);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < 10; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_read_phy(bfe, MII_CONTROL) &
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra MII_CONTROL_RESET) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(500);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra continue;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (i == 10) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "Timeout waiting for PHY to reset");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_state = BFE_PHY_RESET_TIMEOUT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_state = BFE_PHY_RESET_DONE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Make sure timer function is out of our way and especially during
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * detach.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_stop_timer(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_periodic_id) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_periodic_delete(bfe->bfe_periodic_id);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_periodic_id = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Stops the PHY
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_stop_phy(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_CONTROL, MII_CONTROL_PWRDN |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra MII_CONTROL_ISOLATE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.link = LINK_STATE_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_state = BFE_PHY_STOPPED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Report the link status to MAC layer.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_machdl != NULL)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_report_link(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_probe_phy(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int phy;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t status;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_phy_addr) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra status = bfe_read_phy(bfe, MII_STATUS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (status != 0xffff && status != 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_CONTROL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (phy = 0; phy < 32; phy++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_addr = phy;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra status = bfe_read_phy(bfe, MII_STATUS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (status != 0xffff && status != 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_CONTROL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * This timeout function fires at BFE_TIMEOUT_INTERVAL to check the link
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * status.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_timeout(void *arg)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra int resched = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We don't grab any lock because bfe can't go away.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * untimeout() will wait for this timeout instance to complete.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_action & BFE_ACTION_RESTART) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Restart the chip.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_restart(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action &= ~BFE_ACTION_RESTART;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_FAULT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_PKT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_tx_update(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Restart will register a new timeout */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_enter(&bfe->bfe_rwlock, RW_READER);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra hrtime_t hr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra hr = gethrtime();
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_tx_stall_time != 0 &&
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra hr > bfe->bfe_tx_stall_time) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE2(chip__restart, int, bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra char *, "pkt timeout");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action |=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_ACTION_RESTART | BFE_ACTION_RESTART_PKT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_stall_time = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_phy_state == BFE_PHY_STARTED) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Report the link status to MAC layer if link status changed.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_check_link(bfe)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_report_link(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip.link == LINK_STATE_UP) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t val, flow;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_TX_CTRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val &= ~BFE_TX_DUPLEX;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip.duplex == LINK_DUPLEX_FULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val |= BFE_TX_DUPLEX;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra flow = INL(bfe, BFE_RXCONF);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra flow &= ~BFE_RXCONF_FLOW;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RXCONF, flow);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra flow = INL(bfe, BFE_MAC_FLOW);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra flow &= ~(BFE_FLOW_RX_HIWAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_MAC_FLOW, flow);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra resched = 1;
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_TX_CTRL, val);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE1(link__up,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, bfe->bfe_unit);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra if (resched)
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra mac_tx_update(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Starts PHY layer.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_startup_phy(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint16_t bmsr, bmcr, anar;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int prog, s;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int phyid1, phyid2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_probe_phy(bfe) == BFE_FAILURE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_state = BFE_PHY_NOTFOUND;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_reset_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra phyid1 = bfe_read_phy(bfe, MII_PHYIDH);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra phyid2 = bfe_read_phy(bfe, MII_PHYIDL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_id = (phyid1 << 16) | phyid2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmsr = bfe_read_phy(bfe, MII_STATUS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar = bfe_read_phy(bfe, MII_AN_ADVERT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraagain:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar &= ~(MII_ABILITY_100BASE_T4 |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra MII_ABILITY_100BASE_TX_FD | MII_ABILITY_100BASE_TX |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra MII_ABILITY_10BASE_T_FD | MII_ABILITY_10BASE_T);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Supported hardware modes are in bmsr.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.bmsr = bmsr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Assume no capabilities are supported in the hardware.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_aneg = bfe->bfe_cap_100T4 =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_100fdx = bfe->bfe_cap_100hdx =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_10fdx = bfe->bfe_cap_10hdx = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Assume property is set.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra s = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (!(bfe->bfe_chip_action & BFE_ACTION_RESTART_SETPROP)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Property is not set which means bfe_mac_setprop()
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * is not called on us.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra s = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = prog = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_100_BASEX_FD) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_100fdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_TX_FD;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_100fdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_adv_100fdx) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_TX_FD;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_100_BASE_T4) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_100T4 = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_T4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_100T4 = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_adv_100T4) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_T4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_100_BASEX) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_100hdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_TX;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_100hdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_adv_100hdx) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_100BASE_TX;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_10_FD) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_10fdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_10BASE_T_FD;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_10fdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_adv_10fdx) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_10BASE_T_FD;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_10) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_10hdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_10BASE_T;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_10hdx = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_adv_10hdx) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar |= MII_ABILITY_10BASE_T;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prog++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmsr & MII_STATUS_CANAUTONEG) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_cap_aneg = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_adv_aneg = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (prog == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (s == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra "No valid link mode selected. Powering down PHY");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_report_link(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * If property is set then user would have goofed up. So we
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * go back to default properties.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_SETPROP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto again;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_adv_aneg && (bmsr & MII_STATUS_CANAUTONEG)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = (MII_CONTROL_ANE | MII_CONTROL_RSAN);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_adv_100fdx)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = (MII_CONTROL_100MB | MII_CONTROL_FDUPLEX);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else if (bfe->bfe_adv_100hdx)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = MII_CONTROL_100MB;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else if (bfe->bfe_adv_10fdx)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = MII_CONTROL_FDUPLEX;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = 0; /* 10HDX */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (prog)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_AN_ADVERT, anar);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmcr)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_write_phy(bfe, MII_CONTROL, bmcr);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_anar = anar;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_bmcr = bmcr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_state = BFE_PHY_STARTED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_periodic_id == NULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_periodic_id = ddi_periodic_add(bfe_timeout,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void *)bfe, BFE_TIMEOUT_INTERVAL, DDI_IPL_0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE1(first__timeout, int, bfe->bfe_unit);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE4(phy_started, int, bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, bmsr, int, bmcr, int, anar);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reports link status back to MAC Layer.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_report_link(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_link_update(bfe->bfe_machdl, bfe->bfe_chip.link);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reads PHY/MII registers and get the link status for us.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_check_link(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint16_t bmsr, bmcr, anar, anlpar;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int speed, duplex, link;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra speed = bfe->bfe_chip.speed;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra duplex = bfe->bfe_chip.duplex;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra link = bfe->bfe_chip.link;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmsr = bfe_read_phy(bfe, MII_STATUS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_bmsr = bmsr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bmcr = bfe_read_phy(bfe, MII_CONTROL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anar = bfe_read_phy(bfe, MII_AN_ADVERT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_anar = anar;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra anlpar = bfe_read_phy(bfe, MII_AN_LPABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_anlpar = anlpar;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_exp = bfe_read_phy(bfe, MII_AN_EXPANSION);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * If exp register is not present in PHY.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_mii_exp == 0xffff) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_mii_exp = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((bmsr & MII_STATUS_LINKUP) == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.link = LINK_STATE_DOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto done;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.link = LINK_STATE_UP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (!(bmcr & MII_CONTROL_ANE)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Forced mode */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmcr & MII_CONTROL_100MB)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 100000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 10000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bmcr & MII_CONTROL_FDUPLEX)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if ((!(bmsr & MII_STATUS_CANAUTONEG)) ||
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (!(bmsr & MII_STATUS_ANDONE))) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (anar & anlpar & MII_ABILITY_100BASE_TX_FD) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 100000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (anar & anlpar & MII_ABILITY_100BASE_T4) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 100000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (anar & anlpar & MII_ABILITY_100BASE_TX) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 100000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (anar & anlpar & MII_ABILITY_10BASE_T_FD) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 10000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (anar & anlpar & MII_ABILITY_10BASE_T) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 10000000;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misradone:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * If speed or link status or duplex mode changed then report to
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * MAC layer which is done by the caller.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (speed != bfe->bfe_chip.speed ||
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra duplex != bfe->bfe_chip.duplex ||
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra link != bfe->bfe_chip.link) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_cam_write(bfe_t *bfe, uchar_t *d, int index)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = ((uint32_t)d[2] << 24);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= ((uint32_t)d[3] << 16);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= ((uint32_t)d[4] << 8);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= (uint32_t)d[5];
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_CAM_DATA_LO, v);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (BFE_CAM_HI_VALID |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (((uint32_t)d[0]) << 8) |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (((uint32_t)d[1])));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_CAM_DATA_HI, v);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_CAM_CTRL, (BFE_CAM_WRITE |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ((uint32_t)index << BFE_CAM_INDEX_SHIFT)));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_CAM_CTRL, BFE_CAM_BUSY, 10, 1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Chip related functions (halt, reset, start).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_chip_halt(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Disables interrupts.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_INTR_MASK, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_INTR_MASK);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_DISABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Wait until TX and RX finish their job.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_ENET_CTRL, BFE_ENET_DISABLE, 20, 1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Disables DMA engine.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMARX_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMATX_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(10);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_HALT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_chip_restart(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE2(chip__restart, int, bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, bfe->bfe_chip_action);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Halt chip and PHY.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_STOPPED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Init variables.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_init_vars(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reset chip and start PHY.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA descriptor rings.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_tx_desc_init(&bfe->bfe_tx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_rx_desc_init(&bfe->bfe_rx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_ACTIVE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_set_rx_mode(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_enable_chip_intrs(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Disables core by stopping the clock.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_core_disable(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((INL(bfe, BFE_SBTMSLOW) & BFE_RESET))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, (BFE_REJECT | BFE_CLOCK));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_SBTMSLOW, BFE_REJECT, 100, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_SBTMSHIGH, BFE_BUSY, 100, 1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, (BFE_FGC | BFE_CLOCK | BFE_REJECT | BFE_RESET));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_SBTMSLOW);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(10);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, (BFE_REJECT | BFE_RESET));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(10);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Resets core.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_core_reset(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t val;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * First disable the core.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_core_disable(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, (BFE_RESET | BFE_CLOCK | BFE_FGC));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_SBTMSLOW);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (INL(bfe, BFE_SBTMSHIGH) & BFE_SERR)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSHIGH, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_SBIMSTATE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (val & (BFE_IBE | BFE_TO))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBIMSTATE, val & ~(BFE_IBE | BFE_TO));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, (BFE_CLOCK | BFE_FGC));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_SBTMSLOW);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBTMSLOW, BFE_CLOCK);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_SBTMSLOW);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_setup_config(bfe_t *bfe, uint32_t cores)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t bar_orig, val;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Change bar0 window to map sbtopci registers.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bar_orig = pci_config_get32(bfe->bfe_conf_handle, BFE_BAR0_WIN);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra pci_config_put32(bfe->bfe_conf_handle, BFE_BAR0_WIN, BFE_REG_PCI);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Just read it and don't do anything */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_SBIDHIGH) & BFE_IDH_CORE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_SBINTVEC);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val |= cores;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SBINTVEC, val);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_SSB_PCI_TRANS_2);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val |= BFE_SSB_PCI_PREF | BFE_SSB_PCI_BURST;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_SSB_PCI_TRANS_2, val);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Restore bar0 window mapping.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra pci_config_put32(bfe->bfe_conf_handle, BFE_BAR0_WIN, bar_orig);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Resets chip and starts PHY.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_chip_reset(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t val;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Set the interrupt vector for the enet core */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_setup_config(bfe, BFE_INTVEC_ENET0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* check if core is up */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_SBTMSLOW) &
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_RESET | BFE_REJECT | BFE_CLOCK);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (val == BFE_CLOCK) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RCV_LAZY, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_DISABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_ENET_CTRL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_ENET_DISABLE, 10, 1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMATX_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_DMARX_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(20000); /* 20 milli seconds */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (INL(bfe, BFE_DMARX_STAT) & BFE_STAT_EMASK) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_wait_bit(bfe, BFE_DMARX_STAT, BFE_STAT_SIDLE,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 10, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMARX_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_core_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_clear_stats(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_MDIO_CTRL, 0x8d);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_DEVCTRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (!(val & BFE_IPP))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_EPSEL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else if (INL(bfe, BFE_DEVCTRL & BFE_EPR)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL_AND(bfe, BFE_DEVCTRL, ~BFE_EPR);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra drv_usecwait(20000); /* 20 milli seconds */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL_OR(bfe, BFE_MAC_CTRL, BFE_CTRL_CRC32_ENAB | BFE_CTRL_LED);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL_AND(bfe, BFE_MAC_CTRL, ~BFE_CTRL_PDOWN);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RCV_LAZY, ((1 << BFE_LAZY_FC_SHIFT) &
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_LAZY_FC_MASK));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL_OR(bfe, BFE_RCV_LAZY, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RXMAXLEN, bfe->bfe_rx_ring.r_buf_len);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_TXMAXLEN, bfe->bfe_tx_ring.r_buf_len);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_TX_WMARK, 56);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Program DMA channels */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMATX_CTRL, BFE_TX_CTRL_ENABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA addresses need to be added to BFE_PCI_DMA
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMATX_ADDR,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_desc_cookie.dmac_laddress + BFE_PCI_DMA);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMARX_CTRL, (BFE_RX_OFFSET << BFE_RX_CTRL_ROSHIFT)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra | BFE_RX_CTRL_ENABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMARX_ADDR,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_desc_cookie.dmac_laddress + BFE_PCI_DMA);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_startup_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_INITIALIZED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It enables interrupts. Should be the last step while starting chip.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_enable_chip_intrs(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Enable the chip and core */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_ENABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Enable interrupts */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_INTR_MASK, BFE_IMASK_DEF);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Common code to take care of setting RX side mode (filter).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_set_rx_mode(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t val;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ether_addr_t mac[ETHERADDRL] = {0, 0, 0, 0, 0, 0};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We don't touch RX filter if we were asked to suspend. It's fine
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * if chip is not active (no interface is plumbed on us).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_SUSPENDED)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val = INL(bfe, BFE_RXCONF);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val &= ~BFE_RXCONF_PROMISC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val &= ~BFE_RXCONF_DBCAST;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((bfe->bfe_chip_mode & BFE_RX_MODE_ENABLE) == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_CAM_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_CAM_CTRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else if (bfe->bfe_chip_mode & BFE_RX_MODE_PROMISC) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val |= BFE_RXCONF_PROMISC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val &= ~BFE_RXCONF_DBCAST;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Flush everything */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RXCONF, val |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_RXCONF_PROMISC | BFE_RXCONF_ALLMULTI);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_RXCONF);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Disable CAM */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_CAM_CTRL, 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_CAM_CTRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We receive all multicast packets.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra val |= BFE_RXCONF_ALLMULTI;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < BFE_MAX_MULTICAST_TABLE - 1; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_cam_write(bfe, (uchar_t *)mac, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_cam_write(bfe, bfe->bfe_ether_addr, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Enable CAM */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL_OR(bfe, BFE_CAM_CTRL, BFE_CAM_ENABLE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_CAM_CTRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE2(rx__mode__filter, int, bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, val);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_RXCONF, val);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_RXCONF);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reset various variable values to initial state.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_init_vars(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_mode = BFE_RX_MODE_ENABLE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Initial assumption */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.link = LINK_STATE_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.speed = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_periodic_id = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_UNINITIALIZED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_stall_time = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Initializes TX side descriptor entries (bfe_desc_t). Each descriptor entry
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * has control (desc_ctl) and address (desc_addr) member.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_tx_desc_init(bfe_ring_t *r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < r->r_ndesc; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_ctl),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[i].len & BFE_DESC_LEN));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA addresses need to be added to BFE_PCI_DMA
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_addr),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[i].cookie.dmac_laddress + BFE_PCI_DMA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = GET_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v | BFE_DESC_EOT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_curr_desc = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_avail_desc = TX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_cons_desc = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Initializes RX side descriptor entries (bfe_desc_t). Each descriptor entry
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * has control (desc_ctl) and address (desc_addr) member.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_rx_desc_init(bfe_ring_t *r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < r->r_ndesc; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_ctl),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[i].len& BFE_DESC_LEN));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_addr),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[i].cookie.dmac_laddress + BFE_PCI_DMA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Initialize rx header (len, flags) */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bzero(r->r_buf_dma[i].addr, sizeof (bfe_rx_header_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_BUF(r, i, 0, sizeof (bfe_rx_header_t),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = GET_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v | BFE_DESC_EOT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* TAIL of RX Descriptor */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(r->r_bfe, BFE_DMARX_PTR, ((i) * sizeof (bfe_desc_t)));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_curr_desc = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_avail_desc = RX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_chip_start(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra ASSERT_ALL_LOCKS(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Stop the chip first & then Reset the chip. At last enable interrupts.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reset chip and start PHY.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Initailize Descriptor Rings.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_tx_desc_init(&bfe->bfe_tx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_rx_desc_init(&bfe->bfe_rx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_ACTIVE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_mode |= BFE_RX_MODE_ENABLE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_set_rx_mode(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_enable_chip_intrs(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Check link, speed and duplex mode */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_check_link(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Clear chip statistics.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_clear_stats(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ulong_t r;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_MIB_CTRL, BFE_MIB_CLR_ON_READ);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Stat registers are cleared by reading.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (r = BFE_TX_GOOD_O; r <= BFE_TX_PAUSE; r += 4)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) INL(bfe, r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (r = BFE_RX_GOOD_O; r <= BFE_RX_NPAUSE; r += 4)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) INL(bfe, r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Collect chip statistics.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_gather_stats(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ulong_t r;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t *v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t txerr = 0, rxerr = 0, coll = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = &bfe->bfe_hw_stats.tx_good_octets;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (r = BFE_TX_GOOD_O; r <= BFE_TX_PAUSE; r += 4) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *v += INL(bfe, r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = &bfe->bfe_hw_stats.rx_good_octets;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (r = BFE_RX_GOOD_O; r <= BFE_RX_NPAUSE; r += 4) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *v += INL(bfe, r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * TX :
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * -------
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_good_octets, tx_good_pkts, tx_octets
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_pkts, tx_broadcast_pkts, tx_multicast_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_len_64, tx_len_65_to_127, tx_len_128_to_255
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_underruns, tx_total_cols, tx_single_cols
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_multiple_cols, tx_excessive_cols, tx_late_cols
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * tx_defered, tx_carrier_lost, tx_pause_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * RX :
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * -------
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_good_octets, rx_good_pkts, rx_octets
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_pkts, rx_broadcast_pkts, rx_multicast_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_len_64, rx_len_65_to_127, rx_len_128_to_255
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_missed_pkts, rx_crc_align_errs, rx_undersize
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_crc_errs, rx_align_errs, rx_symbol_errs
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * rx_pause_pkts, rx_nonpause_pkts
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_carrier_errors =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_carrier_lost;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* txerr += bfe->bfe_hw_stats.tx_carrier_lost; */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_ex_collisions =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_excessive_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra txerr += bfe->bfe_hw_stats.tx_excessive_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra coll += bfe->bfe_hw_stats.tx_excessive_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_fcs_errors =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.rx_crc_errs;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rxerr += bfe->bfe_hw_stats.rx_crc_errs;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_first_collisions =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_single_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra coll += bfe->bfe_hw_stats.tx_single_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_multi_collisions =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_multiple_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra coll += bfe->bfe_hw_stats.tx_multiple_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_toolong_errors =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.rx_oversize_pkts;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rxerr += bfe->bfe_hw_stats.rx_oversize_pkts;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_tooshort_errors =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.rx_undersize;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rxerr += bfe->bfe_hw_stats.rx_undersize;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_tx_late_collisions +=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_late_cols;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_defer_xmts +=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_hw_stats.tx_defered;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_macrcv_errors += rxerr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_macxmt_errors += txerr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.collisions += coll;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Gets the state for dladm command and all.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_getstat(void *arg, uint_t stat, uint64_t *val)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint64_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int err = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_enter(&bfe->bfe_rwlock, RW_READER);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra switch (stat) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra default:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ENOTSUP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_IFSPEED:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * MAC layer will ask for IFSPEED first and hence we
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * collect it only once.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Update stats from the hardware.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_gather_stats(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_chip.speed;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_100T4:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_adv_100T4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_100FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_ABILITY_100BASE_TX_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_100HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_ABILITY_100BASE_TX) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_10FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_ABILITY_10BASE_T_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_10HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_ABILITY_10BASE_T) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_ASMPAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_AUTONEG:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_adv_aneg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_CAP_PAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_ABILITY_PAUSE) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ADV_REMFAULT:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anar & MII_AN_ADVERT_REMFAULT) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_ALIGN_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* MIB */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_align_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_100T4:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASE_T4) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_100FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASEX_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_100HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASEX) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_10FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_10_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_10HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_10) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_ASMPAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_AUTONEG:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = ((bfe->bfe_mii_bmsr & MII_STATUS_CANAUTONEG) != 0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_PAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CAP_REMFAULT:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmsr & MII_STATUS_REMFAULT) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_CARRIER_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_carrier_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_JABBER_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ENOTSUP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_DEFER_XMTS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_defer_xmts;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_EX_COLLISIONS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* MIB */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_ex_collisions;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_FCS_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* MIB */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_fcs_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_FIRST_COLLISIONS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* MIB */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_first_collisions;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LINK_ASMPAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LINK_AUTONEG:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_bmcr & MII_CONTROL_ANE) != 0 &&
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (bfe->bfe_mii_bmsr & MII_STATUS_ANDONE) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LINK_DUPLEX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_chip.duplex;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_100T4:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_T4) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_100FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_TX_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_100HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_TX) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_10FDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_10BASE_T_FD) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_10HDX:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_10BASE_T) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_ASMPAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_AUTONEG:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_exp & MII_AN_EXP_LPCANAN) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_CAP_PAUSE:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_ABILITY_PAUSE) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_LP_REMFAULT:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (bfe->bfe_mii_anlpar & MII_STATUS_REMFAULT) != 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_MACRCV_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_macrcv_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_MACXMT_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_macxmt_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_MULTI_COLLISIONS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_multi_collisions;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_SQE_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ENOTSUP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_TOOLONG_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_toolong_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_TOOSHORT_ERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_tooshort_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_TX_LATE_COLLISIONS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_tx_late_collisions;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_XCVR_ADDR:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_phy_addr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case ETHER_STAT_XCVR_ID:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_phy_id;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_BRDCSTRCV:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.brdcstrcv;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_BRDCSTXMT:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.brdcstxmt;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_MULTIXMT:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.multixmt;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_COLLISIONS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.collisions;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_IERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ierrors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_IPACKETS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ipackets;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_MULTIRCV:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.multircv;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_NORCVBUF:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.norcvbuf;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_NOXMTBUF:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.noxmtbuf;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_OBYTES:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.obytes;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_OERRORS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* MIB */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.ether_stat_macxmt_errors;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_OPACKETS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.opackets;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_RBYTES:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.rbytes;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_UNDERFLOWS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.underflows;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_STAT_OVERFLOWS:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = bfe->bfe_stats.overflows;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *val = v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (err);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerbfe_mac_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer void *val)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int err = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra switch (num) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_DUPLEX:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer ASSERT(sz >= sizeof (link_duplex_t));
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer bcopy(&bfe->bfe_chip.duplex, val, sizeof (link_duplex_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_SPEED:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer ASSERT(sz >= sizeof (uint64_t));
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer bcopy(&bfe->bfe_chip.speed, val, sizeof (uint64_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_AUTONEG:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_aneg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_ADV_100FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_100FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_ADV_100HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_100HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_ADV_10FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_10fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_10FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_10fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_ADV_10HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_10hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_10HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_10hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_ADV_100T4_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100T4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_100T4_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer *(uint8_t *)val = bfe->bfe_adv_100T4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra default:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ENOTSUP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (err);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic void
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerbfe_mac_propinfo(void *arg, const char *name, mac_prop_id_t num,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_handle_t prh)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer{
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer bfe_t *bfe = (bfe_t *)arg;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer switch (num) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_DUPLEX:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_SPEED:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_ADV_100FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_ADV_100HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_ADV_10FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_ADV_10HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_ADV_100T4_CAP:
7a0c1e298cab158fe4113f2e75e46140eb4825e9Crisson Guanghao Hu case MAC_PROP_EN_100T4_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_AUTONEG:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_aneg);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_EN_100FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_100fdx);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_EN_100HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_100hdx);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_EN_10FDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_10fdx);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer case MAC_PROP_EN_10HDX_CAP:
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_10hdx);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer break;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer }
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer}
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*ARGSUSED*/
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra const void *val)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint8_t *advp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint8_t *capp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int r = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra switch (num) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_100FDX_CAP:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra advp = &bfe->bfe_adv_100fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra capp = &bfe->bfe_cap_100fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_100HDX_CAP:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra advp = &bfe->bfe_adv_100hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra capp = &bfe->bfe_cap_100hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_10FDX_CAP:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra advp = &bfe->bfe_adv_10fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra capp = &bfe->bfe_cap_10fdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_EN_10HDX_CAP:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra advp = &bfe->bfe_adv_10hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra capp = &bfe->bfe_cap_10hdx;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case MAC_PROP_AUTONEG:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra advp = &bfe->bfe_adv_aneg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra capp = &bfe->bfe_cap_aneg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra default:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (ENOTSUP);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (*capp == 0)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (ENOTSUP);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (*advp != *(const uint8_t *)val) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *advp = *(const uint8_t *)val;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action = BFE_ACTION_RESTART_SETPROP;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We need to stop the timer before grabbing locks
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * otherwise we can land-up in deadlock with untimeout.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_timer(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action |= BFE_ACTION_RESTART;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_restart(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We leave SETPROP because properties can be
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * temporary.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action &= ~(BFE_ACTION_RESTART);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* kick-off a potential stopped downstream */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_tx_update(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_set_ether_addr(void *arg, const uint8_t *ea)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bcopy(ea, bfe->bfe_ether_addr, ETHERADDRL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_set_rx_mode(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_start(void *arg)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra bfe_grab_locks(bfe);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra if (bfe_chip_start(bfe) == DDI_FAILURE) {
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (EINVAL);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra }
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra bfe_release_locks(bfe);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra mac_tx_update(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misravoid
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_stop(void *arg)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We need to stop the timer before grabbing locks otherwise
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * we can land-up in deadlock with untimeout.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_timer(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * First halt the chip by disabling interrupts.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_STOPPED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * This will leave the PHY running.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Disable RX register.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_mode &= ~BFE_RX_MODE_ENABLE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_set_rx_mode(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Send a packet down the wire.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_send_a_packet(bfe_t *bfe, mblk_t *mp)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *r = &bfe->bfe_tx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t cur = r->r_curr_desc;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t next;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra size_t pktlen = msgsize(mp);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uchar_t *buf;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(MUTEX_HELD(&r->r_lock));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(mp != NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (pktlen > r->r_buf_len) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra freemsg(mp);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * There is a big reason why we don't check for '0'. It becomes easy
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * for us to not roll over the ring since we are based on producer (tx)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * and consumer (reclaim by an interrupt) model. Especially when we
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * run out of TX descriptor, chip will send a single interrupt and
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * both producer and consumer counter will be same. So we keep a
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * difference of 1 always.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (r->r_avail_desc <= 1) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.noxmtbuf++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_resched = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Get the DMA buffer to hold packet.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra buf = (uchar_t *)r->r_buf_dma[cur].addr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mcopymsg(mp, buf); /* it also frees mp */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Gather statistics.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (buf[0] & 0x1) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bcmp(buf, bfe_broadcast, ETHERADDRL) != 0)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.multixmt++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.brdcstxmt++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.opackets++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.obytes += pktlen;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Program the DMA descriptor (start and end of frame are same).
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra next = cur;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = (pktlen & BFE_DESC_LEN) | BFE_DESC_IOC | BFE_DESC_SOF |
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_DESC_EOF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (cur == (TX_NUM_DESC - 1))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= BFE_DESC_EOT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[cur].desc_ctl), v);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA addresses need to be added to BFE_PCI_DMA
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[cur].desc_addr),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[cur].cookie.dmac_laddress + BFE_PCI_DMA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Sync the packet data for the device.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_BUF(r, cur, 0, pktlen, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Move to next descriptor slot */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_INC_SLOT(next, TX_NUM_DESC);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_curr_desc = next;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * The order should be 1,2,3,... for BFE_DMATX_PTR if 0,1,2,3,...
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * descriptor slot are being programmed.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_DMATX_PTR, next * sizeof (bfe_desc_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra FLUSH(bfe, BFE_DMATX_PTR);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_avail_desc--;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Let timeout know that it must reset the chip if a
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * packet is not sent down the wire for more than 5 seconds.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_stall_time = gethrtime() + (5 * 1000000000ULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misramblk_t *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_transmit_packet(void *arg, mblk_t *mp)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *r = &bfe->bfe_tx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mblk_t *nmp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_enter(&r->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra DTRACE_PROBE1(tx__chip__not__active, int, bfe->bfe_unit);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra freemsgchain(mp);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_exit(&r->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra while (mp != NULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nmp = mp->b_next;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp->b_next = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_send_a_packet(bfe, mp) == BFE_FAILURE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp->b_next = nmp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp = nmp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_exit(&r->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (mp);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_set_promisc(void *arg, boolean_t promiscflag)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (bfe_t *)arg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (EIO);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (promiscflag) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Set Promiscous on */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_mode |= BFE_RX_MODE_PROMISC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_mode &= ~BFE_RX_MODE_PROMISC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_set_rx_mode(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_mac_set_multicast(void *arg, boolean_t add, const uint8_t *macaddr)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It was too much of pain to implement multicast in CAM. Instead
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * we never disable multicast filter.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (0);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic mac_callbacks_t bfe_mac_callbacks = {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer MC_SETPROP | MC_GETPROP | MC_PROPINFO,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_getstat, /* gets stats */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_start, /* starts mac */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_stop, /* stops mac */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_set_promisc, /* sets promisc mode for snoop */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_set_multicast, /* multicast implementation */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_set_ether_addr, /* sets ethernet address (unicast) */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_transmit_packet, /* transmits packet */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer NULL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* ioctl */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* getcap */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* open */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* close */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_setprop,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_mac_getprop,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer bfe_mac_propinfo
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_error_handler(bfe_t *bfe, int intr_mask)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_mask & BFE_ISTAT_RFO) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.overflows++;
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra bfe->bfe_chip_action |=
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra goto action;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_mask & BFE_ISTAT_TFU) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.underflows++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Descriptor Protocol Error */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_mask & BFE_ISTAT_DPE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra "Descriptor Protocol Error. Halting Chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action |=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto action;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Descriptor Error */
00d1eed8323f3add6273b62fe277d00cd8518bcaRichard Lowe if (intr_mask & BFE_ISTAT_DSCE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "Descriptor Error. Restarting Chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto action;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Receive Descr. Underflow */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_mask & BFE_ISTAT_RDU) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra "Receive Descriptor Underflow. Restarting Chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_macrcv_errors++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action |=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto action;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = INL(bfe, BFE_DMATX_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Error while sending a packet */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (v & BFE_STAT_EMASK) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ether_stat_macxmt_errors++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra "Error while sending a packet. Restarting Chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Error while receiving a packet */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = INL(bfe, BFE_DMARX_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (v & BFE_RX_FLAG_ERRORS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ierrors++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra "Error while receiving a packet. Restarting Chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action |=
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraaction:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It will recycle a RX descriptor slot.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_rx_desc_buf_reinit(bfe_t *bfe, uint_t slot)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *r = &bfe->bfe_rx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra slot %= RX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bzero(r->r_buf_dma[slot].addr, sizeof (bfe_rx_header_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_BUF(r, slot, 0, BFE_RX_OFFSET, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = r->r_buf_dma[slot].len & BFE_DESC_LEN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (slot == (RX_NUM_DESC - 1))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= BFE_DESC_EOT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[slot].desc_ctl), v);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * DMA addresses need to be added to BFE_PCI_DMA
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[slot].desc_addr),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[slot].cookie.dmac_laddress + BFE_PCI_DMA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Gets called from interrupt context to handle RX interrupt.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic mblk_t *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_receive(bfe_t *bfe, int intr_mask)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int rxstat, current;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mblk_t *mp = NULL, *rx_head, *rx_tail;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uchar_t *rx_header;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint16_t len;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uchar_t *bp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *r = &bfe->bfe_rx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rxstat = INL(bfe, BFE_DMARX_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra current = (rxstat & BFE_STAT_CDMASK) / sizeof (bfe_desc_t);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra i = r->r_curr_desc;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_head = rx_tail = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE3(receive, int, bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, r->r_curr_desc,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, current);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = r->r_curr_desc; i != current;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_INC_SLOT(i, RX_NUM_DESC)) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Sync the buffer associated with the descriptor table entry.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_BUF(r, i, 0, r->r_buf_dma[i].len,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SYNC_FORKERNEL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_header = (void *)r->r_buf_dma[i].addr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We do this to make sure we are endian neutral. Chip is
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * big endian.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * The header looks like :-
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra *
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Offset 0 -> uint16_t len
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Offset 2 -> uint16_t flags
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Offset 4 -> uint16_t pad[12]
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra len = (rx_header[1] << 8) | rx_header[0];
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra len -= 4; /* CRC bytes need to be removed */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Don't receive this packet if pkt length is greater than
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * MTU + VLAN_TAGSZ.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (len > r->r_buf_len) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Recycle slot for later use */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_rx_desc_buf_reinit(bfe, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra continue;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((mp = allocb(len + VLAN_TAGSZ, BPRI_MED)) != NULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp->b_rptr += VLAN_TAGSZ;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bp = mp->b_rptr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp->b_wptr = bp + len;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* sizeof (bfe_rx_header_t) + 2 */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bcopy(r->r_buf_dma[i].addr +
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_RX_OFFSET, bp, len);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mp->b_next = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (rx_tail == NULL)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_head = rx_tail = mp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_tail->b_next = mp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_tail = mp;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Number of packets received so far */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.ipackets++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Total bytes of packets received so far */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.rbytes += len;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bcmp(mp->b_rptr, bfe_broadcast, ETHERADDRL) == 0)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.brdcstrcv++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra else
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.multircv++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra } else {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_stats.norcvbuf++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Recycle the slot for later use */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_rx_desc_buf_reinit(bfe, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Reinitialize the current descriptor slot's buffer so that
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * it can be reused.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_rx_desc_buf_reinit(bfe, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_curr_desc = i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (rx_head);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_tx_reclaim(bfe_ring_t *r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t cur, start;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t v;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra cur = INL(r->r_bfe, BFE_DMATX_STAT) & BFE_STAT_CDMASK;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra cur = cur / sizeof (bfe_desc_t);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Start with the last descriptor consumed by the chip.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra start = r->r_cons_desc;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE3(tx__reclaim, int, r->r_bfe->bfe_unit,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, start,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int, cur);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * There will be at least one descriptor to process.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra while (start != cur) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_avail_desc++;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v = r->r_buf_dma[start].len & BFE_DESC_LEN;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (start == (TX_NUM_DESC - 1))
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra v |= BFE_DESC_EOT;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[start].desc_ctl), v);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PUT_DESC(r, (uint32_t *)&(r->r_desc[start].desc_addr),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (r->r_buf_dma[start].cookie.dmac_laddress + BFE_PCI_DMA));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Move to next descriptor in TX ring */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra BFE_INC_SLOT(start, TX_NUM_DESC);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_sync(r->r_desc_dma_handle,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, (r->r_ndesc * sizeof (bfe_desc_t)),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SYNC_FORDEV);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_cons_desc = start; /* consumed pointer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_bfe->bfe_tx_stall_time = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (cur);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_tx_done(bfe_t *bfe, int intr_mask)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_t *r = &bfe->bfe_tx_ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int resched = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_enter(&r->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_tx_reclaim(r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_tx_resched) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra resched = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_resched = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_exit(&r->r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (resched);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * ISR for interrupt handling
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic uint_t
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_interrupt(caddr_t arg1, caddr_t arg2)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe = (void *)arg1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t intr_stat;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mblk_t *rx_head = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int resched = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Grab the lock to avoid stopping the chip while this interrupt
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * is handled.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_enter(&bfe->bfe_rwlock, RW_READER);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * It's necessary to read intr stat again because masking interrupt
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * register does not really mask interrupts coming from the chip.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra intr_stat = INL(bfe, BFE_INTR_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra intr_stat &= BFE_IMASK_DEF;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra OUTL(bfe, BFE_INTR_STAT, intr_stat);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) INL(bfe, BFE_INTR_STAT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_stat == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_INTR_UNCLAIMED);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra DTRACE_PROBE2(bfe__interrupt, int, bfe->bfe_unit,
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra int, intr_stat);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * If chip is suspended then we just return.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_chip_state == BFE_CHIP_SUSPENDED) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE1(interrupt__chip__is__suspend, int,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_unit);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_INTR_CLAIMED);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Halt the chip again i.e basically disable interrupts.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DTRACE_PROBE1(interrupt__chip__not__active, int,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_unit);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_INTR_CLAIMED);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* A packet was received */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_stat & BFE_ISTAT_RX) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rx_head = bfe_receive(bfe, intr_stat);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* A packet was sent down the wire */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_stat & BFE_ISTAT_TX) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra resched = bfe_tx_done(bfe, intr_stat);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* There was an error */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (intr_stat & BFE_ISTAT_ERRORS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error_handler(bfe, intr_stat);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_exit(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Pass the list of packets received from chip to MAC layer.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (rx_head) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_rx(bfe->bfe_machdl, 0, rx_head);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Let the MAC start sending pkts to a potential stopped stream.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (resched)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_tx_update(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_INTR_CLAIMED);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Removes registered interrupt handler.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_remove_intr(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_intr_remove_handler(bfe->bfe_intrhdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_intr_free(bfe->bfe_intrhdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Add an interrupt for the driver.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_add_intr(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int nintrs = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int ret;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ret = ddi_intr_alloc(bfe->bfe_dip, &bfe->bfe_intrhdl,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_INTR_TYPE_FIXED, /* type */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* inumber */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 1, /* count */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &nintrs, /* actual nintrs */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_INTR_ALLOC_STRICT);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (ret != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "ddi_intr_alloc() failed"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " : ret : %d", ret);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ret = ddi_intr_add_handler(bfe->bfe_intrhdl, bfe_interrupt, bfe, NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (ret != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "ddi_intr_add_handler() failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_intr_free(bfe->bfe_intrhdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ret = ddi_intr_get_pri(bfe->bfe_intrhdl, &bfe->bfe_intrpri);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (ret != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "ddi_intr_get_pri() failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_remove_intr(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Identify chipset family.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_identify_hardware(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint16_t vid, did;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra vid = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_VENID);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra did = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_DEVID);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < (sizeof (bfe_cards) / sizeof (bfe_cards_t)); i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_cards[i].vendor_id == vid &&
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_cards[i].device_id == did) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "bfe driver is attaching to unknown pci%d,%d"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " vendor/device-id card", vid, did);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (BFE_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Maps device registers.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_regs_map(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra dev_info_t *dip = bfe->bfe_dip;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int ret;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ret = ddi_regs_map_setup(dip, 1, &bfe->bfe_mem_regset.addr, 0, 0,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &bfe_dev_attr, &bfe->bfe_mem_regset.hdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (ret != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "ddi_regs_map_setup failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_unmap_regs(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_regs_map_free(&bfe->bfe_mem_regset.hdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_get_chip_config(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint32_t prom[BFE_EEPROM_SIZE];
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Read EEPROM in prom[]
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < BFE_EEPROM_SIZE; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra prom[i] = INL(bfe, BFE_EEPROM_BASE + i * sizeof (uint32_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[0] = bfe->bfe_ether_addr[0] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 79);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[1] = bfe->bfe_ether_addr[1] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 78);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[2] = bfe->bfe_ether_addr[2] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 81);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[3] = bfe->bfe_ether_addr[3] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 80);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[4] = bfe->bfe_ether_addr[4] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 83);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dev_addr[5] = bfe->bfe_ether_addr[5] =
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra INB(bfe, BFE_EEPROM_BASE + 82);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_phy_addr = -1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Ring Management routines
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_ring_buf_alloc(bfe_t *bfe, bfe_ring_t *r, int slot, int d)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int err;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint_t count = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_alloc_handle(bfe->bfe_dip,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &bfe_dma_attr_buf, DDI_DMA_SLEEP, NULL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &r->r_buf_dma[slot].handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " alloc_handle failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_mem_alloc(r->r_buf_dma[slot].handle,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_buf_len, &bfe_buf_attr, DDI_DMA_STREAMING,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SLEEP, NULL, &r->r_buf_dma[slot].addr,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &r->r_buf_dma[slot].len,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &r->r_buf_dma[slot].acchdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " mem_alloc failed :%d", err);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_addr_bind_handle(r->r_buf_dma[slot].handle,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, r->r_buf_dma[slot].addr,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_buf_dma[slot].len,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (DDI_DMA_RDWR | DDI_DMA_STREAMING),
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SLEEP, NULL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &r->r_buf_dma[slot].cookie,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &count);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_DMA_MAPPED) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " bind_handle failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (count > 1) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " more than one DMA cookie");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_unbind_handle(r->r_buf_dma[slot].handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail2:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_mem_free(&r->r_buf_dma[slot].acchdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail1:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_free_handle(&r->r_buf_dma[slot].handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail0:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_ring_buf_free(bfe_ring_t *r, int slot)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (r->r_buf_dma == NULL)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_unbind_handle(r->r_buf_dma[slot].handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_mem_free(&r->r_buf_dma[slot].acchdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_free_handle(&r->r_buf_dma[slot].handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_buffer_free(bfe_ring_t *r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int i;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < r->r_ndesc; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_buf_free(r, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic void
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_ring_desc_free(bfe_ring_t *r)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_dma_unbind_handle(r->r_desc_dma_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_mem_free(&r->r_desc_acc_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_free_handle(&r->r_desc_dma_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(r->r_buf_dma, r->r_ndesc * sizeof (bfe_dma_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_buf_dma = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_desc = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_ring_desc_alloc(bfe_t *bfe, bfe_ring_t *r, int d)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int err, i, fail = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra caddr_t ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra size_t size_krnl = 0, size_dma = 0, ring_len = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_cookie_t cookie;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra uint_t count = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(bfe != NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra size_krnl = r->r_ndesc * sizeof (bfe_dma_t);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra size_dma = r->r_ndesc * sizeof (bfe_desc_t);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_buf_dma = kmem_zalloc(size_krnl, KM_SLEEP);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_alloc_handle(bfe->bfe_dip, &bfe_dma_attr_desc,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SLEEP, NULL, &r->r_desc_dma_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " ddi_dma_alloc_handle()");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(r->r_buf_dma, size_krnl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_mem_alloc(r->r_desc_dma_handle,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra size_dma, &bfe_buf_attr,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &ring, &ring_len, &r->r_desc_acc_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " ddi_dma_mem_alloc()");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_free_handle(&r->r_desc_dma_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(r->r_buf_dma, size_krnl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = ddi_dma_addr_bind_handle(r->r_desc_dma_handle,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, ring, ring_len,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_SLEEP, NULL,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &cookie, &count);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (err != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " ddi_dma_addr_bind_handle()");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_mem_free(&r->r_desc_acc_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_dma_free_handle(&r->r_desc_dma_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(r->r_buf_dma, size_krnl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We don't want to have multiple cookies. Descriptor should be
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * aligned to PAGESIZE boundary.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ASSERT(count == 1);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* The actual descriptor for the ring */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_desc_len = ring_len;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_desc_cookie = cookie;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra r->r_desc = (void *)ring;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bzero(r->r_desc, size_dma);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bzero(r->r_desc, ring_len);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* For each descriptor, allocate a DMA buffer */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra fail = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra for (i = 0; i < r->r_ndesc; i++) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_ring_buf_alloc(bfe, r, i, d) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra i--;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra fail = 1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (fail) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra while (i-- >= 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_buf_free(r, i);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* We don't need the descriptor anymore */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_desc_free(r);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_rings_alloc(bfe_t *bfe)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* TX */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_init(&bfe->bfe_tx_ring.r_lock, NULL, MUTEX_DRIVER, NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_lockp = &bfe->bfe_tx_ring.r_lock;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_buf_len = BFE_MTU + sizeof (struct ether_header) +
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra VLAN_TAGSZ + ETHERFCSL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_ndesc = TX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_bfe = bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_avail_desc = TX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* RX */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_init(&bfe->bfe_rx_ring.r_lock, NULL, MUTEX_DRIVER, NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_lockp = &bfe->bfe_rx_ring.r_lock;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_buf_len = BFE_MTU + sizeof (struct ether_header) +
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra VLAN_TAGSZ + ETHERFCSL + RX_HEAD_ROOM;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_ndesc = RX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_bfe = bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_avail_desc = RX_NUM_DESC;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Allocate TX Ring */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_ring_desc_alloc(bfe, &bfe->bfe_tx_ring,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_WRITE) != DDI_SUCCESS)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Allocate RX Ring */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_ring_desc_alloc(bfe, &bfe->bfe_rx_ring,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_DMA_READ) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra cmn_err(CE_NOTE, "RX ring allocation failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_desc_free(&bfe->bfe_tx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_tx_ring.r_flags = BFE_RING_ALLOCATED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_rx_ring.r_flags = BFE_RING_ALLOCATED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_resume(dev_info_t *dip)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int err = DDI_SUCCESS;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((bfe = ddi_get_driver_private(dip)) == NULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Unexpected error (no driver private data)"
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra " while resume");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Grab all the locks first.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_RESUME;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_init_vars(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* PHY will also start running */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_chip_start(bfe) == DDI_FAILURE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not resume chip");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra err = DDI_FAILURE;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra if (err == DDI_SUCCESS)
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra mac_tx_update(bfe->bfe_machdl);
954c6b5ec18168de579023aa3735121108026e9bSaurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (err);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int unit;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_register_t *macreg;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int ret;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra switch (cmd) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case DDI_RESUME:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (bfe_resume(dip));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case DDI_ATTACH:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra break;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra default:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra unit = ddi_get_instance(dip);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe = kmem_zalloc(sizeof (bfe_t), KM_SLEEP);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_dip = dip;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_unit = unit;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (pci_config_setup(dip, &bfe->bfe_conf_handle) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "pci_config_setup failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Enable IO space, Bus Master and Memory Space accessess.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ret = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_COMM);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra pci_config_put16(bfe->bfe_conf_handle, PCI_CONF_COMM,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra PCI_COMM_IO | PCI_COMM_MAE | PCI_COMM_ME | ret);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_set_driver_private(dip, bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Identify hardware */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_identify_hardware(bfe) == BFE_FAILURE) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not identify device");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_regs_map(bfe) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not map device registers");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail1;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) bfe_get_chip_config(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Register with MAC layer
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((macreg = mac_alloc(MAC_VERSION)) == NULL) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "mac_alloc() failed");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_driver = bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_dip = dip;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_instance = unit;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_src_addr = bfe->bfe_ether_addr;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_callbacks = &bfe_mac_callbacks;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_min_sdu = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_max_sdu = ETHERMTU;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra macreg->m_margin = VLAN_TAGSZ;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if ((ret = mac_register(macreg, &bfe->bfe_machdl)) != 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "mac_register() failed with %d error", ret);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_free(macreg);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail2;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_free(macreg);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_init(&bfe->bfe_rwlock, NULL, RW_DRIVER,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DDI_INTR_PRI(bfe->bfe_intrpri));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_add_intr(bfe) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not add interrupt");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail3;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe_rings_alloc(bfe) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not allocate TX/RX Ring");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Init and then reset the chip */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_action = 0;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_init_vars(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* PHY will also start running */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_reset(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Even though we enable the interrupts here but chip's interrupt
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * is not enabled yet. It will be enabled once we plumb the interface.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (ddi_intr_enable(bfe->bfe_intrhdl) != DDI_SUCCESS) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_error(dip, "Could not enable interrupt");
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra goto fail4;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail4:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_remove_intr(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail3:
c1374a13e412c4ec42cba867e57347a0e049a822Surya Prakki (void) mac_unregister(bfe->bfe_machdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail2:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_unmap_regs(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail1:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra pci_config_teardown(&bfe->bfe_conf_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrafail0:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(bfe, sizeof (bfe_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic int
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe = ddi_get_driver_private(devinfo);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra switch (cmd) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case DDI_DETACH:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We need to stop the timer before grabbing locks otherwise
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * we can land-up in deadlock with untimeout.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_timer(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * First unregister with MAC layer before stopping DMA
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * engine.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (mac_unregister(bfe->bfe_machdl) != DDI_SUCCESS)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_machdl = NULL;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Quiesce the chip first.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra (void) ddi_intr_disable(bfe->bfe_intrhdl);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* Make sure timer is gone. */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_timer(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Free the DMA resources for buffer and then descriptors
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_tx_ring.r_flags == BFE_RING_ALLOCATED) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* TX */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_buffer_free(&bfe->bfe_tx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_desc_free(&bfe->bfe_tx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (bfe->bfe_rx_ring.r_flags == BFE_RING_ALLOCATED) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /* RX */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_buffer_free(&bfe->bfe_rx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ring_desc_free(&bfe->bfe_rx_ring);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_remove_intr(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_unmap_regs(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra pci_config_teardown(&bfe->bfe_conf_handle);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_destroy(&bfe->bfe_tx_ring.r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mutex_destroy(&bfe->bfe_rx_ring.r_lock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra rw_destroy(&bfe->bfe_rwlock);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra kmem_free(bfe, sizeof (bfe_t));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_set_driver_private(devinfo, NULL);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra case DDI_SUSPEND:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * We need to stop the timer before grabbing locks otherwise
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * we can land-up in deadlock with untimeout.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_timer(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra /*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Grab all the locks first.
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_grab_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_SUSPENDED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_release_locks(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra default:
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_FAILURE);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra/*
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra * Quiesce the card for fast reboot
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrabfe_quiesce(dev_info_t *dev_info)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_t *bfe;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe = ddi_get_driver_private(dev_info);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_chip_halt(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_stop_phy(bfe);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe->bfe_chip_state = BFE_CHIP_QUIESCED;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (DDI_SUCCESS);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct cb_ops bfe_cb_ops = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nulldev, /* cb_open */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nulldev, /* cb_close */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_strategy */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_print */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_dump */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_read */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_write */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_ioctl */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_devmap */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_mmap */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_segmap */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nochpoll, /* cb_chpoll */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_prop_op, /* cb_prop_op */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* cb_stream */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra D_MP | D_HOTPLUG, /* cb_flag */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra CB_REV, /* cb_rev */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* cb_aread */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev /* cb_awrite */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct dev_ops bfe_dev_ops = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra DEVO_REV, /* devo_rev */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra 0, /* devo_refcnt */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* devo_getinfo */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nulldev, /* devo_identify */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nulldev, /* devo_probe */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_attach, /* devo_attach */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_detach, /* devo_detach */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra nodev, /* devo_reset */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &bfe_cb_ops, /* devo_cb_ops */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra NULL, /* devo_bus_ops */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra ddi_power, /* devo_power */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_quiesce /* devo_quiesce */
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct modldrv bfe_modldrv = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &mod_driverops,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra bfe_ident,
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra &bfe_dev_ops
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misrastatic struct modlinkage modlinkage = {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra MODREV_1, (void *)&bfe_modldrv, NULL
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra};
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra_info(struct modinfo *modinfop)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (mod_info(&modlinkage, modinfop));
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra_init(void)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int status;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_init_ops(&bfe_dev_ops, MODULE_NAME);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra status = mod_install(&modlinkage);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (status == DDI_FAILURE)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_fini_ops(&bfe_dev_ops);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (status);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misraint
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra_fini(void)
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra{
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra int status;
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra status = mod_remove(&modlinkage);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra if (status == 0) {
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra mac_fini_ops(&bfe_dev_ops);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra }
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra return (status);
dd52495f0d9ba8ff6d84921ec0500be837896554Saurabh Misra}