d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER START
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The contents of this file are subject to the terms of the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Common Development and Distribution License (the "License").
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You may not use this file except in compliance with the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * or http://www.opensolaris.org/os/licensing.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See the License for the specific language governing permissions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and limitations under the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * When distributing Covered Code, include this CDDL HEADER in each
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * If applicable, add the following below this CDDL HEADER, with the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * fields enclosed by brackets "[]" replaced with your own identifying
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * information: Portions Copyright [yyyy] [name of copyright owner]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER END
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Use is subject to license terms.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * This file is part of the Chelsio T1 Ethernet driver.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Solaris Multithreaded STREAMS Chelsio PCI Ethernet Driver.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Interface code
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/types.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/systm.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/cmn_err.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/ddi.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/sunddi.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/byteorder.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/atomic.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/ethernet.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if PE_PROFILING_ENABLED
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/time.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include <sys/gld.h>
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "ostypes.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "common.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "oschtoe.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_1G
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "fpga_defs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_OFFLOAD
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "mc3.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "mc4.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "sge.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "tp.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_OFFLOAD
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "ulp.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "espi.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "elmer0.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "gmac.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "cphy.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "suni1x10gexp_regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "ch.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MLEN(mp) ((mp)->b_wptr - (mp)->b_rptr)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwextern uint32_t buffers_in_use[];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwextern kmutex_t in_use_l;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwextern uint32_t in_use_index;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void link_start(ch_t *sa, struct pe_port_t *pp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic ch_esb_t *ch_alloc_small_esbbuf(ch_t *sa, uint32_t i);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic ch_esb_t *ch_alloc_big_esbbuf(ch_t *sa, uint32_t i);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid ch_big_rbuf_recycle(ch_esb_t *rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid ch_small_rbuf_recycle(ch_esb_t *rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic const struct board_info *pe_sa_init(ch_t *sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int ch_set_config_data(ch_t *chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid pe_rbuf_pool_free(ch_t *chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void pe_free_driver_resources(ch_t *sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void update_mtu_tab(ch_t *adapter);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pe_change_mtu(ch_t *chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CPL5 Defines (from netinet/cpl5_commands.h)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define FLITSTOBYTES 8
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_0_SIZE 8
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_1_SIZE 16
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_2_SIZE 24
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_3_SIZE 32
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_4_SIZE 40
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define CPL_FORMAT_5_SIZE 48
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define TID_MASK 0xffffff
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define PE_LINK_SPEED_AUTONEG 5
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pe_small_rbuf_pool_init(ch_t *sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pe_big_rbuf_pool_init(ch_t *sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int pe_make_fake_arp(ch_t *chp, unsigned char *arpp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic uint32_t pe_get_ip(unsigned char *arpp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * May be set in /etc/system to 0 to use default latency timer for 10G.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See PCI register 0xc definition.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint enable_latency_timer = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * May be set in /etc/system to 0 to disable hardware checksum for
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * TCP and UDP.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint enable_checksum_offload = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Multiplier for freelist pool.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint fl_sz_multiplier = 6;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint_t
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_intr(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sge_data_in(sa->sge)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->isr_intr++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (DDI_INTR_CLAIMED);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (DDI_INTR_UNCLAIMED);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Each setup struct will call this function to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * initialize.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_init(void* xsa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_t *sa = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa = (ch_t *)xsa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Need to count the number of times this routine is called
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * because we only want the resources to be allocated once.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The 7500 has four ports and so this routine can be called
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * once for each port.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->init_counter == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for_each_port(sa, i) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We only want to initialize the line if it is down.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->port[i].line_up == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw link_start(sa, &sa->port[i]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->port[i].line_up = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_init_hw_modules(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Enable/Disable checksum offloading.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->ch_config.cksum_enabled) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->config_data.offload_ip_cksum) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Notify that HW will do the checksum. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_tp_set_ip_checksum_offload(sa->tp, 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->config_data.offload_tcp_cksum) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Notify that HW will do the checksum. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_tp_set_tcp_checksum_offload(sa->tp, 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->config_data.offload_udp_cksum) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Notify that HW will do the checksum. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_tp_set_udp_checksum_offload(sa->tp, 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_flags |= PEINITDONE;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->init_counter++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Enable interrupts after starting the SGE so
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * that the SGE is ready to handle interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) sge_start(sa->sge);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_interrupts_enable(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * set mtu (either 1500 or bigger)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pe_change_mtu(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef HOST_PAUSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * get the configured value of the MAC.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_tpi_read(sa, SUNI1x10GEXP_REG_TXXG_CONFIG_1 << 2,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &sa->txxg_cfg1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwlink_start(ch_t *sa, struct pe_port_t *p)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cmac *mac = p->mac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac->ops->reset(mac);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mac->ops->macaddress_set)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac->ops->macaddress_set(mac, p->enaddr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_link_start(p->phy, mac, &p->link_config);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * turn off interrupts...
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_stop(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_interrupts_disable(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) sge_stop(sa->sge);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we can still be running an interrupt thread in sge_data_in().
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * If we are, we'll block on the ch_intr lock
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_intr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * output mblk to SGE level and out to the wire.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_start(ch_t *sa, mblk_t *mp, uint32_t flg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mblk_t *m0 = mp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmdQ_ce_t cm[16];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmdQ_ce_t *cmp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmdQ_ce_t *hmp = &cm[0]; /* head of cm table (may be kmem_alloed) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int cm_flg = 0; /* flag (1 - if kmem-alloced) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int nseg = 0; /* number cmdQ_ce entries created */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int mseg = 16; /* maximum entries in hmp arrary */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int freeme = 0; /* we have an mblk to free in case of error */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t ch_bind_dma_handle(ch_t *, int, caddr_t, cmdQ_ce_t *,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if defined(__sparc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t ch_bind_dvma_handle(ch_t *, int, caddr_t, cmdQ_ce_t *,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int rv; /* return value on error */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_OFFLOAD
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (flg & CH_OFFLOAD) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_pa = ((tbuf_t *)mp)->tb_pa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_dh = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_flg = DH_TOE;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_len = ((tbuf_t *)mp)->tb_len;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_mp = mp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* make sure data is flushed to physical memory */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) ddi_dma_sync((ddi_dma_handle_t)((tbuf_t *)mp)->tb_dh,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (off_t)0, hmp->ce_len, DDI_DMA_SYNC_FORDEV);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sge_data_out(sa->sge, 0, mp, hmp, 1, flg) == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * set a flag so we'll restart upper layer when
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * resources become available.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_blked = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif /* CONFIG_CHELSIO_T1_OFFLOAD */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* writes from toe will always have CPL header in place */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (flg & CH_NO_CPL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cpl_tx_pkt *cpl;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* PR2928 & PR3309 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->ch_ip == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ushort_t ethertype = ntohs(*(short *)&mp->b_rptr[12]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (ethertype == ETHERTYPE_ARP) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (is_T2(sa)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We assume here that the arp will be
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * contained in one mblk.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe_make_fake_arp(sa, mp->b_rptr)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->oerr++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_ip = pe_get_ip(mp->b_rptr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * if space in front of packet big enough for CPL
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * header, then use it. We'll allocate an mblk
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * otherwise.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((mp->b_rptr - mp->b_datap->db_base) >= SZ_CPL_TX_PKT) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp->b_rptr -= SZ_CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef SUN_KSTATS
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_need_cpl_space++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw m0 = allocb(SZ_CPL_TX_PKT, BPRI_HI);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (m0 == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->oerr++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw m0->b_wptr = m0->b_rptr + SZ_CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw m0->b_cont = mp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freeme = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp = m0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* fill in cpl header */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl = (struct cpl_tx_pkt *)mp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->opcode = CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->iff = 0; /* XXX port 0 needs fixing with NEMO */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->ip_csum_dis = 1; /* no IP header cksum */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->l4_csum_dis =
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw flg & CH_NO_HWCKSUM; /* CH_NO_HWCKSUM == 1 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->vlan_valid = 0; /* no vlan */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (m0->b_cont) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef SUN_KSTATS
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_multi_mblks++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (mp) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int lseg; /* added by ch_bind_dma_handle() */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int len;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw len = MLEN(mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* skip mlks with no data */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (len == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp = mp->b_cont;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw continue;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * if we've run out of space on stack, then we
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allocate a temporary buffer to hold the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * information. This will kill the the performance,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * but since it shouldn't really occur, we can live
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * with it. Since jumbo frames may map multiple
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * descriptors, we reallocate the hmp[] array before
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we reach the end.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg >= (mseg-4)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmdQ_ce_t *buf;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int j;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw buf = kmem_alloc(sizeof (cmdQ_ce_t) * 2 * mseg,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw KM_SLEEP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (j = 0; j < nseg; j++)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw buf[j] = hmp[j];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cm_flg) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(hmp,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mseg * sizeof (cmdQ_ce_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cm_flg = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp = buf;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mseg = 2*mseg;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We've used up ch table on stack
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if defined(__sparc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->ch_config.enable_dvma) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw lseg = ch_bind_dvma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &hmp[nseg], mseg - nseg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (lseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dvma1++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((lseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &hmp[nseg],
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mseg - nseg)) == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma1++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gonna bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we may have processed
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * previous mblks and have
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * descriptors. If so, we need
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * to free the meta struct
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * entries before freeing
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the mblk.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw lseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr, &hmp[nseg],
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mseg - nseg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (lseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma1++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gona bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we may have processed previous
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * mblks and have descriptors. If so,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we need to free the meta struct
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * entries before freeing the mblk.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else /* defined(__sparc) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw lseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr, &hmp[nseg],
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mseg - nseg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (lseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma1++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gona bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * we may have processed previous mblks and
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * have descriptors. If so, we need to free
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the meta struct entries before freeing
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the mblk.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif /* defined(__sparc) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw nseg += lseg;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mp = mp->b_cont;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * SHOULD NEVER OCCUR, BUT...
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * no data if nseg 0 or
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * nseg 1 and a CPL mblk (CPL mblk only with offload mode)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and no data
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((nseg == 0) || (freeme && (nseg == 1))) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int len;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* we assume that we always have data with one packet */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw len = MLEN(mp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if defined(__sparc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa->ch_config.enable_dvma) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw nseg = ch_bind_dvma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &hmp[0], 16);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dvma2++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw nseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &hmp[0], 16);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma2++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gona bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw nseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr, &hmp[0], 16);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma2++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gona bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else /* defined(__sparc) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw nseg = ch_bind_dma_handle(sa, len,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void *)mp->b_rptr, &hmp[0], 16);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (nseg == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->sge->intr_cnt.tx_no_dma2++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * ran out of space. Gona bale
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif /* defined(__sparc) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * dummy arp message to handle PR3309 & PR2928
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (flg & CH_ARP)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw hmp->ce_flg |= DH_ARP;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sge_data_out(sa->sge, 0, m0, hmp, nseg, flg) == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cm_flg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(hmp, mseg * sizeof (cmdQ_ce_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * set a flag so we'll restart upper layer when
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * resources become available.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((flg & CH_ARP) == 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_blked = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rv = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwerror:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * unmap the physical addresses allocated earlier.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmp = hmp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (--nseg; nseg >= 0; nseg--) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cmp->ce_dh) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cmp->ce_flg == DH_DMA)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_unbind_dma_handle(sa, cmp->ce_dh);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if defined(__sparc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_unbind_dvma_handle(sa, cmp->ce_dh);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmp++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwerror1:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free the temporary array */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cm_flg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(hmp, mseg * sizeof (cmdQ_ce_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * if we've allocated an mblk above, then we need to free it
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * before returning. This is safe since we haven't done anything to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * the original message. The caller, gld, will still have a pointer
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * to the original mblk.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rv == 1) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (freeme) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* we had to allocate an mblk. Free it. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freeb(m0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* adjust the mblk back to original start */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (flg & CH_NO_CPL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw m0->b_rptr += SZ_CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(m0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->oerr++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (rv);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* KLUDGE ALERT. HARD WIRED TO PORT ZERO */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_set_mac(ch_t *sa, unsigned char *ac_enaddr)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->port[0].mac->ops->macaddress_set(sa->port[0].mac, ac_enaddr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* KLUDGE ALERT. HARD WIRED TO PORT ZERO */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned char *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_get_mac(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (sa->port[0].enaddr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* KLUDGE ALERT. HARD WIRED TO ONE PORT */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_set_promiscuous(ch_t *sa, int flag)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cmac *mac = sa->port[0].mac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct t1_rx_mode rm;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw switch (flag) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case 0: /* turn off promiscuous mode */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_flags &= ~(PEPROMISC|PEALLMULTI);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case 1: /* turn on promiscuous mode */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_flags |= PEPROMISC;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case 2: /* turn on multicast reception */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_flags |= PEALLMULTI;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rm.chp = sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rm.mc = sa->ch_mc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac->ops->set_rx_mode(mac, &rm);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_set_mc(ch_t *sa, uint8_t *ep, int flg)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cmac *mac = sa->port[0].mac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct t1_rx_mode rm;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (flg == GLD_MULTI_ENABLE) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_mc_t *mcp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mcp = (ch_mc_t *)kmem_zalloc(sizeof (struct ch_mc),
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw KM_NOSLEEP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mcp == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (GLD_NORESOURCES);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(ep, &mcp->cmc_mca, 6);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mcp->cmc_next = sa->ch_mc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_mc = mcp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_mc_cnt++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else if (flg == GLD_MULTI_DISABLE) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_mc_t **p = &sa->ch_mc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_mc_t *q = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p = &sa->ch_mc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (*p) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (bcmp(ep, (*p)->cmc_mca, 6) == 0) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw q = *p;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *p = (*p)->cmc_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(q, sizeof (*q));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_mc_cnt--;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p = &(*p)->cmc_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (q == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (GLD_BADARG);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (GLD_BADARG);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rm.chp = sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rm.mc = sa->ch_mc;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mac->ops->set_rx_mode(mac, &rm);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_mc_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (GLD_SUCCESS);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: speed - bandwidth of interface
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: intrcnt - # interrupts
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: norcvbuf - # recedived packets dropped by driver
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: oerrors - # bad send packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: ierrors - # bad receive packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: underrun - # bad underrun xmit packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: overrun - # bad overrun recv packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: framing - # bad aligned recv packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: crc - # bad FCS (crc) recv packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: carrier - times carrier was lost
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: collisions - # xmit collisions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: xcollisions - # xmit pkts dropped due to collisions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: late - # late xmit collisions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: defer - # deferred xmit packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: xerrs - # xmit dropped packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: rerrs - # recv dropped packets
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: toolong - # recv pkts too long
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: runt - # recv runt pkts
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: multixmt - # multicast pkts xmitted
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: multircv - # multicast pkts recved
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: brdcstxmt - # broadcast pkts xmitted
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * return: brdcstrcv - # broadcast pkts rcv
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_get_stats(ch_t *sa, uint64_t *speed, uint32_t *intrcnt, uint32_t *norcvbuf,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t *oerrors, uint32_t *ierrors, uint32_t *underrun,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t *overrun, uint32_t *framing, uint32_t *crc,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t *carrier, uint32_t *collisions, uint32_t *xcollisions,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t *late, uint32_t *defer, uint32_t *xerrs, uint32_t *rerrs,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t *toolong, uint32_t *runt, ulong_t *multixmt, ulong_t *multircv,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ulong_t *brdcstxmt, ulong_t *brdcstrcv)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct pe_port_t *pt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int line_speed;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int line_duplex;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int line_is_active;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint64_t v;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw const struct cmac_statistics *sp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pt = &(sa->port[0]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) pt->phy->ops->get_link_status(pt->phy,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &line_is_active, &line_speed, &line_duplex, NULL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw switch (line_speed) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case SPEED_10:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = 10000000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case SPEED_100:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = 100000000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case SPEED_1000:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = 1000000000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case SPEED_10000:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * kludge to get 10,000,000,000 constant (and keep
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * compiler happy).
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v = 10000000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw v *= 1000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = v;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw default:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *intrcnt = sa->isr_intr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *norcvbuf = sa->norcvbuf;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp = sa->port[0].mac->ops->statistics_update(sa->port[0].mac,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MAC_STATS_UPDATE_FULL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *ierrors = sp->RxOctetsBad;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * not sure this is correct. # aborted at driver level +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * # at hardware level
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *oerrors = sa->oerr + sp->TxFramesAbortedDueToXSCollisions +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->TxUnderrun + sp->TxLengthErrors +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->TxInternalMACXmitError +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->TxFramesWithExcessiveDeferral +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->TxFCSErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *underrun = sp->TxUnderrun;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *overrun = sp->RxFrameTooLongErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *framing = sp->RxAlignErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *crc = sp->RxFCSErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *carrier = 0; /* need to find this */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *collisions = sp->TxTotalCollisions;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *xcollisions = sp->TxFramesAbortedDueToXSCollisions;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *late = sp->TxLateCollisions;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *defer = sp->TxFramesWithDeferredXmissions;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *xerrs = sp->TxUnderrun + sp->TxLengthErrors +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->TxInternalMACXmitError + sp->TxFCSErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *rerrs = sp->RxSymbolErrors + sp->RxSequenceErrors + sp->RxRuntErrors +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->RxJabberErrors + sp->RxInternalMACRcvError +
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sp->RxInRangeLengthErrors + sp->RxOutOfRangeLengthField;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *toolong = sp->RxFrameTooLongErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *runt = sp->RxRuntErrors;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *multixmt = sp->TxMulticastFramesOK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *multircv = sp->RxMulticastFramesOK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *brdcstxmt = sp->TxBroadcastFramesOK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *brdcstrcv = sp->RxBroadcastFramesOK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwerror:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *speed = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *intrcnt = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *norcvbuf = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *norcvbuf = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *oerrors = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *ierrors = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *underrun = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *overrun = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *framing = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *crc = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *carrier = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *collisions = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *xcollisions = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *late = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *defer = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *xerrs = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *rerrs = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *toolong = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *runt = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *multixmt = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *multircv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *brdcstxmt = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *brdcstrcv = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_gtm = 0; /* Default: Global Tunnel Mode off */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_global_config = 0x07000000; /* Default: errors, warnings, status */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_is_asic = 0; /* Default: non-ASIC */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_link_speed = PE_LINK_SPEED_AUTONEG; /* Default: auto-negoiate */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_num_of_ports = 1; /* Default: 1 port */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_tp_reset_cm = 1; /* Default: reset CM memory map */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_phy_tx_fifo = 0; /* Default: 0 phy tx fifo depth */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_phy_rx_fifo = 0; /* Default: 0 phy rx fifo depth */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_phy_force_master = 1; /* Default: link always master mode */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_mc5_rtbl_size = 2048; /* Default: TCAM routing table size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_mc5_dbsvr_size = 128; /* Default: TCAM server size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_mc5_parity = 1; /* Default: parity error checking */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_mc5_issue_syn = 0; /* Default: Allow transaction overlap */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_packet_tracing = 0; /* Default: no packet tracing */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_server_region_len =
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DEFAULT_SERVER_REGION_LEN;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_rt_region_len =
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DEFAULT_RT_REGION_LEN;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_offload_ip_cksum = 0; /* Default: no checksum offloading */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_offload_udp_cksum = 1; /* Default: offload UDP ckecksum */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_offload_tcp_cksum = 1; /* Default: offload TCP checksum */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_cmdq_threshold = 0; /* Default: threshold 0 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_flq_threshold = 0; /* Default: SGE flq threshold */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_cmdq0_cnt = /* Default: cmd queue 0 size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_CMDQ0_CNT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_cmdq1_cnt = /* Default: cmd queue 1 size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_CMDQ0_CNT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_flq0_cnt = /* Default: free list queue-0 length */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_FLQ0_CNT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_flq1_cnt = /* Default: free list queue-1 length */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_FLQ0_CNT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_sge_respq_cnt = /* Default: reqsponse queue size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_RESPQ_CNT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_stats = 1; /* Default: Automatic Update MAC stats */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_tx_delay_us = 0; /* Default: No Msec delay to Tx pkts */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint32_t ch_chip = -1; /* Default: use hardware lookup tbl */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_exit_early = 0; /* Default: complete initialization */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_rb_num_of_entries = 1000; /* Default: number ring buffer entries */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_rb_size_of_entries = 64; /* Default: ring buffer entry size */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_rb_flag = 1; /* Default: ring buffer flag */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_type;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint64_t ch_cat_opt0 = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint64_t ch_cat_opt1 = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint32_t ch_timer_delay = 0; /* Default: use value from board entry */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_attach(ch_t *chp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int return_val = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw const struct board_info *bi;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t pcix_cmd;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) ch_set_config_data(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bi = pe_sa_init(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (bi == 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (t1_init_sw_modules(chp, bi) < 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe_small_rbuf_pool_init(chp) == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (pe_big_rbuf_pool_init(chp) == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We gain significaint performance improvements when we
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * increase the PCI's maximum memory read byte count to
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 2K(HW doesn't support 4K at this time) and set the PCI's
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * maximum outstanding split transactions to 4. We want to do
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * this for 10G. Done by software utility.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (board_info(chp)->caps & SUPPORTED_10000baseT_Full) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_os_pci_read_config_4(chp, A_PCICFG_PCIX_CMD,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw &pcix_cmd);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * if the burstsize is set, then use it instead of default
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (chp->ch_config.burstsize_set) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd &= ~0xc0000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd |= (chp->ch_config.burstsize << 18);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * if the split transaction count is set, then use it.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (chp->ch_config.transaction_cnt_set) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd &= ~ 0x700000;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd |= (chp->ch_config.transaction_cnt << 20);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * set ralaxed ordering flag as configured in chxge.conf
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd |= (chp->ch_config.relaxed_ordering << 17);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_os_pci_write_config_4(chp, A_PCICFG_PCIX_CMD,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pcix_cmd);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * set the latency time to F8 for 10G cards.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Done by software utiltiy.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (enable_latency_timer) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (board_info(chp)->caps & SUPPORTED_10000baseT_Full) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) t1_os_pci_write_config_4(chp, 0xc, 0xf800);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * update mtu table (regs: 0x404 - 0x420) with bigger values than
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * default.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw update_mtu_tab(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Clear all interrupts now. Don't enable
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * them until later.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_interrupts_clear(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Function succeeded.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return_val = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (return_val);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * DESC: Read variables set in /boot/loader.conf and save
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * them internally. These internal values are then
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * used to make decisions at run-time on behavior thus
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allowing a certain level of customization.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * OUT: p_config - pointer to config structure that
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * contains all of the new values.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * RTN: 0 - Success;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_set_config_data(ch_t *chp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe_config_data_t *p_config = (pe_config_data_t *)&chp->config_data;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bzero(p_config, sizeof (pe_config_data_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Global Tunnel Mode configuration
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->gtm = ch_gtm;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->global_config = ch_global_config;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (p_config->gtm)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->global_config |= CFGMD_TUNNEL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->tp_reset_cm = ch_tp_reset_cm;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->is_asic = ch_is_asic;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * MC5 configuration.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->mc5_rtbl_size = ch_mc5_rtbl_size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->mc5_dbsvr_size = ch_mc5_dbsvr_size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->mc5_parity = ch_mc5_parity;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->mc5_issue_syn = ch_mc5_issue_syn;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->offload_ip_cksum = ch_offload_ip_cksum;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->offload_udp_cksum = ch_offload_udp_cksum;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->offload_tcp_cksum = ch_offload_tcp_cksum;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->packet_tracing = ch_packet_tracing;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->server_region_len = ch_server_region_len;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->rt_region_len = ch_rt_region_len;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Link configuration.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 5-auto-neg 2-1000Gbps; 1-100Gbps; 0-10Gbps
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->link_speed = ch_link_speed;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->num_of_ports = ch_num_of_ports;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Catp options
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->cat_opt0 = ch_cat_opt0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->cat_opt1 = ch_cat_opt1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * SGE configuration.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_cmdq0_cnt = ch_sge_cmdq0_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_cmdq1_cnt = ch_sge_cmdq1_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_flq0_cnt = ch_sge_flq0_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_flq1_cnt = ch_sge_flq1_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_respq_cnt = ch_sge_respq_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->phy_rx_fifo = ch_phy_rx_fifo;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->phy_tx_fifo = ch_phy_tx_fifo;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_cmdq_threshold = ch_sge_cmdq_threshold;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->sge_flq_threshold = ch_sge_flq_threshold;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->phy_force_master = ch_phy_force_master;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->rb_num_of_entries = ch_rb_num_of_entries;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->rb_size_of_entries = ch_rb_size_of_entries;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->rb_flag = ch_rb_flag;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->exit_early = ch_exit_early;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->chip = ch_chip;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->stats = ch_stats;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw p_config->tx_delay_us = ch_tx_delay_us;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic const struct board_info *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_sa_init(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint16_t device_id;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint16_t device_subid;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw const struct board_info *bi;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->config = sa->config_data.global_config;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw device_id = pci_config_get16(sa->ch_hpci, 2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw device_subid = pci_config_get16(sa->ch_hpci, 0x2e);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bi = t1_get_board_info_from_ids(device_id, device_subid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (bi == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_NOTE,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw "The adapter with device_id %d %d is not supported.\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw device_id, device_subid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (NULL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (t1_get_board_rev(sa, bi, &sa->params)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_NOTE, "unknown device_id %d %d\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw device_id, device_subid);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((const struct board_info *)NULL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (bi);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allocate pool of small receive buffers (with vaddr & paddr) and
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * receiver buffer control structure (ch_esb_t *rbp).
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * XXX we should allow better tuning of the # of preallocated
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free buffers against the # of freelist entries.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_small_rbuf_pool_init(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw extern uint32_t sge_flq0_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw extern uint32_t sge_flq1_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t j;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (is_T2(sa))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw size = sge_flq1_cnt * fl_sz_multiplier;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw size = sge_flq0_cnt * fl_sz_multiplier;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_init(&sa->ch_small_esbl, NULL, MUTEX_DRIVER, sa->ch_icookp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&in_use_l);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw j = in_use_index++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (in_use_index >= SZ_INUSE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in_use_index = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&in_use_l);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_sm_index = j;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_esb_free = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < size; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = ch_alloc_small_esbbuf(sa, j);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * add entry to free list
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_next = sa->ch_small_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_esb_free = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * add entry to owned list
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_owner = sa->ch_small_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_owner = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwerror:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free whatever we've already allocated */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe_rbuf_pool_free(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allocate pool of receive buffers (with vaddr & paddr) and
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * receiver buffer control structure (ch_esb_t *rbp).
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * XXX we should allow better tuning of the # of preallocated
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free buffers against the # of freelist entries.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_big_rbuf_pool_init(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw extern uint32_t sge_flq0_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw extern uint32_t sge_flq1_cnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t j;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (is_T2(sa))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw size = sge_flq0_cnt * fl_sz_multiplier;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw size = sge_flq1_cnt * fl_sz_multiplier;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_init(&sa->ch_big_esbl, NULL, MUTEX_DRIVER, sa->ch_icookp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&in_use_l);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw j = in_use_index++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (in_use_index >= SZ_INUSE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw in_use_index = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&in_use_l);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_index = j;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_esb_free = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < size; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = ch_alloc_big_esbbuf(sa, j);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto error;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_next = sa->ch_big_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_esb_free = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * add entry to owned list
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_owner = sa->ch_big_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_owner = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwerror:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free whatever we've already allocated */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe_rbuf_pool_free(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allocate receive buffer structure and dma mapped buffer (SGE_SM_BUF_SZ bytes)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * note that we will DMA at a 2 byte offset for Solaris when checksum offload
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * is enabled.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic ch_esb_t *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_alloc_small_esbbuf(ch_t *sa, uint32_t i)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = (ch_esb_t *)kmem_zalloc(sizeof (ch_esb_t), KM_SLEEP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((ch_esb_t *)0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if BYTE_ORDER == BIG_ENDIAN
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 1, DMA_STREAM|DMA_SMALN,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_SM_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 0, DMA_STREAM|DMA_SMALN,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_SM_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp->cs_buf == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((ch_esb_t *)0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_sa = sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_index = i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_frtn.free_func = (void (*)())&ch_small_rbuf_recycle;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_frtn.free_arg = (caddr_t)rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * allocate receive buffer structure and dma mapped buffer (SGE_BG_BUF_SZ bytes)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * note that we will DMA at a 2 byte offset for Solaris when checksum offload
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * is enabled.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic ch_esb_t *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_alloc_big_esbbuf(ch_t *sa, uint32_t i)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = (ch_esb_t *)kmem_zalloc(sizeof (ch_esb_t), KM_SLEEP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((ch_esb_t *)0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if BYTE_ORDER == BIG_ENDIAN
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 1, DMA_STREAM|DMA_BGALN,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_BG_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_buf = (caddr_t)ch_alloc_dma_mem(sa, 0, DMA_STREAM|DMA_BGALN,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw SGE_BG_BUF_SZ(sa), &rbp->cs_pa, &rbp->cs_dh, &rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp->cs_buf == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return ((ch_esb_t *)0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_sa = sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_index = i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_frtn.free_func = (void (*)())&ch_big_rbuf_recycle;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_frtn.free_arg = (caddr_t)rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free entries on the receive buffer list.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_rbuf_pool_free(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Now set-up the rest to commit suicide.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (sa->ch_small_owner) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = sa->ch_small_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_owner = rbp->cs_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_flag = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while ((rbp = sa->ch_small_esb_free) != NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* advance head ptr to next entry */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_esb_free = rbp->cs_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free private buffer allocated in ch_alloc_esbbuf() */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free descripter buffer */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* destroy ch_esbl lock */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_destroy(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Now set-up the rest to commit suicide.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (sa->ch_big_owner) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = sa->ch_big_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_owner = rbp->cs_owner;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_owner = NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_flag = 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while ((rbp = sa->ch_big_esb_free) != NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* advance head ptr to next entry */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_esb_free = rbp->cs_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free private buffer allocated in ch_alloc_esbbuf() */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free descripter buffer */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* destroy ch_esbl lock */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_destroy(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_small_rbuf_recycle(ch_esb_t *rbp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_t *sa = rbp->cs_sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp->cs_flag) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free private buffer allocated in ch_alloc_esbbuf()
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw i = rbp->cs_index;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free descripter buffer
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * decrement count of receive buffers freed by callback
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We decrement here so anyone trying to do fini will
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * only remove the driver once the counts go to 0.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&buffers_in_use[i]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_next = sa->ch_small_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_esb_free = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * decrement count of receive buffers freed by callback
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&buffers_in_use[rbp->cs_index]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * callback function from freeb() when esballoced mblk freed.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_big_rbuf_recycle(ch_esb_t *rbp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_t *sa = rbp->cs_sa;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp->cs_flag) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint32_t i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free private buffer allocated in ch_alloc_esbbuf()
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_free_dma_mem(rbp->cs_dh, rbp->cs_ah);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw i = rbp->cs_index;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free descripter buffer
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw kmem_free(rbp, sizeof (ch_esb_t));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * decrement count of receive buffers freed by callback
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We decrement here so anyone trying to do fini will
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * only remove the driver once the counts go to 0.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&buffers_in_use[i]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp->cs_next = sa->ch_big_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_esb_free = rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * decrement count of receive buffers freed by callback
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&buffers_in_use[rbp->cs_index]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * get a pre-allocated, pre-mapped receive buffer from free list.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * (used sge.c)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_esb_t *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_get_small_rbuf(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = sa->ch_small_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_small_esb_free = rbp->cs_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_small_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * get a pre-allocated, pre-mapped receive buffer from free list.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * (used sge.c)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_esb_t *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwch_get_big_rbuf(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ch_esb_t *rbp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rbp = sa->ch_big_esb_free;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rbp) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sa->ch_big_esb_free = rbp->cs_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&sa->ch_big_esbl);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (rbp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_detach(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) sge_stop(sa->sge);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe_free_driver_resources(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_free_driver_resources(ch_t *sa)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (sa) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_free_sw_modules(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* free pool of receive buffers */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pe_rbuf_pool_free(sa);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Processes elmer0 external interrupts in process context.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwext_intr_task(ch_t *adapter)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 enable;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw (void) elmer0_ext_intr_handler(adapter);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Now reenable external interrupts */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_PL_CAUSE, F_PL_INTR_EXT);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw enable = t1_read_reg_4(adapter, A_PL_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_PL_ENABLE, enable | F_PL_INTR_EXT);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter->slow_intr_mask |= F_PL_INTR_EXT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Interrupt-context handler for elmer0 external interrupts.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_elmer0_ext_intr(ch_t *adapter)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 enable = t1_read_reg_4(adapter, A_PL_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_PL_ENABLE, enable & ~F_PL_INTR_EXT);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef NOTYET
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw schedule_work(&adapter->ext_intr_handler_task);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ext_intr_task(adapter);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwuint8_t *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_get_next_mcaddr(struct t1_rx_mode *rmp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint8_t *addr = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rmp->mc) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw addr = rmp->mc->cmc_mca;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw rmp->mc = rmp->mc->cmc_next;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (addr);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_dma_handle_init(ch_t *chp, int cnt)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw free_dh_t *dhe;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#if defined(__sparc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int tcnt = cnt/2;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (; cnt; cnt--) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dhe = ch_get_dvma_handle(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (dhe == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&chp->ch_dh_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dhe->dhe_next = chp->ch_vdh;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw chp->ch_vdh = dhe;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&chp->ch_dh_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cnt += tcnt;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (cnt--) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dhe = ch_get_dma_handle(chp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (dhe == NULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_enter(&chp->ch_dh_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dhe->dhe_next = chp->ch_dh;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw chp->ch_dh = dhe;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mutex_exit(&chp->ch_dh_lck);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Write new values to the MTU table. Caller must validate that the new MTUs
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * are in ascending order. params.mtus[] is initialized by init_mtus()
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * called in t1_init_sw_modules().
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MTUREG(idx) (A_TP_MTU_REG0 + (idx) * 4)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwupdate_mtu_tab(ch_t *adapter)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < NMTUS; ++i) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int mtu = (unsigned int)adapter->params.mtus[i];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, MTUREG(i), mtu);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_change_mtu(ch_t *chp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cmac *mac = chp->port[0].mac;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int ret;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!mac->ops->set_mtu) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (EOPNOTSUPP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (chp->ch_mtu < 68) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (EINVAL);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (ret = mac->ops->set_mtu(mac, chp->ch_mtu)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (ret);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwtypedef struct fake_arp {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_dst[6]; /* ethernet header */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_src[6]; /* ethernet header */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ushort_t fa_typ; /* ethernet header */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ushort_t fa_hrd; /* arp */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ushort_t fa_pro;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_hln;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_pln;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw ushort_t fa_op;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_src_mac[6];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw uint_t fa_src_ip;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_dst_mac[6];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw char fa_dst_ip[4];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw} fake_arp_t;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * PR2928 & PR3309
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * construct packet in mblk and attach it to sge structure.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_make_fake_arp(ch_t *chp, unsigned char *arpp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pesge *sge = chp->sge;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mblk_t *bp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw fake_arp_t *fap;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw static char buf[6] = {0, 7, 0x43, 0, 0, 0};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct cpl_tx_pkt *cpl;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bp = allocb(sizeof (struct fake_arp) + SZ_CPL_TX_PKT, BPRI_HI);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (bp == NULL) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bzero(bp->b_rptr, sizeof (struct fake_arp) + SZ_CPL_TX_PKT);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* fill in cpl header */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl = (struct cpl_tx_pkt *)bp->b_rptr;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->opcode = CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->iff = 0; /* XXX port 0 needs fixing with NEMO */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->ip_csum_dis = 1; /* no IP header cksum */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->l4_csum_dis = 1; /* no tcp/udp cksum */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cpl->vlan_valid = 0; /* no vlan */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw fap = (fake_arp_t *)&bp->b_rptr[SZ_CPL_TX_PKT];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(arpp, fap, sizeof (*fap)); /* copy first arp to mblk */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(buf, fap->fa_dst, 6); /* overwrite dst mac */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw chp->ch_ip = fap->fa_src_ip; /* not used yet */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(buf, fap->fa_dst_mac, 6); /* overwrite dst mac */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bp->b_wptr = bp->b_rptr + sizeof (struct fake_arp)+SZ_CPL_TX_PKT;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw sge_add_fake_arp(sge, (void *)bp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * PR2928 & PR3309
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * free the fake arp's mblk on sge structure.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_free_fake_arp(void *arp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mblk_t *bp = (mblk_t *)(arp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw freemsg(bp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * extract ip address of nic from first outgoing arp.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic uint32_t
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwpe_get_ip(unsigned char *arpp)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw fake_arp_t fap;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * first copy packet to buffer so we know
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * it will be properly aligned.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bcopy(arpp, &fap, sizeof (fap)); /* copy first arp to buffer */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return (fap.fa_src_ip);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* ARGSUSED */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwt1_os_link_changed(ch_t *obj, int port_id, int link_status,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int speed, int duplex, int fc)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw gld_mac_info_t *macinfo = obj->ch_macp;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (link_status) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw gld_linkstate(macinfo, GLD_LINKSTATE_UP);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Link states should be reported to user
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * whenever it changes
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_NOTE, "%s: link is up", adapter_name(obj));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw gld_linkstate(macinfo, GLD_LINKSTATE_DOWN);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Link states should be reported to user
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * whenever it changes
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cmn_err(CE_NOTE, "%s: link is down", adapter_name(obj));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}