oce_main.c revision 5b9d3151a4426af9ad6ef2c2a178f13476b884b3
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Emulex. All rights reserved.
* Use is subject to license terms.
*/
/*
* Source file containing the implementation of the driver entry points
* and related helper functions
*/
#include <oce_impl.h>
#include <oce_stat.h>
#include <oce_ioctl.h>
#define ATTACH_DEV_INIT 0x1
#define ATTACH_FM_INIT 0x2
#define ATTACH_LOCK_INIT 0x4
#define ATTACH_PCI_INIT 0x8
#define ATTACH_HW_INIT 0x10
#define ATTACH_SETUP_TXRX 0x20
#define ATTACH_SETUP_ADAP 0x40
#define ATTACH_SETUP_INTR 0x80
#define ATTACH_STAT_INIT 0x100
#define ATTACH_MAC_REG 0x200
/* ---[ globals and externs ]-------------------------------------------- */
const char oce_ident_string[] = OCE_IDENT_STRING;
const char oce_mod_name[] = OCE_MOD_NAME;
/* driver properties */
static const char flow_control[] = "flow_control";
static const char mtu_prop_name[] = "oce_default_mtu";
static const char tx_ring_size_name[] = "tx_ring_size";
static const char tx_bcopy_limit_name[] = "tx_bcopy_limit";
static const char rx_bcopy_limit_name[] = "rx_bcopy_limit";
static const char rx_frag_size_name[] = "rx_frag_size";
static const char rx_max_bufs_name[] = "rx_max_bufs";
static const char fm_cap_name[] = "oce_fm_capability";
static const char log_level_name[] = "oce_log_level";
static const char lso_capable_name[] = "lso_capable";
static const char rx_pkt_per_intr_name[] = "rx_pkts_per_intr";
static const char tx_reclaim_threshold_name[] = "tx_reclaim_threshold";
static const char rx_rings_name[] = "max_rx_rings";
static const char tx_rings_name[] = "max_tx_rings";
/* --[ static function prototypes here ]------------------------------- */
static struct cb_ops oce_cb_ops = {
nulldev, /* cb_open */
nulldev, /* cb_close */
nodev, /* cb_strategy */
nodev, /* cb_print */
nodev, /* cb_dump */
nodev, /* cb_read */
nodev, /* cb_write */
nodev, /* cb_ioctl */
nodev, /* cb_devmap */
nodev, /* cb_mmap */
nodev, /* cb_segmap */
nochpoll, /* cb_chpoll */
ddi_prop_op, /* cb_prop_op */
NULL, /* cb_stream */
D_MP, /* cb_flag */
CB_REV, /* cb_rev */
nodev, /* cb_aread */
nodev /* cb_awrite */
};
static struct dev_ops oce_dev_ops = {
DEVO_REV, /* devo_rev */
0, /* devo_refcnt */
NULL, /* devo_getinfo */
NULL, /* devo_identify */
nulldev, /* devo_probe */
oce_attach, /* devo_attach */
oce_detach, /* devo_detach */
nodev, /* devo_reset */
&oce_cb_ops, /* devo_cb_ops */
NULL, /* devo_bus_ops */
nodev, /* devo_power */
oce_quiesce /* devo_quiesce */
};
&mod_driverops, /* Type of module. This one is a driver */
(char *)oce_ident_string, /* Description string */
&oce_dev_ops, /* driver ops */
};
static struct modlinkage oce_mod_linkage = {
};
static mac_callbacks_t oce_mac_cb = {
OCE_M_CB_FLAGS, /* mc_callbacks */
oce_m_stat, /* mc_getstat */
oce_m_start, /* mc_start */
oce_m_stop, /* mc_stop */
oce_m_promiscuous, /* mc_setpromisc */
oce_m_multicast, /* mc_multicast */
oce_m_unicast, /* mc_unicast */
oce_m_send, /* mc_tx */
NULL, /* mc_reserve */
oce_m_ioctl, /* mc_ioctl */
oce_m_getcap, /* mc_getcapab */
NULL, /* open */
NULL, /* close */
oce_m_setprop, /* set properties */
oce_m_getprop, /* get properties */
oce_m_propinfo /* properties info */
};
extern char *oce_priv_props[];
/* Module Init */
int
{
} /* _info */
int
_init(void)
{
int ret = 0;
/* install the module */
if (ret) {
}
return (ret);
} /* _init */
int
_fini(void)
{
int ret = 0;
/* remove the module */
if (ret != 0) {
return (ret);
}
return (ret);
} /* _fini */
static int
{
int ret = 0;
switch (cmd) {
case DDI_RESUME:
return (oce_resume(dip));
default:
return (DDI_FAILURE);
case DDI_ATTACH:
break;
}
/* allocate dev */
/* populate the dev structure */
/* get the parameters */
/*
* set the ddi driver private data pointer. This is
* sent to all mac callback entry points
*/
/* setup PCI bars */
if (ret != DDI_SUCCESS) {
"PCI initialization failed with %d", ret);
goto attach_fail;
}
if (ret != DDI_SUCCESS) {
"Interrupt setup failed with %d", ret);
goto attach_fail;
}
/* initialize locks */
/* HW init */
if (ret != DDI_SUCCESS) {
"HW initialization failed with %d", ret);
goto attach_fail;
}
if (ret != DDI_SUCCESS) {
"Failed to init rings");
goto attach_fail;
}
if (ret != DDI_SUCCESS) {
"Failed to setup adapter");
goto attach_fail;
}
if (ret != DDI_SUCCESS) {
"kstat setup Failed with %d", ret);
goto attach_fail;
}
/* mac_register_t */
"MAC_VERSION = 0x%x", MAC_VERSION);
"MAC allocation Failed");
goto attach_fail;
}
/*
* fill the mac structure before calling mac_register
*/
"Driver Private structure = 0x%p", (void *)dev);
/* now register with GLDv3 */
/* regardless of the status, free mac_register */
if (ret != DDI_SUCCESS) {
"MAC registration failed :0x%x", ret);
goto attach_fail;
}
/* correct link status only after start */
"ATTACH SUCCESS");
return (DDI_SUCCESS);
return (DDI_FAILURE);
} /* oce_attach */
static int
{
int pcnt = 0;
int qid;
return (DDI_FAILURE);
}
"Detaching driver: cmd = 0x%x", cmd);
switch (cmd) {
default:
return (DDI_FAILURE);
case DDI_SUSPEND:
return (oce_suspend(dip));
case DDI_DETACH:
break;
} /* switch cmd */
/* Fail detach if MAC unregister is unsuccessfule */
"Failed to unregister MAC ");
}
/* check if the detach is called with out stopping */
} else
/*
* Wait for Packets sent up to be freed
*/
if (pcnt != 0) {
"%d Pending Buffers Detach failed", pcnt);
return (DDI_FAILURE);
}
}
return (DDI_SUCCESS);
} /* oce_detach */
static int
{
int ret = DDI_SUCCESS;
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
return (ret);
}
static int
{
/* Suspend the card */
/* stop the adapter */
}
return (DDI_SUCCESS);
} /* oce_suspend */
static int
{
int ret;
/* get the dev pointer from dip */
return (DDI_SUCCESS);
}
if (ret != DDI_SUCCESS) {
return (DDI_FAILURE);
}
if (ret != DDI_SUCCESS) {
return (DDI_FAILURE);
}
}
return (ret);
} /* oce_resume */
static void
{
/* initialize locks */
} /* oce_init_locks */
static void
{
} /* oce_destroy_locks */
static void
{
if (state & ATTACH_MAC_REG) {
}
if (state & ATTACH_STAT_INIT) {
}
if (state & ATTACH_SETUP_ADAP) {
}
if (state & ATTACH_SETUP_TXRX) {
}
if (state & ATTACH_HW_INIT) {
}
if (state & ATTACH_LOCK_INIT) {
}
if (state & ATTACH_SETUP_INTR) {
(void) oce_teardown_intr(dev);
}
if (state & ATTACH_PCI_INIT) {
}
if (state & ATTACH_FM_INIT) {
}
if (state & ATTACH_DEV_INIT) {
}
} /* oce_unconfigure */
static void
{
/*
* Allowed values for the driver parameters. If all values in a range
* is allowed, the the array has only one value.
*/
END};
/* non tunables */
/* configurable parameters */
mod_mask = 0;
}
severity = 0;
}
} /* oce_get_params */
static int
{
int value = 0;
int i = 0;
while (values[i] != 0xdeadface) {
break;
}
i++;
}
if ((i != 0) && (values[i] == 0xdeadface)) {
}
return (value);
}