bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * CDDL HEADER START
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The contents of this file are subject to the terms of the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Common Development and Distribution License (the "License").
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * You may not use this file except in compliance with the License.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * or http://www.opensolaris.org/os/licensing.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * See the License for the specific language governing permissions
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * and limitations under the License.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner]
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * CDDL HEADER END
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Copyright 2010 QLogic Corporation. All rights reserved.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <qlge.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <sys/atomic.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <sys/strsubr.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <sys/pattr.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <netinet/in.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <netinet/ip.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <netinet/ip6.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <netinet/tcp.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <netinet/udp.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#include <inet/ip.h>
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Local variables
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct ether_addr ql_ether_broadcast_addr =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic char version[] = "GLDv3 QLogic 81XX " VERSIONSTR;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Local function prototypes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic void ql_free_resources(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void ql_fini_kstats(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint32_t ql_get_link_state(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void ql_read_conf(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_alloc_phys(dev_info_t *, ddi_dma_handle_t *,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_device_acc_attr_t *, uint_t, ddi_acc_handle_t *,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t, size_t, caddr_t *, ddi_dma_cookie_t *);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic int ql_alloc_phys_rbuf(dev_info_t *, ddi_dma_handle_t *,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_device_acc_attr_t *, uint_t, ddi_acc_handle_t *,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size_t, size_t, caddr_t *, ddi_dma_cookie_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void ql_free_phys(ddi_dma_handle_t *, ddi_acc_handle_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_set_routing_reg(qlge_t *, uint32_t, uint32_t, int);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_attach(dev_info_t *, ddi_attach_cmd_t);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_detach(dev_info_t *, ddi_detach_cmd_t);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_bringdown_adapter(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_bringup_adapter(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int ql_asic_reset(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void ql_wake_mpi_reset_soft_intr(qlge_t *);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void ql_stop_timer(qlge_t *qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic void ql_fm_fini(qlge_t *qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanint ql_clean_outbound_rx_ring(struct rx_ring *rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * TX dma maping handlers allow multiple sscatter-gather lists
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanddi_dma_attr_t tx_mapping_dma_attr = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DMA_ATTR_V0, /* dma_attr_version */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_LOW_ADDRESS, /* low DMA address range */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_XFER_COUNTER, /* DMA counter register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment, default - 8 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_BURSTSIZES, /* DMA burstsizes */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_MAX_TX_DMA_HANDLES, /* s/g list length */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_GRANULARITY, /* granularity of device */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_DMA_RELAXED_ORDERING /* DMA transfer flags */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Receive buffers and Request/Response queues do not allow scatter-gather lists
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanddi_dma_attr_t dma_attr = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DMA_ATTR_V0, /* dma_attr_version */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_LOW_ADDRESS, /* low DMA address range */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_XFER_COUNTER, /* DMA counter register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_ADDRESS_ALIGNMENT, /* DMA address alignment, default - 8 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_BURSTSIZES, /* DMA burstsizes */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 1, /* s/g list length, i.e no sg list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_GRANULARITY, /* granularity of device */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DMA_XFER_FLAGS /* DMA transfer flags */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Receive buffers do not allow scatter-gather lists
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanddi_dma_attr_t dma_attr_rbuf = {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DMA_ATTR_V0, /* dma_attr_version */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_LOW_ADDRESS, /* low DMA address range */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_HIGH_64BIT_ADDRESS, /* high DMA address range */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_XFER_COUNTER, /* DMA counter register */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan 0x1, /* DMA address alignment, default - 8 */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_BURSTSIZES, /* DMA burstsizes */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_MIN_XFER_SIZE, /* min effective DMA size */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_MAX_XFER_SIZE, /* max DMA xfer size */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_SEGMENT_BOUNDARY, /* segment boundary */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan 1, /* s/g list length, i.e no sg list */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DMA_GRANULARITY, /* granularity of device */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_DMA_RELAXED_ORDERING /* DMA transfer flags */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * DMA access attribute structure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* device register access from host */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanddi_device_acc_attr_t ql_dev_acc_attr = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DEVICE_ATTR_V0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_STRUCTURE_LE_ACC,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_STRICTORDER_ACC
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* host ring descriptors */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanddi_device_acc_attr_t ql_desc_acc_attr = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DEVICE_ATTR_V0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_NEVERSWAP_ACC,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_STRICTORDER_ACC
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* host ring buffer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanddi_device_acc_attr_t ql_buf_acc_attr = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DEVICE_ATTR_V0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_NEVERSWAP_ACC,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_STRICTORDER_ACC
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Hash key table for Receive Side Scaling (RSS) support
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanconst uint8_t key_data[] = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0x23, 0x64, 0xa1, 0xaa, 0x37, 0xc0, 0xed, 0x05, 0x2b, 0x36,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0x50, 0x5c, 0x45, 0x1e, 0x7e, 0xc8, 0x5d, 0x2a, 0x54, 0x2f,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0xe4, 0x3d, 0x0f, 0xbb, 0x91, 0xd9, 0x25, 0x60, 0xd4, 0xf8,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0x12, 0xa0, 0x59, 0x4b, 0x9e, 0x8a, 0x51, 0xda, 0xcd, 0x49};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Shadow Registers:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Outbound queues have a consumer index that is maintained by the chip.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Inbound queues have a producer index that is maintained by the chip.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * For lower overhead, these registers are "shadowed" to host memory
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * which allows the device driver to track the queue progress without
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PCI reads. When an entry is placed on an inbound queue, the chip will
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * update the relevant index register and then copy the value to the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * shadow register in host memory.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Currently, ql_read_sh_reg only read Inbound queues'producer index.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic inline unsigned int
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_read_sh_reg(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t rtn;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* re-synchronize shadow prod index dma buffer before reading */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ddi_dma_sync(qlge->host_copy_shadow_dma_attr.dma_handle,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->prod_idx_sh_reg_offset,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rtn = ddi_get32(qlge->host_copy_shadow_dma_attr.acc_handle,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (uint32_t *)rx_ring->prod_idx_sh_reg);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (rtn);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Read 32 bit atomically
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanuint32_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_atomic_read_32(volatile uint32_t *target)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * atomic_add_32_nv returns the new value after the add,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * we are adding 0 so we should get the original value
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (atomic_add_32_nv(target, 0));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set 32 bit atomically
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_atomic_set_32(volatile uint32_t *target, uint32_t newval)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) atomic_swap_32(target, newval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Setup device PCI configuration registers.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Kernel context.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_pci_config(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t w;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->vendor_id = (uint16_t)pci_config_get16(qlge->pci_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan PCI_CONF_VENID);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->device_id = (uint16_t)pci_config_get16(qlge->pci_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan PCI_CONF_DEVID);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * we want to respect framework's setting of PCI
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * configuration space command register and also
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * want to make sure that all bits of interest to us
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * are properly set in PCI Command register(0x04).
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PCI_COMM_IO 0x1 I/O access enable
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PCI_COMM_MAE 0x2 Memory access enable
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PCI_COMM_ME 0x4 bus master enable
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PCI_COMM_MEMWR_INVAL 0x10 memory write and invalidate enable.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan w = (uint16_t)pci_config_get16(qlge->pci_handle, PCI_CONF_COMM);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan w = (uint16_t)(w & (~PCI_COMM_IO));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan w = (uint16_t)(w | PCI_COMM_MAE | PCI_COMM_ME |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI_COMM_MEMWR_INVAL | */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan pci_config_put16(qlge->pci_handle, PCI_CONF_COMM, w);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan w = pci_config_get16(qlge->pci_handle, 0x54);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan w = (uint16_t)(w & (~0x7000));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan w = (uint16_t)(w | 0x5000);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pci_config_put16(qlge->pci_handle, 0x54, w);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_dump_pci_config(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This routine parforms the neccessary steps to set GLD mac information
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * such as Function number, xgmac mask and shift bits
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_set_mac_info(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan int rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t fn0_net, fn1_net;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* set default value */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->fn0_net = FN0_NET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->fn1_net = FN1_NET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_read_processor_data(qlge, MPI_REG, &value) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) read MPI register failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan fn0_net = (value >> 1) & 0x07;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan fn1_net = (value >> 5) & 0x07;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((fn0_net > 4) || (fn1_net > 4) || (fn0_net == fn1_net)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) bad mpi register value %x, \n"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "nic0 function number %d,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "nic1 function number %d "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "use default\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, value, fn0_net, fn1_net);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->fn0_net = fn0_net;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->fn1_net = fn1_net;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get the function number that the driver is associated with */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->func_number = (uint8_t)((value >> 6) & 0x03);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("status register is:%x, func_number: %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value, qlge->func_number));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* The driver is loaded on a non-NIC function? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->func_number != qlge->fn0_net) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->func_number != qlge->fn1_net)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Invalid function number = 0x%x\n", qlge->func_number);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* network port 0? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->func_number == qlge->fn0_net) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->xgmac_sem_mask = QL_PORT0_XGMAC_SEM_MASK;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->xgmac_sem_bits = QL_PORT0_XGMAC_SEM_BITS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->xgmac_sem_mask = QL_PORT1_XGMAC_SEM_MASK;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->xgmac_sem_bits = QL_PORT1_XGMAC_SEM_BITS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rval = DDI_SUCCESS;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * write to doorbell register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_write_doorbell_reg(qlge_t *qlge, uint32_t *addr, uint32_t data)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_put32(qlge->dev_doorbell_reg_handle, addr, data);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * read from doorbell register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanuint32_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_read_doorbell_reg(qlge_t *qlge, uint32_t *addr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t ret;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ret = ddi_get32(qlge->dev_doorbell_reg_handle, addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (ret);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This function waits for a specific bit to come ready
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * in a given register. It is used mostly by the initialize
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * process, but is also used in kernel thread API such as
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * netdev->set_multi, netdev->set_mac_address, netdev->vlan_rx_add_vid.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wait_reg_rdy(qlge_t *qlge, uint32_t reg, uint32_t bit, uint32_t err_bit)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int count = UDELAY_COUNT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_reg(qlge, reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* check for errors */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((temp & err_bit) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if ((temp & bit) != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(UDELAY_DELAY);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan count--;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Waiting for reg %x to come ready failed.", reg);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The CFG register is used to download TX and RX control blocks
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to the chip. This function waits for an operation to complete.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wait_cfg(qlge_t *qlge, uint32_t bit)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (ql_wait_reg_bit(qlge, REG_CONFIGURATION, bit, BIT_RESET, 0));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Used to issue init control blocks to hw. Maps control block,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * sets address, triggers download, waits for completion.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_write_cfg(qlge_t *qlge, uint32_t bit, uint64_t phy_addr, uint16_t q_id)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t mask;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_sem_spinlock(qlge, SEM_ICB_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_cfg(qlge, bit);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_ICB_ACCESS_ADDRESS_LOWER, LS_64BITS(phy_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_ICB_ACCESS_ADDRESS_UPPER, MS_64BITS(phy_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mask = CFG_Q_MASK | (bit << 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = bit | (q_id << CFG_Q_SHIFT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_CONFIGURATION, (mask | value));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Wait for the bit to clear after signaling hw.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_cfg(qlge, bit);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, SEM_ICB_MASK); /* does flush too */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize adapter instance
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_instance(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Default value */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_INIT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mtu = ETHERMTU; /* set normal size as default */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->page_size = VM_PAGE_SIZE; /* default page size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < MAX_RX_RINGS; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_polls[i] = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_interrupts[i] = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set up the operating parameters.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_list_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set up the max number of unicast list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->unicst_total = MAX_UNICAST_LIST_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->unicst_avail = MAX_UNICAST_LIST_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * read user defined properties in .conf file
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_read_conf(qlge); /* mtu, pause, LSO etc */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_ring_count = qlge->tx_ring_count + qlge->rss_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("mtu is %d \n", qlge->mtu));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* choose Memory Space mapping and get Vendor Id, Device ID etc */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_pci_config(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ip_hdr_offset = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->device_id == 0x8000) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Schultz card */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_CHIP_8100;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* enable just ipv4 chksum offload for Schultz */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_CKSUM_FULL_IPv4;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Schultz firmware does not do pseduo IP header checksum
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * calculation, needed to be done by driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_HW_UNABLE_PSEUDO_HDR_CKSUM;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->lso_enable)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_LSO;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_SUPPORT_SCATTER_GATHER;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Schultz must split packet header */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags |= CFG_ENABLE_SPLIT_HEADER;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->max_read_mbx = 5;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ip_hdr_offset = 2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set Function Number and some of the iocb mac information */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_set_mac_info(qlge) != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Read network settings from NVRAM */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* After nvram is read successfully, update dev_addr */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_get_flash_params(qlge) == DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("mac%d address is \n", qlge->func_number));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < ETHERADDRL; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->dev_addr.ether_addr_octet[i] =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->nic_config.factory_MAC[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Failed to read flash memory",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(qlge->dev_addr.ether_addr_octet,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->unicst_addr[0].addr.ether_addr_octet,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ETHERADDRL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_INIT, "\t flash mac address dump:\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->dev_addr.ether_addr_octet[0], 8, ETHERADDRL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->port_link_state = LS_DOWN;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This hardware semaphore provides the mechanism for exclusive access to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * resources shared between the NIC driver, MPI firmware,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * FCOE firmware and the FC driver.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_sem_trylock(qlge_t *qlge, uint32_t sem_mask)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t sem_bits = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (sem_mask) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_XGMAC0_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_XGMAC0_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_XGMAC1_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_XGMAC1_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_ICB_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_ICB_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_MAC_ADDR_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_MAC_ADDR_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_FLASH_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_FLASH_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_PROBE_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_PROBE_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_RT_IDX_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_RT_IDX_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SEM_PROC_REG_MASK:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sem_bits = SEM_SET << SEM_PROC_REG_SHIFT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Bad Semaphore mask!.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_SEMAPHORE, sem_bits | sem_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (!(ql_read_reg(qlge, REG_SEMAPHORE) & sem_bits));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Lock a specific bit of Semaphore register to gain
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * access to a particular shared register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_sem_spinlock(qlge_t *qlge, uint32_t sem_mask)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan unsigned int wait_count = 30;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (wait_count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!ql_sem_trylock(qlge, sem_mask))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(100);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wait_count--;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) sem_mask 0x%x lock timeout ",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, sem_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Unock a specific bit of Semaphore register to release
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * access to a particular shared register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_sem_unlock(qlge_t *qlge, uint32_t sem_mask)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_SEMAPHORE, sem_mask);
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_read_reg(qlge, REG_SEMAPHORE); /* flush */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get property value from configuration file.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * string = property string pointer.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Returns:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 0xFFFFFFFF = no property else property value.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint32_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_prop(qlge_t *qlge, char *string)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan char buf[256];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get adapter instance parameter. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) sprintf(buf, "hba%d-%s", qlge->instance, string);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, qlge->dip, 0, buf,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (int)0xffffffff);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adapter instance parameter found? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (data == 0xffffffff) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* No, get default parameter. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, qlge->dip, 0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan string, (int)0xffffffff);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (data);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Read user setting from configuration file.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_read_conf(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* clear configuration flags */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cfg_flags = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Set up the default ring sizes. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_size = NUM_TX_RING_ENTRIES;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "tx_ring_size");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->tx_ring_size != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_size = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_ring_size = NUM_RX_RING_ENTRIES;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "rx_ring_size");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->rx_ring_size != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_ring_size = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count = 8;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "tx_ring_count");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->tx_ring_count != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count = 8;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "rss_ring_count");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->rss_ring_count != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get default rx_copy enable/disable. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((data = ql_get_prop(qlge, "force-rx-copy")) == 0xffffffff ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_copy = B_FALSE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("rx copy mode disabled\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (data == 1) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_copy = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("rx copy mode enabled\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan qlge->rx_copy_threshold = qlge->rx_ring_size / 4;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan data = ql_get_prop(qlge, "rx_copy_threshold");
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if ((data != 0xffffffff) && (data != 0)) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan qlge->rx_copy_threshold = data;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan cmn_err(CE_NOTE, "!new rx_copy_threshold %d \n",
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan qlge->rx_copy_threshold);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get mtu packet size. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = ql_get_prop(qlge, "mtu");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((data == ETHERMTU) || (data == JUMBO_MTU)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->mtu != data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mtu = data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "new mtu is %d\n", qlge->mtu);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->mtu == JUMBO_MTU) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_coalesce_usecs = DFLT_RX_COALESCE_WAIT_JUMBO;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_coalesce_usecs = DFLT_TX_COALESCE_WAIT_JUMBO;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_max_coalesced_frames = DFLT_RX_INTER_FRAME_WAIT_JUMBO;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_max_coalesced_frames = DFLT_TX_INTER_FRAME_WAIT_JUMBO;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get pause mode, default is Per Priority mode. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pause = PAUSE_MODE_PER_PRIORITY;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = ql_get_prop(qlge, "pause");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (data <= PAUSE_MODE_PER_PRIORITY) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->pause != data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pause = data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "new pause mode %d\n", qlge->pause);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Receive interrupt delay */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_coalesce_usecs = DFLT_RX_COALESCE_WAIT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "rx_intr_delay");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->rx_coalesce_usecs != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_coalesce_usecs = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Rx inter-packet delay. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_max_coalesced_frames = DFLT_RX_INTER_FRAME_WAIT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "rx_ipkt_delay");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->rx_max_coalesced_frames != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_max_coalesced_frames = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Transmit interrupt delay */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_coalesce_usecs = DFLT_TX_COALESCE_WAIT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "tx_intr_delay");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data != 0xffffffff) && data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->tx_coalesce_usecs != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_coalesce_usecs = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Tx inter-packet delay. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_max_coalesced_frames = DFLT_TX_INTER_FRAME_WAIT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "tx_ipkt_delay");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if data is valid */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((data != 0xffffffff) && data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->tx_max_coalesced_frames != data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_max_coalesced_frames = (uint16_t)data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get split header payload_copy_thresh. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->payload_copy_thresh = DFLT_PAYLOAD_COPY_THRESH;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = ql_get_prop(qlge, "payload_copy_thresh");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if data is valid */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((data != 0xffffffff) && (data != 0)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->payload_copy_thresh != data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->payload_copy_thresh = data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* large send offload (LSO) capability. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->lso_enable = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan data = ql_get_prop(qlge, "lso_enable");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data == 0) || (data == 1)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->lso_enable != data) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->lso_enable = (uint16_t)data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* dcbx capability. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->dcbx_enable = 1;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "dcbx_enable");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if data is valid */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data == 0) || (data == 1)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->dcbx_enable != data) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->dcbx_enable = (uint16_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* fault management enable */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->fm_enable = B_TRUE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "fm-enable");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((data == 0x1) || (data == 0)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->fm_enable = (boolean_t)data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Enable global interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_enable_global_interrupt(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (INTR_EN_EI << 16) | INTR_EN_EI);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->flags |= INTERRUPTS_ENABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Disable global interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_disable_global_interrupt(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, (INTR_EN_EI << 16));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->flags &= ~INTERRUPTS_ENABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Enable one ring interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_enable_completion_interrupt(qlge_t *qlge, uint32_t intr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *ctx = qlge->intr_ctx + intr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("%s(%d): To enable intr %d, irq_cnt %d \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, intr, ctx->irq_cnt));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->intr_type == DDI_INTR_TYPE_MSIX) && intr) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Always enable if we're MSIX multi interrupts and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * it's not the default (zeroeth) interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, ctx->intr_en_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!atomic_dec_32_nv(&ctx->irq_cnt)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, ctx->intr_en_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d): write %x to intr enable register \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, ctx->intr_en_mask));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * ql_forced_disable_completion_interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Used by call from OS, may be called without
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * a pending interrupt so force the disable
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanuint32_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_forced_disable_completion_interrupt(qlge_t *qlge, uint32_t intr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t var = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *ctx = qlge->intr_ctx + intr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("%s(%d): To disable intr %d, irq_cnt %d \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, intr, ctx->irq_cnt));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->intr_type == DDI_INTR_TYPE_MSIX) && intr) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, ctx->intr_dis_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (var);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, ctx->intr_dis_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (var);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Disable a completion interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_disable_completion_interrupt(qlge_t *qlge, uint32_t intr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *ctx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ctx = qlge->intr_ctx + intr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("%s(%d): To disable intr %d, irq_cnt %d \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, intr, ctx->irq_cnt));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * HW disables for us if we're MSIX multi interrupts and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * it's not the default (zeroeth) interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->intr_type == DDI_INTR_TYPE_MSIX) && (intr != 0))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_atomic_read_32(&ctx->irq_cnt) == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_ENABLE, ctx->intr_dis_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&ctx->irq_cnt);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Enable all completion interrupts
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_enable_all_completion_interrupts(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set the count to 1 for Legacy / MSI interrupts or for the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * default interrupt (0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->intr_type != DDI_INTR_TYPE_MSIX) || i == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_atomic_set_32(&qlge->intr_ctx[i].irq_cnt, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_completion_interrupt(qlge, i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Disable all completion interrupts
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_disable_all_completion_interrupts(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set the count to 0 for Legacy / MSI interrupts or for the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * default interrupt (0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->intr_type != DDI_INTR_TYPE_MSIX) || i == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_atomic_set_32(&qlge->intr_ctx[i].irq_cnt, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_completion_interrupt(qlge, i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Update small buffer queue producer index
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_update_sbq_prod_idx(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Update the buffer producer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX, ("sbq: updating prod idx = %d.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge, rx_ring->sbq_prod_idx_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Update large buffer queue producer index
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_update_lbq_prod_idx(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Update the buffer producer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX, ("lbq: updating prod idx = %d.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge, rx_ring->lbq_prod_idx_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Adds a small buffer descriptor to end of its in use list,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * assumes sbq_lock is already taken
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_sbuf_to_in_use_list(struct rx_ring *rx_ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t inuse_idx = rx_ring->sbq_use_tail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use[inuse_idx] = sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (inuse_idx >= rx_ring->sbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_use_tail = inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->sbuf_in_use_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(rx_ring->sbuf_in_use_count <= rx_ring->sbq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get a small buffer descriptor from its in use list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct bq_desc *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_sbuf_from_in_use_list(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Pick from head of in use list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = rx_ring->sbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = rx_ring->sbuf_in_use[inuse_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use[inuse_idx] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (inuse_idx >= rx_ring->sbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_use_head = inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->sbuf_in_use_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->upl_inuse = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if mp is NULL */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* try to remap mp again */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(sbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_buf_size, 0, &sbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a small buffer descriptor to its free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_sbuf_to_free_list(struct rx_ring *rx_ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Add to the end of free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = rx_ring->sbq_free_tail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free[free_idx] = sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(rx_ring->sbuf_free_count <= rx_ring->sbq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (free_idx >= rx_ring->sbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_free_tail = free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->sbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get a small buffer descriptor from its free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct bq_desc *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_sbuf_from_free_list(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = rx_ring->sbq_free_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Pick from top of free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = rx_ring->sbuf_free[free_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free[free_idx] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (free_idx >= rx_ring->sbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_free_head = free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->sbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a large buffer descriptor to its in use list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_lbuf_to_in_use_list(struct rx_ring *rx_ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = rx_ring->lbq_use_tail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use[inuse_idx] = lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (inuse_idx >= rx_ring->lbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_use_tail = inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->lbuf_in_use_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get a large buffer descriptor from in use list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct bq_desc *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_lbuf_from_in_use_list(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Pick from head of in use list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = rx_ring->lbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = rx_ring->lbuf_in_use[inuse_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use[inuse_idx] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (inuse_idx >= rx_ring->lbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan inuse_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_use_head = inuse_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->lbuf_in_use_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->upl_inuse = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if mp is NULL */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* try to remap mp again */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(lbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size, 0, &lbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a large buffer descriptor to free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_lbuf_to_free_list(struct rx_ring *rx_ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Add to the end of free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = rx_ring->lbq_free_tail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free[free_idx] = lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (free_idx >= rx_ring->lbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_free_tail = free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->lbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(rx_ring->lbuf_free_count <= rx_ring->lbq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get a large buffer descriptor from its free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct bq_desc *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_lbuf_from_free_list(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = rx_ring->lbq_free_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Pick from head of free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = rx_ring->lbuf_free[free_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free[free_idx] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (free_idx >= rx_ring->lbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan free_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_free_head = free_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->lbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a small buffer descriptor to free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_refill_sbuf_free_list(struct bq_desc *sbq_desc, boolean_t alloc_memory)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = sbq_desc->rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *sbq_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = (qlge_t *)rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Sync access
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->sbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->upl_inuse = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If we are freeing the buffers as a result of adapter unload, get out
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((sbq_desc->free_buf != NULL) ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mac_flags == QL_MAC_DETACH)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->free_buf == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->sbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->rx_indicate == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "sbq: indicate wrong");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t sb_consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t sb_producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t num_free_buffers;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge, rx_ring->sbq_prod_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sb_producer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sb_consumer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sb_consumer_idx > sb_producer_idx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_buffers = NUM_SMALL_BUFFERS -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (sb_consumer_idx - sb_producer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_buffers = sb_producer_idx - sb_consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (num_free_buffers < qlge->rx_sb_low_count[rx_ring->cq_id])
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_sb_low_count[rx_ring->cq_id] = num_free_buffers;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->rx_indicate > 0xFF000000)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "sbq: indicate(%d) wrong: %d mac_flags %d,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " sbq_desc index %d.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id, rx_ring->rx_indicate, rx_ring->mac_flags,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->index);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (alloc_memory) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(sbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_buf_size, 0, &sbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_failed_sbq_allocs++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Got the packet from the stack decrement rx_indicate count */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_sbuf_to_free_list(rx_ring, sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Rearm if possible */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((rx_ring->sbuf_free_count >= MIN_BUFFERS_FREE_COUNT) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mac_flags == QL_MAC_STARTED)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_entry = rx_ring->sbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_entry += rx_ring->sbq_prod_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (rx_ring->sbuf_free_count > MIN_BUFFERS_ARM_COUNT) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get first one from free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = ql_get_sbuf_from_free_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *sbq_entry = cpu_to_le64(sbq_desc->bd_dma.dma_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_entry++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbq_prod_idx >= rx_ring->sbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_entry = rx_ring->sbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Add to end of in use list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_sbuf_to_in_use_list(rx_ring, sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Update small buffer queue producer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_sbq_prod_idx(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->sbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX_RING, ("%s(%d) exited, sbuf_free_count %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, rx_ring->sbuf_free_count));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * rx recycle call back function
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_release_to_sbuf_free_list(caddr_t p)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc = (struct bq_desc *)(void *)p;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_TRUE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a large buffer descriptor to free list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_refill_lbuf_free_list(struct bq_desc *lbq_desc, boolean_t alloc_memory)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = lbq_desc->rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *lbq_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Sync access */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->lbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->upl_inuse = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If we are freeing the buffers as a result of adapter unload, get out
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((lbq_desc->free_buf != NULL) ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mac_flags == QL_MAC_DETACH)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->free_buf == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->lbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->rx_indicate == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "lbq: indicate wrong");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t lb_consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t lb_producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t num_free_buffers;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge, rx_ring->lbq_prod_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lb_producer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lb_consumer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lb_consumer_idx > lb_producer_idx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_buffers = NUM_LARGE_BUFFERS -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (lb_consumer_idx - lb_producer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_buffers = lb_producer_idx - lb_consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (num_free_buffers < qlge->rx_lb_low_count[rx_ring->cq_id]) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_lb_low_count[rx_ring->cq_id] = num_free_buffers;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->rx_indicate > 0xFF000000)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "lbq: indicate(%d) wrong: %d mac_flags %d,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "lbq_desc index %d",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id, rx_ring->rx_indicate, rx_ring->mac_flags,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->index);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (alloc_memory) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(lbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size, 0, &lbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_failed_lbq_allocs++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Got the packet from the stack decrement rx_indicate count */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_lbuf_to_free_list(rx_ring, lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Rearm if possible */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((rx_ring->lbuf_free_count >= MIN_BUFFERS_FREE_COUNT) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mac_flags == QL_MAC_STARTED)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_entry = rx_ring->lbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_entry += rx_ring->lbq_prod_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (rx_ring->lbuf_free_count > MIN_BUFFERS_ARM_COUNT) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get first one from free list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = ql_get_lbuf_from_free_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *lbq_entry = cpu_to_le64(lbq_desc->bd_dma.dma_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_entry++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbq_prod_idx >= rx_ring->lbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_entry = rx_ring->lbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Add to end of in use list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_lbuf_to_in_use_list(rx_ring, lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Update large buffer queue producer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_lbq_prod_idx(rx_ring->qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->lbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX_RING, ("%s exitd, lbuf_free_count %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, rx_ring->lbuf_free_count));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * rx recycle call back function
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_release_to_lbuf_free_list(caddr_t p)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc = (struct bq_desc *)(void *)p;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_refill_lbuf_free_list(lbq_desc, B_TRUE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * free small buffer queue buffers
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_sbq_buffers(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t j = rx_ring->sbq_free_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int force_cnt = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbuf_free_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = rx_ring->sbuf_free[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->sbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(sbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = rx_ring->sbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbuf_in_use_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = rx_ring->sbuf_in_use[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->sbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(sbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = &rx_ring->sbq_desc[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbq_len; i++, sbq_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set flag so that the callback does not allocate a new buffer
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->upl_inuse != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_cnt++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->bd_dma.dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&sbq_desc->bd_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &sbq_desc->bd_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->bd_dma.dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->bd_dma.acc_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "sbq: free %d inuse %d force %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free_count, rx_ring->sbuf_in_use_count, force_cnt);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbuf_in_use != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(rx_ring->sbuf_in_use, (rx_ring->sbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbuf_free != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(rx_ring->sbuf_free, (rx_ring->sbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* Allocate small buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_sbufs(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbq_use_head = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbq_use_tail = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbuf_in_use_count = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbq_free_head = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbq_free_tail = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbuf_free_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free = kmem_zalloc(rx_ring->sbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *), KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbuf_free == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: sbuf_free_list alloc: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_sbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use = kmem_zalloc(rx_ring->sbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *), KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbuf_in_use == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: sbuf_inuse_list alloc: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_sbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = &rx_ring->sbq_desc[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbq_len; i++, sbq_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Allocate buffer */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_alloc_phys_rbuf(qlge->dip, &sbq_desc->bd_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_buf_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_READ | DDI_DMA_STREAMING,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &sbq_desc->bd_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)rx_ring->sbq_buf_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* default alignment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&sbq_desc->bd_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: ddi_dma_alloc_handle: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_sbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set context for Return buffer callback */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->bd_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->rx_recycle.free_func = ql_release_to_sbuf_free_list;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->rx_recycle.free_arg = (caddr_t)sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->rx_ring = rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->upl_inuse = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->free_buf = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(sbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_buf_size, 0, &sbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s: desballoc() failed", __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_sbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_sbuf_to_free_list(rx_ring, sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanalloc_sbuf_err:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_sbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_lbq_buffers(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t i, j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int force_cnt = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = rx_ring->lbq_free_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbuf_free_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = rx_ring->lbuf_free[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->lbq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(lbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = rx_ring->lbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbuf_in_use_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = rx_ring->lbuf_in_use[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->lbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(lbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = &rx_ring->lbq_desc[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbq_len; i++, lbq_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set flag so that callback will not allocate a new buffer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->free_buf = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->upl_inuse != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_cnt++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->bd_dma.dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&lbq_desc->bd_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &lbq_desc->bd_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->bd_dma.dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->bd_dma.acc_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (force_cnt) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "lbq: free %d inuse %d force %d",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free_count, rx_ring->lbuf_in_use_count,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_cnt);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbuf_in_use != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(rx_ring->lbuf_in_use, (rx_ring->lbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbuf_free != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(rx_ring->lbuf_free, (rx_ring->lbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* Allocate large buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_lbufs(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbq_use_head = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbq_use_tail = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbuf_in_use_count = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbq_free_head = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbq_free_tail = 0;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbuf_free_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free = kmem_zalloc(rx_ring->lbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *), KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbuf_free == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: lbuf_free_list alloc: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_lbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use = kmem_zalloc(rx_ring->lbq_len *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (struct bq_desc *), KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbuf_in_use == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: lbuf_inuse_list alloc: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_lbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_buf_size = (qlge->mtu == ETHERMTU) ?
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan LRG_BUF_NORMAL_SIZE : LRG_BUF_JUMBO_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = &rx_ring->lbq_desc[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbq_len; i++, lbq_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size = lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Allocate buffer */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_alloc_phys_rbuf(qlge->dip, &lbq_desc->bd_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_buf_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_READ | DDI_DMA_STREAMING,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &lbq_desc->bd_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)rx_ring->lbq_buf_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* default alignment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&lbq_desc->bd_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: ddi_dma_alloc_handle: failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_lbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set context for Return buffer callback */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->bd_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->rx_recycle.free_func = ql_release_to_lbuf_free_list;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->rx_recycle.free_arg = (caddr_t)lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->rx_ring = rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->upl_inuse = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->free_buf = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->mp =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan desballoc((unsigned char *)(lbq_desc->bd_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size, 0, &lbq_desc->rx_recycle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s: desballoc() failed", __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_lbuf_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_lbuf_to_free_list(rx_ring, lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } /* For all large buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanalloc_lbuf_err:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_lbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free rx buffers
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_rx_buffers(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_lbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_sbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate rx buffers
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_rx_buffers(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_sbufs(qlge, rx_ring) != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_lbufs(qlge, rx_ring) != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto alloc_err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].type == RX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_sb_low_count[i] = NUM_SMALL_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_lb_low_count[i] = NUM_LARGE_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cq_low_count[i] = NUM_RX_RING_ENTRIES;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanalloc_err:
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan ql_free_rx_buffers(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize large buffer queue ring
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_lbq_ring(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(rx_ring->lbq_desc, rx_ring->lbq_len * sizeof (struct bq_desc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbq_len; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = &rx_ring->lbq_desc[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc->index = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize small buffer queue ring
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_sbq_ring(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(rx_ring->sbq_desc, rx_ring->sbq_len * sizeof (struct bq_desc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbq_len; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = &rx_ring->sbq_desc[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc->index = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Calculate the pseudo-header checksum if hardware can not do
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_pseudo_cksum(uint8_t *buf)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t cksum;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t iphl;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t proto;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphl = (uint16_t)(4 * (buf[0] & 0xF));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = (((uint16_t)buf[2])<<8) + buf[3] - iphl;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += proto = buf[9];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[12])<<8) + buf[13];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[14])<<8) + buf[15];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[16])<<8) + buf[17];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[18])<<8) + buf[19];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = (cksum>>16) + (cksum & 0xFFFF);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = (cksum>>16) + (cksum & 0xFFFF);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Point it to the TCP/UDP header, and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * update the checksum field.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan buf += iphl + ((proto == IPPROTO_TCP) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan TCP_CKSUM_OFFSET : UDP_CKSUM_OFFSET);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *(uint16_t *)(void *)buf = (uint16_t)htons((uint16_t)cksum);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Transmit an incoming packet.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanmblk_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_ring_tx(void *arg, mblk_t *mp)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring = (struct tx_ring *)arg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = tx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t tx_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->port_link_state == LS_DOWN) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* can not send message while link is down */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *tp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tp = mp->b_next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp->b_next = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = tp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if mac is not started, driver is not ready, can not send */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->mac_flags != QL_MAC_STARTED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d)ring not started, mode %d "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " return packets",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, tx_ring->mac_flags);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* we must try to send all */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if number of available slots is less than a threshold,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * then quit
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->tx_free_count <= TX_STOP_THRESHOLD) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->queue_stopped = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) no resources",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->defer++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If we return the buffer back we are expected to call
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * mac_tx_ring_update() when resources are available
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan next = mp->b_next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp->b_next = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_send_common(tx_ring, mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp->b_next = next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_count++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * After all msg blocks are mapped or copied to tx buffer,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * trigger the hardware to send!
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_count > 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(tx_ring->qlge, tx_ring->prod_idx_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This function builds an mblk list for the given inbound
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * completion.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic mblk_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_build_rx_mp(qlge_t *qlge, struct rx_ring *rx_ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ib_mac_iocb_rsp *ib_mac_rsp)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp1 = NULL; /* packet header */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp2 = NULL; /* packet content */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t err_flag = (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t payload_len = le32_to_cpu(ib_mac_rsp->data_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t header_len = le32_to_cpu(ib_mac_rsp->hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t pkt_len = payload_len + header_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t done;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *curr_ial_ptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t ial_data_addr_low;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t actual_data_addr_low;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp_ial = NULL; /* ial chained packets */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t size;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan uint32_t cp_offset;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan boolean_t rx_copy = B_FALSE;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mblk_t *tp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check if error flags are set
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (err_flag != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag & IB_MAC_IOCB_RSP_ERR_OVERSIZE) != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->frame_too_long++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag & IB_MAC_IOCB_RSP_ERR_UNDERSIZE) != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->frame_too_short++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag & IB_MAC_IOCB_RSP_ERR_CRC) != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->fcs_err++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "bad packet, type 0x%x", err_flag);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "qlge_ring_rx: bad response iocb dump\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)ib_mac_rsp, 8,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (struct ib_mac_iocb_rsp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* header should not be in large buffer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "header in large buffer or invalid!");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan err_flag |= 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if whole packet is too big than rx buffer size */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (pkt_len > qlge->max_frame_size) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "ql_build_rx_mpframe too long(%d)!", pkt_len);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan err_flag |= 1;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (qlge->rx_copy ||
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (rx_ring->sbuf_in_use_count <= qlge->rx_copy_threshold) ||
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (rx_ring->lbuf_in_use_count <= qlge->rx_copy_threshold)) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan rx_copy = B_TRUE;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan /* if using rx copy mode, we need to allocate a big enough buffer */
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan qlge->stats.norcvbuf++;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp = allocb(payload_len + header_len + qlge->ip_hdr_offset,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan BPRI_MED);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp == NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan cmn_err(CE_WARN, "rx copy failed to allocate memory");
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr += qlge->ip_hdr_offset;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Handle the header buffer if present.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * packet header must be valid and saved in one small buffer
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * broadcast/multicast packets' headers not splitted
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HS)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX, ("Header of %d bytes in small buffer.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan header_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Sync access */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = ql_get_sbuf_from_in_use_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(sbq_desc != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Validate addresses from the ASIC with the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * expected sbuf address
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (cpu_to_le64(sbq_desc->bd_dma.dma_addr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != ib_mac_rsp->hdr_addr) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Small buffer address mismatch */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) ring%d packet saved"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " in wrong small buffer",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, rx_ring->cq_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto fatal_error;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* get this packet */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1 = sbq_desc->mp;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan /* Flush DMA'd data */
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (void) ddi_dma_sync(sbq_desc->bd_dma.dma_handle,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan 0, header_len, DDI_DMA_SYNC_FORKERNEL);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag != 0)|| (mp1 == NULL)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* failed on this packet, put it back for re-arming */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "get header from small buffer fail");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_FALSE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1 = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp != NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan bcopy(sbq_desc->bd_dma.vaddr, tp->b_rptr,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan header_len);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_FALSE);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp1 = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->ip_hdr_offset != 0)&&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (header_len < SMALL_BUFFER_SIZE)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * copy entire header to a 2 bytes boundary
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * address for 8100 adapters so that the IP
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * header can be on a 4 byte boundary address
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(mp1->b_rptr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (mp1->b_rptr + SMALL_BUFFER_SIZE +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ip_hdr_offset),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan header_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1->b_rptr += SMALL_BUFFER_SIZE +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ip_hdr_offset;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Adjust the mp payload_len to match
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the packet header payload_len
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1->b_wptr = mp1->b_rptr + header_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1->b_next = mp1->b_cont = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "\t RX packet header dump:\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)mp1->b_rptr, 8, header_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * packet data or whole packet can be in small or one or
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * several large buffer(s)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The data is in a single small buffer.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = ql_get_sbuf_from_in_use_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(sbq_desc != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%d bytes in a single small buffer, sbq_desc = %p, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "sbq_desc->bd_dma.dma_addr = %x,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " ib_mac_rsp->data_addr = %x, mp = %p\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan payload_len, sbq_desc, sbq_desc->bd_dma.dma_addr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ib_mac_rsp->data_addr, sbq_desc->mp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Validate addresses from the ASIC with the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * expected sbuf address
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (cpu_to_le64(sbq_desc->bd_dma.dma_addr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != ib_mac_rsp->data_addr) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Small buffer address mismatch */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) ring%d packet saved"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " in wrong small buffer",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, rx_ring->cq_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto fatal_error;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* get this packet */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = sbq_desc->mp;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (void) ddi_dma_sync(sbq_desc->bd_dma.dma_handle,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan 0, payload_len, DDI_DMA_SYNC_FORKERNEL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag != 0) || (mp2 == NULL)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* failed on this packet, put it back for re-arming */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "ignore bad data from small buffer");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_FALSE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp != NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan bcopy(sbq_desc->bd_dma.vaddr,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + header_len, payload_len);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_wptr =
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + header_len + payload_len;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_FALSE);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp2 = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adjust the buffer length to match the payload_len */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2->b_wptr = mp2->b_rptr + payload_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2->b_next = mp2->b_cont = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Flush DMA'd data */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "\t RX packet payload dump:\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)mp2->b_rptr, 8, payload_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if payload is too small , copy to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the end of packet header
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((mp1 != NULL) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (payload_len <= qlge->payload_copy_thresh) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (pkt_len <
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (SMALL_BUFFER_SIZE - qlge->ip_hdr_offset))) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(mp2->b_rptr, mp1->b_wptr, payload_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1->b_wptr += payload_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp2);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_DL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The data is in a single large buffer.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = ql_get_lbuf_from_in_use_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%d bytes in a single large buffer, lbq_desc = %p, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "lbq_desc->bd_dma.dma_addr = %x,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " ib_mac_rsp->data_addr = %x, mp = %p\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan payload_len, lbq_desc, lbq_desc->bd_dma.dma_addr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ib_mac_rsp->data_addr, lbq_desc->mp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(lbq_desc != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Validate addresses from the ASIC with
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the expected lbuf address
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (cpu_to_le64(lbq_desc->bd_dma.dma_addr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != ib_mac_rsp->data_addr) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Large buffer address mismatch */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) ring%d packet saved"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " in wrong large buffer",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, rx_ring->cq_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto fatal_error;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = lbq_desc->mp;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan /* Flush DMA'd data */
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (void) ddi_dma_sync(lbq_desc->bd_dma.dma_handle,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan 0, payload_len, DDI_DMA_SYNC_FORKERNEL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((err_flag != 0) || (mp2 == NULL)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "ignore bad data from large buffer");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* failed on this packet, put it back for re-arming */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_refill_lbuf_free_list(lbq_desc, B_FALSE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp != NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan bcopy(lbq_desc->bd_dma.vaddr,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + header_len, payload_len);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_wptr =
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + header_len + payload_len;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ql_refill_lbuf_free_list(lbq_desc, B_FALSE);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp2 = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Adjust the buffer length to match
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the packet payload_len
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2->b_wptr = mp2->b_rptr + payload_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2->b_next = mp2->b_cont = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "\t RX packet payload dump:\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)mp2->b_rptr, 8, payload_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if payload is too small , copy to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the end of packet header
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((mp1 != NULL) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (payload_len <= qlge->payload_copy_thresh) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (pkt_len<
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (SMALL_BUFFER_SIZE - qlge->ip_hdr_offset))) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(mp2->b_rptr, mp1->b_wptr, payload_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp1->b_wptr += payload_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp2);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp2 = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (payload_len) { /* ial case */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * payload available but not in sml nor lrg buffer,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * so, it is saved in IAL
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "packet chained in IAL \n");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* lrg buf addresses are saved in one small buffer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = ql_get_sbuf_from_in_use_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan curr_ial_ptr = (uint64_t *)sbq_desc->bd_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan done = 0;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan cp_offset = 0;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (!done) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ial_data_addr_low =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint32_t)(le64_to_cpu(*curr_ial_ptr) &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0xFFFFFFFE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* check if this is the last packet fragment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan done = (uint32_t)(le64_to_cpu(*curr_ial_ptr) & 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan curr_ial_ptr++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The data is in one or several large buffer(s).
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = ql_get_lbuf_from_in_use_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan actual_data_addr_low =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint32_t)(lbq_desc->bd_dma.dma_addr &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0xFFFFFFFE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ial_data_addr_low != actual_data_addr_low) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "packet saved in wrong ial lrg buffer"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " expected %x, actual %lx",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ial_data_addr_low,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uintptr_t)lbq_desc->bd_dma.dma_addr);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan goto fatal_error;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size = (payload_len < rx_ring->lbq_buf_size)?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan payload_len : rx_ring->lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan payload_len -= size;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2 = lbq_desc->mp;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((err_flag != 0) || (mp2 == NULL)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan "ignore bad data from large buffer");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_refill_lbuf_free_list(lbq_desc, B_FALSE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2 = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp != NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan (void) ddi_dma_sync(
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan lbq_desc->bd_dma.dma_handle,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan 0, size, DDI_DMA_SYNC_FORKERNEL);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan bcopy(lbq_desc->bd_dma.vaddr,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + header_len + cp_offset,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan size);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_wptr =
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_rptr + size + cp_offset +
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan header_len;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan cp_offset += size;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ql_refill_lbuf_free_list(lbq_desc, B_FALSE);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp2 = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (mp_ial == NULL) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp_ial = mp2;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan linkb(mp_ial, mp2);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2->b_next = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2->b_cont = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2->b_wptr = mp2->b_rptr + size;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Flush DMA'd data */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ddi_dma_sync(lbq_desc->bd_dma.dma_handle,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan 0, size, DDI_DMA_SYNC_FORKERNEL);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_RX, ("ial %d payload received \n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_DUMP(DBG_RX, "\t Mac data dump:\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (uint8_t *)mp2->b_rptr, 8, size);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (err_flag != 0) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* failed on this packet, put it back for re-arming */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "ignore bad data from small buffer");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_refill_sbuf_free_list(sbq_desc, B_FALSE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp2 = mp_ial;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan freemsg(sbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * some packets' hdr not split, then send mp2 upstream, otherwise,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * concatenate message block mp2 to the tail of message header, mp1
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!err_flag) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (rx_copy) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp != NULL) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_next = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_cont = NULL;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan tp->b_wptr = tp->b_rptr +
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan header_len + payload_len;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp = tp;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (mp1) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (mp2) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan QL_PRINT(DBG_RX,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ("packet in mp1 and mp2\n"));
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan /* mp1->b_cont = mp2; */
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan linkb(mp1, mp2);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp = mp1;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan QL_PRINT(DBG_RX,
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan ("packet in mp1 only\n"));
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp = mp1;
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan } else if (mp2) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan QL_PRINT(DBG_RX, ("packet in mp2 only\n"));
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan mp = mp2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanfatal_error:
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* fatal Error! */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan if (tp) {
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan freemsg(tp);
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan }
a6766df40e85f57b203ec7f2143dd1a99e6fe03dSukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* *mp->b_wptr = 0; */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_wake_asic_reset_soft_intr(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Bump completion queue consumer index.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_update_cq(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->curr_entry++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->cnsmr_idx >= rx_ring->cq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->curr_entry = rx_ring->cq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Update completion queue consumer index.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_write_cq_idx(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge, rx_ring->cnsmr_idx_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Processes a SYS-Chip Event Notification Completion Event.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The incoming notification event that describes a link up/down
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * or some sorts of error happens.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_process_chip_ae_intr(qlge_t *qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ib_sys_event_iocb_rsp *ib_sys_event_rsp_ptr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint8_t eventType = ib_sys_event_rsp_ptr->event_type;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t soft_req = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (eventType) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_PORT_LINK_UP: /* 0x0h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_MBX, ("Port Link Up\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_PORT_LINK_DOWN: /* 0x1h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_MBX, ("Port Link Down\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_MULTIPLE_CAM_HITS : /* 0x6h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "A multiple CAM hits look up error "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "occurred");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan soft_req |= NEED_HW_RESET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_SOFT_ECC_ERR: /* 0x7h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Soft ECC error detected");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan soft_req |= NEED_HW_RESET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_MGMT_FATAL_ERR: /* 0x8h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Management (MPI) Processor fatal"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " error occured");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan soft_req |= NEED_MPI_RESET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_MAC_INTERRUPT: /* 0x9h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_MBX, ("MAC Interrupt"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case SYS_EVENT_PCI_ERR_READING_SML_LRG_BUF: /* 0x40h */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "PCI Error reading small/large "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "buffers occured");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan soft_req |= NEED_HW_RESET;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX, ("%s(%d) unknown Sys Event: "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "type 0x%x occured",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, eventType));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((soft_req & NEED_MPI_RESET) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_wake_mpi_reset_soft_intr(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if ((soft_req & NEED_HW_RESET) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_wake_asic_reset_soft_intr(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * set received packet checksum flag
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_set_rx_cksum(mblk_t *mp, struct ib_mac_iocb_rsp *net_rsp)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t flags;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Not TCP or UDP packet? nothing more to do */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (((net_rsp->flags2 & IB_MAC_IOCB_RSP_T) == 0) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((net_rsp->flags2 & IB_MAC_IOCB_RSP_U) == 0))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* No CKO support for IPv6 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((net_rsp->flags3 & IB_MAC_IOCB_RSP_V6) != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If checksum error, don't set flags; stack will calculate
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * checksum, detect the error and update statistics
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (((net_rsp->flags1 & IB_MAC_IOCB_RSP_TE) != 0) ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((net_rsp->flags1 & IB_MAC_IOCB_RSP_IE) != 0))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* TCP or UDP packet and checksum valid */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (((net_rsp->flags2 & IB_MAC_IOCB_RSP_T) != 0) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((net_rsp->flags1 & IB_MAC_IOCB_RSP_NU) == 0)) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer flags = HCK_FULLCKSUM_OK;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_hcksum_set(mp, 0, 0, 0, 0, flags);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (((net_rsp->flags2 & IB_MAC_IOCB_RSP_U) != 0) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((net_rsp->flags1 & IB_MAC_IOCB_RSP_NU) == 0)) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer flags = HCK_FULLCKSUM_OK;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_hcksum_set(mp, 0, 0, 0, 0, flags);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This function goes through h/w descriptor in one specified rx ring,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * receives the data if the descriptor status shows the data is ready.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * It returns a chain of mblks containing the received data, to be
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * passed up to mac_rx_ring().
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanmblk_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_ring_rx(struct rx_ring *rx_ring, int poll_bytes)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t prod = ql_read_sh_reg(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ib_mac_iocb_rsp *net_rsp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mblk_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t **mblk_tail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t received_bytes = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t length;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#ifdef QLGE_PERFORMANCE
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t pkt_ct = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t num_free_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge, rx_ring->cnsmr_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan consumer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (consumer_idx > producer_idx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_entries = (consumer_idx - producer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_entries = NUM_RX_RING_ENTRIES - (
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx - consumer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (num_free_entries < qlge->cq_low_count[rx_ring->cq_id])
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cq_low_count[rx_ring->cq_id] = num_free_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_head = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_tail = &mblk_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan while ((prod != rx_ring->cnsmr_idx)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s cq_id = %d, prod = %d, cnsmr = %d.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, rx_ring->cq_id, prod, rx_ring->cnsmr_idx));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan net_rsp = (struct ib_mac_iocb_rsp *)rx_ring->curr_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_sync(rx_ring->cq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (off_t)((uintptr_t)net_rsp -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uintptr_t)rx_ring->cq_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (*net_rsp), DDI_DMA_SYNC_FORKERNEL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "qlge_ring_rx: rx completion iocb\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->curr_entry, 8, (size_t)sizeof (*net_rsp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (net_rsp->opcode) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case OPCODE_IB_MAC_IOCB:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adding length of pkt header and payload */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan length = le32_to_cpu(net_rsp->data_len) +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan le32_to_cpu(net_rsp->hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((poll_bytes != QLGE_POLL_ALL) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((received_bytes + length) > poll_bytes)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan continue;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan received_bytes += length;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#ifdef QLGE_PERFORMANCE
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pkt_ct++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = ql_build_rx_mp(qlge, rx_ring, net_rsp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->mac_flags != QL_MAC_STARTED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Increment number of packets we have
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * indicated to the stack, should be
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * decremented when we get it back
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * or when freemsg is called
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(rx_ring->rx_indicate
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan <= rx_ring->cq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s do not send to OS,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " mac_flags %d, indicate %d",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, rx_ring->mac_flags,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("cq_id = %d, packet "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "dropped, mac not "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "enabled.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_pkt_dropped_mac_unenabled++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* rx_lock is expected to be held */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * IP full packet has been
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * successfully verified by
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * H/W and is correct
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_set_rx_cksum(mp, net_rsp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_packets++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_bytes += length;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *mblk_tail = mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_tail = &mp->b_next;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("cq_id = %d, packet dropped\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_packets_dropped_no_buffer++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case OPCODE_IB_SYS_EVENT_IOCB:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_process_chip_ae_intr(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (struct ib_sys_event_iocb_rsp *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan net_rsp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "%s Ring(%d)Hit default case, not handled!"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " dropping the packet, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "opcode = %x.", __func__, rx_ring->cq_id,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan net_rsp->opcode);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* increment cnsmr_idx and curr_entry */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_cq(rx_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan prod = ql_read_sh_reg(qlge, rx_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#ifdef QLGE_PERFORMANCE
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (pkt_ct >= 7)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[7]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 6)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[6]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 5)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[5]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 4)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[4]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 3)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[3]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 2)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[2]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 1)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[1]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (pkt_ct == 0)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->hist[0]++;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* update cnsmr_idx */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_cq_idx(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* do not enable interrupt for polling mode */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (poll_bytes == QLGE_POLL_ALL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_completion_interrupt(rx_ring->qlge, rx_ring->irq);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mblk_head);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* Process an outbound completion from an rx ring. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_process_mac_tx_intr(qlge_t *qlge, struct ob_mac_iocb_rsp *mac_rsp)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_ring_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[mac_rsp->txq_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc = tx_ring->wq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc += mac_rsp->tid;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring_desc->tx_type == USE_DMA) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d): tx type USE_DMA\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Release the DMA resource that is used for
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * DMA binding.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (j = 0; j < tx_ring_desc->tx_dma_handle_used; j++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_unbind_handle(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->tx_dma_handle[j]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->tx_dma_handle_used = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free the mblk after sending completed
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring_desc->mp != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(tx_ring_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->obytes += tx_ring_desc->tx_bytes;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->opackets++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_rsp->flags1 & (OB_MAC_IOCB_RSP_E | OB_MAC_IOCB_RSP_S |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_RSP_L | OB_MAC_IOCB_RSP_B)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->errxmt++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_E) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Total descriptor length did not match "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "transfer length.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_S) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Frame too short to be legal, not sent.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_rsp->flags1 & OB_MAC_IOCB_RSP_L) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Frame too long, but sent anyway.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_rsp->flags3 & OB_MAC_IOCB_RSP_B) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("PCI backplane error. Frame not sent.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&tx_ring->tx_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * clean up tx completion iocbs
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t prod = ql_read_sh_reg(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ob_mac_iocb_rsp *net_rsp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan boolean_t resume_tx = B_FALSE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t num_free_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge, rx_ring->cnsmr_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan consumer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (consumer_idx > producer_idx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_entries = (consumer_idx - producer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan num_free_entries = NUM_RX_RING_ENTRIES -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (producer_idx - consumer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (num_free_entries < qlge->cq_low_count[rx_ring->cq_id])
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cq_low_count[rx_ring->cq_id] = num_free_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* While there are entries in the completion queue. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (prod != rx_ring->cnsmr_idx) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_RX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s cq_id = %d, prod = %d, cnsmr = %d.\n", __func__,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id, prod, rx_ring->cnsmr_idx));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan net_rsp = (struct ob_mac_iocb_rsp *)rx_ring->curr_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_sync(rx_ring->cq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (off_t)((uintptr_t)net_rsp -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uintptr_t)rx_ring->cq_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (*net_rsp), DDI_DMA_SYNC_FORKERNEL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_RX, "ql_clean_outbound_rx_ring: "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "response packet data\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->curr_entry, 8,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (*net_rsp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (net_rsp->opcode) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case OPCODE_OB_MAC_OFFLOAD_IOCB:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case OPCODE_OB_MAC_IOCB:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_process_mac_tx_intr(qlge, net_rsp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "%s Hit default case, not handled! "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "dropping the packet,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " opcode = %x.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, net_rsp->opcode);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan count++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_cq(rx_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan prod = ql_read_sh_reg(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_cq_idx(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan net_rsp = (struct ob_mac_iocb_rsp *)rx_ring->curr_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[net_rsp->txq_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->queue_stopped &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (tx_ring->tx_free_count > TX_RESUME_THRESHOLD)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The queue got stopped because the tx_ring was full.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Wake it up, because it's now at least 25% empty.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->queue_stopped = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan resume_tx = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Don't hold the lock during OS callback */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (resume_tx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RESUME_TX(tx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * reset asic when error happens
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_asic_reset_work(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = (qlge_t *)((void *)arg1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->gen_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_do_stop(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Write default ethernet address to chip register Mac
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Address slot 0 and Enable Primary Mac Function.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_unicst_set(qlge,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (uint8_t *)qlge->unicst_addr[0].addr.ether_addr_octet, 0);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->mac_flags = QL_MAC_INIT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan status = ql_do_start(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto error;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->mac_flags = QL_MAC_STARTED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->gen_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_RESTORED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerror:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "qlge up/down cycle failed, closing device");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Reset MPI
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_mpi_reset_work(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = (qlge_t *)((void *)arg1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_reset_mpi_risc(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Process MPI mailbox messages
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_mpi_event_work(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = (qlge_t *)((void *)arg1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_do_mpi_intr(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* Fire up a handler to reset the MPI processor. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wake_asic_reset_soft_intr(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_trigger_softint(qlge->asic_reset_intr_hdl, NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wake_mpi_reset_soft_intr(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_trigger_softint(qlge->mpi_reset_intr_hdl, NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wake_mpi_event_soft_intr(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_trigger_softint(qlge->mpi_event_intr_hdl, NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This handles a fatal error, MPI activity, and the default
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * rx_ring in an MSI-X multiple interrupt vector environment.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * In MSI/Legacy environment it also process the rest of
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the rx_rings.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_isr(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = (struct rx_ring *)((void *)arg1);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct rx_ring *ob_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *intr_ctx = &qlge->intr_ctx[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t var, prod;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int work_done = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan _NOTE(ARGUNUSED(arg2));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ++qlge->rx_interrupts[rx_ring->cq_id];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_atomic_read_32(&qlge->intr_ctx[0].irq_cnt)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RSVD7, 0xfeed0002);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_ERROR_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_INTERRUPT_STATUS_1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_completion_interrupt(qlge, intr_ctx->intr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * process send completes on first stride tx ring if available
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->isr_stride) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring = &qlge->rx_ring[qlge->isr_stride];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_read_sh_reg(qlge, ob_ring) !=
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring->cnsmr_idx) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_clean_outbound_rx_ring(ob_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check the default queue and wake handler if active.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[0];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan prod = ql_read_sh_reg(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("rx-ring[0] prod index 0x%x, consumer 0x%x ",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan prod, rx_ring->cnsmr_idx));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* check if interrupt is due to incoming packet */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (prod != rx_ring->cnsmr_idx) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("Waking handler for rx_ring[0].\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_completion_interrupt(qlge, intr_ctx->intr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = ql_ring_rx(rx_ring, QLGE_POLL_ALL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mp != NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RX_UPSTREAM(rx_ring, mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan work_done++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If interrupt is not due to incoming packet, read status
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * register to see if error happens or mailbox interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((var & STATUS_FE) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RSVD7, 0xfeed0003);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Got fatal error, STS = %x.", var);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_ERROR_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Resetting chip. Error Status Register = 0x%x",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_wake_asic_reset_soft_intr(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check MPI processor activity.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((var & STATUS_PI) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * We've got an async event or mailbox completion.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Handle it and clear the source of the interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RSVD7, 0xfeed0004);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("Got MPI processor interrupt.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_completion_interrupt(qlge, intr_ctx->intr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_wake_mpi_event_soft_intr(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan work_done++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->intr_type != DDI_INTR_TYPE_MSIX) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Start the DPC for each active queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 1; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_read_sh_reg(qlge, rx_ring) !=
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Waking handler for rx_ring[%d].\n", i));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_completion_interrupt(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->irq);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type == TX_Q) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_clean_outbound_rx_ring(
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_completion_interrupt(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->qlge, rx_ring->irq);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = ql_ring_rx(rx_ring, QLGE_POLL_ALL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mp != NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RX_UPSTREAM(rx_ring, mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->mac_flags ==
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_MAC_STOPPED)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "%s rx_indicate(%d) %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, i,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan work_done++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_completion_interrupt(qlge, intr_ctx->intr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (work_done ? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * MSI-X Multiple Vector Interrupt Handler for outbound (TX) completions.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_msix_tx_isr(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = (struct rx_ring *)((void *)arg1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan _NOTE(ARGUNUSED(arg2));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ++qlge->rx_interrupts[rx_ring->cq_id];
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_clean_outbound_rx_ring(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_completion_interrupt(rx_ring->qlge, rx_ring->irq);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * MSI-X Multiple Vector Interrupt Handler
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/* ARGSUSED */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic uint_t
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_msix_isr(caddr_t arg1, caddr_t arg2)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct rx_ring *rx_ring = (struct rx_ring *)((void *)arg1);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct rx_ring *ob_ring;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mblk_t *mp;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan _NOTE(ARGUNUSED(arg2));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INTR, ("%s for ring %d\n", __func__, rx_ring->cq_id));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_disable_completion_interrupt(qlge, rx_ring->irq);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * process send completes on stride tx ring if available
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->isr_stride) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring = rx_ring + qlge->isr_stride;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_read_sh_reg(qlge, ob_ring) !=
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring->cnsmr_idx) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ++qlge->rx_interrupts[ob_ring->cq_id];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_clean_outbound_rx_ring(ob_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ++qlge->rx_interrupts[rx_ring->cq_id];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mp = ql_ring_rx(rx_ring, QLGE_POLL_ALL);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (mp != NULL)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan RX_UPSTREAM(rx_ring, mp);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (DDI_INTR_CLAIMED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Poll n_bytes of chained incoming packets
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanmblk_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_ring_rx_poll(void *arg, int n_bytes)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = (struct rx_ring *)arg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t var;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(n_bytes >= 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s for ring(%d) to read max %d bytes\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, rx_ring->cq_id, n_bytes));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ++qlge->rx_polls[rx_ring->cq_id];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (n_bytes == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = ql_ring_rx(rx_ring, n_bytes);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((rx_ring->cq_id == 0) && (mp == NULL)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check for fatal error.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((var & STATUS_FE) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RSVD7, 0xfeed0003);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan var = ql_read_reg(qlge, REG_ERROR_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Got fatal error %x.", var);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_wake_asic_reset_soft_intr(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check MPI processor activity.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((var & STATUS_PI) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * We've got an async event or mailbox completion.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Handle it and clear the source of the interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RSVD7, 0xfeed0004);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_do_mpi_intr(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * MSI-X Multiple Vector Interrupt Handler for inbound (RX) completions.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ARGSUSED */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_msix_rx_isr(caddr_t arg1, caddr_t arg2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring = (struct rx_ring *)((void *)arg1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = rx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan _NOTE(ARGUNUSED(arg2));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INTR, ("%s for ring %d\n", __func__, rx_ring->cq_id));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ++qlge->rx_interrupts[rx_ring->cq_id];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = ql_ring_rx(rx_ring, QLGE_POLL_ALL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mp != NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RX_UPSTREAM(rx_ring, mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_INTR_CLAIMED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate DMA Buffer for ioctl service
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_ioctl_dma_buf(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t phy_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t alloc_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan alloc_size = qlge->ioctl_buf_dma_attr.mem_len =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan max(WCS_MPI_CODE_RAM_LENGTH, MEMC_MPI_RAM_LENGTH);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &qlge->ioctl_buf_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_buf_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->ioctl_buf_dma_attr.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)alloc_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* alignment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&qlge->ioctl_buf_dma_attr.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): ioctl DMA allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan phy_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ioctl_buf_dma_attr.vaddr == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): failed.", __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ioctl_buf_dma_attr.dma_addr = phy_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_MBX, ("%s: ioctl_dma_buf_virt_addr = 0x%lx, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "phy_addr = 0x%lx\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->ioctl_buf_dma_attr.vaddr, phy_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Function to free physical memory.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_phys(ddi_dma_handle_t *dma_handle, ddi_acc_handle_t *acc_handle)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (*dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_unbind_handle(*dma_handle);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (*acc_handle != NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_mem_free(acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_free_handle(dma_handle);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *acc_handle = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Function to free ioctl dma buffer.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_ioctl_dma_buf(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ioctl_buf_dma_attr.dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&qlge->ioctl_buf_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->ioctl_buf_dma_attr.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ioctl_buf_dma_attr.vaddr = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ioctl_buf_dma_attr.dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free shadow register space used for request and completion queues
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_shadow_space(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->host_copy_shadow_dma_attr.dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&qlge->host_copy_shadow_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->host_copy_shadow_dma_attr.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->host_copy_shadow_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (qlge->host_copy_shadow_dma_attr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->buf_q_ptr_base_addr_dma_attr.dma_handle != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&qlge->buf_q_ptr_base_addr_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->buf_q_ptr_base_addr_dma_attr.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->buf_q_ptr_base_addr_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (qlge->buf_q_ptr_base_addr_dma_attr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate shadow register space for request and completion queues
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_shadow_space(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->host_copy_shadow_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_dev_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->host_copy_shadow_dma_attr.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)VM_PAGE_SIZE, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)4, /* 4 bytes alignment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&qlge->host_copy_shadow_dma_attr.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->host_copy_shadow_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (qlge->host_copy_shadow_dma_attr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Unable to allocate DMA memory for "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "response shadow registers", __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->host_copy_shadow_dma_attr.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->buf_q_ptr_base_addr_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->buf_q_ptr_base_addr_dma_attr.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)VM_PAGE_SIZE, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)4, /* 4 bytes alignment */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&qlge->buf_q_ptr_base_addr_dma_attr.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->buf_q_ptr_base_addr_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (qlge->buf_q_ptr_base_addr_dma_attr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Unable to allocate DMA memory "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "for request shadow registers",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_wqp_sh_area;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->buf_q_ptr_base_addr_dma_attr.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerr_wqp_sh_area:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&qlge->host_copy_shadow_dma_attr.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->host_copy_shadow_dma_attr.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->host_copy_shadow_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (qlge->host_copy_shadow_dma_attr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize a tx ring
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_tx_ring(struct tx_ring *tx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ob_mac_iocb_req *mac_iocb_ptr = tx_ring->wq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_ring_desc = tx_ring->wq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < tx_ring->wq_len; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->index = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->queue_entry = mac_iocb_ptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->tx_free_count = tx_ring->wq_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->queue_stopped = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free one tx ring resources
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_tx_resources(struct tx_ring *tx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_ring_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i, j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (tx_ring->wq_dma.dma_handle != NULL) {
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan ql_free_phys(&tx_ring->wq_dma.dma_handle,
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan &tx_ring->wq_dma.acc_handle);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan bzero(&tx_ring->wq_dma, sizeof (tx_ring->wq_dma));
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->wq_desc != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc = tx_ring->wq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < tx_ring->wq_len; i++, tx_ring_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (j = 0; j < QL_MAX_TX_DMA_HANDLES; j++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring_desc->tx_dma_handle[j]) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The unbinding will happen in tx
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * completion, here we just free the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * handles
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_free_handle(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &(tx_ring_desc->tx_dma_handle[j]));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->tx_dma_handle[j] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring_desc->oal != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->oal_dma_addr = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->oal = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->copy_buffer = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->copy_buffer_dma_addr = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&tx_ring_desc->oal_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring_desc->oal_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(tx_ring->wq_desc,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_len * sizeof (struct tx_ring_desc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_desc = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* free the wqicb struct */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->wqicb_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&tx_ring->wqicb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring->wqicb_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&tx_ring->wqicb_dma, sizeof (tx_ring->wqicb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate work (request) queue memory and transmit
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * descriptors for this transmit ring
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_tx_resources(qlge_t *qlge, struct tx_ring *tx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_ring_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i, j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t length;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* allocate dma buffers for obiocbs */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &tx_ring->wq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring->wq_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)tx_ring->wq_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)128, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&tx_ring->wq_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&tx_ring->wq_dma, sizeof (&tx_ring->wq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): reqQ allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_desc =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_zalloc(tx_ring->wq_len * sizeof (struct tx_ring_desc),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->wq_desc == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc = tx_ring->wq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate a large enough structure to hold the following
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 1. oal buffer MAX_SGELEMENTS * sizeof (oal_entry) bytes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 2. copy buffer of QL_MAX_COPY_LENGTH bytes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan length = (sizeof (struct oal_entry) * MAX_SG_ELEMENTS)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan + QL_MAX_COPY_LENGTH;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < tx_ring->wq_len; i++, tx_ring_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring_desc->oal_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring_desc->oal_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)length, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* default alignment:8 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&tx_ring_desc->oal_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&tx_ring_desc->oal_dma,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (tx_ring_desc->oal_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): reqQ tx buf &"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "oal alloc failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan goto err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->oal = tx_ring_desc->oal_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->oal_dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->copy_buffer =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t)((uint8_t *)tx_ring_desc->oal
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + (sizeof (struct oal_entry) * MAX_SG_ELEMENTS));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->copy_buffer_dma_addr =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (tx_ring_desc->oal_dma_addr
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + (sizeof (struct oal_entry) * MAX_SG_ELEMENTS));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Allocate dma handles for transmit buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (j = 0; j < QL_MAX_TX_DMA_HANDLES; j++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_dma_alloc_handle(qlge->dip,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_mapping_dma_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_DONTWAIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0, &tx_ring_desc->tx_dma_handle[j])
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != DDI_SUCCESS) {
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan tx_ring_desc->tx_dma_handle[j] = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "!%s: ddi_dma_alloc_handle: "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "tx_dma_handle "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "alloc failed", __func__);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan ql_free_phys(
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan &tx_ring_desc->oal_dma.dma_handle,
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan &tx_ring_desc->oal_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* alloc a wqicb control block to load this tx ring to hw */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &tx_ring->wqicb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &tx_ring->wqicb_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (struct wqicb_t), /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&tx_ring->wqicb_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&tx_ring->wqicb_dma, sizeof (tx_ring->wqicb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): wqicb allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan goto err;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wqicb_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerr:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_tx_resources(tx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free one rx ring resources
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_rx_resources(struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free the small buffer queue. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbq_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&rx_ring->sbq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->sbq_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->sbq_dma, sizeof (rx_ring->sbq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free the small buffer queue control blocks. */
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (rx_ring->sbq_desc != NULL) {
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan kmem_free(rx_ring->sbq_desc, rx_ring->sbq_len *
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan sizeof (struct bq_desc));
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->sbq_desc = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free the large buffer queue. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbq_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&rx_ring->lbq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->lbq_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->lbq_dma, sizeof (rx_ring->lbq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free the large buffer queue control blocks. */
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (rx_ring->lbq_desc != NULL) {
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan kmem_free(rx_ring->lbq_desc, rx_ring->lbq_len *
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan sizeof (struct bq_desc));
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan rx_ring->lbq_desc = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free cqicb struct */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->cqicb_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&rx_ring->cqicb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->cqicb_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->cqicb_dma, sizeof (rx_ring->cqicb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Free the rx queue. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->cq_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&rx_ring->cq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->cq_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->cq_dma, sizeof (rx_ring->cq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate queues and buffers for this completions queue based
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * on the values in the parameter structure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_rx_resources(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &rx_ring->cq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->cq_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)rx_ring->cq_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)128, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&rx_ring->cq_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->cq_dma, sizeof (rx_ring->cq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): rspQ allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbq_len != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate small buffer queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &rx_ring->sbq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->sbq_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)rx_ring->sbq_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)128, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&rx_ring->sbq_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->sbq_dma, sizeof (rx_ring->sbq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "%s(%d): small buffer queue allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate small buffer queue control blocks.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_desc =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_zalloc(rx_ring->sbq_len * sizeof (struct bq_desc),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbq_desc == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "sbq control block allocation failed.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_init_sbq_ring(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbq_len != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate large buffer queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &rx_ring->lbq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->lbq_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)rx_ring->lbq_size, /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)128, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&rx_ring->lbq_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->lbq_dma, sizeof (rx_ring->lbq_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): lbq allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate large buffer queue control blocks.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_desc =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_zalloc(rx_ring->lbq_len * sizeof (struct bq_desc),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan KM_NOSLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbq_desc == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Large buffer queue control block allocation "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "failed.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_init_lbq_ring(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &rx_ring->cqicb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &rx_ring->cqicb_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (struct cqicb_t), /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&rx_ring->cqicb_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&rx_ring->cqicb_dma, sizeof (rx_ring->cqicb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): cqicb allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cqicb_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerr_mem:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_rx_resources(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Frees tx/rx queues memory resources
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_mem_resources(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ricb_dma.dma_handle) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* free the ricb struct */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(&qlge->ricb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->ricb_dma.acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->ricb_dma, sizeof (qlge->ricb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_rx_buffers(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_ioctl_dma_buf(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_tx_resources(&qlge->tx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_rx_resources(&qlge->rx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_shadow_space(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate buffer queues, large buffers and small buffers etc
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This API is called in the gld_attach member function. It is called
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * only once. Later reset,reboot should not re-allocate all rings and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * buffers.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_mem_resources(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Allocate space for our shadow registers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_shadow_space(qlge))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_rx_resources(qlge, &qlge->rx_ring[i]) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "RX resource allocation failed.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Allocate tx queue resources */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_tx_resources(qlge, &qlge->tx_ring[i]) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Tx resource allocation failed.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_ioctl_dma_buf(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_rx_buffers(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "?%s(%d): ql_alloc_rx_buffers failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_ALLOC_RX_BUF;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_phys(qlge->dip, &qlge->ricb_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_desc_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->ricb_dma.acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (struct ricb), /* mem size */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)0, /* alignment:128 bytes boundary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&qlge->ricb_dma.vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero(&qlge->ricb_dma, sizeof (qlge->ricb_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): ricb allocation failed.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan goto err_mem;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ricb_dma.dma_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerr_mem:
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan ql_free_mem_resources(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Function used to allocate physical memory and zero it.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_alloc_phys_rbuf(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_device_acc_attr_t *device_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint_t dma_flags,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_acc_handle_t *acc_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t size,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t alignment,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan caddr_t *vaddr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t *dma_cookie)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t rlen;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint_t cnt;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Workaround for SUN XMITS buffer must end and start on 8 byte
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * boundary. Else, hardware will overrun the buffer. Simple fix is
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to make sure buffer has enough room for overrun.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (size & 7) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size += 8 - (size & 7);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adjust the alignment if requested */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (alignment) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan dma_attr.dma_attr_align = alignment;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate DMA handle
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ddi_dma_alloc_handle(dip, &dma_attr_rbuf, DDI_DMA_DONTWAIT, NULL,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan dma_handle) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, QL_BANG "%s: ddi_dma_alloc_handle FAILED",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (QL_ERROR);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate DMA memory
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_dma_mem_alloc(*dma_handle, size, device_acc_attr,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_flags & (DDI_DMA_CONSISTENT|DDI_DMA_STREAMING),
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_DMA_DONTWAIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_free_handle(dma_handle);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *acc_handle = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (QL_ERROR);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ddi_dma_addr_bind_handle(*dma_handle, NULL, *vaddr, rlen,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_flags, DDI_DMA_DONTWAIT, NULL,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_cookie, &cnt) != DDI_DMA_MAPPED) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_dma_mem_free(acc_handle);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_dma_free_handle(dma_handle);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan __func__);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *acc_handle = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (QL_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (cnt != 1) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_free_phys(dma_handle, acc_handle);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "%s: cnt != 1; Failed segment count",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan __func__);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (QL_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan bzero((caddr_t)*vaddr, rlen);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (0);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Function used to allocate physical memory and zero it.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic int
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_alloc_phys(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_device_acc_attr_t *device_acc_attr,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint_t dma_flags,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_acc_handle_t *acc_handle,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size_t size,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size_t alignment,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan caddr_t *vaddr,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_dma_cookie_t *dma_cookie)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size_t rlen;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint_t cnt;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Workaround for SUN XMITS buffer must end and start on 8 byte
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * boundary. Else, hardware will overrun the buffer. Simple fix is
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * to make sure buffer has enough room for overrun.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (size & 7) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan size += 8 - (size & 7);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Adjust the alignment if requested */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (alignment) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_attr.dma_attr_align = alignment;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Allocate DMA handle
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_DONTWAIT, NULL,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_handle) != DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, QL_BANG "%s: ddi_dma_alloc_handle FAILED",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan __func__);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (QL_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Allocate DMA memory
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ddi_dma_mem_alloc(*dma_handle, size, device_acc_attr,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_flags & (DDI_DMA_CONSISTENT|DDI_DMA_STREAMING),
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_DMA_DONTWAIT,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_free_handle(dma_handle);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *acc_handle = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (QL_ERROR);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_dma_addr_bind_handle(*dma_handle, NULL, *vaddr, rlen,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_flags, DDI_DMA_DONTWAIT, NULL,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan dma_cookie, &cnt) != DDI_DMA_MAPPED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_mem_free(acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_free_handle(dma_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *acc_handle = NULL;
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan *dma_handle = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (QL_ERROR);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (cnt != 1) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_phys(dma_handle, acc_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s: cnt != 1; Failed segment count",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (QL_ERROR);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero((caddr_t)*vaddr, rlen);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add interrupt handlers based on the interrupt type.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Before adding the interrupt handlers, the interrupt vectors should
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * have been allocated, and the rx/tx rings have also been allocated.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_intr_handlers(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int vector = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rc, i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *intr_ctx = &qlge->intr_ctx[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (qlge->intr_type) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_MSIX:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add interrupt handler for rx and tx rings: vector[0 -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * (qlge->intr_cnt -1)].
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (vector = 0; vector < qlge->intr_cnt; vector++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_atomic_set_32(&intr_ctx->irq_cnt, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * associate interrupt vector with interrupt handler
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_add_handler(qlge->htable[vector],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (ddi_intr_handler_t *)intr_ctx->handler,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void *)&qlge->rx_ring[vector], NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("rx_ring[%d] 0x%p\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan vector, &qlge->rx_ring[vector]));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Add rx interrupt handler failed. "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "return: %d, vector: %d", rc, vector));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (vector--; vector >= 0; vector--) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_remove_handler(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->htable[vector]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_MSI:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add interrupt handlers for the only vector
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_atomic_set_32(&intr_ctx->irq_cnt, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_add_handler(qlge->htable[vector],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_isr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t)&qlge->rx_ring[0], NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Add MSI interrupt handler failed: %d\n", rc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_FIXED:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add interrupt handlers for the only vector
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_atomic_set_32(&intr_ctx->irq_cnt, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_add_handler(qlge->htable[vector],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_isr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t)&qlge->rx_ring[0], NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Add legacy interrupt handler failed: %d\n", rc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Enable interrupts */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Block enable */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->intr_cap & DDI_INTR_FLAG_BLOCK) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Block enabling %d interrupt(s)\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_cnt));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_block_enable(qlge->htable, qlge->intr_cnt);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else { /* Non block enable */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Non Block Enabling interrupt %d "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "handle 0x%x\n", i, qlge->htable[i]));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_enable(qlge->htable[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_INTR_ENABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Here we build the intr_ctx structures based on
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * our rx_ring count and intr vector count.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The intr_ctx structure is used to hook each vector
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to possibly different handlers.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_resolve_queues_to_irqs(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct intr_ctx *intr_ctx = &qlge->intr_ctx[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->intr_type == DDI_INTR_TYPE_MSIX) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Each rx_ring has its own intr_ctx since we
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * have separate vectors for each queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This only true when MSI-X is enabled.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++, intr_ctx++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].irq = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->qlge = qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * We set up each vectors enable/disable/read bits so
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * there's no bit/mask calculations in critical path.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_en_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_ENABLE | INTR_EN_IHD_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_IHD | i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_dis_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_DISABLE | INTR_EN_IHD_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_IHD | i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_read_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_READ | INTR_EN_IHD_MASK | INTR_EN_IHD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan | i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (i == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Default queue handles bcast/mcast plus
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * async events.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->handler = ql_isr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (qlge->rx_ring[i].type == TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Outbound queue is for outbound completions
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * only.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->isr_stride)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->handler = ql_msix_isr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->handler = ql_msix_tx_isr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Inbound queues handle unicast frames only.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->isr_stride)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->handler = ql_msix_isr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->handler = ql_msix_rx_isr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan i = qlge->intr_cnt;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan for (; i < qlge->rx_ring_count; i++, intr_ctx++) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan int iv = i - qlge->isr_stride;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_ring[i].irq = iv;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->intr = iv;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->qlge = qlge;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * We set up each vectors enable/disable/read bits so
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * there's no bit/mask calculations in critical path.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->intr_en_mask =
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_ENABLE | INTR_EN_IHD_MASK |
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_IHD | iv;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->intr_dis_mask =
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_DISABLE | INTR_EN_IHD_MASK |
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_IHD | iv;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->intr_read_mask =
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan INTR_EN_TYPE_READ | INTR_EN_IHD_MASK | INTR_EN_IHD
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan | iv;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->rx_ring[i].type == TX_Q) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Outbound queue is for outbound completions
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * only.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan intr_ctx->handler = ql_msix_isr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Inbound queues handle unicast frames only.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->handler = ql_msix_rx_isr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * All rx_rings use the same intr_ctx since
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * there is only one vector.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->qlge = qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * We set up each vectors enable/disable/read bits so
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * there's no bit/mask calculations in the critical path.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_en_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_ENABLE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_dis_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_DISABLE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->intr_read_mask =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan INTR_EN_TYPE_READ;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Single interrupt means one handler for all rings.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan intr_ctx->handler = ql_isr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].irq = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Free allocated interrupts.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_irq_vectors(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_INTR_ENABLED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable all interrupts */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->intr_cap & DDI_INTR_FLAG_BLOCK) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Call ddi_intr_block_disable() */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_block_disable(qlge->htable,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_cnt);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_disable(qlge->htable[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_INTR_ENABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->intr_cnt; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_ADD_INTERRUPT)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_remove_handler(qlge->htable[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_INTR_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_free(qlge->htable[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Free intr failed: %d",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_INTR_ALLOC)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_INTR_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_ADD_INTERRUPT)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_ADD_INTERRUPT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->htable) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(qlge->htable, qlge->intr_size);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->htable = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate interrupt vectors
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * For legacy and MSI, only 1 handle is needed.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * For MSI-X, if fewer than 2 vectors are available, return failure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Upon success, this maps the vectors to rx and tx rings for
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * interrupts.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_request_irq_vectors(qlge_t *qlge, int intr_type)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan dev_info_t *devinfo;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t request, orig;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int count, avail, actual;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int minimum;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan devinfo = qlge->dip;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (intr_type) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_FIXED:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request = 1; /* Request 1 legacy interrupt handle */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan minimum = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupt type: legacy\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_MSI:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request = 1; /* Request 1 MSI interrupt handle */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan minimum = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupt type: MSI\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_INTR_TYPE_MSIX:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Ideal number of vectors for the adapter is
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * # rss rings + tx completion rings for default completion
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request = qlge->rx_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan orig = request;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (request > (MAX_RX_RINGS))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request = MAX_RX_RINGS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan minimum = 2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupt type: MSI-X\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Invalid parameter\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupt handles requested: %d minimum: %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request, minimum));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get number of supported interrupts
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_get_nintrs(devinfo, intr_type, &count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((rc != DDI_SUCCESS) || (count < minimum)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Get interrupt number failed. Return: %d, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "count: %d\n", rc, count));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupts supported: %d\n", count));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get number of available interrupts
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_get_navail(devinfo, intr_type, &avail);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((rc != DDI_SUCCESS) || (avail < minimum)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("Get interrupt available number failed. Return:"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " %d, available: %d\n", rc, avail));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("interrupts available: %d\n", avail));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (avail < request) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Request %d handles, %d available\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request, avail));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan request = avail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan actual = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_cnt = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate an array of interrupt handles
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_size = (size_t)(request * sizeof (ddi_intr_handle_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->htable = kmem_alloc(qlge->intr_size, KM_SLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_alloc(devinfo, qlge->htable, intr_type, 0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (int)request, &actual, DDI_INTR_ALLOC_NORMAL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d) Allocate interrupts failed. return:"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " %d, request: %d, actual: %d",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, rc, request, actual);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto ql_intr_alloc_fail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_cnt = actual;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_INTR_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If the actual number of vectors is less than the minumum
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * then fail.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (actual < minimum) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Insufficient interrupt handles available: %d", actual);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto ql_intr_alloc_fail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * For MSI-X, actual might force us to reduce number of tx & rx rings
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((intr_type == DDI_INTR_TYPE_MSIX) && (orig > actual)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (actual >= (orig / 2)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan count = orig / 2;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->isr_stride = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else if (actual >= (orig / 4)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan count = orig / 4;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->isr_stride = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else if (actual >= (orig / 8)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan count = orig / 8;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->isr_stride = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else if (actual < MAX_RX_RINGS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring_count = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rss_ring_count = actual - 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->intr_cnt = count;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rx_ring_count = qlge->tx_ring_count +
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->rss_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_NOTE, "!qlge(%d) tx %d, rss %d, stride %d\n", qlge->instance,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->tx_ring_count, qlge->rss_ring_count, qlge->isr_stride);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get priority for first vector, assume remaining are all the same
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_get_pri(qlge->htable[0], &qlge->intr_pri);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Get interrupt priority failed: %d\n", rc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto ql_intr_alloc_fail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ddi_intr_get_cap(qlge->htable[0], &qlge->intr_cap);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Get interrupt cap failed: %d\n", rc));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto ql_intr_alloc_fail;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_type = intr_type;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_intr_alloc_fail:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_irq_vectors(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate interrupt vector(s) for one of the following interrupt types, MSI-X,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * MSI or Legacy. In MSI and Legacy modes we only support a single receive and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * transmit queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_alloc_irqs(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int intr_types;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get supported interrupt types
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_intr_get_supported_types(qlge->dip, &intr_types)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d):ddi_intr_get_supported_types failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) Interrupt types supported %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, intr_types));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Install MSI-X interrupts */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((intr_types & DDI_INTR_TYPE_MSIX) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) MSI-X interrupt supported %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, intr_types));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_request_irq_vectors(qlge, DDI_INTR_TYPE_MSIX);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval == DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) MSI-X interrupt allocation failed,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " trying MSI interrupts ...\n", __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * We will have 2 completion queues in MSI / Legacy mode,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Queue 0 for default completions
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Queue 1 for transmit completions
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rss_ring_count = 1; /* Default completion queue (0) for all */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring_count = 1; /* Single tx completion queue */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring_count = qlge->tx_ring_count + qlge->rss_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) Falling back to single completion queue \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add the h/w interrupt handler and initialise mutexes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If OS supports MSIX interrupt but fails to allocate, then try
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * MSI interrupt. If MSI interrupt allocation fails also, then roll
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * back to fixed interrupt.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (intr_types & DDI_INTR_TYPE_MSI) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_request_irq_vectors(qlge, DDI_INTR_TYPE_MSI);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval == DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_type = DDI_INTR_TYPE_MSI;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) use MSI Interrupt \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Try Fixed interrupt Legacy mode */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_request_irq_vectors(qlge, DDI_INTR_TYPE_FIXED);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d):Legacy mode interrupt "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "allocation failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->intr_type = DDI_INTR_TYPE_FIXED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d) use Fixed Interrupt \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_free_rx_tx_locks(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&tx_ring->tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&rx_ring->rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&rx_ring->sbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&rx_ring->lbq_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Frees all resources allocated during attach.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Input:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * dip = pointer to device information structure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * sequence = bits indicating resources to free.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Context:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Kernel context.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_free_resources(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable driver timer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_stop_timer(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_MAC_REGISTERED) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) mac_unregister(qlge->mh);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_MAC_REGISTERED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_MAC_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Nothing to do, macp is already freed */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_MAC_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_PCI_CONFIG_SETUP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan pci_config_teardown(&qlge->pci_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_PCI_CONFIG_SETUP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathan if (qlge->sequence & INIT_INTR_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_irq_vectors(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_ADD_INTERRUPT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_ADD_SOFT_INTERRUPT) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_remove_softint(qlge->mpi_event_intr_hdl);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_remove_softint(qlge->mpi_reset_intr_hdl);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_intr_remove_softint(qlge->asic_reset_intr_hdl);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_ADD_SOFT_INTERRUPT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_KSTATS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_fini_kstats(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_KSTATS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_MUTEX) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_destroy(&qlge->mbx_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cv_destroy(&qlge->cv_mbx_intr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_MUTEX;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_LOCKS_CREATED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_rx_tx_locks(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_LOCKS_CREATED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_MEMORY_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_mem_resources(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_MEMORY_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_REGS_SETUP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_regs_map_free(&qlge->dev_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_REGS_SETUP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_DOORBELL_REGS_SETUP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_regs_map_free(&qlge->dev_doorbell_reg_handle);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_DOORBELL_REGS_SETUP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * free flash flt table that allocated in attach stage
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->flt.ql_flt_entry_ptr != NULL)&&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->flt.header.length != 0)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->flt.ql_flt_entry_ptr = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->sequence & INIT_FM) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_fini(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->sequence &= ~INIT_FM;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_prop_remove_all(qlge->dip);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_set_driver_private(qlge->dip, NULL);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* finally, free qlge structure */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_SOFTSTATE_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kmem_free(qlge, sizeof (qlge_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set promiscuous mode of the driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Caller must catch HW_LOCK
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_set_promiscuous(qlge_t *qlge, int mode)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mode) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_set_routing_reg(qlge, RT_IDX_PROMISCUOUS_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_VALID, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_set_routing_reg(qlge, RT_IDX_PROMISCUOUS_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_VALID, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Write 'data1' to Mac Protocol Address Index Register and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 'data2' to Mac Protocol Address Data Register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Assuming that the Mac Protocol semaphore lock has been acquired.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_write_mac_proto_regs(qlge_t *qlge, uint32_t data1, uint32_t data2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int return_value = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_wait_reg_bit(qlge, REG_MAC_PROTOCOL_ADDRESS_INDEX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan MAC_PROTOCOL_ADDRESS_INDEX_MW, BIT_SET, 5) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Wait for MAC_PROTOCOL Address Register "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "timeout.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return_value = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_ADDRESS_INDEX /* A8 */, data1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_DATA /* 0xAC */, data2);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanout:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (return_value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Enable the 'index'ed multicast address in the host memory's multicast_list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_multicast_address(qlge_t *qlge, int index)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rtn_val = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t offset;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value1, value2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Acquire the required semaphore */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_sem_spinlock(qlge, QL_MAC_PROTOCOL_SEM_MASK) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rtn_val);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Program Offset0 - lower 32 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan offset = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value1 = MAC_PROTOCOL_ADDRESS_ENABLE | MAC_PROTOCOL_TYPE_MULTICAST |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (index << 4) | offset;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value2 = ((qlge->multicast_list[index].addr.ether_addr_octet[2] << 24)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[3] << 16)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[4] << 8)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[5]));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_write_mac_proto_regs(qlge, value1, value2) != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Program offset1: upper 16 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan offset = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value1 = MAC_PROTOCOL_ADDRESS_ENABLE | MAC_PROTOCOL_TYPE_MULTICAST |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (index<<4) | offset;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value2 = ((qlge->multicast_list[index].addr.ether_addr_octet[0] << 8)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |qlge->multicast_list[index].addr.ether_addr_octet[1]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_write_mac_proto_regs(qlge, value1, value2) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rtn_val = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanout:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, QL_MAC_PROTOCOL_SEM_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rtn_val);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Disable the 'index'ed multicast address in the host memory's multicast_list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_remove_multicast_address(qlge_t *qlge, int index)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rtn_val = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t offset;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value1, value2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Acquire the required semaphore */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_sem_spinlock(qlge, QL_MAC_PROTOCOL_SEM_MASK) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rtn_val);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Program Offset0 - lower 32 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan offset = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value1 = (MAC_PROTOCOL_TYPE_MULTICAST | offset)|(index<<4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value2 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((qlge->multicast_list[index].addr.ether_addr_octet[2] << 24)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[3] << 16)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[4] << 8)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |(qlge->multicast_list[index].addr.ether_addr_octet[5]));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_write_mac_proto_regs(qlge, value1, value2) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Program offset1: upper 16 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan offset = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value1 = (MAC_PROTOCOL_TYPE_MULTICAST | offset)|(index<<4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value2 = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_write_mac_proto_regs(qlge, value1, value2) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rtn_val = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanout:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, QL_MAC_PROTOCOL_SEM_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rtn_val);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Add a new multicast address to the list of supported list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This API is called after OS called gld_set_multicast (GLDv2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * or m_multicst (GLDv3)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Restriction:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The number of maximum multicast address is limited by hardware.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_add_to_multicast_list(qlge_t *qlge, uint8_t *ep)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t index = qlge->multicast_list_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((ep[0] & 01) == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = EINVAL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if there is an availabe space in multicast_list, then add it */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (index < MAX_MULTICAST_LIST_SIZE) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(ep, qlge->multicast_list[index].addr.ether_addr_octet,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ETHERADDRL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* increment the total number of addresses in multicast list */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_add_multicast_address(qlge, index);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_list_count++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d): added to index of multicast list= 0x%x, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "total %d\n", __func__, qlge->instance, index,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_list_count));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (index > MAX_MULTICAST_HW_SIZE) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!qlge->multicast_promisc) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_ALLMULTI_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_MCAST, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing reg "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "for mcast promisc mode.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ENOENT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_promisc = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ENOENT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Remove an old multicast address from the list of supported multicast
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * addresses. This API is called after OS called gld_set_multicast (GLDv2)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * or m_multicst (GLDv3)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The number of maximum multicast address is limited by hardware.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_remove_from_multicast_list(qlge_t *qlge, uint8_t *ep)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t total = qlge->multicast_list_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rmv_index = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t length = sizeof (ql_multicast_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < total; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (bcmp(ep, &qlge->multicast_list[i].addr, ETHERADDRL) != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan continue;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rmv_index = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* block move the reset of other multicast address forward */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan length = ((total -1) -i) * sizeof (ql_multicast_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (length > 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(&qlge->multicast_list[i+1],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->multicast_list[i], length);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_list_count--;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->multicast_list_count <= MAX_MULTICAST_HW_SIZE) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * there is a deletion in multicast list table,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * re-enable them
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = rmv_index; i < qlge->multicast_list_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan i++) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_add_multicast_address(qlge, i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* and disable the last one */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_remove_multicast_address(qlge, i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* disable multicast promiscuous mode */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->multicast_promisc) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_ALLMULTI_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_MCAST, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing reg for "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "mcast promisc mode.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* write to config register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->multicast_promisc = B_FALSE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Read a XGMAC register
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_read_xgmac_reg(qlge_t *qlge, uint32_t addr, uint32_t *val)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rtn_val = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* wait for XGMAC Address register RDY bit set */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_wait_reg_bit(qlge, REG_XGMAC_ADDRESS, XGMAC_ADDRESS_RDY,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan BIT_SET, 10) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* start rx transaction */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_XGMAC_ADDRESS, addr|XGMAC_ADDRESS_READ_TRANSACT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * wait for XGMAC Address register RDY bit set,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * which indicates data is ready
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_wait_reg_bit(qlge, REG_XGMAC_ADDRESS, XGMAC_ADDRESS_RDY,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan BIT_SET, 10) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto out;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* read data from XGAMC_DATA register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *val = ql_read_reg(qlge, REG_XGMAC_DATA);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rtn_val = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanout:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rtn_val);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Implement checksum offload for IPv4 IP packets
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_hw_csum_setup(qlge_t *qlge, uint32_t pflags, caddr_t bp,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ob_mac_iocb_req *mac_iocb_ptr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ip *iphdr = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ether_header *ethhdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ether_vlan_header *ethvhdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tcphdr *tcp_hdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t etherType;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int mac_hdr_len, ip_hdr_len, tcp_udp_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int ip_hdr_off, tcp_udp_hdr_off, hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ethhdr = (struct ether_header *)((void *)bp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ethvhdr = (struct ether_vlan_header *)((void *)bp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Is this vlan packet? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ntohs(ethvhdr->ether_tpid) == ETHERTYPE_VLAN) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_vlan_header);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan etherType = ntohs(ethvhdr->ether_type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_header);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan etherType = ntohs(ethhdr->ether_type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Is this IPv4 or IPv6 packet? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (IPH_HDR_VERSION((ipha_t *)(void *)(bp+mac_hdr_len)) ==
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan IPV4_VERSION) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (etherType == ETHERTYPE_IP /* 0800 */) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr = (struct ip *)(void *)(bp+mac_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d) : IPv4 None IP packet type 0x%x\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, etherType));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* ipV4 packets */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (iphdr != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ip_hdr_len = IPH_HDR_LENGTH(iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d) : IPv4 header length using IPH_HDR_LENGTH:"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " %d bytes \n", __func__, qlge->instance, ip_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ip_hdr_off = mac_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : ip_hdr_len=%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, ip_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag0 = (uint8_t)(mac_iocb_ptr->flag0 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_IPv4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (pflags & HCK_IPV4_HDRCKSUM) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : Do IPv4 header checksum\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode = OPCODE_OB_MAC_OFFLOAD_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag2 = (uint8_t)(mac_iocb_ptr->flag2 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_IC);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr->ip_sum = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->hdr_off = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(ip_hdr_off);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (pflags & HCK_FULLCKSUM) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (iphdr->ip_p == IPPROTO_TCP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_hdr =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (struct tcphdr *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)iphdr + ip_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : Do TCP checksum\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OPCODE_OB_MAC_OFFLOAD_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag1 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag1 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_TC);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag2 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag2 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_IC);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr->ip_sum = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off = mac_hdr_len+ip_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len = tcp_hdr->th_off*4;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d): tcp header len:%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, tcp_udp_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off = ip_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off <<= 6;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off |= tcp_udp_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)cpu_to_le16(hdr_off);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->protocol_hdr_len = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(mac_hdr_len + ip_hdr_len +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if the chip is unable to do pseudo header
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * cksum calculation, do it in then put the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * result to the data passed to the chip
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->cfg_flags &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CFG_HW_UNABLE_PSEUDO_HDR_CKSUM) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_pseudo_cksum((uint8_t *)iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (iphdr->ip_p == IPPROTO_UDP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : Do UDP checksum\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OPCODE_OB_MAC_OFFLOAD_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag1 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag1 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_UC);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag2 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag2 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_IC);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr->ip_sum = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off = mac_hdr_len + ip_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len = sizeof (struct udphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d):udp header len:%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, tcp_udp_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off = ip_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off <<= 6;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off |= tcp_udp_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)cpu_to_le16(hdr_off);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->protocol_hdr_len = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(mac_hdr_len + ip_hdr_len
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + tcp_udp_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if the chip is unable to calculate pseudo
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * hdr cksum,do it in then put the result to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the data passed to the chip
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->cfg_flags &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CFG_HW_UNABLE_PSEUDO_HDR_CKSUM) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_pseudo_cksum((uint8_t *)iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * For TSO/LSO:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * MAC frame transmission with TCP large segment offload is performed in the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * same way as the MAC frame transmission with checksum offload with the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * exception that the maximum TCP segment size (MSS) must be specified to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * allow the chip to segment the data into legal sized frames.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The host also needs to calculate a pseudo-header checksum over the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * following fields:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Source IP Address, Destination IP Address, and the Protocol.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The TCP length is not included in the pseudo-header calculation.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The pseudo-header checksum is place in the TCP checksum field of the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * prototype header.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_lso_pseudo_cksum(uint8_t *buf)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t cksum;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t iphl;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t proto;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Calculate the LSO pseudo-header checksum.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphl = (uint16_t)(4 * (buf[0] & 0xF));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = proto = buf[9];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[12])<<8) + buf[13];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[14])<<8) + buf[15];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[16])<<8) + buf[17];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum += (((uint16_t)buf[18])<<8) + buf[19];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = (cksum>>16) + (cksum & 0xFFFF);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cksum = (cksum>>16) + (cksum & 0xFFFF);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Point it to the TCP/UDP header, and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * update the checksum field.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan buf += iphl + ((proto == IPPROTO_TCP) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan TCP_CKSUM_OFFSET : UDP_CKSUM_OFFSET);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *(uint16_t *)(void *)buf = (uint16_t)htons((uint16_t)cksum);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * For IPv4 IP packets, distribute the tx packets evenly among tx rings
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathantypedef uint32_t ub4; /* unsigned 4-byte quantities */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathantypedef uint8_t ub1;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#define hashsize(n) ((ub4)1<<(n))
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#define hashmask(n) (hashsize(n)-1)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#define mix(a, b, c) \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{ \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan a -= b; a -= c; a ^= (c>>13); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan b -= c; b -= a; b ^= (a<<8); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c -= a; c -= b; c ^= (b>>13); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan a -= b; a -= c; a ^= (c>>12); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan b -= c; b -= a; b ^= (a<<16); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c -= a; c -= b; c ^= (b>>5); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan a -= b; a -= c; a ^= (c>>3); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan b -= c; b -= a; b ^= (a<<10); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c -= a; c -= b; c ^= (b>>15); \
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanub4
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanhash(k, length, initval)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanregister ub1 *k; /* the key */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanregister ub4 length; /* the length of the key */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanregister ub4 initval; /* the previous hash, or an arbitrary value */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan register ub4 a, b, c, len;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Set up the internal state */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan len = length;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c = initval; /* the previous hash value */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* handle most of the key */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan while (len >= 12) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mix(a, b, c);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan k += 12;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan len -= 12;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* handle the last 11 bytes */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan c += length;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* all the case statements fall through */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan switch (len) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 11: c += ((ub4)k[10]<<24);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 10: c += ((ub4)k[9]<<16);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 9 : c += ((ub4)k[8]<<8);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* the first byte of c is reserved for the length */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 8 : b += ((ub4)k[7]<<24);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 7 : b += ((ub4)k[6]<<16);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 6 : b += ((ub4)k[5]<<8);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 5 : b += k[4];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 4 : a += ((ub4)k[3]<<24);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 3 : a += ((ub4)k[2]<<16);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 2 : a += ((ub4)k[1]<<8);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* FALLTHRU */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan case 1 : a += k[0];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* case 0: nothing left to add */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mix(a, b, c);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* report the result */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (c);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanuint8_t
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_tx_hashing(qlge_t *qlge, caddr_t bp)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct ip *iphdr = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct ether_header *ethhdr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct ether_vlan_header *ethvhdr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct tcphdr *tcp_hdr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct udphdr *udp_hdr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t etherType;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan int mac_hdr_len, ip_hdr_len;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t h = 0; /* 0 by default */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint8_t tx_ring_id = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t ip_src_addr = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t ip_desc_addr = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint16_t src_port = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint16_t dest_port = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint8_t key[12];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) entered \n", __func__, qlge->instance));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ethhdr = (struct ether_header *)((void *)bp);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ethvhdr = (struct ether_vlan_header *)((void *)bp);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->tx_ring_count == 1)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (tx_ring_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Is this vlan packet? */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ntohs(ethvhdr->ether_tpid) == ETHERTYPE_VLAN) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_vlan_header);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan etherType = ntohs(ethvhdr->ether_type);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_header);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan etherType = ntohs(ethhdr->ether_type);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Is this IPv4 or IPv6 packet? */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (etherType == ETHERTYPE_IP /* 0800 */) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (IPH_HDR_VERSION((ipha_t *)(void *)(bp+mac_hdr_len))
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan == IPV4_VERSION) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan iphdr = (struct ip *)(void *)(bp+mac_hdr_len);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (((unsigned long)iphdr) & 0x3) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* IP hdr not 4-byte aligned */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (tx_ring_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* ipV4 packets */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (iphdr) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ip_hdr_len = IPH_HDR_LENGTH(iphdr);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ip_src_addr = iphdr->ip_src.s_addr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ip_desc_addr = iphdr->ip_dst.s_addr;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (iphdr->ip_p == IPPROTO_TCP) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan tcp_hdr = (struct tcphdr *)(void *)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ((uint8_t *)iphdr + ip_hdr_len);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan src_port = tcp_hdr->th_sport;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dest_port = tcp_hdr->th_dport;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan } else if (iphdr->ip_p == IPPROTO_UDP) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan udp_hdr = (struct udphdr *)(void *)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ((uint8_t *)iphdr + ip_hdr_len);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan src_port = udp_hdr->uh_sport;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dest_port = udp_hdr->uh_dport;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[0] = (uint8_t)((ip_src_addr) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[1] = (uint8_t)((ip_src_addr >> 8) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[2] = (uint8_t)((ip_src_addr >> 16) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[3] = (uint8_t)((ip_src_addr >> 24) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[4] = (uint8_t)((ip_desc_addr) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[5] = (uint8_t)((ip_desc_addr >> 8) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[6] = (uint8_t)((ip_desc_addr >> 16) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[7] = (uint8_t)((ip_desc_addr >> 24) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[8] = (uint8_t)((src_port) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[9] = (uint8_t)((src_port >> 8) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[10] = (uint8_t)((dest_port) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan key[11] = (uint8_t)((dest_port >> 8) &0xFF);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan h = hash(key, 12, 0); /* return 32 bit */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan tx_ring_id = (h & (qlge->tx_ring_count - 1));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (tx_ring_id >= qlge->tx_ring_count) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "%s bad tx_ring_id %d\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan __func__, tx_ring_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan tx_ring_id = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (tx_ring_id);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Tell the hardware to do Large Send Offload (LSO)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Some fields in ob_mac_iocb need to be set so hardware can know what is
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the incoming packet, TCP or UDP, whether a VLAN tag needs to be inserted
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * in the right place of the packet etc, thus, hardware can process the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * packet correctly.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_hw_lso_setup(qlge_t *qlge, uint32_t mss, caddr_t bp,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ob_mac_iocb_req *mac_iocb_ptr)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ip *iphdr = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ether_header *ethhdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ether_vlan_header *ethvhdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tcphdr *tcp_hdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct udphdr *udp_hdr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t etherType;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t mac_hdr_len, ip_hdr_len, tcp_udp_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t ip_hdr_off, tcp_udp_hdr_off, hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ethhdr = (struct ether_header *)(void *)bp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ethvhdr = (struct ether_vlan_header *)(void *)bp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Is this vlan packet? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ntohs(ethvhdr->ether_tpid) == ETHERTYPE_VLAN) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_vlan_header);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan etherType = ntohs(ethvhdr->ether_type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_hdr_len = sizeof (struct ether_header);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan etherType = ntohs(ethhdr->ether_type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Is this IPv4 or IPv6 packet? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (IPH_HDR_VERSION((ipha_t *)(void *)(bp + mac_hdr_len)) ==
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan IPV4_VERSION) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (etherType == ETHERTYPE_IP /* 0800 */) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr = (struct ip *)(void *)(bp+mac_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* EMPTY */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : IPv4 None IP packet"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " type 0x%x\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, etherType));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (iphdr != NULL) { /* ipV4 packets */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ip_hdr_len = (uint16_t)IPH_HDR_LENGTH(iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d) : IPv4 header length using IPH_HDR_LENGTH: %d"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " bytes \n", __func__, qlge->instance, ip_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ip_hdr_off = mac_hdr_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : ip_hdr_len=%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, ip_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag0 = (uint8_t)(mac_iocb_ptr->flag0 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_IPv4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->cfg_flags & CFG_CKSUM_FULL_IPv4) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (iphdr->ip_p == IPPROTO_TCP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_hdr = (struct tcphdr *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)iphdr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ip_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : Do TSO on TCP "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "packet\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OPCODE_OB_MAC_OFFLOAD_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag1 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag1 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_LSO);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr->ip_sum = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)(mac_hdr_len+ip_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)(tcp_hdr->th_off*4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d): tcp header len:%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, tcp_udp_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off = ip_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off <<= 6;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off |= tcp_udp_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)cpu_to_le16(hdr_off);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->protocol_hdr_len = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(mac_hdr_len + ip_hdr_len +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->mss = (uint16_t)cpu_to_le16(mss);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if the chip is unable to calculate pseudo
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * header checksum, do it in then put the result
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to the data passed to the chip
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->cfg_flags &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CFG_HW_UNABLE_PSEUDO_HDR_CKSUM)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_lso_pseudo_cksum((uint8_t *)iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (iphdr->ip_p == IPPROTO_UDP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan udp_hdr = (struct udphdr *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)iphdr
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + ip_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) : Do TSO on UDP "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "packet\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OPCODE_OB_MAC_OFFLOAD_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->flag1 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t)(mac_iocb_ptr->flag1 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan OB_MAC_IOCB_REQ_LSO);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan iphdr->ip_sum = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)(mac_hdr_len+ip_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)(udp_hdr->uh_ulen*4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d):udp header len:%d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, tcp_udp_hdr_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off = ip_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_off <<= 6;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hdr_off |= tcp_udp_hdr_off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->hdr_off =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)cpu_to_le16(hdr_off);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->protocol_hdr_len = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(mac_hdr_len + ip_hdr_len +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tcp_udp_hdr_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->mss = (uint16_t)cpu_to_le16(mss);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if the chip is unable to do pseudo header
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * checksum calculation, do it here then put the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * result to the data passed to the chip
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->cfg_flags &
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CFG_HW_UNABLE_PSEUDO_HDR_CKSUM)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_lso_pseudo_cksum((uint8_t *)iphdr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Generic packet sending function which is used to send one packet.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_send_common(struct tx_ring *tx_ring, mblk_t *mp)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_cb;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ob_mac_iocb_req *mac_iocb_ptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *tp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t msg_len = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan caddr_t bp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t nbyte, total_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint_t i = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int j = 0, frags = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t phy_addr_low, phy_addr_high;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t phys_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan clock_t now;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t pflags = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t mss = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan enum tx_mode_t tx_mode;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct oal_entry *oal_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint_t ncookies, oal_entries, max_oal_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t max_seg_len = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan boolean_t use_lso = B_FALSE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct oal_entry *tx_entry = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct oal_entry *last_oal_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge = tx_ring->qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_cookie_t dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size_t tx_buf_len = QL_MAX_COPY_LENGTH;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int force_pullup = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tp = mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan total_len = msg_len = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan max_oal_entries = TX_DESC_PER_IOCB + MAX_SG_ELEMENTS-1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Calculate number of data and segments in the incoming message */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (tp = mp; tp != NULL; tp = tp->b_cont) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan nbyte = MBLKL(tp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan total_len += nbyte;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan max_seg_len = max(nbyte, max_seg_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("Requested sending data in %d segments, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "total length: %d\n", frags, nbyte));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan frags++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (total_len >= QL_LSO_MAX) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "%s: quit, packet oversize %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, (int)total_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bp = (caddr_t)mp->b_rptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (bp[0] & 1) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (bcmp(bp, ql_ether_broadcast_addr.ether_addr_octet,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ETHERADDRL) == 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("Broadcast packet\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->brdcstxmt++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("multicast packet\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->multixmt++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->obytes += total_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->opackets ++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("total requested sending data length: %d, in %d segs,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " max seg len: %d\n", total_len, frags, max_seg_len));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* claim a free slot in tx ring */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb = &tx_ring->wq_desc[tx_ring->prod_idx];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* get the tx descriptor */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr = tx_cb->queue_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan bzero((void *)mac_iocb_ptr, 20);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(tx_cb->mp == NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Decide to use DMA map or copy mode.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * DMA map mode must be used when the total msg length is more than the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * tx buffer length.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (total_len > tx_buf_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_mode = USE_DMA;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else if (max_seg_len > QL_MAX_COPY_LENGTH)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_mode = USE_DMA;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_mode = USE_COPY;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->chksum_cap) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_hcksum_get(mp, NULL, NULL, NULL, NULL, &pflags);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("checksum flag is :0x%x, card capability "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "is 0x%x \n", pflags, qlge->chksum_cap));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->lso_enable) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t lso_flags = 0;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer mac_lso_get(mp, &mss, &lso_flags);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan use_lso = (lso_flags == HW_LSO);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("mss :%d, use_lso %x \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mss, use_lso));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathando_pullup:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* concatenate all frags into one large packet if too fragmented */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (((tx_mode == USE_DMA)&&(frags > QL_MAX_TX_DMA_HANDLES)) ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_pullup) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mblk_t *mp1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((mp1 = msgpullup(mp, -1)) != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = mp1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan frags = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->tx_fail_dma_bind++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto bad;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_bytes = (uint32_t)total_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->mp = mp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_dma_handle_used = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_mode == USE_DMA) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan msg_len = total_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->tid = tx_ring->prod_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->frame_len = (uint32_t)cpu_to_le32(msg_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->txq_idx = tx_ring->wq_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry = &mac_iocb_ptr->oal_entry[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan oal_entry = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (tp = mp, oal_entries = j = 0; tp != NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tp = tp->b_cont) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if too many tx dma handles needed */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= QL_MAX_TX_DMA_HANDLES) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->tx_no_dma_handle++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!force_pullup) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_pullup = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto do_pullup;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto bad;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan nbyte = (uint16_t)MBLKL(tp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (nbyte == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan continue;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ddi_dma_addr_bind_handle(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_dma_handle[j], NULL,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t)tp->b_rptr, nbyte,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_DONTWAIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0, &dma_cookie, &ncookies);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("map sending data segment: %d, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "length: %d, spans in %d cookies\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j, nbyte, ncookies));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status != DDI_DMA_MAPPED) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto bad;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Each fragment can span several cookies. One cookie
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * will use one tx descriptor to transmit.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = ncookies; i > 0; i--, tx_entry++,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan oal_entries++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The number of TX descriptors that can be
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * saved in tx iocb and oal list is limited
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (oal_entries > max_oal_entries) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->tx_no_dma_cookie++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!force_pullup) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan force_pullup = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto do_pullup;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto bad;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((oal_entries == TX_DESC_PER_IOCB) &&
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan !oal_entry) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Time to switch to an oal list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The last entry should be copied
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to first entry in the oal list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan oal_entry = tx_cb->oal;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &mac_iocb_ptr->oal_entry[
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan TX_DESC_PER_IOCB-1];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(tx_entry, oal_entry,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (*oal_entry));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * last entry should be updated to
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * point to the extended oal list itself
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_addr_low =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan LS_64BITS(tx_cb->oal_dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_addr_high =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan MS_64BITS(tx_cb->oal_dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Point tx_entry to the oal list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * second entry
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry = &oal_entry[1];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_len =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint32_t)cpu_to_le32(dma_cookie.dmac_size);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan phys_addr = dma_cookie.dmac_laddress;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_addr_low =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(phys_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_addr_high =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(phys_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan last_oal_entry = tx_entry;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (i > 1)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_dma_nextcookie(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_dma_handle[j],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &dma_cookie);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if OAL is used, the last oal entry in tx iocb indicates
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * number of additional address/len pairs in OAL
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (oal_entries > TX_DESC_PER_IOCB) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry = &mac_iocb_ptr->oal_entry[TX_DESC_PER_IOCB-1];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_entry->buf_len = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (cpu_to_le32((sizeof (struct oal_entry) *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (oal_entries -TX_DESC_PER_IOCB+1))|OAL_CONT_ENTRY));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan last_oal_entry->buf_len = cpu_to_le32(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan le32_to_cpu(last_oal_entry->buf_len)|OAL_LAST_ENTRY);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_dma_handle_used = j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("total tx_dma_handle_used %d cookies %d \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j, oal_entries));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bp = (caddr_t)mp->b_rptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_mode == USE_COPY) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bp = tx_cb->copy_buffer;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan off = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan nbyte = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan frags = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Copy up to tx_buf_len of the transmit data
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * from mp to tx buffer
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (tp = mp; tp != NULL; tp = tp->b_cont) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan nbyte = MBLKL(tp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((off + nbyte) <= tx_buf_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bcopy(tp->b_rptr, &bp[off], nbyte);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan off += nbyte;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan frags ++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan msg_len = off;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->opcode = OPCODE_OB_MAC_IOCB;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->tid = tx_ring->prod_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->frame_len = (uint32_t)cpu_to_le32(msg_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->txq_idx = tx_ring->wq_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("Copy Mode:actual sent data length is: %d, "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "from %d segaments\n", msg_len, frags));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan phys_addr = tx_cb->copy_buffer_dma_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan phy_addr_low = cpu_to_le32(LS_64BITS(phys_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan phy_addr_high = cpu_to_le32(MS_64BITS(phys_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP(DBG_TX, "\t requested sending data:\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)tx_cb->copy_buffer, 8, total_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->oal_entry[0].buf_len = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(msg_len | OAL_LAST_ENTRY);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->oal_entry[0].buf_addr_low = phy_addr_low;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_iocb_ptr->oal_entry[0].buf_addr_high = phy_addr_high;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp); /* no need, we have copied */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } /* End of Copy Mode */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Do TSO/LSO on TCP packet? */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (use_lso && mss) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_hw_lso_setup(qlge, mss, bp, mac_iocb_ptr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else if (pflags & qlge->chksum_cap) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Do checksum offloading */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_hw_csum_setup(qlge, pflags, bp, mac_iocb_ptr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* let device know the latest outbound IOCB */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_sync(tx_ring->wq_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (off_t)((uintptr_t)mac_iocb_ptr - (uintptr_t)tx_ring->wq_dma.vaddr),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (size_t)sizeof (*mac_iocb_ptr), DDI_DMA_SYNC_FORDEV);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_mode == USE_DMA) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* let device know the latest outbound OAL if necessary */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (oal_entries > TX_DESC_PER_IOCB) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_sync(tx_cb->oal_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (off_t)0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (sizeof (struct oal_entry) *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (oal_entries -TX_DESC_PER_IOCB+1)),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_DMA_SYNC_FORDEV);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else { /* for USE_COPY mode, tx buffer has changed */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* let device know the latest change */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_sync(tx_cb->oal_dma.dma_handle,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* copy buf offset */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (off_t)(sizeof (oal_entry) * MAX_SG_ELEMENTS),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan msg_len, DDI_DMA_SYNC_FORDEV);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* save how the packet was sent */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_cb->tx_type = tx_mode;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_DUMP_REQ_PKT(qlge, mac_iocb_ptr, tx_cb->oal, oal_entries);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* reduce the number of available tx slot */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_dec_32(&tx_ring->tx_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->prod_idx >= tx_ring->wq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan now = ddi_get_lbolt();
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->last_tx_time = now;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanbad:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * if for any reason driver can not send, delete
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the message pointer, mp
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan now = ddi_get_lbolt();
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mp = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan tx_cb->mp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < j; i++)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_unbind_handle(tx_cb->tx_dma_handle[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_TX, ("%s(%d) failed at 0x%x",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, (int)now));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initializes hardware and driver software flags before the driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * is finally ready to work.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_do_start(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rings_done;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(qlge != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Reset adapter */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_asic_reset(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_buf_size = (uint16_t)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ((qlge->mtu == ETHERMTU)? LRG_BUF_NORMAL_SIZE : LRG_BUF_JUMBO_SIZE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[0].lbq_buf_size != lbq_buf_size) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "realloc buffers old: %d new: %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[0].lbq_buf_size, lbq_buf_size);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Check if any ring has buffers still with upper layers
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If buffers are pending with upper layers, we use the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * existing buffers and don't reallocate new ones
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Unfortunately there is no way to evict buffers from
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * upper layers. Using buffers with the current size may
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * cause slightly sub-optimal performance, but that seems
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to be the easiest way to handle this situation.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rings_done = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->rx_indicate == 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rings_done++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * No buffers pending with upper layers;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * reallocte them for new MTU size
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rings_done >= qlge->rx_ring_count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* free large buffer pool */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_sbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_lbq_buffers(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* reallocate large buffer pool */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type != TX_Q) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_alloc_sbufs(qlge, rx_ring);
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_alloc_lbufs(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_bringup_adapter(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "qlge bringup adapter failed");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_or_32(&qlge->flags, ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if adapter is up successfully but was bad before */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->flags & ADAPTER_ERROR) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan atomic_and_32(&qlge->flags, ~ADAPTER_ERROR);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip, DDI_SERVICE_RESTORED);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get current link state */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->port_link_state = ql_get_link_state(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->port_link_state == LS_UP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d) Link UP !!\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* If driver detects a carrier on */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CARRIER_ON(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d) Link down\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* If driver detects a lack of carrier */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CARRIER_OFF(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_STARTED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Stop currently running driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Driver needs to stop routing new packets to driver and wait until
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * all pending tx/rx buffers to be free-ed.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_do_stop(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rc = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t i, j, k;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc, *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(qlge != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CARRIER_OFF(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = ql_bringdown_adapter(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rc != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "qlge bringdown adapter failed.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rc = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (k = 0; k < qlge->rx_ring_count; k++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[k];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = rx_ring->lbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "ring %d: move %d lbufs in use list"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " to free list %d\n total %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan k, rx_ring->lbuf_in_use_count,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free_count,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use_count +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->lbuf_in_use_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = rx_ring->lbuf_in_use[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->lbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc->mp) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(lbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_use_head = j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_use_tail = j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbuf_in_use_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = rx_ring->sbq_use_head;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "ring %d: move %d sbufs in use list,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " to free list %d\n total %d \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan k, rx_ring->sbuf_in_use_count,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free_count,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use_count +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_free_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < rx_ring->sbuf_in_use_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = rx_ring->sbuf_in_use[j];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (j >= rx_ring->sbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan j = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc->mp) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan atomic_inc_32(&rx_ring->rx_indicate);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan freemsg(sbq_desc->mp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_use_head = j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_use_tail = j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbuf_in_use_count = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_STOPPED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Support
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_disable_isr(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * disable the hardware interrupt
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ISP_DISABLE_GLOBAL_INTRS(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->flags &= ~INTERRUPTS_ENABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * busy wait for 'usecs' microseconds.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanqlge_delay(clock_t usecs)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan drv_usecwait(usecs);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * retrieve firmware details.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanpci_cfg_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_pci_config(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (&(qlge->pci_cfg));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get current Link status
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic uint32_t
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_link_state(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t bitToCheck = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp, linkState;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->func_number == qlge->fn0_net) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bitToCheck = STS_PL0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bitToCheck = STS_PL1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d) chip status reg: 0x%x\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, temp));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (temp & bitToCheck) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan linkState = LS_UP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan linkState = LS_DOWN;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (CFG_IST(qlge, CFG_CHIP_8100)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* for Schultz, link Speed is fixed to 10G, full duplex */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->speed = SPEED_10G;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->duplex = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (linkState);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get current link status and report to OS
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_get_and_report_link_state(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t cur_link_state;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Get current link state */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cur_link_state = ql_get_link_state(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if link state has changed */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (cur_link_state != qlge->port_link_state) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->port_link_state = cur_link_state;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->port_link_state == LS_UP) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d) Link UP !!\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* If driver detects a carrier on */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CARRIER_ON(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d) Link down\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* If driver detects a lack of carrier */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CARRIER_OFF(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * timer callback function executed after timer expires
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_timer(void* arg)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_get_and_report_link_state((qlge_t *)arg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * stop the running timer if activated
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_stop_timer(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan timeout_id_t timer_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable driver timer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ql_timer_timeout_id != NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan timer_id = qlge->ql_timer_timeout_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_timer_timeout_id = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) untimeout(timer_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * stop then restart timer
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_restart_timer(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_stop_timer(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_timer_ticks = TICKS_PER_SEC / 4;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_timer_timeout_id = timeout(ql_timer,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void *)qlge, qlge->ql_timer_ticks);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ************************************************************************* */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Hardware K-Stats Data Structures and Subroutines
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ************************************************************************* */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic const ql_ksindex_t ql_kstats_hw[] = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI related hardware information */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 0, "Vendor Id" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 1, "Device Id" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 2, "Command" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 3, "Status" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 4, "Revision Id" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 5, "Cache Line Size" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 6, "Latency Timer" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 7, "Header Type" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 9, "I/O base addr" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 10, "Control Reg Base addr low" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 11, "Control Reg Base addr high" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 12, "Doorbell Reg Base addr low" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 13, "Doorbell Reg Base addr high" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 14, "Subsystem Vendor Id" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 15, "Subsystem Device ID" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 16, "PCIe Device Control" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 17, "PCIe Link Status" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { -1, NULL },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * kstat update function for PCI registers
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_kstats_get_pci_regs(kstat_t *ksp, int flag)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_named_t *knp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (flag != KSTAT_READ)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (EACCES);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge = ksp->ks_private;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan knp = ksp->ks_data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.vendor_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.device_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.command;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.revision;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.cache_line_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.latency_timer;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.header_type;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.io_base_address;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_lower;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pci_cfg.pci_cntl_reg_set_mem_base_address_upper;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pci_cfg.pci_doorbell_mem_base_address_lower;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->pci_cfg.pci_doorbell_mem_base_address_upper;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.sub_vendor_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.sub_device_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.pcie_device_control;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->pci_cfg.link_status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic const ql_ksindex_t ql_kstats_mii[] = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* MAC/MII related hardware information */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 0, "mtu"},
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { -1, NULL},
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * kstat update function for MII related information.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_kstats_mii_update(kstat_t *ksp, int flag)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_named_t *knp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (flag != KSTAT_READ)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (EACCES);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge = ksp->ks_private;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan knp = ksp->ks_data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->mtu;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic const ql_ksindex_t ql_kstats_reg[] = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Register information */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 0, "System (0x08)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 1, "Reset/Fail Over(0x0Ch" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 2, "Function Specific Control(0x10)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 3, "Status (0x30)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 4, "Intr Enable (0x34)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 5, "Intr Status1 (0x3C)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 6, "Error Status (0x54)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 7, "XGMAC Flow Control(0x11C)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 8, "XGMAC Tx Pause Frames(0x230)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 9, "XGMAC Rx Pause Frames(0x388)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 10, "XGMAC Rx FIFO Drop Count(0x5B8)" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 11, "interrupts actually allocated" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 12, "interrupts on rx ring 0" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 13, "interrupts on rx ring 1" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 14, "interrupts on rx ring 2" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 15, "interrupts on rx ring 3" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 16, "interrupts on rx ring 4" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 17, "interrupts on rx ring 5" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 18, "interrupts on rx ring 6" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 19, "interrupts on rx ring 7" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 20, "polls on rx ring 0" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 21, "polls on rx ring 1" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 22, "polls on rx ring 2" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 23, "polls on rx ring 3" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 24, "polls on rx ring 4" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 25, "polls on rx ring 5" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 26, "polls on rx ring 6" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 27, "polls on rx ring 7" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 28, "tx no resource on ring 0" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 29, "tx dma bind fail on ring 0" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 30, "tx dma no handle on ring 0" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { 31, "tx dma no cookie on ring 0" },
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan { 32, "MPI firmware major version" },
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan { 33, "MPI firmware minor version" },
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan { 34, "MPI firmware sub version" },
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan { 35, "rx no resource" },
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan { -1, NULL},
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * kstat update function for device register set
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_kstats_get_reg_and_dev_stats(kstat_t *ksp, int flag)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_named_t *knp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t val32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (flag != KSTAT_READ)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (EACCES);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge = ksp->ks_private;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan knp = ksp->ks_data;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_SYSTEM);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_RESET_FAILOVER);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_FUNCTION_SPECIFIC_CONTROL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_INTERRUPT_ENABLE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_INTERRUPT_STATUS_1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = ql_read_reg(qlge, REG_ERROR_STATUS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_sem_spinlock(qlge, qlge->xgmac_sem_mask)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_read_xgmac_reg(qlge, REG_XGMAC_FLOW_CONTROL, &val32);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = val32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_read_xgmac_reg(qlge, REG_XGMAC_MAC_TX_PAUSE_PKTS, &val32);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = val32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_read_xgmac_reg(qlge, REG_XGMAC_MAC_RX_PAUSE_PKTS, &val32);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = val32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_read_xgmac_reg(qlge, REG_XGMAC_MAC_RX_FIFO_DROPS, &val32);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = val32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, qlge->xgmac_sem_mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->intr_cnt;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < 8; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->rx_interrupts[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < 8; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->rx_polls[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[0];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = tx_ring->defer;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = tx_ring->tx_fail_dma_bind;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = tx_ring->tx_no_dma_handle;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = tx_ring->tx_no_dma_cookie;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->fw_version_info.major_version;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->fw_version_info.minor_version;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (knp++)->value.ui32 = qlge->fw_version_info.sub_minor_version;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan val32 += rx_ring->rx_packets_dropped_no_buffer;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (knp++)->value.ui32 = val32;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic kstat_t *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_setup_named_kstat(qlge_t *qlge, int instance, char *name,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan const ql_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_t *ksp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_named_t *knp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan char *np;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int type;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan size /= sizeof (ql_ksindex_t);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ksp = kstat_create(ADAPTER_NAME, instance, name, "net",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan KSTAT_TYPE_NAMED, ((uint32_t)size) - 1, KSTAT_FLAG_PERSISTENT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ksp == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ksp->ks_private = qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ksp->ks_update = update;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (*np) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan type = KSTAT_DATA_UINT32;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case '&':
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan np += 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan type = KSTAT_DATA_CHAR;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_named_init(knp, np, (uint8_t)type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_install(ksp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (ksp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Setup various kstat
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_kstats(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Hardware KStats */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_kstats[QL_KSTAT_CHIP] = ql_setup_named_kstat(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->instance, "chip", ql_kstats_hw,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (ql_kstats_hw), ql_kstats_get_pci_regs);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ql_kstats[QL_KSTAT_CHIP] == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* MII KStats */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_kstats[QL_KSTAT_LINK] = ql_setup_named_kstat(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->instance, "mii", ql_kstats_mii,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (ql_kstats_mii), ql_kstats_mii_update);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ql_kstats[QL_KSTAT_LINK] == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* REG KStats */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->ql_kstats[QL_KSTAT_REG] = ql_setup_named_kstat(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->instance, "reg", ql_kstats_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (ql_kstats_reg), ql_kstats_get_reg_and_dev_stats);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ql_kstats[QL_KSTAT_REG] == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * delete all kstat
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanvoid
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_fini_kstats(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < QL_KSTAT_COUNT; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->ql_kstats[i] != NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan kstat_delete(qlge->ql_kstats[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ************************************************************************* */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * kstat end
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* ************************************************************************* */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Setup the parameters for receive and transmit rings including buffer sizes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * and completion queue sizes
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_setup_rings(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint8_t i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_buf_size = (uint16_t)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ((qlge->mtu == ETHERMTU)? LRG_BUF_NORMAL_SIZE : LRG_BUF_JUMBO_SIZE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * rx_ring[0] is always the default queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * qlge->rx_ring_count:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Total number of rx_rings. This includes a number
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * of outbound completion handler rx_rings, and a
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * number of inbound completion handler rx_rings.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * rss is only enabled if we have more than 1 rx completion
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * queue. If we have a single rx completion queue
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * then all rx completions go to this queue and
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the last completion queue
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring_first_cq_id = qlge->rss_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero((void *)tx_ring, sizeof (*tx_ring));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->qlge = qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_id = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_len = qlge->tx_ring_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_size = (uint32_t)(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_len * sizeof (struct ob_mac_iocb_req));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The completion queue ID for the tx rings start
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * immediately after the last rss completion queue.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->cq_id = (uint16_t)(i + qlge->tx_ring_first_cq_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero((void *)rx_ring, sizeof (*rx_ring));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->qlge = qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id = i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (i != 0)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cpu = (i) % qlge->rx_ring_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cpu = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (i < qlge->rss_ring_count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Inbound completions (RSS) queues
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Default queue is queue 0 which handles
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * unicast plus bcast/mcast and async events.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Other inbound queues handle unicast frames only.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_len = qlge->rx_ring_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_size = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_len * sizeof (struct net_rsp_iocb));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_len = NUM_LARGE_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_size = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->lbq_len * sizeof (uint64_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size = lbq_buf_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_len = NUM_SMALL_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_size = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->sbq_len * sizeof (uint64_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->type = RX_Q;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d)Allocating rss completion queue %d "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "on cpu %d\n", __func__, qlge->instance,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id, rx_ring->cpu));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Outbound queue handles outbound completions only
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* outbound cq is same size as tx_ring it services. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("rx_ring 0x%p i %d\n", rx_ring, i));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_len = qlge->tx_ring_size;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_size = (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_len * sizeof (struct net_rsp_iocb));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_len = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_size = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_buf_size = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_len = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_size = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_buf_size = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->type = TX_Q;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s(%d)Allocating TX completion queue %d on"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " cpu %d\n", __func__, qlge->instance,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id, rx_ring->cpu));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_start_rx_ring(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct cqicb_t *cqicb = (struct cqicb_t *)rx_ring->cqicb_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan void *shadow_reg = (uint8_t *)qlge->host_copy_shadow_dma_attr.vaddr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_id * sizeof (uint64_t) * RX_TX_RING_SHADOW_SPACE)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* first shadow area is used by wqicb's host copy of consumer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + sizeof (uint64_t);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t shadow_reg_dma = qlge->host_copy_shadow_dma_attr.dma_addr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_id * sizeof (uint64_t) * RX_TX_RING_SHADOW_SPACE)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan + sizeof (uint64_t);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* lrg/sml bufq pointers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint8_t *buf_q_base_reg =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint8_t *)qlge->buf_q_ptr_base_addr_dma_attr.vaddr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_id * sizeof (uint64_t) * BUF_Q_PTR_SPACE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t buf_q_base_reg_dma =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->buf_q_ptr_base_addr_dma_attr.dma_addr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (rx_ring->cq_id * sizeof (uint64_t) * BUF_Q_PTR_SPACE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan caddr_t doorbell_area =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->doorbell_reg_iobase + (VM_PAGE_SIZE * (128 + rx_ring->cq_id));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int err = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t bq_len;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t tmp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *base_indirect_ptr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int page_entries;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set up the shadow registers for this ring. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->prod_idx_sh_reg = shadow_reg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->prod_idx_sh_reg_dma = shadow_reg_dma;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan rx_ring->prod_idx_sh_reg_offset = (off_t)(((rx_ring->cq_id *
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan sizeof (uint64_t) * RX_TX_RING_SHADOW_SPACE) + sizeof (uint64_t)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_base_indirect = (uint64_t *)(void *)buf_q_base_reg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_base_indirect_dma = buf_q_base_reg_dma;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s rx ring(%d): prod_idx virtual addr = 0x%lx,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " phys_addr 0x%lx\n", __func__, rx_ring->cq_id,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->prod_idx_sh_reg, rx_ring->prod_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan buf_q_base_reg += ((BUF_Q_PTR_SPACE / 2) * sizeof (uint64_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan buf_q_base_reg_dma += ((BUF_Q_PTR_SPACE / 2) * sizeof (uint64_t));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_base_indirect = (uint64_t *)(void *)buf_q_base_reg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_base_indirect_dma = buf_q_base_reg_dma;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI doorbell mem area + 0x00 for consumer index register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx_db_reg = (uint32_t *)(void *)doorbell_area;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *rx_ring->prod_idx_sh_reg = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->curr_entry = rx_ring->cq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI doorbell mem area + 0x04 for valid register */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->valid_db_reg = (uint32_t *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)doorbell_area + 0x04);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI doorbell mem area + 0x18 for large buffer consumer */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx_db_reg = (uint32_t *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)doorbell_area + 0x18);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* PCI doorbell mem area + 0x1c */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx_db_reg = (uint32_t *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)doorbell_area + 0x1c);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero((void *)cqicb, sizeof (*cqicb));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->msix_vect = (uint8_t)rx_ring->irq;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bq_len = (uint16_t)((rx_ring->cq_len == 65536) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)0 : (uint16_t)rx_ring->cq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->len = (uint16_t)cpu_to_le16(bq_len | LEN_V | LEN_CPP_CONT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->cq_base_addr_lo =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(rx_ring->cq_dma.dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->cq_base_addr_hi =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(rx_ring->cq_dma.dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->prod_idx_addr_lo =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(rx_ring->prod_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->prod_idx_addr_hi =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(rx_ring->prod_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set up the control block load flags.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->flags = FLAGS_LC | /* Load queue base address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan FLAGS_LV | /* Load MSI-X vector */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan FLAGS_LI; /* Load irq delay values */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Load lbq values */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->flags = (uint8_t)(cqicb->flags | FLAGS_LL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tmp = (uint64_t)rx_ring->lbq_dma.dma_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan base_indirect_ptr = (uint64_t *)rx_ring->lbq_base_indirect;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan page_entries = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan do {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *base_indirect_ptr = cpu_to_le64(tmp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tmp += VM_PAGE_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan base_indirect_ptr++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan page_entries++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } while (page_entries < (int)(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((rx_ring->lbq_len * sizeof (uint64_t)) / VM_PAGE_SIZE)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->lbq_addr_lo =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(rx_ring->lbq_base_indirect_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->lbq_addr_hi =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(rx_ring->lbq_base_indirect_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bq_len = (uint16_t)((rx_ring->lbq_buf_size == 65536) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)0 : (uint16_t)rx_ring->lbq_buf_size);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->lbq_buf_size = (uint16_t)cpu_to_le16(bq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bq_len = (uint16_t)((rx_ring->lbq_len == 65536) ? (uint16_t)0 :
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)rx_ring->lbq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->lbq_len = (uint16_t)cpu_to_le16(bq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_curr_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbq_len) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Load sbq values */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->flags = (uint8_t)(cqicb->flags | FLAGS_LS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tmp = (uint64_t)rx_ring->sbq_dma.dma_addr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan base_indirect_ptr = (uint64_t *)rx_ring->sbq_base_indirect;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan page_entries = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan do {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *base_indirect_ptr = cpu_to_le64(tmp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tmp += VM_PAGE_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan base_indirect_ptr++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan page_entries++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } while (page_entries < (uint32_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (((rx_ring->sbq_len * sizeof (uint64_t)) / VM_PAGE_SIZE)));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->sbq_addr_lo =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(rx_ring->sbq_base_indirect_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->sbq_addr_hi =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(rx_ring->sbq_base_indirect_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->sbq_buf_size = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16((uint16_t)(rx_ring->sbq_buf_size/2));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bq_len = (uint16_t)((rx_ring->sbq_len == 65536) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)0 : (uint16_t)rx_ring->sbq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->sbq_len = (uint16_t)cpu_to_le16(bq_len);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_curr_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (rx_ring->type) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case TX_Q:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->irq_delay = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(qlge->tx_coalesce_usecs);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->pkt_delay = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(qlge->tx_max_coalesced_frames);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DEFAULT_Q:
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cqicb->irq_delay = (uint16_t)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cpu_to_le16(qlge->rx_coalesce_usecs);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cqicb->pkt_delay = (uint16_t)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cpu_to_le16(qlge->rx_max_coalesced_frames);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RX_Q:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Inbound completion handling rx_rings run in
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * separate NAPI contexts.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->irq_delay = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(qlge->rx_coalesce_usecs);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cqicb->pkt_delay = (uint16_t)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le16(qlge->rx_max_coalesced_frames);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Invalid rx_ring->type = %d.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Initializing rx completion queue %d.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* QL_DUMP_CQICB(qlge, cqicb); */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan err = ql_write_cfg(qlge, CFG_LCQ, rx_ring->cqicb_dma.dma_addr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cq_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (err) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Failed to load CQICB.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (err);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_packets_dropped_no_buffer = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_pkt_dropped_mac_unenabled = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_failed_sbq_allocs = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_failed_lbq_allocs = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_packets = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->rx_bytes = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->frame_too_long = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->frame_too_short = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->fcs_err = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (err);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * start RSS
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_start_rss(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct ricb *ricb = (struct ricb *)qlge->ricb_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint8_t *hash_id = (uint8_t *)ricb->hash_cq_id;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan bzero((void *)ricb, sizeof (*ricb));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ricb->base_cq = RSS_L4K;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ricb->flags =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RSS_RT6);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ricb->mask = (uint16_t)cpu_to_le16(RSS_HASH_CQ_ID_MAX - 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Fill out the Indirection Table.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < RSS_HASH_CQ_ID_MAX; i++)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan hash_id[i] = (uint8_t)(i & (qlge->rss_ring_count - 1));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) memcpy(&ricb->ipv6_hash_key[0], key_data, 40);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) memcpy(&ricb->ipv4_hash_key[0], key_data, 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Initializing RSS.\n"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_write_cfg(qlge, CFG_LR, qlge->ricb_dma.dma_addr, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Failed to load RICB.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * load a tx ring control block to hw and start this ring
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_start_tx_ring(qlge_t *qlge, struct tx_ring *tx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct wqicb_t *wqicb = (struct wqicb_t *)tx_ring->wqicb_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan caddr_t doorbell_area =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->doorbell_reg_iobase + (VM_PAGE_SIZE * tx_ring->wq_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan void *shadow_reg = (uint8_t *)qlge->host_copy_shadow_dma_attr.vaddr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (tx_ring->wq_id * sizeof (uint64_t)) * RX_TX_RING_SHADOW_SPACE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t shadow_reg_dma = qlge->host_copy_shadow_dma_attr.dma_addr +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (tx_ring->wq_id * sizeof (uint64_t)) * RX_TX_RING_SHADOW_SPACE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int err = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Assign doorbell registers for this tx_ring.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* TX PCI doorbell mem area for tx producer index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx_db_reg = (uint32_t *)(void *)doorbell_area;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* TX PCI doorbell mem area + 0x04 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->valid_db_reg = (uint32_t *)(void *)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((uint8_t *)(void *)doorbell_area + 0x04);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Assign shadow registers for this tx_ring.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->cnsmr_idx_sh_reg = shadow_reg;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->cnsmr_idx_sh_reg_dma = shadow_reg_dma;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *tx_ring->cnsmr_idx_sh_reg = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s tx ring(%d): cnsmr_idx virtual addr = 0x%lx,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " phys_addr 0x%lx\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, tx_ring->wq_id, tx_ring->cnsmr_idx_sh_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->cnsmr_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->len =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (uint16_t)cpu_to_le16(tx_ring->wq_len | Q_LEN_V | Q_LEN_CPP_CONT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->flags = cpu_to_le16(Q_FLAGS_LC |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan Q_FLAGS_LB | Q_FLAGS_LI | Q_FLAGS_LO);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->cq_id_rss = (uint16_t)cpu_to_le16(tx_ring->cq_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->rid = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->wq_addr_lo = cpu_to_le32(LS_64BITS(tx_ring->wq_dma.dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->wq_addr_hi = cpu_to_le32(MS_64BITS(tx_ring->wq_dma.dma_addr));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->cnsmr_idx_addr_lo =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(LS_64BITS(tx_ring->cnsmr_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan wqicb->cnsmr_idx_addr_hi =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cpu_to_le32(MS_64BITS(tx_ring->cnsmr_idx_sh_reg_dma));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_init_tx_ring(tx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* QL_DUMP_WQICB(qlge, wqicb); */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan err = ql_write_cfg(qlge, CFG_LRQ, tx_ring->wqicb_dma.dma_addr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->wq_id);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (err) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Failed to load WQICB.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (err);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (err);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set up a MAC, multicast or VLAN address for the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * inbound frame matching.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_set_mac_addr_reg(qlge_t *qlge, uint8_t *addr, uint32_t type,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t index)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t offset = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (type) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case MAC_ADDR_TYPE_MULTI_MAC:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case MAC_ADDR_TYPE_CAM_MAC: {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t cam_output;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t upper = (addr[0] << 8) | addr[1];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t lower =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (addr[5]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("Adding %s ", (type ==
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan MAC_ADDR_TYPE_MULTI_MAC) ?
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "MULTICAST" : "UNICAST"));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("addr %02x %02x %02x %02x %02x %02x at index %d in "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "the CAM.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan addr[0], addr[1], addr[2], addr[3], addr[4],
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan addr[5], index));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_reg_rdy(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan REG_MAC_PROTOCOL_ADDRESS_INDEX, MAC_ADDR_MW, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* offset 0 - lower 32 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_ADDRESS_INDEX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (offset++) |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (index << MAC_ADDR_IDX_SHIFT) | /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan type); /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_DATA, lower);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_reg_rdy(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan REG_MAC_PROTOCOL_ADDRESS_INDEX, MAC_ADDR_MW, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* offset 1 - upper 16 bits of the MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_ADDRESS_INDEX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (offset++) |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (index << MAC_ADDR_IDX_SHIFT) | /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan type); /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_DATA, upper);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_reg_rdy(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan REG_MAC_PROTOCOL_ADDRESS_INDEX, MAC_ADDR_MW, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* offset 2 - CQ ID associated with this MAC address */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_ADDRESS_INDEX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (offset) | (index << MAC_ADDR_IDX_SHIFT) | /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan type); /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This field should also include the queue id
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * and possibly the function id. Right now we hardcode
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * the route field to NIC core.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (type == MAC_ADDR_TYPE_CAM_MAC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cam_output = (CAM_OUT_ROUTE_NIC |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->func_number << CAM_OUT_FUNC_SHIFT) |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (0 <<
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan CAM_OUT_CQ_ID_SHIFT));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* route to NIC core */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_MAC_PROTOCOL_DATA,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cam_output);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Address type %d not yet supported.", type);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * The NIC function for this chip has 16 routing indexes. Each one can be used
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to route different frame types to various inbound queues. We send broadcast
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * multicast/error frames to the default queue for slow handling,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * and CAM hit/RSS frames to the fast handling queues.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_set_routing_reg(qlge_t *qlge, uint32_t index, uint32_t mask, int enable)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t value = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s mask %s the routing reg.\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (enable ? "Adding" : "Removing"),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_ALL_ERR_SLOT) ? "MAC ERROR/ALL ERROR" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_IP_CSUM_ERR_SLOT) ? "IP CSUM ERROR" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index ==
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TCP_UDP_CSUM_ERR_SLOT) ? "TCP/UDP CSUM ERROR" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_BCAST_SLOT) ? "BROADCAST" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_MCAST_MATCH_SLOT) ? "MULTICAST MATCH" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_ALLMULTI_SLOT) ? "ALL MULTICAST MATCH" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_UNUSED6_SLOT) ? "UNUSED6" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_UNUSED7_SLOT) ? "UNUSED7" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_RSS_MATCH_SLOT) ? "RSS ALL/IPV4 MATCH" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_RSS_IPV6_SLOT) ? "RSS IPV6" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_RSS_TCP4_SLOT) ? "RSS TCP4" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_RSS_TCP6_SLOT) ? "RSS TCP6" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_CAM_HIT_SLOT) ? "CAM HIT" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_UNUSED013) ? "UNUSED13" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_UNUSED014) ? "UNUSED14" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ((index == RT_IDX_PROMISCUOUS_SLOT) ? "PROMISCUOUS" : ""),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (enable ? "to" : "from")));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (mask) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_CAM_HIT:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_CAM_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_CAM_HIT_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_VALID: /* Promiscuous Mode frames. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_DFLT_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_PROMISCUOUS_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_ERR: /* Pass up MAC,IP,TCP/UDP error frames. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_DFLT_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_ALL_ERR_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_BCAST: /* Pass up Broadcast frames to default Q. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_DFLT_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_BCAST_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_MCAST: /* Pass up All Multicast frames. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_CAM_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_CAM_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case RT_IDX_RSS_MATCH: /* Pass up matched RSS frames. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_RSS | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (RT_IDX_RSS_MATCH_SLOT << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case 0: /* Clear the E-bit on an entry. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = RT_IDX_DST_DFLT_Q | /* dest */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_TYPE_NICQ | /* type */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (index << RT_IDX_IDX_SHIFT); /* index */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Mask type %d not yet supported.",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mask);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = -EPERM;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (value != 0) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_reg_rdy(qlge, REG_ROUTING_INDEX, RT_IDX_MW, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value |= (enable ? RT_IDX_E : 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_ROUTING_INDEX, value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_ROUTING_DATA, enable ? mask : 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Clear all the entries in the routing table.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Caller must get semaphore in advance.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_stop_routing(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Clear all the entries in the routing table. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < 16; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge, i, 0, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Stop routing failed. ");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/* Initialize the frame-to-queue routing. */
cddcb3dae85e03889ec217ef3da5a8898f4f66c7Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_route_initialize(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_sem_spinlock(qlge, SEM_RT_IDX_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Clear all the entries in the routing table. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_stop_routing(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing register for broadcast packets.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If we have more than one inbound queue, then turn on RSS in the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * routing block.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rss_ring_count > 1) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge, RT_IDX_RSS_MATCH_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_RSS_MATCH, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing register for MATCH RSS "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "packets.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge, RT_IDX_CAM_HIT_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_CAM_HIT, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing register for CAM packets.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto exit;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_set_routing_reg(qlge, RT_IDX_MCAST_MATCH_SLOT,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RT_IDX_MCAST_MATCH, 1);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init routing register for Multicast "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "packets.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanexit:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, SEM_RT_IDX_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize hardware
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_device_initialize(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t value, mask;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t pause = PAUSE_MODE_DISABLED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan boolean_t update_port_config = B_FALSE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t pause_bit_mask;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan boolean_t dcbx_enable = B_FALSE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t dcbx_bit_mask = 0x10;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set up the System register to halt on errors.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = SYS_EFE | SYS_FAE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mask = value << 16;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_SYSTEM, mask | value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set the default queue. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = NIC_RCV_CFG_DFQ;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mask = NIC_RCV_CFG_DFQ_MASK;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_NIC_RECEIVE_CONFIGURATION, mask | value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Enable the MPI interrupt. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_MASK, (INTR_MASK_PI << 16)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan | INTR_MASK_PI);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Enable the function, set pagesize, enable error checking. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value = FSC_FE | FSC_EPC_INBOUND | FSC_EPC_OUTBOUND |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan FSC_EC | FSC_VM_PAGE_4K | FSC_DBRST_1024;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set/clear header splitting. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (CFG_IST(qlge, CFG_ENABLE_SPLIT_HEADER)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan value |= FSC_SH;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_SPLIT_HEADER, SMALL_BUFFER_SIZE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mask = FSC_VM_PAGESIZE_MASK |
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan FSC_DBL_MASK | FSC_DBRST_MASK | (value << 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_FUNCTION_SPECIFIC_CONTROL, mask | value);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * check current port max frame size, if different from OS setting,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * then we need to change
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->max_frame_size =
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mtu == ETHERMTU)? NORMAL_FRAME_SIZE : JUMBO_FRAME_SIZE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_enter(&qlge->mbx_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan status = ql_get_port_cfg(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_exit(&qlge->mbx_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (status == DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if current frame size is smaller than required size */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->port_cfg_info.max_frame_size <
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->max_frame_size) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_MBX,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ("update frame size, current %d, new %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->port_cfg_info.max_frame_size,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->max_frame_size));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->port_cfg_info.max_frame_size =
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->max_frame_size;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg |= ENABLE_JUMBO;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan update_port_config = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->port_cfg_info.link_cfg & STD_PAUSE)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan pause = PAUSE_MODE_STANDARD;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else if (qlge->port_cfg_info.link_cfg & PP_PAUSE)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan pause = PAUSE_MODE_PER_PRIORITY;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (pause != qlge->pause) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pause_bit_mask = 0x60; /* bit 5-6 */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* clear pause bits */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg &= ~pause_bit_mask;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->pause == PAUSE_MODE_STANDARD)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg |= STD_PAUSE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan else if (qlge->pause == PAUSE_MODE_PER_PRIORITY)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg |= PP_PAUSE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan update_port_config = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->port_cfg_info.link_cfg & DCBX_ENABLE)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dcbx_enable = B_TRUE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (dcbx_enable != qlge->dcbx_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg &= ~dcbx_bit_mask;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->dcbx_enable)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info.link_cfg |= DCBX_ENABLE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan update_port_config = B_TRUE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* if need to update port configuration */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (update_port_config) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_enter(&qlge->mbx_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_set_mpi_port_config(qlge,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->port_cfg_info);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan mutex_exit(&qlge->mbx_mutex);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "ql_get_port_cfg failed");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Start up the rx queues. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_start_rx_ring(qlge, &qlge->rx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to start rx ring[%d]", i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If there is more than one inbound completion queue
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * then download a RICB to configure RSS.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rss_ring_count > 1) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_start_rss(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "Failed to start RSS.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Start up the tx queues. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_start_tx_ring(qlge, &qlge->tx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to start tx ring[%d]", i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->selected_tx_ring = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Set the frame routing filter. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_route_initialize(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "Failed to init CAM/Routing tables.");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Issue soft reset to chip.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_asic_reset(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_RESET_FAILOVER, FUNCTION_RESET_MASK
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan |FUNCTION_RESET);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_wait_reg_bit(qlge, REG_RESET_FAILOVER, FUNCTION_RESET,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan BIT_RESET, 0) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "TIMEOUT!!! errored out of resetting the chip!");
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If there are more than MIN_BUFFERS_ARM_COUNT small buffer descriptors in
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * its free list, move xMIN_BUFFERS_ARM_COUNT descriptors to its in use list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to be used by hardware.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_arm_sbuf(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *sbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *sbq_entry = rx_ring->sbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t arm_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->sbuf_free_count > rx_ring->sbq_len-MIN_BUFFERS_ARM_COUNT)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan arm_count = (rx_ring->sbq_len-MIN_BUFFERS_ARM_COUNT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adjust to a multiple of 16 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan arm_count = (rx_ring->sbuf_free_count / 16) * 16;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "adjust sbuf arm_count %d\n", arm_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < arm_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_desc = ql_get_sbuf_from_free_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (sbq_desc == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Arm asic */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *sbq_entry = cpu_to_le64(sbq_desc->bd_dma.dma_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sbq_entry++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* link the descriptors to in_use_list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_sbuf_to_in_use_list(rx_ring, sbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->sbq_prod_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_sbq_prod_idx(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * If there are more than MIN_BUFFERS_ARM_COUNT large buffer descriptors in
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * its free list, move xMIN_BUFFERS_ARM_COUNT descriptors to its in use list
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to be used by hardware.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_arm_lbuf(qlge_t *qlge, struct rx_ring *rx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct bq_desc *lbq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint64_t *lbq_entry = rx_ring->lbq_dma.vaddr;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t arm_count;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rx_ring->lbuf_free_count > rx_ring->lbq_len-MIN_BUFFERS_ARM_COUNT)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan arm_count = (rx_ring->lbq_len-MIN_BUFFERS_ARM_COUNT);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Adjust to a multiple of 16 */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan arm_count = (rx_ring->lbuf_free_count / 16) * 16;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "adjust lbuf arm_count %d\n", arm_count);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < arm_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_desc = ql_get_lbuf_from_free_list(rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (lbq_desc == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Arm asic */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *lbq_entry = cpu_to_le64(lbq_desc->bd_dma.dma_addr);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan lbq_entry++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* link the descriptors to in_use_list */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_add_lbuf_to_in_use_list(rx_ring, lbq_desc);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->lbq_prod_idx++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_update_lbq_prod_idx(qlge, rx_ring);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initializes the adapter by configuring request and response queues,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * allocates and ARMs small and large receive buffers to the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * hardware
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_bringup_adapter(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_device_initialize(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "?%s(%d): ql_device_initialize failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan goto err_bringup;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_ADAPTER_UP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_TRACK_BUFFER_USAGE
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_sb_low_count[i] = NUM_SMALL_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_lb_low_count[i] = NUM_LARGE_BUFFERS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->cq_low_count[i] = NUM_RX_RING_ENTRIES;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Arm buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].type != TX_Q) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_arm_sbuf(qlge, &qlge->rx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_arm_lbuf(qlge, &qlge->rx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Enable work/request queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->tx_ring[i].valid_db_reg)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].valid_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan REQ_Q_VALID);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Enable completion queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].valid_db_reg)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].valid_db_reg,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan RSP_Q_VALID);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->tx_ring[i].tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].mac_flags = QL_MAC_STARTED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->tx_ring[i].tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->rx_ring[i].rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].mac_flags = QL_MAC_STARTED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->rx_ring[i].rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* This mutex will get re-acquired in enable_completion interrupt */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Traffic can start flowing now */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_all_completion_interrupts(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_enable_global_interrupt(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= ADAPTER_INIT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanerr_bringup:
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_asic_reset(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize mutexes of each rx/tx rings
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_init_rx_tx_locks(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&tx_ring->tx_lock, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&rx_ring->rx_lock, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&rx_ring->sbq_lock, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&rx_ring->lbq_lock, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*ARGSUSED*/
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan/*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Simply call pci_ereport_post which generates ereports for errors
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * that occur in the PCI local bus configuration status registers.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic int
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pci_ereport_post(dip, err, NULL);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan return (err->fme_status);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic void
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_fm_init(qlge_t *qlge)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_iblock_cookie_t iblk;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("ql_fm_init(%d) entered, FMA capability %x\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->instance, qlge->fm_capabilities));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Register capabilities with IO Fault Services. The capabilities
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * set above may not be supported by the parent nexus, in that case
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * some capability bits may be cleared.
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_capabilities)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_init(qlge->dip, &qlge->fm_capabilities, &iblk);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Initialize pci ereport capabilities if ereport capable
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_EREPORT_CAP(qlge->fm_capabilities) ||
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_FM_ERRCB_CAP(qlge->fm_capabilities)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pci_ereport_setup(qlge->dip);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Register error callback if error callback capable */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_ERRCB_CAP(qlge->fm_capabilities)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_handler_register(qlge->dip,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_error_cb, (void*) qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * DDI_FLGERR_ACC indicates:
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Driver will check its access handle(s) for faults on
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * a regular basis by calling ddi_fm_acc_err_get
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Driver is able to cope with incorrect results of I/O
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * operations resulted from an I/O fault
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_ACC_ERR_CAP(qlge->fm_capabilities)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_dev_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * DDI_DMA_FLAGERR indicates:
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Driver will check its DMA handle(s) for faults on a
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * regular basis using ddi_fm_dma_err_get
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Driver is able to cope with incorrect results of DMA
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * operations resulted from an I/O fault
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_DMA_ERR_CAP(qlge->fm_capabilities)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan tx_mapping_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("ql_fm_init(%d) done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->instance));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanstatic void
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathanql_fm_fini(qlge_t *qlge)
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan{
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("ql_fm_fini(%d) entered\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->instance));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Only unregister FMA capabilities if we registered some */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_capabilities) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Release any resources allocated by pci_ereport_setup()
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_EREPORT_CAP(qlge->fm_capabilities) ||
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_FM_ERRCB_CAP(qlge->fm_capabilities))
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan pci_ereport_teardown(qlge->dip);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Un-register error callback if error callback capable
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (DDI_FM_ERRCB_CAP(qlge->fm_capabilities))
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_handler_unregister(qlge->dip);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Unregister from IO Fault Services */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_fini(qlge->dip);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("ql_fm_fini(%d) done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->instance));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * ql_attach - Driver attach.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int instance;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge_t *qlge = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint16_t w;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_register_t *macp = NULL;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan uint32_t data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* first get the instance */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan instance = ddi_get_instance(dip);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (cmd) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_ATTACH:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate our per-device-instance structure
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge = (qlge_t *)kmem_zalloc(sizeof (*qlge), KM_SLEEP);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ASSERT(qlge != NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_SOFTSTATE_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->dip = dip;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->instance = instance;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* Set up the coalescing parameters. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->ql_dbgprnt = 0;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#if QL_DEBUG
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->ql_dbgprnt = QL_DEBUG;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan#endif /* QL_DEBUG */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Initialize for fma support
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* fault management (fm) capabilities. */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->fm_capabilities =
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan data = ql_get_prop(qlge, "fm-capable");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (data <= 0xf) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->fm_capabilities = data;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_init(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->sequence |= INIT_FM;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("ql_attach(%d): fma init done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Setup the ISP8x00 registers address mapping to be
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * accessed by this particular driver.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 0x0 Configuration Space
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 0x1 I/O Space
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 0x2 1st Memory Space address - Control Register Set
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * 0x3 2nd Memory Space address - Doorbell Memory Space
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan w = 2;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_regs_map_setup(dip, w, (caddr_t *)&qlge->iobase, 0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan sizeof (dev_reg_t), &ql_dev_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->dev_handle) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Unable to map device "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "registers", ADAPTER_NAME, instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach: I/O base = 0x%x\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->iobase));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_REGS_SETUP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* map Doorbell memory space */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan w = 3;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_regs_map_setup(dip, w,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (caddr_t *)&qlge->doorbell_reg_iobase, 0,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan 0x100000 /* sizeof (dev_doorbell_reg_t) */,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_dev_acc_attr,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &qlge->dev_doorbell_reg_handle) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Unable to map Doorbell "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "registers",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME, instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach: Doorbell I/O base = 0x%x\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->doorbell_reg_iobase));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_DOORBELL_REGS_SETUP;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Allocate a macinfo structure for this instance
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): mac_alloc failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, instance);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* save adapter status to dip private data */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_set_driver_private(dip, qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): Allocate macinfo structure done\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_MAC_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Attach this instance of the device
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Setup PCI Local Bus Configuration resource. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (pci_config_setup(dip, &qlge->pci_handle) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d):Unable to get PCI resources",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME, instance);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_PCI_CONFIG_SETUP;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach(%d): pci_config_setup done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_init_instance(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): Unable to initialize device "
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan "instance", ADAPTER_NAME, instance);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->fm_enable) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_fm_ereport(qlge, DDI_FM_DEVICE_INVAL_STATE);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ddi_fm_service_impact(qlge->dip,
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan DDI_SERVICE_LOST);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach(%d): ql_init_instance done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Setup interrupt vectors */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_alloc_irqs(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_INTR_ALLOC;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach(%d): ql_alloc_irqs done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Configure queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_setup_rings(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_SETUP_RINGS;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_attach(%d): setup rings done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan instance));
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Allocate memory resources
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_alloc_mem_resources(qlge) != DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): memory allocation failed",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->sequence |= INIT_MEMORY_ALLOC;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_GLD, ("ql_alloc_mem_resources(%d) done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Map queues to interrupt vectors
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_resolve_queues_to_irqs(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Initialize mutex, need the interrupt priority */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_init_rx_tx_locks(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_LOCKS_CREATED;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): ql_init_rx_tx_locks done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Use a soft interrupt to do something that we do not want
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to do in regular network functions or with mutexs being held
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_intr_add_softint(qlge->dip, &qlge->mpi_event_intr_hdl,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_SOFTPRI_MIN, ql_mpi_event_work, (caddr_t)qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_intr_add_softint(qlge->dip, &qlge->asic_reset_intr_hdl,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_SOFTPRI_MIN, ql_asic_reset_work, (caddr_t)qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ddi_intr_add_softint(qlge->dip, &qlge->mpi_reset_intr_hdl,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_SOFTPRI_MIN, ql_mpi_reset_work, (caddr_t)qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_ADD_SOFT_INTERRUPT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): ddi_intr_add_softint done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * mutex to protect the adapter state structure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * initialize mutexes according to the interrupt priority
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&qlge->gen_mutex, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&qlge->hw_mutex, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_init(&qlge->mbx_mutex, NULL, MUTEX_DRIVER,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan DDI_INTR_PRI(qlge->intr_pri));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Mailbox wait and interrupt conditional variable. */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cv_init(&qlge->cv_mbx_intr, NULL, CV_DRIVER, NULL);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_MUTEX;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): mutex_init done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * KStats
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (ql_init_kstats(qlge) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): KState initialization failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME, instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_KSTATS;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): ql_init_kstats done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initialize gld macinfo structure
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_gld3_init(qlge, macp);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * Add interrupt handlers
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (ql_add_intr_handlers(qlge) != DDI_SUCCESS) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "Failed to add interrupt "
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan "handlers");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan break;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->sequence |= INIT_ADD_INTERRUPT;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan QL_PRINT(DBG_INIT, ("%s(%d): Add interrupt handler done\n",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /*
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan * MAC Register
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (mac_register(macp, &qlge->mh) != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "%s(%d): mac_register failed",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence |= INIT_MAC_REGISTERED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d): mac_register done\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME, instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_free(macp);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan macp = NULL;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_ATTACHED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ddi_report_dev(dip);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_SUCCESS;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * DDI_RESUME
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * When called with cmd set to DDI_RESUME, attach() must
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * restore the hardware state of a device (power may have been
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * removed from the device), allow pending requests to con-
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * tinue, and service new requests. In this case, the driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * must not make any assumptions about the state of the
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * hardware, but must restore the state of the device except
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * for the power level of components.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_RESUME:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge = (qlge_t *)QL_GET_DEV(dip)) == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan QL_PRINT(DBG_GLD, ("%s(%d)-DDI_RESUME\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_do_start(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan /* if failed to attach */
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if ((cmd == DDI_ATTACH) && (rval != DDI_SUCCESS) && (qlge != NULL)) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_WARN, "qlge driver attach failed, sequence %x",
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan qlge->sequence);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_free_resources(qlge);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Unbind all pending tx dma handles during driver bring down
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic void
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_unbind_pending_tx_dma_handle(struct tx_ring *tx_ring)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan struct tx_ring_desc *tx_ring_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i, j;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring->wq_desc) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc = tx_ring->wq_desc;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < tx_ring->wq_len; i++, tx_ring_desc++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (j = 0; j < tx_ring_desc->tx_dma_handle_used; j++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (tx_ring_desc->tx_dma_handle[j]) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ddi_dma_unbind_handle(
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->tx_dma_handle[j]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring_desc->tx_dma_handle_used = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan } /* end of for loop */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Wait for all the packets sent to the chip to finish transmission
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * to prevent buffers to be unmapped before or during a transmit operation
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wait_tx_quiesce(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int count = MAX_TX_WAIT_COUNT, i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rings_done;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan volatile struct tx_ring *tx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t consumer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan uint32_t temp;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int done = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan while (!done) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rings_done = 0;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring = &qlge->tx_ring[i];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan consumer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (qlge->isr_stride) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan struct rx_ring *ob_ring;
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring = &qlge->rx_ring[tx_ring->cq_id];
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan if (producer_idx != ob_ring->cnsmr_idx) {
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan cmn_err(CE_NOTE, " force clean \n");
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan (void) ql_clean_outbound_rx_ring(
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ob_ring);
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Get the pending iocb count, ones which have not been
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * pulled down by the chip
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (producer_idx >= consumer_idx)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = (producer_idx - consumer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = (tx_ring->wq_len - consumer_idx) +
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((tx_ring->tx_free_count + temp) >= tx_ring->wq_len)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rings_done++;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan else {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan done = 1;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* If all the rings are done */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rings_done >= qlge->tx_ring_count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "%s(%d) done successfully \n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(100);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan count--;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (!count) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan count = MAX_TX_WAIT_COUNT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#ifdef QLGE_LOAD_UNLOAD
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan volatile struct rx_ring *rx_ring;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "%s(%d): Waiting for %d pending"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " Transmits on queue %d to complete .\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->tx_ring[i].wq_len -
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].tx_free_count),
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan i);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring = &qlge->rx_ring[i+1];
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rx_ring->cnsmr_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan consumer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "%s(%d): Transmit completion queue %d,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " Producer %d, Consumer %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan i+1,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx, consumer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan temp = ql_read_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan tx_ring->prod_idx_db_reg);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx = temp & 0x0000ffff;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan consumer_idx = (temp >> 16);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_NOTE, "%s(%d): Transmit request queue %d,"
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan " Producer %d, Consumer %d\n",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan __func__, qlge->instance, i,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan producer_idx, consumer_idx);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan#endif
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* For now move on */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Stop the request queue */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->tx_ring[i].valid_db_reg) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].valid_db_reg, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Wait for all the receives indicated to the stack to come back
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_wait_rx_complete(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable all the completion queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].valid_db_reg) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].valid_db_reg, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Wait for OS to return all rx buffers */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(QL_ONE_SEC_DELAY);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * stop the driver
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_bringdown_adapter(qlge_t *qlge)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int status = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_BRINGDOWN;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & ADAPTER_INIT) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* stop forwarding external packets to driver */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_sem_spinlock(qlge, SEM_RT_IDX_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (status)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_stop_routing(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, SEM_RT_IDX_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Set the flag for receive and transmit
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * operations to cease
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->tx_ring[i].tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].mac_flags = QL_MAC_STOPPED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->tx_ring[i].tx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->rx_ring[i].rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].mac_flags = QL_MAC_STOPPED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->rx_ring[i].rx_lock);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Need interrupts to be running while the transmit
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * completions are cleared. Wait for the packets
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * queued to the chip to be sent out
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (void) ql_wait_tx_quiesce(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Interrupts not needed from now */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_all_completion_interrupts(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable Global interrupt */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_global_interrupt(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Wait for all the indicated packets to come back */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan status = ql_wait_rx_complete(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Reset adapter */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_asic_reset(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Unbind all tx dma handles to prevent pending tx descriptors'
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * dma handles from being re-used.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_unbind_pending_tx_dma_handle(&qlge->tx_ring[i]);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~ADAPTER_INIT;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->hw_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (status);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * ql_detach
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Used to remove all the states associated with a given
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * instances of a device node prior to the removal of that
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * instance from the system.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic int
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_SUCCESS;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan switch (cmd) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_DETACH:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge = QL_GET_DEV(dip)) == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = ql_bringdown_adapter(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval != DDI_SUCCESS)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_DETACH;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* free memory resources */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->sequence & INIT_MEMORY_ALLOC) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_free_mem_resources(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->sequence &= ~INIT_MEMORY_ALLOC;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
accf27a5824ae84dfac7b089c4325917231a7d15Sukumar Swaminathan ql_free_resources(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan case DDI_SUSPEND:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge = QL_GET_DEV(dip)) == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_enter(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge->mac_flags == QL_MAC_ATTACHED) ||
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (qlge->mac_flags == QL_MAC_STARTED)) {
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_do_stop(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_SUSPENDED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mutex_exit(&qlge->gen_mutex);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan default:
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = DDI_FAILURE;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan break;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * quiesce(9E) entry point.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This function is called when the system is single-threaded at high
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * PIL with preemption disabled. Therefore, this function must not be
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * blocked.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan *
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanql_quiesce(dev_info_t *dip)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_t *qlge;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int i;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if ((qlge = QL_GET_DEV(dip)) == NULL)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_FAILURE);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (CFG_IST(qlge, CFG_CHIP_8100)) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* stop forwarding external packets to driver */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_sem_spinlock(qlge, SEM_RT_IDX_MASK);
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_stop_routing(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_sem_unlock(qlge, SEM_RT_IDX_MASK);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Stop all the request queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->tx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->tx_ring[i].valid_db_reg) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->tx_ring[i].valid_db_reg, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(QL_ONE_SEC_DELAY/4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Interrupts not needed from now */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable MPI interrupt */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_reg(qlge, REG_INTERRUPT_MASK,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan (INTR_MASK_PI << 16));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_disable_global_interrupt(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Disable all the rx completion queues */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan for (i = 0; i < qlge->rx_ring_count; i++) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (qlge->rx_ring[i].valid_db_reg) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ql_write_doorbell_reg(qlge,
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->rx_ring[i].valid_db_reg, 0);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(QL_ONE_SEC_DELAY/4);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge->mac_flags = QL_MAC_STOPPED;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan /* Reset adapter */
0662fbf4a5c0ae38617fd0fe521817c65a4dca3fSukumar Swaminathan (void) ql_asic_reset(qlge);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan qlge_delay(100);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (DDI_SUCCESS);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar SwaminathanQL_STREAM_OPS(ql_ops, ql_attach, ql_detach);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Loadable Driver Interface Structures.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Declare and initialize the module configuration section...
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct modldrv modldrv = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &mod_driverops, /* type of module: driver */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan version, /* name of module */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan &ql_ops /* driver dev_ops */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanstatic struct modlinkage modlinkage = {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan MODREV_1, &modldrv, NULL
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan};
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Loadable Module Routines
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * _init
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Initializes a loadable module. It is called before any other
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * routine in a loadable module.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan_init(void)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_init_ops(&ql_ops, ADAPTER_NAME);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = mod_install(&modlinkage);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval != DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_fini_ops(&ql_ops);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan cmn_err(CE_WARN, "?Unable to install/attach driver '%s'",
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan ADAPTER_NAME);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * _fini
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Prepares a module for unloading. It is called when the system
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * wants to unload a module. If the module determines that it can
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * be unloaded, then _fini() returns the value returned by
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * mod_remove(). Upon successful return from _fini() no other
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * routine in the module will be called before _init() is called.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan_fini(void)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan int rval;
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan rval = mod_remove(&modlinkage);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan if (rval == DDI_SUCCESS) {
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan mac_fini_ops(&ql_ops);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan }
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (rval);
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan/*
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * _info
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan * Returns information about loadable module.
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan */
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathanint
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan_info(struct modinfo *modinfop)
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan{
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan return (mod_info(&modlinkage, modinfop));
bafec74292ca6805e5acb387856f4e60a5314b37Sukumar Swaminathan}