56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * This file and its contents are supplied under the terms of the
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Common Development and Distribution License ("CDDL"), version 1.0.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * You may only use this file in accordance with the terms of version
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * 1.0 of the CDDL.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * A full copy of the text of the CDDL should have accompanied this
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * source. A copy of the CDDL is also available via the Internet at
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * http://www.illumos.org/license/CDDL.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * This file is part of the Chelsio T4 support code.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Copyright (C) 2010-2013 Chelsio Communications. All rights reserved.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * This program is distributed in the hope that it will be useful, but WITHOUT
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * release for licensing terms and conditions.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/ddi.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/sunddi.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/sunndi.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/modctl.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/conf.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/devops.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/pci.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/atomic.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/types.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/file.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/errno.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/open.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/cred.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/stat.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/mkdev.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include <sys/queue.h>
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "version.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "common/common.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "common/t4_regs.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "firmware/t4_fw.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "firmware/t4_cfg.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#include "t4_l2t.h"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_cb_open(dev_t *devp, int flag, int otyp, cred_t *credp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_cb_close(dev_t dev, int flag, int otyp, cred_t *credp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_cb_ioctl(dev_t dev, int cmd, intptr_t d, int mode, cred_t *credp,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int *rp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastruct cb_ops t4_cb_ops = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_open = t4_cb_open,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_close = t4_cb_close,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_strategy = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_print = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_dump = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_read = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_write = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_ioctl = t4_cb_ioctl,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_devmap = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_mmap = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_segmap = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_chpoll = nochpoll,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_prop_op = ddi_prop_op,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_flag = D_MP,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_rev = CB_REV,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_aread = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .cb_awrite = nodev
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void *arg, void *result);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_bus_config(dev_info_t *dip, uint_t flags, ddi_bus_config_op_t op,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void *arg, dev_info_t **cdipp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_bus_unconfig(dev_info_t *dip, uint_t flags,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_bus_config_op_t op, void *arg);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastruct bus_ops t4_bus_ops = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .busops_rev = BUSO_REV,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .bus_ctl = t4_bus_ctl,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .bus_prop_op = ddi_bus_prop_op,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .bus_config = t4_bus_config,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .bus_unconfig = t4_bus_unconfig,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_devo_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void **rp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_devo_probe(dev_info_t *dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_devo_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_devo_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int t4_devo_quiesce(dev_info_t *dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastruct dev_ops t4_dev_ops = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_rev = DEVO_REV,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_getinfo = t4_devo_getinfo,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_identify = nulldev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_probe = t4_devo_probe,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_attach = t4_devo_attach,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_detach = t4_devo_detach,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_reset = nodev,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_cb_ops = &t4_cb_ops,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_bus_ops = &t4_bus_ops,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devo_quiesce = &t4_devo_quiesce,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic struct modldrv modldrv = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .drv_modops = &mod_driverops,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .drv_linkinfo = "Chelsio T4 nexus " DRV_VERSION,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .drv_dev_ops = &t4_dev_ops
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic struct modlinkage modlinkage = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .ml_rev = MODREV_1,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .ml_linkage = {&modldrv, NULL},
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid *t4_list;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastruct intrs_and_queues {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int intr_type; /* DDI_INTR_TYPE_* */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nirq; /* Number of vectors */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int intr_fwd; /* Interrupts forwarded */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int ntxq10g; /* # of NIC txq's for each 10G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nrxq10g; /* # of NIC rxq's for each 10G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int ntxq1g; /* # of NIC txq's for each 1G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nrxq1g; /* # of NIC rxq's for each 1G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nofldtxq10g; /* # of TOE txq's for each 10G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nofldrxq10g; /* # of TOE rxq's for each 10G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nofldtxq1g; /* # of TOE txq's for each 1G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nofldrxq1g; /* # of TOE rxq's for each 1G port */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int cpl_not_handled(struct sge_iq *iq, const struct rss_header *rss,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mblk_t *m);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint t4_register_cpl_handler(struct adapter *sc, int opcode, cpl_handler_t h);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic unsigned int getpf(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int prep_firmware(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int upload_config_file(struct adapter *sc, uint32_t *mt, uint32_t *ma);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int partition_resources(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int get_params__pre_init(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int get_params__post_init(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic void setup_memwin(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int prop_lookup_int_array(struct adapter *sc, char *name, int *data,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t count);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int prop_lookup_int_array(struct adapter *sc, char *name, int *data,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t count);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int init_driver_props(struct adapter *sc, struct driver_properties *p);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int remove_extra_props(struct adapter *sc, int n10g, int n1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int cfg_itype_and_nqueues(struct adapter *sc, int n10g, int n1g,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct intrs_and_queues *iaq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int add_child_node(struct adapter *sc, int idx);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int remove_child_node(struct adapter *sc, int idx);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic kstat_t *setup_kstats(struct adapter *sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int toe_capability(struct port_info *pi, int enable);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int activate_uld(struct adapter *sc, int id, struct uld_softc *usc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int deactivate_uld(struct uld_softc *usc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic kmutex_t t4_adapter_list_lock;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic SLIST_HEAD(, adapter) t4_adapter_list;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic kmutex_t t4_uld_list_lock;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic SLIST_HEAD(, uld_info) t4_uld_list;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana_init(void)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_soft_state_init(&t4_list, sizeof (struct adapter), 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = mod_install(&modlinkage);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_soft_state_fini(&t4_list);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_init(&t4_adapter_list_lock, NULL, MUTEX_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_INIT(&t4_adapter_list);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_init(&t4_uld_list_lock, NULL, MUTEX_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_INIT(&t4_uld_list);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana_fini(void)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = mod_remove(&modlinkage);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_soft_state_fini(&t4_list);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana_info(struct modinfo *mi)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (mod_info(&modlinkage, mi));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* ARGSUSED */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_devo_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **rp)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana minor_t minor;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana minor = getminor((dev_t)arg); /* same as instance# in our case */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (cmd == DDI_INFO_DEVT2DEVINFO) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, minor);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(sc->dev == (dev_t)arg);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *rp = (void *)sc->dip;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else if (cmd == DDI_INFO_DEVT2INSTANCE)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *rp = (void *) (unsigned long) minor;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_devo_probe(dev_info_t *dip)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, id, *reg;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t n, pf;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "device-id", 0xffff);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (id == 0xffff)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_PROBE_DONTCARE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "reg", &reg, &n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_PROBE_DONTCARE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pf = PCI_REG_FUNC_G(reg[0]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_free(reg);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Prevent driver attachment on any PF except 0 on the FPGA */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (id == 0xa000 && pf != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_PROBE_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_PROBE_DONTCARE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_devo_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc = NULL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge *s;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i, instance, rc = DDI_SUCCESS, n10g, n1g, rqidx, tqidx, q;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int irq = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int ofld_rqidx, ofld_tqidx;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana char name[16];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct driver_properties *prp;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct intrs_and_queues iaq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_device_acc_attr_t da = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devacc_attr_version = DDI_DEVICE_ATTR_V0,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana .devacc_attr_dataorder = DDI_UNORDERED_OK_ACC
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana };
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (cmd != DDI_ATTACH)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Allocate space for soft state.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_soft_state_zalloc(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to allocate soft state: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->dip = dip;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->dev = makedevice(ddi_driver_major(dip), instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_init(&sc->lock, NULL, MUTEX_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cv_init(&sc->cv, NULL, CV_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_init(&sc->sfl_lock, NULL, MUTEX_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_INSERT_HEAD(&t4_adapter_list, sc, link);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->pf = getpf(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->pf > 8) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = EINVAL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to determine PCI PF# of device");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->mbox = sc->pf;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Enable access to the PCI config space.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = pci_config_setup(dip, &sc->pci_regh);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to enable PCI config space access: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* TODO: Set max read request to 4K */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Enable MMIO access.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_regs_map_setup(dip, 1, &sc->regp, 0, 0, &da, &sc->regh);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to map device registers: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) memset(sc->chan_map, 0xff, sizeof (sc->chan_map));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Initialize cpl handler.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < ARRAY_SIZE(sc->cpl_handler); i++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->cpl_handler[i] = cpl_not_handled;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Prepare the adapter for operation.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_prep_adapter(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN, "failed to prepare adapter: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Do this really early. Note that minor number = instance.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) snprintf(name, sizeof (name), "%s,%d", T4_NEXUS_NAME, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_create_minor_node(dip, name, S_IFCHR, instance,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana DDI_NT_NEXUS, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to create device node: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = DDI_SUCCESS; /* carry on */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Initialize the driver properties */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana prp = &sc->props;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) init_driver_props(sc, prp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Do this early. Memory window is required for loading config file. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana setup_memwin(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Prepare the firmware for operation */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = prep_firmware(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = get_params__pre_init(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_sge_init(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->flags & MASTER_PF) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* get basic stuff going */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_fw_initialize(sc, sc->mbox);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "early init failed: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = get_params__post_init(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * TODO: This is the place to call t4_set_filter_mode()
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* tweak some settings */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, A_TP_SHIFT_CNT, V_SYNSHIFTMAX(6) | V_RXTSHIFTMAXR1(4) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_RXTSHIFTMAXR2(15) | V_PERSHIFTBACKOFFMAX(8) | V_PERSHIFTMAX(8) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_KEEPALIVEMAXR1(4) | V_KEEPALIVEMAXR2(9));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, A_ULP_RX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Work-around for bug 2619
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Set DisableVlan field in TP_RSS_CONFIG_VRT register so that the
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * VLAN tag extraction is disabled.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_set_reg_field(sc, A_TP_RSS_CONFIG_VRT, F_DISABLEVLAN, F_DISABLEVLAN);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Store filter mode */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_read_indirect(sc, A_TP_PIO_ADDR, A_TP_PIO_DATA, &sc->filter_mode, 1,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana A_TP_VLAN_PRI_MAP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * First pass over all the ports - allocate VIs and initialize some
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * basic parameters like mac address, port type, etc. We also figure
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * out whether a port is 10G or 1G and use that information when
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * calculating how many interrupts to attempt to allocate.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g = n1g = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = kmem_zalloc(sizeof (*pi), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->port[i] = pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* These must be set before t4_port_init */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->adapter = sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->port_id = i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Allocate the vi and initialize parameters like mac addr */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_port_init(pi, sc->mbox, sc->pf, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "unable to initialize port %d: %d", i, rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(pi, sizeof (*pi));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->port[i] = NULL; /* indicates init failed */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_init(&pi->lock, NULL, MUTEX_DRIVER, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->mtu = ETHERMTU;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (is_10G_port(pi) != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->tmr_idx = prp->tmr_idx_10g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->pktc_idx = prp->pktc_idx_10g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n1g++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->tmr_idx = prp->tmr_idx_1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->pktc_idx = prp->pktc_idx_1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->xact_addr_filt = -1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_mc_init(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana setbit(&sc->registered_device_map, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) remove_extra_props(sc, n10g, n1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->registered_device_map == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN, "no usable ports");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = DDI_FAILURE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = cfg_itype_and_nqueues(sc, n10g, n1g, &iaq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_type = iaq.intr_type;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_count = iaq.nirq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s = &sc->sge;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->nrxq = n10g * iaq.nrxq10g + n1g * iaq.nrxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->ntxq = n10g * iaq.ntxq10g + n1g * iaq.ntxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->neq = s->ntxq + s->nrxq; /* the fl in an rxq is an eq */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* control queues, 1 per port + 1 mgmtq */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->neq += sc->params.nports + 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->niq = s->nrxq + 1; /* 1 extra for firmware event queue */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (iaq.intr_fwd != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags |= INTR_FWD;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (is_offload(sc) != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->nofldrxq = n10g * iaq.nofldrxq10g + n1g * iaq.nofldrxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->nofldtxq = n10g * iaq.nofldtxq10g + n1g * iaq.nofldtxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->neq += s->nofldtxq + s->nofldrxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->niq += s->nofldrxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->ofld_rxq = kmem_zalloc(s->nofldrxq *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sizeof (struct sge_ofld_rxq), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->ofld_txq = kmem_zalloc(s->nofldtxq *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sizeof (struct sge_wrq), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->ctrlq = kmem_zalloc(sc->params.nports *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sizeof (struct sge_wrq), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->rxq = kmem_zalloc(s->nrxq * sizeof (struct sge_rxq), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->txq = kmem_zalloc(s->ntxq * sizeof (struct sge_txq), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->iqmap = kmem_zalloc(s->niq * sizeof (struct sge_iq *), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->eqmap = kmem_zalloc(s->neq * sizeof (struct sge_eq *), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_handle = kmem_zalloc(sc->intr_count *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sizeof (ddi_intr_handle_t), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Second pass over the ports. This time we know the number of rx and
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * tx queues that each port should get.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rqidx = tqidx = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ofld_rqidx = ofld_tqidx = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi = sc->port[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->first_rxq = rqidx;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->nrxq = is_10G_port(pi) ? iaq.nrxq10g : iaq.nrxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->first_txq = tqidx;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->ntxq = is_10G_port(pi) ? iaq.ntxq10g : iaq.ntxq1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rqidx += pi->nrxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana tqidx += pi->ntxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (is_offload(sc) != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->first_ofld_rxq = ofld_rqidx;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->nofldrxq = max(1, pi->nrxq / 4);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->first_ofld_txq = ofld_tqidx;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->nofldtxq = max(1, pi->ntxq / 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ofld_rqidx += pi->nofldrxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ofld_tqidx += pi->nofldtxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Enable hw checksumming and LSO for all ports by default.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * They can be disabled using ndd (hw_csum and hw_lso).
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->features |= (CXGBE_HW_CSUM | CXGBE_HW_LSO);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->l2t = t4_init_l2t(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Setup Interrupts.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_intr_alloc(dip, sc->intr_handle, sc->intr_type, 0,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_count, &i, DDI_INTR_ALLOC_STRICT);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to allocate %d interrupt(s) of type %d: %d, %d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_count, sc->intr_type, rc, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(sc->intr_count == i); /* allocation was STRICT */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_get_cap(sc->intr_handle[0], &sc->intr_cap);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_get_pri(sc->intr_handle[0], &sc->intr_pri);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->intr_count == 1) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(sc->flags & INTR_FWD);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_add_handler(sc->intr_handle[0], t4_intr_all, sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana &s->fwq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Multiple interrupts. The first one is always error intr */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_add_handler(sc->intr_handle[0], t4_intr_err, sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana irq++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* The second one is always the firmware event queue */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_add_handler(sc->intr_handle[1], t4_intr, sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana &s->fwq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana irq++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Note that if INTR_FWD is set then either the NIC rx
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * queues or (exclusive or) the TOE rx queueus will be taking
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * direct interrupts.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * There is no need to check for is_offload(sc) as nofldrxq
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * will be 0 if offload is disabled.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi = sc->port[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_rxq *rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_ofld_rxq *ofld_rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Skip over the NIC queues if they aren't taking direct
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * interrupts.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if ((sc->flags & INTR_FWD) &&
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->nofldrxq > pi->nrxq)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto ofld_queues;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rxq = &s->rxq[pi->first_rxq];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (q = 0; q < pi->nrxq; q++, rxq++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_add_handler(
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_handle[irq], t4_intr, sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana &rxq->iq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana irq++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Skip over the offload queues if they aren't taking
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * direct interrupts.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if ((sc->flags & INTR_FWD))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaofld_queues:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ofld_rxq = &s->ofld_rxq[pi->first_ofld_rxq];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (q = 0; q < pi->nofldrxq; q++, ofld_rxq++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_add_handler(
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_handle[irq], t4_intr, sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana &ofld_rxq->iq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana irq++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags |= INTR_ALLOCATED;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(rc == DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_report_dev(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n10g && n1g) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "%dx10G %dx1G (%d rxq, %d txq total) %d %s.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g, n1g, rqidx, tqidx, sc->intr_count,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_type == DDI_INTR_TYPE_MSIX ? "MSI-X interrupts" :
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_type == DDI_INTR_TYPE_MSI ? "MSI interrupts" :
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "fixed interrupt");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "%dx%sG (%d rxq, %d txq per port) %d %s.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g ? n10g : n1g,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g ? "10" : "1",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g ? iaq.nrxq10g : iaq.nrxq1g,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n10g ? iaq.ntxq10g : iaq.ntxq1g,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_count,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_type == DDI_INTR_TYPE_MSIX ? "MSI-X interrupts" :
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_type == DDI_INTR_TYPE_MSI ? "MSI interrupts" :
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "fixed interrupt");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->ksp = setup_kstats(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_devo_detach(dip, DDI_DETACH);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* rc may have errno style errors or DDI errors */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = DDI_FAILURE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_devo_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int instance, i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge *s;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (cmd != DDI_DETACH)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->flags & FULL_INIT_DONE) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_intr_disable(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = sc->port[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi && pi->flags & PORT_INIT_DONE)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) port_full_uninit(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) adapter_full_uninit(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Safe to call no matter what */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_remove_all(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_remove_minor_node(dip, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->ksp != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_delete(sc->ksp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s = &sc->sge;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->rxq != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->rxq, s->nrxq * sizeof (struct sge_rxq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->ofld_txq != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->ofld_txq, s->nofldtxq * sizeof (struct sge_wrq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->ofld_rxq != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->ofld_rxq,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana s->nofldrxq * sizeof (struct sge_ofld_rxq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->ctrlq != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->ctrlq,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.nports * sizeof (struct sge_wrq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->txq != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->txq, s->ntxq * sizeof (struct sge_txq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->iqmap != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->iqmap, s->niq * sizeof (struct sge_iq *));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->eqmap != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(s->eqmap, s->neq * sizeof (struct sge_eq *));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (s->rxbuf_cache != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rxbuf_cache_destroy(s->rxbuf_cache);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->flags & INTR_ALLOCATED) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < sc->intr_count; i++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_remove_handler(sc->intr_handle[i]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_free(sc->intr_handle[i]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags &= ~INTR_ALLOCATED;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->intr_handle != NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(sc->intr_handle,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->intr_count * sizeof (*sc->intr_handle));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = sc->port[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi != NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_destroy(&pi->lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(pi, sizeof (*pi));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana clrbit(&sc->registered_device_map, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->flags & FW_OK)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_fw_bye(sc, sc->mbox);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->regh != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_regs_map_free(&sc->regh);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->pci_regh != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pci_config_teardown(&sc->pci_regh);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_REMOVE_HEAD(&t4_adapter_list, link);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_destroy(&sc->lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cv_destroy(&sc->cv);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_destroy(&sc->sfl_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifdef DEBUG
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(sc, sizeof (*sc));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_soft_state_free(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_devo_quiesce(dev_info_t *dip)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int instance;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_set_reg_field(sc, A_SGE_CONTROL, F_GLOBALENABLE, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_intr_disable(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, A_PL_RST, F_PIORSTMODE | F_PIORST);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void *result)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana char s[4];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_info_t *child = (dev_info_t *)arg;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana switch (op) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case DDI_CTLOPS_REPORTDEV:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = ddi_get_parent_data(rdip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->child_inst = ddi_get_instance(rdip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cmn_err(CE_CONT, "?%s%d is port %s on %s%d\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_node_name(rdip), ddi_get_instance(rdip),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_get_name_addr(rdip), ddi_driver_name(dip),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_get_instance(dip));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case DDI_CTLOPS_INITCHILD:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = ddi_get_parent_data(child);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_NOT_WELL_FORMED);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) snprintf(s, sizeof (s), "%d", pi->port_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_set_name_addr(child, s);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case DDI_CTLOPS_UNINITCHILD:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_set_name_addr(child, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case DDI_CTLOPS_ATTACH:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case DDI_CTLOPS_DETACH:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana default:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ddi_ctlops(dip, rdip, op, arg, result));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_bus_config(dev_info_t *dip, uint_t flags, ddi_bus_config_op_t op, void *arg,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_info_t **cdipp)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int instance, i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (op == BUS_CONFIG_ONE) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana char *c;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * arg is something like "cxgb@0" where 0 is the port_id hanging
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * off this nexus.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana c = arg;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (*(c + 1))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana c++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* There should be exactly 1 digit after '@' */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (*(c - 1) != '@')
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (NDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i = *c - '0';
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (add_child_node(sc, i) != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (NDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana flags |= NDI_ONLINE_ATTACH;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else if (op == BUS_CONFIG_ALL || op == BUS_CONFIG_DRIVER) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Allocate and bind all child device nodes */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) add_child_node(sc, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana flags |= NDI_ONLINE_ATTACH;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ndi_busop_bus_config(dip, flags, op, arg, cdipp, 0));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_bus_unconfig(dev_info_t *dip, uint_t flags, ddi_bus_config_op_t op,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void *arg)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int instance, i, rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = ddi_get_instance(dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (op == BUS_CONFIG_ONE || op == BUS_UNCONFIG_ALL ||
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana op == BUS_UNCONFIG_DRIVER)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana flags |= NDI_UNCONFIG;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ndi_busop_bus_unconfig(dip, flags, op, arg);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (op == BUS_UNCONFIG_ONE) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana char *c;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana c = arg;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (*(c + 1))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana c++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (*(c - 1) != '@')
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (NDI_SUCCESS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i = *c - '0';
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = remove_child_node(sc, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else if (op == BUS_UNCONFIG_ALL || op == BUS_UNCONFIG_DRIVER) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) remove_child_node(sc, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* ARGSUSED */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_cb_open(dev_t *devp, int flag, int otyp, cred_t *credp)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (otyp != OTYP_CHR)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, getminor(*devp));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ENXIO);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (atomic_cas_uint(&sc->open, 0, EBUSY));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* ARGSUSED */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_cb_close(dev_t dev, int flag, int otyp, cred_t *credp)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, getminor(dev));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) atomic_swap_uint(&sc->open, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* ARGSUSED */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_cb_ioctl(dev_t dev, int cmd, intptr_t d, int mode, cred_t *credp, int *rp)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int instance;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana void *data = (void *)d;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (crgetuid(credp) != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EPERM);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana instance = getminor(dev);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc = ddi_get_soft_state(t4_list, instance);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (t4_ioctl(sc, cmd, data, mode));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic unsigned int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanagetpf(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, *data;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t n, pf;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sc->dip,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana DDI_PROP_DONTPASS, "reg", &data, &n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to lookup \"reg\" property: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0xff);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pf = PCI_REG_FUNC_G(data[0]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_free(data);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (pf);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Install a compatible firmware (if required), establish contact with it,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * become the master, and reset the device.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaprep_firmware(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana enum dev_state state;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Check firmware version and install a different one if necessary */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = t4_check_fw_version(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint32_t v;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* This is what the driver has */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana v = V_FW_HDR_FW_VER_MAJOR(T4FW_VERSION_MAJOR) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_HDR_FW_VER_MINOR(T4FW_VERSION_MINOR) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_HDR_FW_VER_MICRO(T4FW_VERSION_MICRO) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_HDR_FW_VER_BUILD(T4FW_VERSION_BUILD);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Always upgrade, even for minor/micro/build mismatches.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Downgrade only for a major version mismatch.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc < 0 || v > sc->params.fw_vers) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "installing firmware %d.%d.%d.%d on card.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana T4FW_VERSION_MAJOR, T4FW_VERSION_MINOR,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana T4FW_VERSION_MICRO, T4FW_VERSION_BUILD);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_load_fw(sc, t4fw_data, t4fw_size);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to install firmware: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* refresh */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_check_fw_version(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Contact firmware, request master */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = t4_fw_hello(sc, sc->mbox, sc->mbox, MASTER_MUST, &state);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc < 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to connect to the firmware: %d.", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == sc->mbox)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags |= MASTER_PF;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Reset device */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_fw_reset(sc, sc->mbox, F_PIORSTMODE | F_PIORST);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "firmware reset failed: %d.", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != ETIMEDOUT && rc != EIO)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_fw_bye(sc, sc->mbox);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Partition adapter resources as specified in the config file. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->flags & MASTER_PF) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Handle default vs special T4 config file */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = partition_resources(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto err; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags |= FW_OK;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaerr:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define FW_PARAM_DEV(param) \
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define FW_PARAM_PFVF(param) \
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Upload configuration file to card's memory.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaupload_config_file(struct adapter *sc, uint32_t *mt, uint32_t *ma)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint32_t param, val, mtype, maddr, bar, off, win, remaining;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana const uint32_t *b;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Figure out where the firmware wants us to upload it. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param = FW_PARAM_DEV(CF);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, &param, &val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Firmwares without config file support will fail this way */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to query config file location: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *mt = mtype = G_FW_PARAMS_PARAM_Y(val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *ma = maddr = G_FW_PARAMS_PARAM_Z(val) << 16;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (maddr & 3) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "cannot upload config file (type %u, addr %x).\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mtype, maddr);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EFAULT);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Translate mtype/maddr to an address suitable for the PCIe window */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana val = t4_read_reg(sc, A_MA_TARGET_MEM_ENABLE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana val &= F_EDRAM0_ENABLE | F_EDRAM1_ENABLE | F_EXT_MEM_ENABLE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana switch (mtype) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case FW_MEMTYPE_CF_EDC0:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (!(val & F_EDRAM0_ENABLE))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto err;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bar = t4_read_reg(sc, A_MA_EDRAM0_BAR);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana maddr += G_EDRAM0_BASE(bar) << 20;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana break;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case FW_MEMTYPE_CF_EDC1:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (!(val & F_EDRAM1_ENABLE))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto err;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bar = t4_read_reg(sc, A_MA_EDRAM1_BAR);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana maddr += G_EDRAM1_BASE(bar) << 20;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana break;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana case FW_MEMTYPE_CF_EXTMEM:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (!(val & F_EXT_MEM_ENABLE))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto err;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bar = t4_read_reg(sc, A_MA_EXT_MEMORY_BAR);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana maddr += G_EXT_MEM_BASE(bar) << 20;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana break;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana default:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaerr:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "cannot upload config file (type %u, enabled %u).\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mtype, val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EFAULT);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Position the PCIe window (we use memwin2) to the 16B aligned area
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * just at/before the upload location.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana win = maddr & ~0xf;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana off = maddr - win; /* offset from the start of the window. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, 2), win);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_read_reg(sc,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, 2));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana remaining = t4cfg_size;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (remaining > FLASH_CFG_MAX_SIZE ||
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana remaining > MEMWIN2_APERTURE - off) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN, "cannot upload config file all at"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana " once (size %u, max %u, room %u).\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana remaining, FLASH_CFG_MAX_SIZE, MEMWIN2_APERTURE - off);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EFBIG);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * TODO: sheer laziness. We deliberately added 4 bytes of useless
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * stuffing/comments at the end of the config file so it's ok to simply
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * throw away the last remaining bytes when the config file is not an
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * exact multiple of 4.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_BAD_PTR_CAST_ALIGN */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana b = (const uint32_t *)t4cfg_data;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; remaining >= 4; i += 4, remaining -= 4)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, MEMWIN2_BASE + off + i, *b++);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Partition chip resources for use between various PFs, VFs, etc. This is done
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * by uploading the firmware configuration file to the adapter and instructing
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * the firmware to process it.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanapartition_resources(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct fw_caps_config_cmd caps;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint32_t mtype, maddr, finicsum, cfcsum;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = upload_config_file(sc, &mtype, &maddr);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mtype = FW_MEMTYPE_CF_FLASH;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana maddr = t4_flash_cfg_addr(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(&caps, sizeof (caps));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.op_to_write = BE_32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana F_FW_CMD_REQUEST | F_FW_CMD_READ);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.cfvalid_to_len16 = BE_32(F_FW_CAPS_CONFIG_CMD_CFVALID |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(maddr >> 16) | FW_LEN16(caps));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof (caps), &caps);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to pre-process config file: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana finicsum = ntohl(caps.finicsum);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cfcsum = ntohl(caps.cfcsum);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (finicsum != cfcsum) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "WARNING: config file checksum mismatch: %08x %08x\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana finicsum, cfcsum);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->cfcsum = cfcsum;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* TODO: Need to configure this correctly */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.toecaps = htons(FW_CAPS_CONFIG_TOE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.iscsicaps = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.rdmacaps = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.fcoecaps = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* TODO: Disable VNIC cap for now */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana F_FW_CMD_REQUEST | F_FW_CMD_WRITE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.cfvalid_to_len16 = htonl(FW_LEN16(caps));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof (caps), NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to process config file: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Retrieve parameters that are needed (or nice to have) prior to calling
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * t4_sge_init and t4_fw_initialize.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaget_params__pre_init(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint32_t param[2], val[2];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct fw_devlog_cmd cmd;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct devlog_params *dlog = &sc->params.devlog;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[0] = FW_PARAM_DEV(PORTVEC);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[1] = FW_PARAM_DEV(CCLK);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 2, param, val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to query parameters (pre_init): %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.portvec = val[0];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.nports = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (val[0]) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.nports++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana val[0] &= val[0] - 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.vpd.cclk = val[1];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Read device log parameters. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(&cmd, sizeof (cmd));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cmd.op_to_write = htonl(V_FW_CMD_OP(FW_DEVLOG_CMD) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana F_FW_CMD_REQUEST | F_FW_CMD_READ);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cmd.retval_len16 = htonl(FW_LEN16(cmd));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_wr_mbox(sc, sc->mbox, &cmd, sizeof (cmd), &cmd);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to get devlog parameters: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(dlog, sizeof (*dlog));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = 0; /* devlog isn't critical for device operation */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana val[0] = ntohl(cmd.memtype_devlog_memaddr16_devlog);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dlog->memtype = G_FW_DEVLOG_CMD_MEMTYPE_DEVLOG(val[0]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dlog->start = G_FW_DEVLOG_CMD_MEMADDR16_DEVLOG(val[0]) << 4;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dlog->size = ntohl(cmd.memsize_devlog);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Retrieve various parameters that are of interest to the driver. The device
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * has been initialized by the firmware at this point.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaget_params__post_init(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint32_t param[7], val[7];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct fw_caps_config_cmd caps;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[0] = FW_PARAM_PFVF(IQFLINT_START);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[1] = FW_PARAM_PFVF(EQ_START);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[2] = FW_PARAM_PFVF(FILTER_START);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[3] = FW_PARAM_PFVF(FILTER_END);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to query parameters (post_init): %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* LINTED: E_ASSIGN_NARROW_CONV */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->sge.iq_start = val[0];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->sge.eq_start = val[1];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.ftid_base = val[2];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.nftids = val[3] - val[2] + 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* get capabilites */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(&caps, sizeof (caps));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana F_FW_CMD_REQUEST | F_FW_CMD_READ);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana caps.cfvalid_to_len16 = htonl(FW_LEN16(caps));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof (caps), &caps);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to get card capabilities: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (caps.toecaps != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* query offload-related parameters */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[0] = FW_PARAM_DEV(NTID);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[1] = FW_PARAM_PFVF(SERVER_START);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[2] = FW_PARAM_PFVF(SERVER_END);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[3] = FW_PARAM_PFVF(TDDP_START);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[4] = FW_PARAM_PFVF(TDDP_END);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana param[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to query TOE parameters: %d.\n", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.ntids = val[0];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.natids = min(sc->tids.ntids / 2, MAX_ATIDS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.stid_base = val[1];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->tids.nstids = val[2] - val[1] + 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->vres.ddp.start = val[3];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->vres.ddp.size = val[4] - val[3] + 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.ofldq_wr_cred = val[5];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.offload = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* These are finalized by FW initialization, load their values now */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana val[0] = t4_read_reg(sc, A_TP_TIMER_RESOLUTION);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.tp.tre = G_TIMERRESOLUTION(val[0]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->params.tp.dack_re = G_DELAYEDACKRESOLUTION(val[0]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_read_mtu_tbl(sc, sc->params.mtus, NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* TODO: verify */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic void
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanasetup_memwin(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pci_regspec_t *data;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t n;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uintptr_t bar0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, sc->dip,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana DDI_PROP_DONTPASS, "assigned-addresses", (int **)&data, &n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to lookup \"assigned-addresses\" property: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n /= sizeof (*data);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bar0 = ((uint64_t)data[0].pci_phys_mid << 32) | data[0].pci_phys_low;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_free(data);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN, 0),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (bar0 + MEMWIN0_BASE) | V_BIR(0) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_WINDOW(ilog2(MEMWIN0_APERTURE) - 10));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN, 1),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (bar0 + MEMWIN1_BASE) | V_BIR(0) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_WINDOW(ilog2(MEMWIN1_APERTURE) - 10));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN, 2),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (bar0 + MEMWIN2_BASE) | V_BIR(0) |
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_WINDOW(ilog2(MEMWIN2_APERTURE) - 10));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Reads the named property and fills up the "data" array (which has at least
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * "count" elements). We first try and lookup the property for our dev_t and
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * then retry with DDI_DEV_T_ANY if it's not found.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Returns non-zero if the property was found and "data" has been updated.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaprop_lookup_int_array(struct adapter *sc, char *name, int *data, uint_t count)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_info_t *dip = sc->dip;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_t dev = sc->dev;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, *d;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t i, n;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_lookup_int_array(dev, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana name, &d, &n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == DDI_PROP_SUCCESS)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto found;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_PROP_NOT_FOUND) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to lookup property %s for minor %d: %d.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana name, getminor(dev), rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana name, &d, &n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == DDI_PROP_SUCCESS)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto found;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_PROP_NOT_FOUND) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to lookup property %s: %d.", name, rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanafound:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n > count) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "property %s has too many elements (%d), ignoring extras",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana name, n);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < n && i < count; i++)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data[i] = d[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_free(d);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaprop_lookup_int(struct adapter *sc, char *name, int defval)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_prop_get_int(sc->dev, sc->dip, DDI_PROP_DONTPASS, name, -1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != -1)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ddi_prop_get_int(DDI_DEV_T_ANY, sc->dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana name, defval));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanainit_driver_props(struct adapter *sc, struct driver_properties *p)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_t dev = sc->dev;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana dev_info_t *dip = sc->dip;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i, *data;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t tmr[SGE_NTIMERS] = {5, 10, 20, 50, 100, 200};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t cnt[SGE_NCOUNTERS] = {1, 8, 16, 32}; /* 63 max */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Holdoff timer
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data = &p->timer_val[0];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < SGE_NTIMERS; i++)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data[i] = tmr[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) prop_lookup_int_array(sc, "holdoff-timer-values", data,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SGE_NTIMERS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < SGE_NTIMERS; i++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int limit = 200U;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (data[i] > limit) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "holdoff timer %d is too high (%d), lowered to %d.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i, data[i], limit);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data[i] = limit;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int_array(dev, dip, "holdoff-timer-values",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data, SGE_NTIMERS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Holdoff packet counter
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data = &p->counter_val[0];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < SGE_NCOUNTERS; i++)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data[i] = cnt[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) prop_lookup_int_array(sc, "holdoff-pkt-counter-values", data,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SGE_NCOUNTERS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < SGE_NCOUNTERS; i++) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int limit = M_THRESHOLD_0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (data[i] > limit) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "holdoff pkt-counter %d is too high (%d), "
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "lowered to %d.", i, data[i], limit);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data[i] = limit;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int_array(dev, dip, "holdoff-pkt-counter-values",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana data, SGE_NCOUNTERS);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Maximum # of tx and rx queues to use for each 10G and 1G port.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_ntxq_10g = prop_lookup_int(sc, "max-ntxq-10G-port", 8);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-ntxq-10G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_ntxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nrxq_10g = prop_lookup_int(sc, "max-nrxq-10G-port", 8);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-nrxq-10G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nrxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_ntxq_1g = prop_lookup_int(sc, "max-ntxq-1G-port", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-ntxq-1G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_ntxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nrxq_1g = prop_lookup_int(sc, "max-nrxq-1G-port", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-nrxq-1G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nrxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldtxq_10g = prop_lookup_int(sc, "max-nofldtxq-10G-port", 8);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-ntxq-10G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldtxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldrxq_10g = prop_lookup_int(sc, "max-nofldrxq-10G-port", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-nrxq-10G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldrxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldtxq_1g = prop_lookup_int(sc, "max-nofldtxq-1G-port", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-ntxq-1G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldtxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldrxq_1g = prop_lookup_int(sc, "max-nofldrxq-1G-port", 1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "max-nrxq-1G-port",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->max_nofldrxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Holdoff parameters for 10G and 1G ports.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->tmr_idx_10g = prop_lookup_int(sc, "holdoff-timer-idx-10G", 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "holdoff-timer-idx-10G",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->tmr_idx_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->pktc_idx_10g = prop_lookup_int(sc, "holdoff-pktc-idx-10G", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "holdoff-pktc-idx-10G",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->pktc_idx_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->tmr_idx_1g = prop_lookup_int(sc, "holdoff-timer-idx-1G", 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "holdoff-timer-idx-1G",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->tmr_idx_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->pktc_idx_1g = prop_lookup_int(sc, "holdoff-pktc-idx-1G", 2);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "holdoff-pktc-idx-1G",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->pktc_idx_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Size (number of entries) of each tx and rx queue.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i = prop_lookup_int(sc, "qsize-txq", TX_EQ_QSIZE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->qsize_txq = max(i, 128);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (p->qsize_txq != i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "using %d instead of %d as the tx queue size",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->qsize_txq, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "qsize-txq", p->qsize_txq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana i = prop_lookup_int(sc, "qsize-rxq", RX_IQ_QSIZE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->qsize_rxq = max(i, 128);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (p->qsize_rxq & 7)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->qsize_rxq--;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (p->qsize_rxq != i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "using %d instead of %d as the rx queue size",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->qsize_rxq, i);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "qsize-rxq", p->qsize_rxq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Interrupt types allowed.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Bits 0, 1, 2 = INTx, MSI, MSI-X respectively. See sys/ddi_intr.h
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana p->intr_types = prop_lookup_int(sc, "interrupt-types",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana DDI_INTR_TYPE_MSIX | DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_FIXED);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_update_int(dev, dip, "interrupt-types", p->intr_types);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Forwarded interrupt queues. Create this property to force the driver
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * to use forwarded interrupt queues.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (ddi_prop_exists(dev, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "interrupt-forwarding") != 0 ||
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "interrupt-forwarding") != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana UNIMPLEMENTED();
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_create(dev, dip, DDI_PROP_CANSLEEP,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "interrupt-forwarding", NULL, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaremove_extra_props(struct adapter *sc, int n10g, int n1g)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n10g == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip, "max-ntxq-10G-port");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip, "max-nrxq-10G-port");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "holdoff-timer-idx-10G");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "holdoff-pktc-idx-10G");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n1g == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip, "max-ntxq-1G-port");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip, "max-nrxq-1G-port");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "holdoff-timer-idx-1G");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_prop_remove(sc->dev, sc->dip, "holdoff-pktc-idx-1G");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanacfg_itype_and_nqueues(struct adapter *sc, int n10g, int n1g,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct intrs_and_queues *iaq)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct driver_properties *p = &sc->props;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, itype, itypes, navail, nc, nrxq10g, nrxq1g, n;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int nofldrxq10g = 0, nofldrxq1g = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana bzero(iaq, sizeof (*iaq));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana nc = ncpus; /* our snapshot of the number of CPUs */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->ntxq10g = min(nc, p->max_ntxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->ntxq1g = min(nc, p->max_ntxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nrxq10g = nrxq10g = min(nc, p->max_nrxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nrxq1g = nrxq1g = min(nc, p->max_nrxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldtxq10g = min(nc, p->max_nofldtxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldtxq1g = min(nc, p->max_nofldtxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldrxq10g = nofldrxq10g = min(nc, p->max_nofldrxq_10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldrxq1g = nofldrxq1g = min(nc, p->max_nofldrxq_1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_intr_get_supported_types(sc->dip, &itypes);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to determine supported interrupt types: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (itype = DDI_INTR_TYPE_MSIX; itype; itype >>= 1) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(itype == DDI_INTR_TYPE_MSIX ||
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana itype == DDI_INTR_TYPE_MSI ||
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana itype == DDI_INTR_TYPE_FIXED);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if ((itype & itypes & p->intr_types) == 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue; /* not supported or not allowed */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana navail = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ddi_intr_get_navail(sc->dip, itype, &navail);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS || navail == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to get # of interrupts for type %d: %d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana itype, rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue; /* carry on */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->intr_type = itype;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#if MAC_VERSION == 1
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->ntxq10g = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->ntxq1g = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (navail == 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana continue;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Best option: an interrupt vector for errors, one for the
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * firmware event queue, and one each for each rxq (NIC as well
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * as offload).
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq = T4_EXTRA_INTR;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n10g * (nrxq10g + nofldrxq10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n1g * (nrxq1g + nofldrxq1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (iaq->nirq <= navail &&
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (itype != DDI_INTR_TYPE_MSI || ISP2(iaq->nirq))) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->intr_fwd = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto allocate;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Second best option: an interrupt vector for errors, one for
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * the firmware event queue, and one each for either NIC or
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * offload rxq's.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq = T4_EXTRA_INTR;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n10g * max(nrxq10g, nofldrxq10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n1g * max(nrxq1g, nofldrxq1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (iaq->nirq <= navail &&
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (itype != DDI_INTR_TYPE_MSI || ISP2(iaq->nirq))) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->intr_fwd = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto allocate;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Next best option: an interrupt vector for errors, one for the
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * firmware event queue, and at least one per port. At this
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * point we know we'll have to downsize nrxq or nofldrxq to fit
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * what's available to us.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq = T4_EXTRA_INTR;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n10g + n1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (iaq->nirq <= navail) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int leftover = navail - iaq->nirq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n10g > 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int target = max(nrxq10g, nofldrxq10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (n < target && leftover >= n10g) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana leftover -= n10g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n10g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nrxq10g = min(n, nrxq10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldrxq10g = min(n, nofldrxq10g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (n1g > 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int target = max(nrxq1g, nofldrxq1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (n < target && leftover >= n1g) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana leftover -= n1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq += n1g;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana n++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nrxq1g = min(n, nrxq1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldrxq1g = min(n, nofldrxq1g);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (itype != DDI_INTR_TYPE_MSI || ISP2(iaq->nirq)) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->intr_fwd = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto allocate;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Least desirable option: one interrupt vector for everything.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nirq = iaq->nrxq10g = iaq->nrxq1g = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->nofldrxq10g = iaq->nofldrxq1g = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iaq->intr_fwd = 1;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaallocate:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "failed to find a usable interrupt type. supported=%d, allowed=%d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana itypes, p->intr_types);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (DDI_FAILURE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaadd_child_node(struct adapter *sc, int idx)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (idx < 0 || idx >= sc->params.nports)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = sc->port[idx];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ENODEV); /* t4_port_init failed earlier */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PORT_LOCK(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi->dip != NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = 0; /* EEXIST really, but then bus_config fails */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ndi_devi_alloc(sc->dip, T4_PORT_NAME, DEVI_SID_NODEID, &pi->dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != DDI_SUCCESS || pi->dip == NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ENOMEM;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_set_parent_data(pi->dip, pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ndi_devi_bind_driver(pi->dip, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PORT_UNLOCK(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaremove_child_node(struct adapter *sc, int idx)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (idx < 0 || idx >= sc->params.nports)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi = sc->port[idx];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi == NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ENODEV);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PORT_LOCK(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi->dip == NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ENODEV;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ndi_devi_free(pi->dip);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->dip = NULL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PORT_UNLOCK(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define KS_UINIT(x) kstat_named_init(&kstatp->x, #x, KSTAT_DATA_ULONG)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define KS_CINIT(x) kstat_named_init(&kstatp->x, #x, KSTAT_DATA_CHAR)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define KS_U_SET(x, y) kstatp->x.value.ul = (y)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define KS_C_SET(x, ...) \
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) snprintf(kstatp->x.value.c, 16, __VA_ARGS__)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * t4nex:X:config
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastruct t4_kstats {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t chip_ver;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t fw_vers;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t tp_vers;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t driver_version;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t serial_number;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t ec_level;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t id;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t bus_type;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t bus_width;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t bus_speed;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t core_clock;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t port_cnt;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t port_type;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t pci_vendor_id;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_named_t pci_device_id;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana};
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic kstat_t *
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanasetup_kstats(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_t *ksp;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct t4_kstats *kstatp;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int ndata;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct pci_params *p = &sc->params.pci;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct vpd_params *v = &sc->params.vpd;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint16_t pci_vendor, pci_device;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ndata = sizeof (struct t4_kstats) / sizeof (kstat_named_t);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ksp = kstat_create(T4_NEXUS_NAME, ddi_get_instance(sc->dip), "config",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "nexus", KSTAT_TYPE_NAMED, ndata, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (ksp == NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN, "failed to initialize kstats.");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstatp = (struct t4_kstats *)ksp->ks_data;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_UINIT(chip_ver);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(fw_vers);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(tp_vers);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(driver_version);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(serial_number);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(ec_level);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(bus_type);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(bus_width);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(bus_speed);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_UINIT(core_clock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_UINIT(port_cnt);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(port_type);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(pci_vendor_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_CINIT(pci_device_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_U_SET(chip_ver, sc->params.rev);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(fw_vers, "%d.%d.%d.%d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(tp_vers, "%d.%d.%d.%d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MAJOR(sc->params.tp_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MINOR(sc->params.tp_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_MICRO(sc->params.tp_vers),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana G_FW_HDR_FW_VER_BUILD(sc->params.tp_vers));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(driver_version, DRV_VERSION);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(serial_number, "%s", v->sn);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(ec_level, "%s", v->ec);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(id, "%s", v->id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(bus_type, "pci-express");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(bus_width, "x%d lanes", p->width);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(bus_speed, "%d", p->speed);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_U_SET(core_clock, v->cclk);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_U_SET(port_cnt, sc->params.nports);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg2(sc, PCI_CONF_VENID, &pci_vendor);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(pci_vendor_id, "0x%x", pci_vendor);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg2(sc, PCI_CONF_DEVID, &pci_device);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(pci_device_id, "0x%x", pci_device);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#define PSTR(pi) (pi ? (is_10G_port(pi) ? "10G" : "1G") : "-")
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana KS_C_SET(port_type, "%s/%s/%s/%s", PSTR(sc->port[0]), PSTR(sc->port[1]),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana PSTR(sc->port[2]), PSTR(sc->port[3]));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#undef PSTR
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Do NOT set ksp->ks_update. These kstats do not change. */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* Install the kstat */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ksp->ks_private = (void *)sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kstat_install(ksp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ksp);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaadapter_full_init(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i, rc = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = t4_setup_adapter_queues(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->intr_cap & DDI_INTR_FLAG_BLOCK)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_block_enable(sc->intr_handle, sc->intr_count);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < sc->intr_count; i++)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_enable(sc->intr_handle[i]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_intr_enable(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags |= FULL_INIT_DONE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* TODO: wrong place to enable TOE capability */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (is_offload(sc) != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_port(sc, i) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct port_info *pi = sc->port[i];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = toe_capability(pi, 1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "Failed to activate toe capability: %d",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = 0; /* not a fatal error */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) adapter_full_uninit(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaadapter_full_uninit(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i, rc = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->intr_cap & DDI_INTR_FLAG_BLOCK)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_block_disable(sc->intr_handle, sc->intr_count);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for (i = 0; i < sc->intr_count; i++)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) ddi_intr_disable(sc->intr_handle[i]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = t4_teardown_adapter_queues(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana sc->flags &= ~FULL_INIT_DONE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaport_full_init(struct port_info *pi)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc = pi->adapter;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint16_t *rss;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_rxq *rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc, i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT((pi->flags & PORT_INIT_DONE) == 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Allocate tx/rx/fl queues for this port.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = t4_setup_port_queues(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done; /* error message displayed already */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Setup RSS for this port.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rss = kmem_zalloc(pi->nrxq * sizeof (*rss), KM_SLEEP);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_rxq(pi, i, rxq) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rss[i] = rxq->iq.abs_id;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = -t4_config_rss_range(sc, sc->mbox, pi->viid, 0,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->rss_size, rss, pi->nrxq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana kmem_free(rss, pi->nrxq * sizeof (*rss));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_WARN, "rss_config failed: %d", rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->flags |= PORT_INIT_DONE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) port_full_uninit(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Idempotent.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaport_full_uninit(struct port_info *pi)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(pi->flags & PORT_INIT_DONE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) t4_teardown_port_queues(pi);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->flags &= ~PORT_INIT_DONE;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaenable_port_queues(struct port_info *pi)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc = pi->adapter;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_iq *iq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_rxq *rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_ofld_rxq *ofld_rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(pi->flags & PORT_INIT_DONE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * TODO: whatever was queued up after we set iq->state to IQS_DISABLED
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * back in disable_port_queues will be processed now, after an unbounded
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * delay. This can't be good.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_ofld_rxq(pi, i, ofld_rxq) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iq = &ofld_rxq->iq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (atomic_cas_uint(&iq->state, IQS_DISABLED, IQS_IDLE) !=
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana IQS_DISABLED)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana panic("%s: iq %p wasn't disabled", __func__,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void *)iq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_SEINTARM(iq->intr_params) | V_INGRESSQID(iq->cntxt_id));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_rxq(pi, i, rxq) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana iq = &rxq->iq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (atomic_cas_uint(&iq->state, IQS_DISABLED, IQS_IDLE) !=
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana IQS_DISABLED)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana panic("%s: iq %p wasn't disabled", __func__,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void *) iq);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana V_SEINTARM(iq->intr_params) | V_INGRESSQID(iq->cntxt_id));
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadisable_port_queues(struct port_info *pi)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int i;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc = pi->adapter;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_rxq *rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct sge_ofld_rxq *ofld_rxq;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(pi->flags & PORT_INIT_DONE);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * TODO: need proper implementation for all tx queues (ctrl, eth, ofld).
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_ofld_rxq(pi, i, ofld_rxq) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (atomic_cas_uint(&ofld_rxq->iq.state, IQS_IDLE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana IQS_DISABLED) != IQS_IDLE)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana msleep(1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_rxq(pi, i, rxq) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (atomic_cas_uint(&rxq->iq.state, IQS_IDLE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana IQS_DISABLED) != IQS_IDLE)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana msleep(1);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&sc->sfl_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_ofld_rxq(pi, i, ofld_rxq)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ofld_rxq->fl.flags |= FL_DOOMED;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana for_each_rxq(pi, i, rxq)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rxq->fl.flags |= FL_DOOMED;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&sc->sfl_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /* TODO: need to wait for all fl's to be removed from sc->sfl */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_fatal_err(struct adapter *sc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_set_reg_field(sc, A_SGE_CONTROL, F_GLOBALENABLE, 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_intr_disable(sc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(sc->dip, CE_WARN,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "encountered fatal error, adapter stopped.");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_os_find_pci_capability(struct adapter *sc, int cap)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint16_t stat;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint8_t cap_ptr, cap_id;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg2(sc, PCI_CONF_STAT, &stat);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if ((stat & PCI_STAT_CAP) == 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0); /* does not implement capabilities */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg1(sc, PCI_CONF_CAP_PTR, &cap_ptr);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana while (cap_ptr) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg1(sc, cap_ptr + PCI_CAP_ID, &cap_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (cap_id == cap)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (cap_ptr); /* found */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana t4_os_pci_read_cfg1(sc, cap_ptr + PCI_CAP_NEXT_PTR, &cap_ptr);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0); /* not found */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_os_portmod_changed(const struct adapter *sc, int idx)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana static const char *mod_str[] = {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM"
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana };
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana const struct port_info *pi = sc->port[idx];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_NOTE, "transceiver unplugged.");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "unknown transceiver inserted.\n");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_NOTE,
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana "unsupported transceiver inserted.\n");
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else if (pi->mod_type > 0 && pi->mod_type < ARRAY_SIZE(mod_str))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_NOTE, "%s transceiver inserted.\n",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mod_str[pi->mod_type]);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana else
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana cxgb_printf(pi->dip, CE_NOTE, "transceiver (type %d) inserted.",
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana pi->mod_type);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/* ARGSUSED */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanacpl_not_handled(struct sge_iq *iq, const struct rss_header *rss, mblk_t *m)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (m != NULL)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana freemsg(m);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_register_cpl_handler(struct adapter *sc, int opcode, cpl_handler_t h)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana uint_t *loc, new;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (opcode >= ARRAY_SIZE(sc->cpl_handler))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (EINVAL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana new = (uint_t)(unsigned long) (h ? h : cpl_not_handled);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana loc = (uint_t *)&sc->cpl_handler[opcode];
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana (void) atomic_swap_uint(loc, new);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#ifndef TCP_OFFLOAD_DISABLE
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanatoe_capability(struct port_info *pi, int enable)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc = pi->adapter;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (!is_offload(sc))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (ENODEV);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (enable != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (isset(&sc->offload_map, pi->port_id) != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->offload_map == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = activate_uld(sc, ULD_TOM, &sc->tom);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana setbit(&sc->offload_map, pi->port_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana } else {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (!isset(&sc->offload_map, pi->port_id))
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana clrbit(&sc->offload_map, pi->port_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (sc->offload_map == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = deactivate_uld(&sc->tom);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc != 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana setbit(&sc->offload_map, pi->port_id);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana/*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * Add an upper layer driver to the global list.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_register_uld(struct uld_info *ui)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct uld_info *u;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_FOREACH(u, &t4_uld_list, link) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (u->uld_id == ui->uld_id) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = EEXIST;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_INSERT_HEAD(&t4_uld_list, ui, link);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ui->refcount = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaint
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_unregister_uld(struct uld_info *ui)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc = EINVAL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct uld_info *u;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_FOREACH(u, &t4_uld_list, link) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (u == ui) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (ui->refcount > 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = EBUSY;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_REMOVE(&t4_uld_list, ui, uld_info, link);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = 0;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanaactivate_uld(struct adapter *sc, int id, struct uld_softc *usc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc = EAGAIN;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct uld_info *ui;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_FOREACH(ui, &t4_uld_list, link) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (ui->uld_id == id) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = ui->attach(sc, &usc->softc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(usc->softc != NULL);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ui->refcount++;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana usc->uld = ui;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanastatic int
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadeactivate_uld(struct uld_softc *usc)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana int rc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (usc->uld == NULL || usc->softc == NULL) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = EINVAL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana goto done;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana rc = usc->uld->detach(usc->softc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana if (rc == 0) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana ASSERT(usc->uld->refcount > 0);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana usc->uld->refcount--;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana usc->uld = NULL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana usc->softc = NULL;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanadone:
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_uld_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana return (rc);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanavoid
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushanat4_iterate(void (*func)(int, void *), void *arg)
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana{
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana struct adapter *sc;
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_enter(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana SLIST_FOREACH(sc, &t4_adapter_list, link) {
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana /*
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * func should not make any assumptions about what state sc is
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana * in - the only guarantee is that sc->sc_lock is a valid lock.
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana */
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana func(ddi_get_instance(sc->dip), arg);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana }
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana mutex_exit(&t4_adapter_list_lock);
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana}
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana
56b2bdd1f04d465cfe4a95b88ae5cba5884154e4Gireesh Nagabhushana#endif