111374SSukumar.Swaminathan@Sun.COM /*
211374SSukumar.Swaminathan@Sun.COM * CDDL HEADER START
311374SSukumar.Swaminathan@Sun.COM *
411374SSukumar.Swaminathan@Sun.COM * The contents of this file are subject to the terms of the
511374SSukumar.Swaminathan@Sun.COM * Common Development and Distribution License (the "License").
611374SSukumar.Swaminathan@Sun.COM * You may not use this file except in compliance with the License.
711374SSukumar.Swaminathan@Sun.COM *
811374SSukumar.Swaminathan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911374SSukumar.Swaminathan@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011374SSukumar.Swaminathan@Sun.COM * See the License for the specific language governing permissions
1111374SSukumar.Swaminathan@Sun.COM * and limitations under the License.
1211374SSukumar.Swaminathan@Sun.COM *
1311374SSukumar.Swaminathan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411374SSukumar.Swaminathan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511374SSukumar.Swaminathan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611374SSukumar.Swaminathan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711374SSukumar.Swaminathan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811374SSukumar.Swaminathan@Sun.COM *
1911374SSukumar.Swaminathan@Sun.COM * CDDL HEADER END
2011374SSukumar.Swaminathan@Sun.COM */
2111374SSukumar.Swaminathan@Sun.COM
2211374SSukumar.Swaminathan@Sun.COM /*
2312043SSukumar.Swaminathan@Sun.COM * Copyright 2010 Emulex. All rights reserved.
2411374SSukumar.Swaminathan@Sun.COM * Use is subject to license terms.
2511374SSukumar.Swaminathan@Sun.COM */
2611374SSukumar.Swaminathan@Sun.COM
2711374SSukumar.Swaminathan@Sun.COM /*
2811374SSukumar.Swaminathan@Sun.COM * Source file containing the implementation of the driver entry points
2911374SSukumar.Swaminathan@Sun.COM * and related helper functions
3011374SSukumar.Swaminathan@Sun.COM */
3111374SSukumar.Swaminathan@Sun.COM
3211374SSukumar.Swaminathan@Sun.COM #include <oce_impl.h>
3311374SSukumar.Swaminathan@Sun.COM #include <oce_stat.h>
3411374SSukumar.Swaminathan@Sun.COM #include <oce_ioctl.h>
3511374SSukumar.Swaminathan@Sun.COM
3611374SSukumar.Swaminathan@Sun.COM #define ATTACH_DEV_INIT 0x1
3711374SSukumar.Swaminathan@Sun.COM #define ATTACH_FM_INIT 0x2
3811723SSukumar.Swaminathan@Sun.COM #define ATTACH_LOCK_INIT 0x4
3911723SSukumar.Swaminathan@Sun.COM #define ATTACH_PCI_INIT 0x8
4011723SSukumar.Swaminathan@Sun.COM #define ATTACH_HW_INIT 0x10
4111723SSukumar.Swaminathan@Sun.COM #define ATTACH_SETUP_TXRX 0x20
4211723SSukumar.Swaminathan@Sun.COM #define ATTACH_SETUP_ADAP 0x40
43*13020SSukumar.Swaminathan@Sun.COM #define ATTACH_SETUP_INTR 0x80
4411374SSukumar.Swaminathan@Sun.COM #define ATTACH_STAT_INIT 0x100
4511374SSukumar.Swaminathan@Sun.COM #define ATTACH_MAC_REG 0x200
4611374SSukumar.Swaminathan@Sun.COM
4711374SSukumar.Swaminathan@Sun.COM /* ---[ globals and externs ]-------------------------------------------- */
4811374SSukumar.Swaminathan@Sun.COM const char oce_ident_string[] = OCE_IDENT_STRING;
4911374SSukumar.Swaminathan@Sun.COM const char oce_mod_name[] = OCE_MOD_NAME;
5011374SSukumar.Swaminathan@Sun.COM
5111374SSukumar.Swaminathan@Sun.COM /* driver properties */
52*13020SSukumar.Swaminathan@Sun.COM static const char flow_control[] = "flow_control";
53*13020SSukumar.Swaminathan@Sun.COM static const char mtu_prop_name[] = "oce_default_mtu";
54*13020SSukumar.Swaminathan@Sun.COM static const char tx_ring_size_name[] = "tx_ring_size";
55*13020SSukumar.Swaminathan@Sun.COM static const char tx_bcopy_limit_name[] = "tx_bcopy_limit";
56*13020SSukumar.Swaminathan@Sun.COM static const char rx_bcopy_limit_name[] = "rx_bcopy_limit";
57*13020SSukumar.Swaminathan@Sun.COM static const char rx_frag_size_name[] = "rx_frag_size";
58*13020SSukumar.Swaminathan@Sun.COM static const char rx_max_bufs_name[] = "rx_max_bufs";
59*13020SSukumar.Swaminathan@Sun.COM static const char fm_cap_name[] = "oce_fm_capability";
60*13020SSukumar.Swaminathan@Sun.COM static const char log_level_name[] = "oce_log_level";
61*13020SSukumar.Swaminathan@Sun.COM static const char lso_capable_name[] = "lso_capable";
62*13020SSukumar.Swaminathan@Sun.COM static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr";
63*13020SSukumar.Swaminathan@Sun.COM static const char tx_reclaim_threshold_name[] = "tx_reclaim_threshold";
64*13020SSukumar.Swaminathan@Sun.COM static const char rx_rings_name[] = "max_rx_rings";
65*13020SSukumar.Swaminathan@Sun.COM static const char tx_rings_name[] = "max_tx_rings";
6611374SSukumar.Swaminathan@Sun.COM
6711374SSukumar.Swaminathan@Sun.COM /* --[ static function prototypes here ]------------------------------- */
6811374SSukumar.Swaminathan@Sun.COM static int oce_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd);
6911374SSukumar.Swaminathan@Sun.COM static int oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
7011374SSukumar.Swaminathan@Sun.COM static int oce_quiesce(dev_info_t *dip);
7111374SSukumar.Swaminathan@Sun.COM static int oce_suspend(dev_info_t *dip);
7211374SSukumar.Swaminathan@Sun.COM static int oce_resume(dev_info_t *dip);
7311374SSukumar.Swaminathan@Sun.COM static void oce_unconfigure(struct oce_dev *dev);
7411374SSukumar.Swaminathan@Sun.COM static void oce_init_locks(struct oce_dev *dev);
7511374SSukumar.Swaminathan@Sun.COM static void oce_destroy_locks(struct oce_dev *dev);
7611374SSukumar.Swaminathan@Sun.COM static void oce_get_params(struct oce_dev *dev);
77*13020SSukumar.Swaminathan@Sun.COM static int oce_get_prop(struct oce_dev *dev, char *propname, int minval,
78*13020SSukumar.Swaminathan@Sun.COM int maxval, int defval, uint32_t *values);
7911374SSukumar.Swaminathan@Sun.COM
8011374SSukumar.Swaminathan@Sun.COM static struct cb_ops oce_cb_ops = {
8111374SSukumar.Swaminathan@Sun.COM nulldev, /* cb_open */
8211374SSukumar.Swaminathan@Sun.COM nulldev, /* cb_close */
8311374SSukumar.Swaminathan@Sun.COM nodev, /* cb_strategy */
8411374SSukumar.Swaminathan@Sun.COM nodev, /* cb_print */
8511374SSukumar.Swaminathan@Sun.COM nodev, /* cb_dump */
8611374SSukumar.Swaminathan@Sun.COM nodev, /* cb_read */
8711374SSukumar.Swaminathan@Sun.COM nodev, /* cb_write */
8811374SSukumar.Swaminathan@Sun.COM nodev, /* cb_ioctl */
8911374SSukumar.Swaminathan@Sun.COM nodev, /* cb_devmap */
9011374SSukumar.Swaminathan@Sun.COM nodev, /* cb_mmap */
9111374SSukumar.Swaminathan@Sun.COM nodev, /* cb_segmap */
9211374SSukumar.Swaminathan@Sun.COM nochpoll, /* cb_chpoll */
9311374SSukumar.Swaminathan@Sun.COM ddi_prop_op, /* cb_prop_op */
9411374SSukumar.Swaminathan@Sun.COM NULL, /* cb_stream */
9511374SSukumar.Swaminathan@Sun.COM D_MP, /* cb_flag */
9611374SSukumar.Swaminathan@Sun.COM CB_REV, /* cb_rev */
9711374SSukumar.Swaminathan@Sun.COM nodev, /* cb_aread */
9811374SSukumar.Swaminathan@Sun.COM nodev /* cb_awrite */
9911374SSukumar.Swaminathan@Sun.COM };
10011374SSukumar.Swaminathan@Sun.COM
10111374SSukumar.Swaminathan@Sun.COM static struct dev_ops oce_dev_ops = {
10211374SSukumar.Swaminathan@Sun.COM DEVO_REV, /* devo_rev */
10311374SSukumar.Swaminathan@Sun.COM 0, /* devo_refcnt */
10411374SSukumar.Swaminathan@Sun.COM NULL, /* devo_getinfo */
10511374SSukumar.Swaminathan@Sun.COM NULL, /* devo_identify */
10611374SSukumar.Swaminathan@Sun.COM nulldev, /* devo_probe */
10711374SSukumar.Swaminathan@Sun.COM oce_attach, /* devo_attach */
10811374SSukumar.Swaminathan@Sun.COM oce_detach, /* devo_detach */
10911374SSukumar.Swaminathan@Sun.COM nodev, /* devo_reset */
11011374SSukumar.Swaminathan@Sun.COM &oce_cb_ops, /* devo_cb_ops */
11111374SSukumar.Swaminathan@Sun.COM NULL, /* devo_bus_ops */
11211374SSukumar.Swaminathan@Sun.COM nodev, /* devo_power */
11311374SSukumar.Swaminathan@Sun.COM oce_quiesce /* devo_quiesce */
11411374SSukumar.Swaminathan@Sun.COM };
11511374SSukumar.Swaminathan@Sun.COM
11611374SSukumar.Swaminathan@Sun.COM static struct modldrv oce_drv = {
11711374SSukumar.Swaminathan@Sun.COM &mod_driverops, /* Type of module. This one is a driver */
11811374SSukumar.Swaminathan@Sun.COM (char *)oce_ident_string, /* Description string */
11911374SSukumar.Swaminathan@Sun.COM &oce_dev_ops, /* driver ops */
12011374SSukumar.Swaminathan@Sun.COM };
12111374SSukumar.Swaminathan@Sun.COM
12211374SSukumar.Swaminathan@Sun.COM static struct modlinkage oce_mod_linkage = {
12311374SSukumar.Swaminathan@Sun.COM MODREV_1, &oce_drv, NULL
12411374SSukumar.Swaminathan@Sun.COM };
12511374SSukumar.Swaminathan@Sun.COM
12611878SVenu.Iyer@Sun.COM #define OCE_M_CB_FLAGS (MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP | \
12711878SVenu.Iyer@Sun.COM MC_PROPINFO)
12811374SSukumar.Swaminathan@Sun.COM static mac_callbacks_t oce_mac_cb = {
12911374SSukumar.Swaminathan@Sun.COM OCE_M_CB_FLAGS, /* mc_callbacks */
13011374SSukumar.Swaminathan@Sun.COM oce_m_stat, /* mc_getstat */
13111374SSukumar.Swaminathan@Sun.COM oce_m_start, /* mc_start */
13211374SSukumar.Swaminathan@Sun.COM oce_m_stop, /* mc_stop */
13311374SSukumar.Swaminathan@Sun.COM oce_m_promiscuous, /* mc_setpromisc */
13411374SSukumar.Swaminathan@Sun.COM oce_m_multicast, /* mc_multicast */
13511374SSukumar.Swaminathan@Sun.COM oce_m_unicast, /* mc_unicast */
13611374SSukumar.Swaminathan@Sun.COM oce_m_send, /* mc_tx */
13712043SSukumar.Swaminathan@Sun.COM NULL, /* mc_reserve */
13811374SSukumar.Swaminathan@Sun.COM oce_m_ioctl, /* mc_ioctl */
13911374SSukumar.Swaminathan@Sun.COM oce_m_getcap, /* mc_getcapab */
14011374SSukumar.Swaminathan@Sun.COM NULL, /* open */
14111374SSukumar.Swaminathan@Sun.COM NULL, /* close */
14211374SSukumar.Swaminathan@Sun.COM oce_m_setprop, /* set properties */
14311878SVenu.Iyer@Sun.COM oce_m_getprop, /* get properties */
14411878SVenu.Iyer@Sun.COM oce_m_propinfo /* properties info */
14511374SSukumar.Swaminathan@Sun.COM };
14611374SSukumar.Swaminathan@Sun.COM
14711878SVenu.Iyer@Sun.COM extern char *oce_priv_props[];
14811374SSukumar.Swaminathan@Sun.COM
14911374SSukumar.Swaminathan@Sun.COM /* Module Init */
15011374SSukumar.Swaminathan@Sun.COM int
_info(struct modinfo * modinfop)15111374SSukumar.Swaminathan@Sun.COM _info(struct modinfo *modinfop)
15211374SSukumar.Swaminathan@Sun.COM {
15311374SSukumar.Swaminathan@Sun.COM return (mod_info(&oce_mod_linkage, modinfop));
15411374SSukumar.Swaminathan@Sun.COM } /* _info */
15511374SSukumar.Swaminathan@Sun.COM
15611374SSukumar.Swaminathan@Sun.COM int
_init(void)15711374SSukumar.Swaminathan@Sun.COM _init(void)
15811374SSukumar.Swaminathan@Sun.COM {
15911374SSukumar.Swaminathan@Sun.COM int ret = 0;
16011374SSukumar.Swaminathan@Sun.COM
16111374SSukumar.Swaminathan@Sun.COM /* install the module */
16211374SSukumar.Swaminathan@Sun.COM mac_init_ops(&oce_dev_ops, "oce");
16311374SSukumar.Swaminathan@Sun.COM
16411374SSukumar.Swaminathan@Sun.COM ret = mod_install(&oce_mod_linkage);
16511374SSukumar.Swaminathan@Sun.COM if (ret) {
16611374SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "mod_install failed rval=%x", ret);
16711374SSukumar.Swaminathan@Sun.COM }
16811374SSukumar.Swaminathan@Sun.COM
16911374SSukumar.Swaminathan@Sun.COM return (ret);
17011374SSukumar.Swaminathan@Sun.COM } /* _init */
17111374SSukumar.Swaminathan@Sun.COM
17211374SSukumar.Swaminathan@Sun.COM
17311374SSukumar.Swaminathan@Sun.COM int
_fini(void)17411374SSukumar.Swaminathan@Sun.COM _fini(void)
17511374SSukumar.Swaminathan@Sun.COM {
17611374SSukumar.Swaminathan@Sun.COM int ret = 0;
17711374SSukumar.Swaminathan@Sun.COM /* remove the module */
17811374SSukumar.Swaminathan@Sun.COM ret = mod_remove(&oce_mod_linkage);
17911374SSukumar.Swaminathan@Sun.COM if (ret != 0) {
18011374SSukumar.Swaminathan@Sun.COM return (ret);
18111374SSukumar.Swaminathan@Sun.COM }
18211374SSukumar.Swaminathan@Sun.COM
18311374SSukumar.Swaminathan@Sun.COM mac_fini_ops(&oce_dev_ops);
18411374SSukumar.Swaminathan@Sun.COM
18511374SSukumar.Swaminathan@Sun.COM return (ret);
18611374SSukumar.Swaminathan@Sun.COM } /* _fini */
18711374SSukumar.Swaminathan@Sun.COM
18811374SSukumar.Swaminathan@Sun.COM
18911374SSukumar.Swaminathan@Sun.COM static int
oce_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)19011374SSukumar.Swaminathan@Sun.COM oce_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
19111374SSukumar.Swaminathan@Sun.COM {
19211374SSukumar.Swaminathan@Sun.COM int ret = 0;
19311374SSukumar.Swaminathan@Sun.COM struct oce_dev *dev = NULL;
19411374SSukumar.Swaminathan@Sun.COM mac_register_t *mac;
19511374SSukumar.Swaminathan@Sun.COM
19611374SSukumar.Swaminathan@Sun.COM switch (cmd) {
19711374SSukumar.Swaminathan@Sun.COM case DDI_RESUME:
19811374SSukumar.Swaminathan@Sun.COM return (oce_resume(dip));
19911374SSukumar.Swaminathan@Sun.COM default:
20011374SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
20111374SSukumar.Swaminathan@Sun.COM
20211374SSukumar.Swaminathan@Sun.COM case DDI_ATTACH:
20311374SSukumar.Swaminathan@Sun.COM break;
20411374SSukumar.Swaminathan@Sun.COM }
20511374SSukumar.Swaminathan@Sun.COM
20611374SSukumar.Swaminathan@Sun.COM /* allocate dev */
207*13020SSukumar.Swaminathan@Sun.COM dev = kmem_zalloc(sizeof (struct oce_dev), KM_SLEEP);
20811374SSukumar.Swaminathan@Sun.COM
20911374SSukumar.Swaminathan@Sun.COM /* populate the dev structure */
21011374SSukumar.Swaminathan@Sun.COM dev->dip = dip;
21111374SSukumar.Swaminathan@Sun.COM dev->dev_id = ddi_get_instance(dip);
21211374SSukumar.Swaminathan@Sun.COM dev->suspended = B_FALSE;
21311374SSukumar.Swaminathan@Sun.COM
21411374SSukumar.Swaminathan@Sun.COM /* get the parameters */
21511374SSukumar.Swaminathan@Sun.COM oce_get_params(dev);
21611374SSukumar.Swaminathan@Sun.COM
21711374SSukumar.Swaminathan@Sun.COM /*
21811374SSukumar.Swaminathan@Sun.COM * set the ddi driver private data pointer. This is
21911374SSukumar.Swaminathan@Sun.COM * sent to all mac callback entry points
22011374SSukumar.Swaminathan@Sun.COM */
22111374SSukumar.Swaminathan@Sun.COM ddi_set_driver_private(dip, dev);
22211374SSukumar.Swaminathan@Sun.COM
22311374SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_DEV_INIT;
22411374SSukumar.Swaminathan@Sun.COM
22511374SSukumar.Swaminathan@Sun.COM oce_fm_init(dev);
22611374SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_FM_INIT;
22711374SSukumar.Swaminathan@Sun.COM
22811374SSukumar.Swaminathan@Sun.COM /* setup PCI bars */
22911374SSukumar.Swaminathan@Sun.COM ret = oce_pci_init(dev);
23011374SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
23111374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
23211374SSukumar.Swaminathan@Sun.COM "PCI initialization failed with %d", ret);
23311374SSukumar.Swaminathan@Sun.COM goto attach_fail;
23411374SSukumar.Swaminathan@Sun.COM }
23511374SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_PCI_INIT;
23611374SSukumar.Swaminathan@Sun.COM
237*13020SSukumar.Swaminathan@Sun.COM ret = oce_setup_intr(dev);
238*13020SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
239*13020SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
240*13020SSukumar.Swaminathan@Sun.COM "Interrupt setup failed with %d", ret);
241*13020SSukumar.Swaminathan@Sun.COM goto attach_fail;
242*13020SSukumar.Swaminathan@Sun.COM
243*13020SSukumar.Swaminathan@Sun.COM }
244*13020SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_SETUP_INTR;
245*13020SSukumar.Swaminathan@Sun.COM
246*13020SSukumar.Swaminathan@Sun.COM /* initialize locks */
247*13020SSukumar.Swaminathan@Sun.COM oce_init_locks(dev);
248*13020SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_LOCK_INIT;
249*13020SSukumar.Swaminathan@Sun.COM
250*13020SSukumar.Swaminathan@Sun.COM
25111723SSukumar.Swaminathan@Sun.COM /* HW init */
25211723SSukumar.Swaminathan@Sun.COM ret = oce_hw_init(dev);
25311723SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
25411374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
25511723SSukumar.Swaminathan@Sun.COM "HW initialization failed with %d", ret);
25611374SSukumar.Swaminathan@Sun.COM goto attach_fail;
25711374SSukumar.Swaminathan@Sun.COM }
25811723SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_HW_INIT;
25911374SSukumar.Swaminathan@Sun.COM
26011723SSukumar.Swaminathan@Sun.COM ret = oce_init_txrx(dev);
26111723SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
26211723SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
26311723SSukumar.Swaminathan@Sun.COM "Failed to init rings");
26411374SSukumar.Swaminathan@Sun.COM goto attach_fail;
26511374SSukumar.Swaminathan@Sun.COM }
26611723SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_SETUP_TXRX;
26711374SSukumar.Swaminathan@Sun.COM
26811723SSukumar.Swaminathan@Sun.COM ret = oce_setup_adapter(dev);
26911723SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
27011723SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
27111723SSukumar.Swaminathan@Sun.COM "Failed to setup adapter");
27211374SSukumar.Swaminathan@Sun.COM goto attach_fail;
27311374SSukumar.Swaminathan@Sun.COM }
27411723SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_SETUP_ADAP;
27511374SSukumar.Swaminathan@Sun.COM
27611374SSukumar.Swaminathan@Sun.COM
27711374SSukumar.Swaminathan@Sun.COM ret = oce_stat_init(dev);
27811374SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
27911374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
28011374SSukumar.Swaminathan@Sun.COM "kstat setup Failed with %d", ret);
28111374SSukumar.Swaminathan@Sun.COM goto attach_fail;
28211374SSukumar.Swaminathan@Sun.COM }
28311374SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_STAT_INIT;
28411374SSukumar.Swaminathan@Sun.COM
28511374SSukumar.Swaminathan@Sun.COM /* mac_register_t */
28611374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_NOTE, MOD_CONFIG,
28711374SSukumar.Swaminathan@Sun.COM "MAC_VERSION = 0x%x", MAC_VERSION);
28811374SSukumar.Swaminathan@Sun.COM mac = mac_alloc(MAC_VERSION);
28911374SSukumar.Swaminathan@Sun.COM if (mac == NULL) {
29011374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
29111374SSukumar.Swaminathan@Sun.COM "MAC allocation Failed");
29211374SSukumar.Swaminathan@Sun.COM goto attach_fail;
29311374SSukumar.Swaminathan@Sun.COM }
29411374SSukumar.Swaminathan@Sun.COM /*
29511374SSukumar.Swaminathan@Sun.COM * fill the mac structure before calling mac_register
29611374SSukumar.Swaminathan@Sun.COM */
29711374SSukumar.Swaminathan@Sun.COM mac->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
29811374SSukumar.Swaminathan@Sun.COM mac->m_driver = dev;
29911374SSukumar.Swaminathan@Sun.COM mac->m_dip = dip;
30011374SSukumar.Swaminathan@Sun.COM mac->m_src_addr = dev->mac_addr;
30111374SSukumar.Swaminathan@Sun.COM mac->m_callbacks = &oce_mac_cb;
30211374SSukumar.Swaminathan@Sun.COM mac->m_min_sdu = 0;
30311374SSukumar.Swaminathan@Sun.COM mac->m_max_sdu = dev->mtu;
30411374SSukumar.Swaminathan@Sun.COM mac->m_margin = VLAN_TAGSZ;
30511374SSukumar.Swaminathan@Sun.COM mac->m_priv_props = oce_priv_props;
30611374SSukumar.Swaminathan@Sun.COM
30711374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_NOTE, MOD_CONFIG,
30811374SSukumar.Swaminathan@Sun.COM "Driver Private structure = 0x%p", (void *)dev);
30911374SSukumar.Swaminathan@Sun.COM
31011374SSukumar.Swaminathan@Sun.COM /* now register with GLDv3 */
31111374SSukumar.Swaminathan@Sun.COM ret = mac_register(mac, (mac_handle_t *)&dev->mac_handle);
31211374SSukumar.Swaminathan@Sun.COM /* regardless of the status, free mac_register */
31311374SSukumar.Swaminathan@Sun.COM mac_free(mac);
31411374SSukumar.Swaminathan@Sun.COM mac = NULL;
31511374SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
31611374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
31711374SSukumar.Swaminathan@Sun.COM "MAC registration failed :0x%x", ret);
31811374SSukumar.Swaminathan@Sun.COM goto attach_fail;
31911374SSukumar.Swaminathan@Sun.COM
32011374SSukumar.Swaminathan@Sun.COM }
32111374SSukumar.Swaminathan@Sun.COM
32211374SSukumar.Swaminathan@Sun.COM /* correct link status only after start */
323*13020SSukumar.Swaminathan@Sun.COM dev->link_status = LINK_STATE_UNKNOWN;
324*13020SSukumar.Swaminathan@Sun.COM mac_link_update(dev->mac_handle, dev->link_status);
32511374SSukumar.Swaminathan@Sun.COM
32611374SSukumar.Swaminathan@Sun.COM dev->attach_state |= ATTACH_MAC_REG;
32711374SSukumar.Swaminathan@Sun.COM dev->state |= STATE_INIT;
32812043SSukumar.Swaminathan@Sun.COM
32911374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_NOTE, MOD_CONFIG, "%s",
33011374SSukumar.Swaminathan@Sun.COM "ATTACH SUCCESS");
33111374SSukumar.Swaminathan@Sun.COM
33211374SSukumar.Swaminathan@Sun.COM return (DDI_SUCCESS);
33311374SSukumar.Swaminathan@Sun.COM
33411374SSukumar.Swaminathan@Sun.COM attach_fail:
33511374SSukumar.Swaminathan@Sun.COM oce_unconfigure(dev);
33611374SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
33711374SSukumar.Swaminathan@Sun.COM } /* oce_attach */
33811374SSukumar.Swaminathan@Sun.COM
33911374SSukumar.Swaminathan@Sun.COM static int
oce_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)34011374SSukumar.Swaminathan@Sun.COM oce_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
34111374SSukumar.Swaminathan@Sun.COM {
34211723SSukumar.Swaminathan@Sun.COM struct oce_dev *dev;
34311723SSukumar.Swaminathan@Sun.COM int pcnt = 0;
344*13020SSukumar.Swaminathan@Sun.COM int qid;
34511374SSukumar.Swaminathan@Sun.COM
34611723SSukumar.Swaminathan@Sun.COM dev = ddi_get_driver_private(dip);
34711723SSukumar.Swaminathan@Sun.COM if (dev == NULL) {
34811723SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
34911723SSukumar.Swaminathan@Sun.COM }
35011374SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_NOTE, MOD_CONFIG,
35111374SSukumar.Swaminathan@Sun.COM "Detaching driver: cmd = 0x%x", cmd);
35211374SSukumar.Swaminathan@Sun.COM
35311374SSukumar.Swaminathan@Sun.COM switch (cmd) {
35411723SSukumar.Swaminathan@Sun.COM default:
35511723SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
35611374SSukumar.Swaminathan@Sun.COM case DDI_SUSPEND:
35711374SSukumar.Swaminathan@Sun.COM return (oce_suspend(dip));
35811723SSukumar.Swaminathan@Sun.COM case DDI_DETACH:
35911723SSukumar.Swaminathan@Sun.COM break;
36011723SSukumar.Swaminathan@Sun.COM } /* switch cmd */
36111374SSukumar.Swaminathan@Sun.COM
36211723SSukumar.Swaminathan@Sun.COM /* Fail detach if MAC unregister is unsuccessfule */
36311723SSukumar.Swaminathan@Sun.COM if (mac_unregister(dev->mac_handle) != 0) {
36411723SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG, "%s",
36511723SSukumar.Swaminathan@Sun.COM "Failed to unregister MAC ");
36611723SSukumar.Swaminathan@Sun.COM }
36711723SSukumar.Swaminathan@Sun.COM dev->attach_state &= ~ATTACH_MAC_REG;
36811723SSukumar.Swaminathan@Sun.COM
36911723SSukumar.Swaminathan@Sun.COM /* check if the detach is called with out stopping */
37011723SSukumar.Swaminathan@Sun.COM DEV_LOCK(dev);
37111723SSukumar.Swaminathan@Sun.COM if (dev->state & STATE_MAC_STARTED) {
37211723SSukumar.Swaminathan@Sun.COM dev->state &= ~STATE_MAC_STARTED;
37311723SSukumar.Swaminathan@Sun.COM oce_stop(dev);
37411723SSukumar.Swaminathan@Sun.COM DEV_UNLOCK(dev);
37511723SSukumar.Swaminathan@Sun.COM } else
37611723SSukumar.Swaminathan@Sun.COM DEV_UNLOCK(dev);
37711723SSukumar.Swaminathan@Sun.COM
37811723SSukumar.Swaminathan@Sun.COM /*
37911723SSukumar.Swaminathan@Sun.COM * Wait for Packets sent up to be freed
38011723SSukumar.Swaminathan@Sun.COM */
381*13020SSukumar.Swaminathan@Sun.COM for (qid = 0; qid < dev->rx_rings; qid++) {
382*13020SSukumar.Swaminathan@Sun.COM pcnt = oce_rx_pending(dev, dev->rq[qid], DEFAULT_DRAIN_TIME);
383*13020SSukumar.Swaminathan@Sun.COM if (pcnt != 0) {
384*13020SSukumar.Swaminathan@Sun.COM oce_log(dev, CE_WARN, MOD_CONFIG,
385*13020SSukumar.Swaminathan@Sun.COM "%d Pending Buffers Detach failed", pcnt);
386*13020SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
387*13020SSukumar.Swaminathan@Sun.COM }
38811723SSukumar.Swaminathan@Sun.COM }
38911723SSukumar.Swaminathan@Sun.COM oce_unconfigure(dev);
39011723SSukumar.Swaminathan@Sun.COM
39111374SSukumar.Swaminathan@Sun.COM return (DDI_SUCCESS);
39211374SSukumar.Swaminathan@Sun.COM } /* oce_detach */
39311374SSukumar.Swaminathan@Sun.COM
39411374SSukumar.Swaminathan@Sun.COM static int
oce_quiesce(dev_info_t * dip)39511374SSukumar.Swaminathan@Sun.COM oce_quiesce(dev_info_t *dip)
39611374SSukumar.Swaminathan@Sun.COM {
39711374SSukumar.Swaminathan@Sun.COM int ret = DDI_SUCCESS;
39811374SSukumar.Swaminathan@Sun.COM struct oce_dev *dev = ddi_get_driver_private(dip);
39911374SSukumar.Swaminathan@Sun.COM
40011374SSukumar.Swaminathan@Sun.COM if (dev == NULL) {
40111374SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
40211374SSukumar.Swaminathan@Sun.COM }
40311374SSukumar.Swaminathan@Sun.COM if (dev->suspended) {
40411374SSukumar.Swaminathan@Sun.COM return (DDI_SUCCESS);
40511374SSukumar.Swaminathan@Sun.COM }
40611374SSukumar.Swaminathan@Sun.COM
40711723SSukumar.Swaminathan@Sun.COM oce_chip_di(dev);
40811374SSukumar.Swaminathan@Sun.COM
40911374SSukumar.Swaminathan@Sun.COM ret = oce_reset_fun(dev);
41011374SSukumar.Swaminathan@Sun.COM
41111374SSukumar.Swaminathan@Sun.COM return (ret);
41211374SSukumar.Swaminathan@Sun.COM }
41311374SSukumar.Swaminathan@Sun.COM
41411374SSukumar.Swaminathan@Sun.COM static int
oce_suspend(dev_info_t * dip)41511374SSukumar.Swaminathan@Sun.COM oce_suspend(dev_info_t *dip)
41611374SSukumar.Swaminathan@Sun.COM {
41711374SSukumar.Swaminathan@Sun.COM struct oce_dev *dev = ddi_get_driver_private(dip);
41811374SSukumar.Swaminathan@Sun.COM
41911374SSukumar.Swaminathan@Sun.COM mutex_enter(&dev->dev_lock);
42011374SSukumar.Swaminathan@Sun.COM /* Suspend the card */
42111374SSukumar.Swaminathan@Sun.COM dev->suspended = B_TRUE;
42211374SSukumar.Swaminathan@Sun.COM /* stop the adapter */
42311374SSukumar.Swaminathan@Sun.COM if (dev->state & STATE_MAC_STARTED) {
42411374SSukumar.Swaminathan@Sun.COM oce_stop(dev);
42511723SSukumar.Swaminathan@Sun.COM oce_unsetup_adapter(dev);
42611374SSukumar.Swaminathan@Sun.COM }
42711374SSukumar.Swaminathan@Sun.COM dev->state &= ~STATE_MAC_STARTED;
42811374SSukumar.Swaminathan@Sun.COM mutex_exit(&dev->dev_lock);
42911374SSukumar.Swaminathan@Sun.COM return (DDI_SUCCESS);
43011374SSukumar.Swaminathan@Sun.COM } /* oce_suspend */
43111374SSukumar.Swaminathan@Sun.COM
43211374SSukumar.Swaminathan@Sun.COM static int
oce_resume(dev_info_t * dip)43311374SSukumar.Swaminathan@Sun.COM oce_resume(dev_info_t *dip)
43411374SSukumar.Swaminathan@Sun.COM {
43511374SSukumar.Swaminathan@Sun.COM struct oce_dev *dev;
43611374SSukumar.Swaminathan@Sun.COM int ret;
43711374SSukumar.Swaminathan@Sun.COM
43811374SSukumar.Swaminathan@Sun.COM /* get the dev pointer from dip */
43911374SSukumar.Swaminathan@Sun.COM dev = ddi_get_driver_private(dip);
44011374SSukumar.Swaminathan@Sun.COM mutex_enter(&dev->dev_lock);
44111374SSukumar.Swaminathan@Sun.COM if (!dev->suspended) {
44211374SSukumar.Swaminathan@Sun.COM mutex_exit(&dev->dev_lock);
44311374SSukumar.Swaminathan@Sun.COM return (DDI_SUCCESS);
44411374SSukumar.Swaminathan@Sun.COM }
445*13020SSukumar.Swaminathan@Sun.COM if (!(dev->state & STATE_MAC_STARTED)) {
44611723SSukumar.Swaminathan@Sun.COM ret = oce_setup_adapter(dev);
44711723SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
44811723SSukumar.Swaminathan@Sun.COM mutex_exit(&dev->dev_lock);
44911723SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
45011723SSukumar.Swaminathan@Sun.COM }
45111374SSukumar.Swaminathan@Sun.COM ret = oce_start(dev);
45211374SSukumar.Swaminathan@Sun.COM if (ret != DDI_SUCCESS) {
45311374SSukumar.Swaminathan@Sun.COM mutex_exit(&dev->dev_lock);
45411374SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
45511374SSukumar.Swaminathan@Sun.COM }
45611374SSukumar.Swaminathan@Sun.COM }
45711374SSukumar.Swaminathan@Sun.COM dev->suspended = B_FALSE;
45811374SSukumar.Swaminathan@Sun.COM dev->state |= STATE_MAC_STARTED;
45911374SSukumar.Swaminathan@Sun.COM mutex_exit(&dev->dev_lock);
46011374SSukumar.Swaminathan@Sun.COM return (ret);
46111374SSukumar.Swaminathan@Sun.COM } /* oce_resume */
46211374SSukumar.Swaminathan@Sun.COM
46311374SSukumar.Swaminathan@Sun.COM static void
oce_init_locks(struct oce_dev * dev)46411374SSukumar.Swaminathan@Sun.COM oce_init_locks(struct oce_dev *dev)
46511374SSukumar.Swaminathan@Sun.COM {
46611374SSukumar.Swaminathan@Sun.COM /* initialize locks */
46711374SSukumar.Swaminathan@Sun.COM mutex_init(&dev->dev_lock, NULL, MUTEX_DRIVER,
46811374SSukumar.Swaminathan@Sun.COM DDI_INTR_PRI(dev->intr_pri));
46911374SSukumar.Swaminathan@Sun.COM mutex_init(&dev->bmbx_lock, NULL, MUTEX_DRIVER,
47011374SSukumar.Swaminathan@Sun.COM DDI_INTR_PRI(dev->intr_pri));
47111374SSukumar.Swaminathan@Sun.COM } /* oce_init_locks */
47211374SSukumar.Swaminathan@Sun.COM
47311374SSukumar.Swaminathan@Sun.COM static void
oce_destroy_locks(struct oce_dev * dev)47411374SSukumar.Swaminathan@Sun.COM oce_destroy_locks(struct oce_dev *dev)
47511374SSukumar.Swaminathan@Sun.COM {
47611374SSukumar.Swaminathan@Sun.COM mutex_destroy(&dev->dev_lock);
47711374SSukumar.Swaminathan@Sun.COM mutex_destroy(&dev->bmbx_lock);
47811374SSukumar.Swaminathan@Sun.COM } /* oce_destroy_locks */
47911374SSukumar.Swaminathan@Sun.COM
48011374SSukumar.Swaminathan@Sun.COM static void
oce_unconfigure(struct oce_dev * dev)48111374SSukumar.Swaminathan@Sun.COM oce_unconfigure(struct oce_dev *dev)
48211374SSukumar.Swaminathan@Sun.COM {
48311374SSukumar.Swaminathan@Sun.COM uint32_t state = dev->attach_state;
48411374SSukumar.Swaminathan@Sun.COM
48511374SSukumar.Swaminathan@Sun.COM if (state & ATTACH_MAC_REG) {
48611374SSukumar.Swaminathan@Sun.COM (void) mac_unregister(dev->mac_handle);
48711374SSukumar.Swaminathan@Sun.COM }
48811374SSukumar.Swaminathan@Sun.COM if (state & ATTACH_STAT_INIT) {
48911374SSukumar.Swaminathan@Sun.COM oce_stat_fini(dev);
49011374SSukumar.Swaminathan@Sun.COM }
49111723SSukumar.Swaminathan@Sun.COM if (state & ATTACH_SETUP_ADAP) {
49211723SSukumar.Swaminathan@Sun.COM oce_unsetup_adapter(dev);
49311723SSukumar.Swaminathan@Sun.COM }
49411723SSukumar.Swaminathan@Sun.COM
49511723SSukumar.Swaminathan@Sun.COM if (state & ATTACH_SETUP_TXRX) {
49611723SSukumar.Swaminathan@Sun.COM oce_fini_txrx(dev);
49711723SSukumar.Swaminathan@Sun.COM }
49811723SSukumar.Swaminathan@Sun.COM
49911723SSukumar.Swaminathan@Sun.COM if (state & ATTACH_HW_INIT) {
50011723SSukumar.Swaminathan@Sun.COM oce_hw_fini(dev);
50111374SSukumar.Swaminathan@Sun.COM }
502*13020SSukumar.Swaminathan@Sun.COM if (state & ATTACH_LOCK_INIT) {
503*13020SSukumar.Swaminathan@Sun.COM oce_destroy_locks(dev);
504*13020SSukumar.Swaminathan@Sun.COM }
505*13020SSukumar.Swaminathan@Sun.COM
506*13020SSukumar.Swaminathan@Sun.COM if (state & ATTACH_SETUP_INTR) {
507*13020SSukumar.Swaminathan@Sun.COM (void) oce_teardown_intr(dev);
508*13020SSukumar.Swaminathan@Sun.COM }
50911374SSukumar.Swaminathan@Sun.COM if (state & ATTACH_PCI_INIT) {
51011374SSukumar.Swaminathan@Sun.COM oce_pci_fini(dev);
51111374SSukumar.Swaminathan@Sun.COM }
51211374SSukumar.Swaminathan@Sun.COM if (state & ATTACH_FM_INIT) {
51311374SSukumar.Swaminathan@Sun.COM oce_fm_fini(dev);
51411374SSukumar.Swaminathan@Sun.COM }
51511374SSukumar.Swaminathan@Sun.COM if (state & ATTACH_DEV_INIT) {
51611374SSukumar.Swaminathan@Sun.COM ddi_set_driver_private(dev->dip, NULL);
51711374SSukumar.Swaminathan@Sun.COM kmem_free(dev, sizeof (struct oce_dev));
51811374SSukumar.Swaminathan@Sun.COM }
51911374SSukumar.Swaminathan@Sun.COM } /* oce_unconfigure */
52011374SSukumar.Swaminathan@Sun.COM
52111374SSukumar.Swaminathan@Sun.COM static void
oce_get_params(struct oce_dev * dev)52211374SSukumar.Swaminathan@Sun.COM oce_get_params(struct oce_dev *dev)
52311374SSukumar.Swaminathan@Sun.COM {
52411374SSukumar.Swaminathan@Sun.COM uint32_t log_level;
52511374SSukumar.Swaminathan@Sun.COM uint16_t mod_mask;
52611374SSukumar.Swaminathan@Sun.COM uint16_t severity;
527*13020SSukumar.Swaminathan@Sun.COM /*
528*13020SSukumar.Swaminathan@Sun.COM * Allowed values for the driver parameters. If all values in a range
529*13020SSukumar.Swaminathan@Sun.COM * is allowed, the the array has only one value.
530*13020SSukumar.Swaminathan@Sun.COM */
531*13020SSukumar.Swaminathan@Sun.COM uint32_t fc_values[] = {OCE_FC_NONE, OCE_FC_TX, OCE_FC_RX,
532*13020SSukumar.Swaminathan@Sun.COM OCE_DEFAULT_FLOW_CONTROL, END};
533*13020SSukumar.Swaminathan@Sun.COM uint32_t mtu_values[] = {OCE_MIN_MTU, OCE_MAX_MTU, END};
534*13020SSukumar.Swaminathan@Sun.COM uint32_t tx_rs_values[] = {SIZE_256, SIZE_512, SIZE_1K, SIZE_2K, END};
535*13020SSukumar.Swaminathan@Sun.COM uint32_t tx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
536*13020SSukumar.Swaminathan@Sun.COM SIZE_2K, END};
537*13020SSukumar.Swaminathan@Sun.COM uint32_t rx_bcl_values[] = {SIZE_128, SIZE_256, SIZE_512, SIZE_1K,
538*13020SSukumar.Swaminathan@Sun.COM SIZE_2K, END};
539*13020SSukumar.Swaminathan@Sun.COM uint32_t rq_fs_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
540*13020SSukumar.Swaminathan@Sun.COM uint32_t rq_mb_values[] = {SIZE_2K, SIZE_4K, SIZE_8K, END};
541*13020SSukumar.Swaminathan@Sun.COM uint32_t lso_capable_values[] = {0, 1, END};
542*13020SSukumar.Swaminathan@Sun.COM uint32_t fm_caps_values[] = {DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY,
543*13020SSukumar.Swaminathan@Sun.COM END};
544*13020SSukumar.Swaminathan@Sun.COM uint32_t tx_rt_values[] = {END};
545*13020SSukumar.Swaminathan@Sun.COM uint32_t rx_ppi_values[] = {END};
546*13020SSukumar.Swaminathan@Sun.COM uint32_t rx_rings_values[] = {END};
547*13020SSukumar.Swaminathan@Sun.COM uint32_t tx_rings_values[] = {END};
548*13020SSukumar.Swaminathan@Sun.COM uint32_t log_level_values[] = {END};
54911374SSukumar.Swaminathan@Sun.COM
55011374SSukumar.Swaminathan@Sun.COM /* non tunables */
55111374SSukumar.Swaminathan@Sun.COM dev->rx_ring_size = OCE_DEFAULT_RX_RING_SIZE;
55211374SSukumar.Swaminathan@Sun.COM
55311374SSukumar.Swaminathan@Sun.COM /* configurable parameters */
554*13020SSukumar.Swaminathan@Sun.COM dev->flow_control = oce_get_prop(dev, (char *)flow_control, OCE_FC_NONE,
555*13020SSukumar.Swaminathan@Sun.COM OCE_DEFAULT_FLOW_CONTROL, OCE_DEFAULT_FLOW_CONTROL, fc_values);
55611374SSukumar.Swaminathan@Sun.COM
557*13020SSukumar.Swaminathan@Sun.COM dev->mtu = oce_get_prop(dev, (char *)mtu_prop_name, OCE_MIN_MTU,
558*13020SSukumar.Swaminathan@Sun.COM OCE_MAX_MTU, OCE_MIN_MTU, mtu_values);
559*13020SSukumar.Swaminathan@Sun.COM
560*13020SSukumar.Swaminathan@Sun.COM dev->tx_ring_size = oce_get_prop(dev, (char *)tx_ring_size_name,
561*13020SSukumar.Swaminathan@Sun.COM SIZE_256, SIZE_2K, OCE_DEFAULT_TX_RING_SIZE, tx_rs_values);
562*13020SSukumar.Swaminathan@Sun.COM
563*13020SSukumar.Swaminathan@Sun.COM dev->tx_bcopy_limit = oce_get_prop(dev, (char *)tx_bcopy_limit_name,
564*13020SSukumar.Swaminathan@Sun.COM SIZE_128, SIZE_2K, OCE_DEFAULT_TX_BCOPY_LIMIT, tx_bcl_values);
56511374SSukumar.Swaminathan@Sun.COM
566*13020SSukumar.Swaminathan@Sun.COM dev->rx_bcopy_limit = oce_get_prop(dev, (char *)rx_bcopy_limit_name,
567*13020SSukumar.Swaminathan@Sun.COM SIZE_128, SIZE_2K, OCE_DEFAULT_RX_BCOPY_LIMIT, rx_bcl_values);
568*13020SSukumar.Swaminathan@Sun.COM
569*13020SSukumar.Swaminathan@Sun.COM dev->rq_frag_size = oce_get_prop(dev, (char *)rx_frag_size_name,
570*13020SSukumar.Swaminathan@Sun.COM SIZE_2K, SIZE_8K, OCE_RQ_BUF_SIZE, rq_fs_values);
571*13020SSukumar.Swaminathan@Sun.COM
572*13020SSukumar.Swaminathan@Sun.COM dev->rq_max_bufs = oce_get_prop(dev, (char *)rx_max_bufs_name, SIZE_2K,
573*13020SSukumar.Swaminathan@Sun.COM SIZE_8K, OCE_RQ_NUM_BUFFERS, rq_mb_values);
57411374SSukumar.Swaminathan@Sun.COM
575*13020SSukumar.Swaminathan@Sun.COM dev->lso_capable = oce_get_prop(dev, (char *)lso_capable_name, 0,
576*13020SSukumar.Swaminathan@Sun.COM 1, 1, lso_capable_values);
577*13020SSukumar.Swaminathan@Sun.COM
578*13020SSukumar.Swaminathan@Sun.COM dev->fm_caps = oce_get_prop(dev, (char *)fm_cap_name,
579*13020SSukumar.Swaminathan@Sun.COM DDI_FM_NOT_CAPABLE, OCE_FM_CAPABILITY, OCE_FM_CAPABILITY,
580*13020SSukumar.Swaminathan@Sun.COM fm_caps_values);
581*13020SSukumar.Swaminathan@Sun.COM
582*13020SSukumar.Swaminathan@Sun.COM dev->tx_reclaim_threshold = oce_get_prop(dev,
583*13020SSukumar.Swaminathan@Sun.COM (char *)tx_reclaim_threshold_name, 0, dev->tx_ring_size/2,
584*13020SSukumar.Swaminathan@Sun.COM OCE_DEFAULT_TX_RECLAIM_THRESHOLD, tx_rt_values);
58511374SSukumar.Swaminathan@Sun.COM
586*13020SSukumar.Swaminathan@Sun.COM dev->rx_pkt_per_intr = oce_get_prop(dev, (char *)rx_pkt_per_intr_name,
587*13020SSukumar.Swaminathan@Sun.COM 0, dev->rx_ring_size/2, OCE_DEFAULT_RX_PKT_PER_INTR, rx_ppi_values);
588*13020SSukumar.Swaminathan@Sun.COM
589*13020SSukumar.Swaminathan@Sun.COM dev->rx_rings = oce_get_prop(dev, (char *)rx_rings_name,
590*13020SSukumar.Swaminathan@Sun.COM OCE_DEFAULT_RQS, OCE_MAX_RQS, OCE_DEFAULT_RQS, rx_rings_values);
59111374SSukumar.Swaminathan@Sun.COM
592*13020SSukumar.Swaminathan@Sun.COM dev->tx_rings = oce_get_prop(dev, (char *)tx_rings_name,
593*13020SSukumar.Swaminathan@Sun.COM OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, OCE_DEFAULT_WQS, tx_rings_values);
59411374SSukumar.Swaminathan@Sun.COM
595*13020SSukumar.Swaminathan@Sun.COM log_level = oce_get_prop(dev, (char *)log_level_name, 0,
596*13020SSukumar.Swaminathan@Sun.COM OCE_MAX_LOG_SETTINGS, OCE_DEFAULT_LOG_SETTINGS, log_level_values);
597*13020SSukumar.Swaminathan@Sun.COM
59811374SSukumar.Swaminathan@Sun.COM severity = (uint16_t)(log_level & 0xffff);
59911374SSukumar.Swaminathan@Sun.COM mod_mask = (uint16_t)(log_level >> 16);
60011374SSukumar.Swaminathan@Sun.COM if (mod_mask > MOD_ISR) {
60111374SSukumar.Swaminathan@Sun.COM mod_mask = 0;
60211374SSukumar.Swaminathan@Sun.COM }
60311374SSukumar.Swaminathan@Sun.COM if (severity > CE_IGNORE) {
60411374SSukumar.Swaminathan@Sun.COM severity = 0;
60511374SSukumar.Swaminathan@Sun.COM }
60611374SSukumar.Swaminathan@Sun.COM
60711374SSukumar.Swaminathan@Sun.COM dev->mod_mask = mod_mask;
60811374SSukumar.Swaminathan@Sun.COM dev->severity = severity;
60911374SSukumar.Swaminathan@Sun.COM } /* oce_get_params */
610*13020SSukumar.Swaminathan@Sun.COM
611*13020SSukumar.Swaminathan@Sun.COM static int
oce_get_prop(struct oce_dev * dev,char * propname,int minval,int maxval,int defval,uint32_t * values)612*13020SSukumar.Swaminathan@Sun.COM oce_get_prop(struct oce_dev *dev, char *propname, int minval, int maxval,
613*13020SSukumar.Swaminathan@Sun.COM int defval, uint32_t *values)
614*13020SSukumar.Swaminathan@Sun.COM {
615*13020SSukumar.Swaminathan@Sun.COM int value = 0;
616*13020SSukumar.Swaminathan@Sun.COM int i = 0;
617*13020SSukumar.Swaminathan@Sun.COM
618*13020SSukumar.Swaminathan@Sun.COM value = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
619*13020SSukumar.Swaminathan@Sun.COM DDI_PROP_DONTPASS, propname, defval);
620*13020SSukumar.Swaminathan@Sun.COM
621*13020SSukumar.Swaminathan@Sun.COM if (value > maxval)
622*13020SSukumar.Swaminathan@Sun.COM value = maxval;
623*13020SSukumar.Swaminathan@Sun.COM
624*13020SSukumar.Swaminathan@Sun.COM if (value < minval)
625*13020SSukumar.Swaminathan@Sun.COM value = minval;
626*13020SSukumar.Swaminathan@Sun.COM
627*13020SSukumar.Swaminathan@Sun.COM while (values[i] != 0xdeadface) {
628*13020SSukumar.Swaminathan@Sun.COM if (values[i] == value) {
629*13020SSukumar.Swaminathan@Sun.COM break;
630*13020SSukumar.Swaminathan@Sun.COM }
631*13020SSukumar.Swaminathan@Sun.COM i++;
632*13020SSukumar.Swaminathan@Sun.COM }
633*13020SSukumar.Swaminathan@Sun.COM
634*13020SSukumar.Swaminathan@Sun.COM if ((i != 0) && (values[i] == 0xdeadface)) {
635*13020SSukumar.Swaminathan@Sun.COM value = defval;
636*13020SSukumar.Swaminathan@Sun.COM }
637*13020SSukumar.Swaminathan@Sun.COM
638*13020SSukumar.Swaminathan@Sun.COM return (value);
639*13020SSukumar.Swaminathan@Sun.COM }
640